UNPKG

@neo-one/smart-contract-compiler

Version:

NEO•ONE TypeScript smart contract compiler.

374 lines (373 loc) 63.1 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const ts_utils_1 = require("@neo-one/ts-utils"); const utils_1 = require("@neo-one/utils"); const lodash_1 = tslib_1.__importDefault(require("lodash")); const typescript_1 = tslib_1.__importDefault(require("typescript")); const utils_2 = require("../../utils"); const types_1 = require("./types"); const getMember = (sym, name) => ts_utils_1.tsUtils.symbol.getMemberOrThrow(sym, name); const getExportOrMember = (sym, name) => { const member = ts_utils_1.tsUtils.symbol.getMember(sym, name); return member === undefined ? ts_utils_1.tsUtils.symbol.getExportOrThrow(sym, name) : member; }; const findNonNull = (value) => value.find((val) => val !== undefined); const throwIfNull = (value) => { if (value == undefined) { throw new Error('Something went wrong.'); } return value; }; class Builtins { constructor(context) { this.context = context; this.builtinMembers = new Map(); this.allBuiltinMembers = new Map(); this.builtinInterfaces = new Map(); this.builtinValues = new Map(); this.builtinOverrides = new Map(); this.memoized = utils_2.createMemoized(); } isBuiltinSymbol(symbol) { return symbol !== undefined && (this.builtinValues.has(symbol) || this.builtinInterfaces.has(symbol)); } isBuiltinIdentifier(value) { return (this.getAnyInterfaceSymbolMaybe(value) !== undefined || this.getAnyTypeSymbolMaybe(value) !== undefined || this.getAnyValueSymbolMaybe(value) !== undefined); } isBuiltinFile(file) { return this.getContract() === file; } getMember(value, prop) { return this.memoized('get-member', `${utils_2.nodeKey(value)}:${utils_2.nodeKey(prop)}`, () => { const propSymbol = this.context.analysis.getSymbol(prop); if (propSymbol === undefined) { return undefined; } const valueSymbol = this.context.analysis.getTypeSymbol(value); if (valueSymbol === undefined) { return this.allBuiltinMembers.get(propSymbol); } if (!ts_utils_1.tsUtils.guards.isSuperExpression(value)) { const overridenMember = this.walkOverridesForMember(valueSymbol, propSymbol); if (overridenMember !== undefined) { return overridenMember; } } const members = this.getAllMembers(valueSymbol); return members.get(propSymbol); }); } getOnlyMember(value, name) { return this.getOnlyMemberBase(value, name, (result) => result[1]); } getOnlyMemberSymbol(value, name) { return throwIfNull(this.getOnlyMemberBase(value, name, (result) => result[0])); } getMembers(name, isMember, isEligible, symbolMembers = false) { const filterPseudoSymbol = (symbol, key) => { const symbolSymbol = this.getInterfaceSymbolBase('SymbolConstructor', this.getGlobals()); return ts_utils_1.tsUtils.symbol.getMember(symbolSymbol, key) !== symbol; }; const isSymbolKey = (key) => key.startsWith('__@'); let testKey = (key) => !isSymbolKey(key); let modifyKey = (key) => key; if (symbolMembers) { testKey = isSymbolKey; modifyKey = (key) => key.slice(3); } const members = this.getAllMembers(this.getAnyInterfaceSymbol(name)); const mutableMembers = []; members.forEach((builtin, memberSymbol) => { const memberName = ts_utils_1.tsUtils.symbol.getName(memberSymbol); if (isMember(builtin) && filterPseudoSymbol(memberSymbol, memberName) && testKey(memberName) && isEligible(builtin)) { mutableMembers.push([modifyKey(memberName), builtin]); } }); return mutableMembers; } getInterface(value) { const valueSymbol = this.context.analysis.getSymbol(value); if (valueSymbol === undefined) { return undefined; } return this.builtinInterfaces.get(valueSymbol); } getInterfaceSymbol(value) { return this.getAnyInterfaceSymbol(value); } getValue(value) { const valueSymbol = this.context.analysis.getSymbol(value); if (valueSymbol === undefined) { return undefined; } return this.builtinValues.get(valueSymbol); } getValueInterface(value) { const builtinValue = this.getValue(value); return builtinValue === undefined || !types_1.isBuiltinValueObject(builtinValue) ? undefined : builtinValue.type; } getValueSymbol(value) { return this.getAnyValueSymbol(value); } getTypeSymbol(name) { return this.getAnyTypeSymbol(name); } isInterface(node, testType, name) { return this.memoized('is-interface', `${utils_2.typeKey(testType)}:${name}`, () => { const symbol = this.context.analysis.getSymbolForType(node, testType); if (symbol === undefined) { return false; } const interfaceSymbol = this.getAnyInterfaceSymbol(name); return symbol === interfaceSymbol; }); } isType(node, testType, name) { return this.memoized('is-type', `${utils_2.typeKey(testType)}:${name}`, () => { const symbol = this.context.analysis.getSymbolForType(node, testType); if (symbol === undefined) { return false; } if (name === 'Fixed') { const fixedTagSymbol = this.getAnyInterfaceSymbol('FixedTag'); if (symbol === fixedTagSymbol) { return true; } } if (name === 'ForwardedValue') { const forwardedValueTagSymbol = this.getAnyInterfaceSymbol('ForwardedValueTag'); if (symbol === forwardedValueTagSymbol) { return true; } } const typeSymbol = this.getAnyTypeSymbol(name); return symbol === typeSymbol; }); } isValue(node, name) { return this.memoized('is-value', `${utils_2.nodeKey(node)}:${name}`, () => { const symbol = this.context.analysis.getSymbol(node); if (symbol === undefined) { return false; } const valueSymbol = this.getAnyValueSymbol(name); return symbol === valueSymbol; }); } addMember(valueSymbol, memberSymbol, builtin) { let members = this.builtinMembers.get(valueSymbol); if (members === undefined) { members = new Map(); this.builtinMembers.set(valueSymbol, members); } members.set(memberSymbol, builtin); this.allBuiltinMembers.set(memberSymbol, builtin); const memberSymbolName = ts_utils_1.tsUtils.symbol.getName(memberSymbol); if (memberSymbolName.startsWith('__@')) { const symbolSymbol = this.getInterfaceSymbolBase('SymbolConstructor', this.getGlobals()); const memberSymbolSymbol = getMember(symbolSymbol, memberSymbolName.slice(3)); members.set(memberSymbolSymbol, builtin); this.allBuiltinMembers.set(memberSymbolSymbol, builtin); } } addOverride(superSymbol, overrideSymbol) { this.builtinOverrides.set(superSymbol, overrideSymbol); } addGlobalMember(value, member, builtin) { this.addMemberBase(value, member, builtin, this.getGlobals()); } addContractMember(value, member, builtin) { this.addMemberBase(value, member, builtin, this.getContract()); } addInterface(value, builtin) { this.addInterfaceBase(value, builtin, this.getGlobals()); } addContractInterface(value, builtin) { this.addInterfaceBase(value, builtin, this.getContract()); } addValue(value, builtin) { this.addValueBase(value, builtin, this.getGlobals()); } addTestValue(value, builtin) { const file = this.getTestGlobals(); if (file === undefined) { return; } this.addValueBase(value, builtin, file); } addContractValue(value, builtin) { this.addValueBase(value, builtin, this.getContract()); } walkOverridesForMember(valueSymbol, propSymbol) { const overrideValueSymbol = this.builtinOverrides.get(valueSymbol); if (overrideValueSymbol === undefined) { return undefined; } let overridePropSymbol = this.builtinOverrides.get(propSymbol); if (overridePropSymbol === undefined) { overridePropSymbol = propSymbol; } const member = this.walkOverridesForMember(overrideValueSymbol, overridePropSymbol); if (member !== undefined) { return member; } const overridenMembers = this.getAllMembers(overrideValueSymbol); return overridenMembers.get(overridePropSymbol); } getOnlyMemberBase(value, name, getValue) { return this.memoized('only-member-base', `${value}$${name}`, () => { const symbol = this.getAnyInterfaceOrValueSymbol(value); const members = this.getAllMembers(symbol); const result = [...members.entries()].find(([memberSymbol]) => ts_utils_1.tsUtils.symbol.getName(memberSymbol) === name); return result === undefined ? undefined : getValue(result); }); } getAllMembers(symbol) { return this.memoized('get-all-members', ts_utils_1.symbolKey(symbol), () => { const interfaceMembers = this.builtinMembers.get(symbol); const memberEntries = [...this.getInheritedSymbols(symbol)].reduce((acc, parentInterfaceSymbol) => { const parentInterfaceMembers = this.builtinMembers.get(parentInterfaceSymbol); if (parentInterfaceMembers === undefined) { return acc; } return [...parentInterfaceMembers.entries()].concat(acc); }, interfaceMembers === undefined ? [] : [...interfaceMembers.entries()]); return new Map(memberEntries); }); } addMemberBase(value, member, builtin, file) { let valueSymbol = this.getInterfaceSymbolMaybe(value, file); let memberSymbol; if (valueSymbol === undefined) { valueSymbol = this.getValueSymbolBase(value, file); memberSymbol = getExportOrMember(valueSymbol, member); } else { memberSymbol = getMember(valueSymbol, member); } this.addMember(valueSymbol, memberSymbol, builtin); } getAnyInterfaceOrValueSymbol(value) { const valueSymbol = this.getAnyInterfaceSymbolMaybe(value); return valueSymbol === undefined ? this.getAnyValueSymbol(value) : valueSymbol; } addInterfaceBase(value, builtin, file) { this.builtinInterfaces.set(this.getInterfaceSymbolBase(value, file), builtin); } addValueBase(value, builtin, file) { this.builtinValues.set(this.getValueSymbolBase(value, file), builtin); } getAnyValueSymbol(name) { return this.memoized('any-value-symbol', name, () => throwIfNull(this.getAnyValueSymbolMaybe(name))); } getAnyValueSymbolMaybe(name) { return this.memoized('get-any-value-symbol-maybe', name, () => findNonNull(this.getFiles().map((file) => this.getValueSymbolMaybe(name, file)))); } getValueSymbolBase(name, file) { return throwIfNull(this.getValueSymbolMaybe(name, file)); } getValueSymbolMaybe(name, file) { let decl = ts_utils_1.tsUtils.statement.getVariableDeclaration(file, name); if (decl === undefined) { decl = ts_utils_1.tsUtils.statement.getFunction(file, name); } if (decl === undefined) { decl = ts_utils_1.tsUtils.statement.getEnum(file, name); } if (decl === undefined) { decl = ts_utils_1.tsUtils.statement.getClass(file, name); } if (decl === undefined) { return undefined; } return ts_utils_1.tsUtils.node.getSymbol(this.context.typeChecker, decl); } getAnyInterfaceSymbol(name) { return this.memoized('any-interface-symbol', name, () => throwIfNull(this.getAnyInterfaceSymbolMaybe(name))); } getAnyInterfaceSymbolMaybe(name) { return this.memoized('get-any-interface-symbol-maybe', name, () => findNonNull(this.getFiles().map((file) => this.getInterfaceSymbolMaybe(name, file)))); } getInterfaceSymbolBase(name, file) { return throwIfNull(this.getInterfaceSymbolMaybe(name, file)); } getInterfaceSymbolMaybe(name, file) { return this.getInterfaceSymbols(file)[name]; } getInterfaceSymbols(file) { return this.memoized('interface-symbols', ts_utils_1.tsUtils.file.getFilePath(file), () => { const interfaceDecls = ts_utils_1.tsUtils.statement.getInterfaces(file); const decls = interfaceDecls.concat(ts_utils_1.tsUtils.statement.getEnums(file)); return lodash_1.default.fromPairs(decls.map((decl) => { const type = ts_utils_1.tsUtils.type_.getType(this.context.typeChecker, decl); const symbol = ts_utils_1.tsUtils.type_.getSymbol(type); return [ts_utils_1.tsUtils.node.getName(decl), symbol]; })); }); } getInheritedSymbols(symbol, baseTypes = []) { return this.memoized('get-inherited-symbols', ts_utils_1.symbolKey(symbol), () => { const symbols = new Set(); for (const decl of ts_utils_1.tsUtils.symbol.getDeclarations(symbol)) { if (typescript_1.default.isInterfaceDeclaration(decl) || typescript_1.default.isClassDeclaration(decl) || typescript_1.default.isClassExpression(decl)) { let baseType = baseTypes[0]; let nextBaseTypes = baseTypes.slice(1); if (baseTypes.length === 0) { const currentBaseTypes = ts_utils_1.tsUtils.class_.getBaseTypesFlattened(this.context.typeChecker, decl); baseType = currentBaseTypes[0]; nextBaseTypes = currentBaseTypes.slice(1); } if (baseType !== undefined) { const baseSymbol = this.context.analysis.getSymbolForType(decl, baseType); if (baseSymbol !== undefined) { symbols.add(baseSymbol); this.getInheritedSymbols(baseSymbol, nextBaseTypes).forEach((inheritedSymbol) => { symbols.add(inheritedSymbol); }); } } } } return symbols; }); } getAnyTypeSymbol(name) { return this.memoized('get-any-type-symbol', name, () => throwIfNull(this.getAnyTypeSymbolMaybe(name))); } getAnyTypeSymbolMaybe(name) { return this.memoized('get-any-type-symbol-maybe', name, () => findNonNull(this.getFiles().map((file) => this.getTypeSymbolMaybe(name, file)))); } getTypeSymbolMaybe(name, file) { return this.getTypeSymbols(file)[name]; } getTypeSymbols(file) { return this.memoized('type-symbols', ts_utils_1.tsUtils.file.getFilePath(file), () => { const decls = ts_utils_1.tsUtils.statement.getTypeAliases(file); return lodash_1.default.fromPairs(decls.map((decl) => { const type = ts_utils_1.tsUtils.type_.getType(this.context.typeChecker, decl); const symbol = ts_utils_1.tsUtils.type_.getAliasSymbol(type); return [ts_utils_1.tsUtils.node.getName(decl), symbol]; })); }); } getFiles() { return this.memoized('file-cache', 'files', () => [this.getGlobals(), this.getContract(), this.getTestGlobals()].filter(utils_1.utils.notNull)); } getGlobals() { return this.memoized('file-cache', 'globals', () => ts_utils_1.tsUtils.file.getSourceFileOrThrow(this.context.program, this.context.host.getSmartContractPath('global.d.ts'))); } getContract() { return this.memoized('file-cache', 'contract', () => ts_utils_1.tsUtils.file.getSourceFileOrThrow(this.context.program, this.context.host.getSmartContractPath('index.d.ts'))); } getTestGlobals() { return this.memoized('file-cache', 'test', () => ts_utils_1.tsUtils.file.getSourceFile(this.context.program, this.context.host.getSmartContractPath('harness.d.ts'))); } } exports.Builtins = Builtins; //# sourceMappingURL=data:application/json;charset=utf8;base64,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LFVBQVUsRUFBRSxFQUFFLElBQUksQ0FBQyxXQUFXLEVBQUUsRUFBRSxJQUFJLENBQUMsY0FBYyxFQUFFLENBQUMsQ0FBQyxNQUFNLENBQUMsYUFBSyxDQUFDLE9BQU8sQ0FBQyxDQUNyRixDQUFDO0lBQ0osQ0FBQztJQUVPLFVBQVU7UUFDaEIsT0FBTyxJQUFJLENBQUMsUUFBUSxDQUFDLFlBQVksRUFBRSxTQUFTLEVBQUUsR0FBRyxFQUFFLENBQ2pELGtCQUFPLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsT0FBTyxFQUFFLElBQUksQ0FBQyxPQUFPLENBQUMsSUFBSSxDQUFDLG9CQUFvQixDQUFDLGFBQWEsQ0FBQyxDQUFDLENBQy9HLENBQUM7SUFDSixDQUFDO0lBRU8sV0FBVztRQUNqQixPQUFPLElBQUksQ0FBQyxRQUFRLENBQUMsWUFBWSxFQUFFLFVBQVUsRUFBRSxHQUFHLEVBQUUsQ0FDbEQsa0JBQU8sQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsWUFBWSxDQUFDLENBQUMsQ0FDOUcsQ0FBQztJQUNKLENBQUM7SUFFTyxjQUFjO1FBQ3BCLE9BQU8sSUFBSSxDQUFDLFFBQVEsQ0FBQyxZQUFZLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUM5QyxrQkFBTyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxPQUFPLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsb0JBQW9CLENBQUMsY0FBYyxDQUFDLENBQUMsQ0FDekcsQ0FBQztJQUNKLENBQUM7Q0FDRjtBQWhlRCw0QkFnZUMiLCJmaWxlIjoibmVvLW9uZS1zbWFydC1jb250cmFjdC1jb21waWxlci9zcmMvY29tcGlsZS9idWlsdGlucy9CdWlsdGlucy5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IHN5bWJvbEtleSwgdHNVdGlscyB9IGZyb20gJ0BuZW8tb25lL3RzLXV0aWxzJztcbmltcG9ydCB7IHV0aWxzIH0gZnJvbSAnQG5lby1vbmUvdXRpbHMnO1xuaW1wb3J0IF8gZnJvbSAnbG9kYXNoJztcbmltcG9ydCB0cyBmcm9tICd0eXBlc2NyaXB0JztcbmltcG9ydCB7IENvbnRleHQgfSBmcm9tICcuLi8uLi9Db250ZXh0JztcbmltcG9ydCB7IGNyZWF0ZU1lbW9pemVkLCBub2RlS2V5LCB0eXBlS2V5IH0gZnJvbSAnLi4vLi4vdXRpbHMnO1xuaW1wb3J0IHsgQnVpbHRpbiwgaXNCdWlsdGluVmFsdWVPYmplY3QgfSBmcm9tICcuL3R5cGVzJztcblxuY29uc3QgZ2V0TWVtYmVyID0gKHN5bTogdHMuU3ltYm9sLCBuYW1lOiBzdHJpbmcpID0+IHRzVXRpbHMuc3ltYm9sLmdldE1lbWJlck9yVGhyb3coc3ltLCBuYW1lKTtcbmNvbnN0IGdldEV4cG9ydE9yTWVtYmVyID0gKHN5bTogdHMuU3ltYm9sLCBuYW1lOiBzdHJpbmcpID0+IHtcbiAgY29uc3QgbWVtYmVyID0gdHNVdGlscy5zeW1ib2wuZ2V0TWVtYmVyKHN5bSwgbmFtZSk7XG5cbiAgcmV0dXJuIG1lbWJlciA9PT0gdW5kZWZpbmVkID8gdHNVdGlscy5zeW1ib2wuZ2V0RXhwb3J0T3JUaHJvdyhzeW0sIG5hbWUpIDogbWVtYmVyO1xufTtcblxuY29uc3QgZmluZE5vbk51bGwgPSA8VD4odmFsdWU6IFJlYWRvbmx5QXJyYXk8VCB8IHVuZGVmaW5lZD4pOiBUIHwgdW5kZWZpbmVkID0+IHZhbHVlLmZpbmQoKHZhbCkgPT4gdmFsICE9PSB1bmRlZmluZWQpO1xuXG5jb25zdCB0aHJvd0lmTnVsbCA9IDxUPih2YWx1ZTogVCB8IHVuZGVmaW5lZCB8IG51bGwpOiBUID0+IHtcbiAgaWYgKHZhbHVlID09IHVuZGVmaW5lZCkge1xuICAgIC8qIGlzdGFuYnVsIGlnbm9yZSBuZXh0ICovXG4gICAgdGhyb3cgbmV3IEVycm9yKCdTb21ldGhpbmcgd2VudCB3cm9uZy4nKTtcbiAgfVxuXG4gIHJldHVybiB2YWx1ZTtcbn07XG5cbmV4cG9ydCBjbGFzcyBCdWlsdGlucyB7XG4gIHByaXZhdGUgcmVhZG9ubHkgYnVpbHRpbk1lbWJlcnM6IE1hcDx0cy5TeW1ib2wsIE1hcDx0cy5TeW1ib2wsIEJ1aWx0aW4+PiA9IG5ldyBNYXAoKTtcbiAgcHJpdmF0ZSByZWFkb25seSBhbGxCdWlsdGluTWVtYmVyczogTWFwPHRzLlN5bWJvbCwgQnVpbHRpbj4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgYnVpbHRpbkludGVyZmFjZXM6IE1hcDx0cy5TeW1ib2wsIEJ1aWx0aW4+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIHJlYWRvbmx5IGJ1aWx0aW5WYWx1ZXM6IE1hcDx0cy5TeW1ib2wsIEJ1aWx0aW4+ID0gbmV3IE1hcCgpO1xuICBwcml2YXRlIHJlYWRvbmx5IGJ1aWx0aW5PdmVycmlkZXM6IE1hcDx0cy5TeW1ib2wsIHRzLlN5bWJvbD4gPSBuZXcgTWFwKCk7XG4gIHByaXZhdGUgcmVhZG9ubHkgbWVtb2l6ZWQgPSBjcmVhdGVNZW1vaXplZCgpO1xuXG4gIHB1YmxpYyBjb25zdHJ1Y3Rvcihwcml2YXRlIHJlYWRvbmx5IGNvbnRleHQ6IENvbnRleHQpIHt9XG5cbiAgcHVibGljIGlzQnVpbHRpblN5bWJvbChzeW1ib2w6IHRzLlN5bWJvbCB8IHVuZGVmaW5lZCk6IGJvb2xlYW4ge1xuICAgIHJldHVybiBzeW1ib2wgIT09IHVuZGVmaW5lZCAmJiAodGhpcy5idWlsdGluVmFsdWVzLmhhcyhzeW1ib2wpIHx8IHRoaXMuYnVpbHRpbkludGVyZmFjZXMuaGFzKHN5bWJvbCkpO1xuICB9XG5cbiAgcHVibGljIGlzQnVpbHRpbklkZW50aWZpZXIodmFsdWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiAoXG4gICAgICB0aGlzLmdldEFueUludGVyZmFjZVN5bWJvbE1heWJlKHZhbHVlKSAhPT0gdW5kZWZpbmVkIHx8XG4gICAgICB0aGlzLmdldEFueVR5cGVTeW1ib2xNYXliZSh2YWx1ZSkgIT09IHVuZGVmaW5lZCB8fFxuICAgICAgdGhpcy5nZXRBbnlWYWx1ZVN5bWJvbE1heWJlKHZhbHVlKSAhPT0gdW5kZWZpbmVkXG4gICAgKTtcbiAgfVxuXG4gIHB1YmxpYyBpc0J1aWx0aW5GaWxlKGZpbGU6IHRzLlNvdXJjZUZpbGUpOiBib29sZWFuIHtcbiAgICByZXR1cm4gdGhpcy5nZXRDb250cmFjdCgpID09PSBmaWxlO1xuICB9XG5cbiAgcHVibGljIGdldE1lbWJlcih2YWx1ZTogdHMuTm9kZSwgcHJvcDogdHMuTm9kZSk6IEJ1aWx0aW4gfCB1bmRlZmluZWQge1xuICAgIHJldHVybiB0aGlzLm1lbW9pemVkKCdnZXQtbWVtYmVyJywgYCR7bm9kZUtleSh2YWx1ZSl9OiR7bm9kZUtleShwcm9wKX1gLCAoKSA9PiB7XG4gICAgICBjb25zdCBwcm9wU3ltYm9sID0gdGhpcy5jb250ZXh0LmFuYWx5c2lzLmdldFN5bWJvbChwcm9wKTtcbiAgICAgIGlmIChwcm9wU3ltYm9sID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIHVuZGVmaW5lZDtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdmFsdWVTeW1ib2wgPSB0aGlzLmNvbnRleHQuYW5hbHlzaXMuZ2V0VHlwZVN5bWJvbCh2YWx1ZSk7XG4gICAgICBpZiAodmFsdWVTeW1ib2wgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICByZXR1cm4gdGhpcy5hbGxCdWlsdGluTWVtYmVycy5nZXQocHJvcFN5bWJvbCk7XG4gICAgICB9XG5cbiAgICAgIC8vIFN1cGVyIGhhY2t5IC0gb25seSB3b3JrcyBmb3IgdGhlIHNwZWNpYWwgd2F5IHNtYXJ0IGNvbnRyYWN0cyBhcmUgY29tcGlsZWQuXG4gICAgICBpZiAoIXRzVXRpbHMuZ3VhcmRzLmlzU3VwZXJFeHByZXNzaW9uKHZhbHVlKSkge1xuICAgICAgICBjb25zdCBvdmVycmlkZW5NZW1iZXIgPSB0aGlzLndhbGtPdmVycmlkZXNGb3JNZW1iZXIodmFsdWVTeW1ib2wsIHByb3BTeW1ib2wpO1xuICAgICAgICBpZiAob3ZlcnJpZGVuTWVtYmVyICE9PSB1bmRlZmluZWQpIHtcbiAgICAgICAgICByZXR1cm4gb3ZlcnJpZGVuTWVtYmVyO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IG1lbWJlcnMgPSB0aGlzLmdldEFsbE1lbWJlcnModmFsdWVTeW1ib2wpO1xuXG4gICAgICByZXR1cm4gbWVtYmVycy5nZXQocHJvcFN5bWJvbCk7XG4gICAgfSk7XG4gIH1cblxuICBwdWJsaWMgZ2V0T25seU1lbWJlcih2YWx1ZTogc3RyaW5nLCBuYW1lOiBzdHJpbmcpOiBCdWlsdGluIHwgdW5kZWZpbmVkIHtcbiAgICByZXR1cm4gdGhpcy5nZXRPbmx5TWVtYmVyQmFzZSh2YWx1ZSwgbmFtZSwgKHJlc3VsdCkgPT4gcmVzdWx0WzFdKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRPbmx5TWVtYmVyU3ltYm9sKHZhbHVlOiBzdHJpbmcsIG5hbWU6IHN0cmluZyk6IHRzLlN5bWJvbCB7XG4gICAgcmV0dXJuIHRocm93SWZOdWxsKHRoaXMuZ2V0T25seU1lbWJlckJhc2UodmFsdWUsIG5hbWUsIChyZXN1bHQpID0+IHJlc3VsdFswXSkpO1xuICB9XG5cbiAgcHVibGljIGdldE1lbWJlcnM8VCBleHRlbmRzIEJ1aWx0aW4+KFxuICAgIG5hbWU6IHN0cmluZyxcbiAgICBpc01lbWJlcjogKGJ1aWx0aW46IEJ1aWx0aW4pID0+IGJ1aWx0aW4gaXMgVCxcbiAgICBpc0VsaWdpYmxlOiAoYnVpbHRpbjogVCkgPT4gYm9vbGVhbixcbiAgICBzeW1ib2xNZW1iZXJzID0gZmFsc2UsXG4gICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lOiByZWFkb25seS1hcnJheVxuICApOiBSZWFkb25seUFycmF5PFtzdHJpbmcsIFRdPiB7XG4gICAgY29uc3QgZmlsdGVyUHNldWRvU3ltYm9sID0gKHN5bWJvbDogdHMuU3ltYm9sLCBrZXk6IHN0cmluZykgPT4ge1xuICAgICAgY29uc3Qgc3ltYm9sU3ltYm9sID0gdGhpcy5nZXRJbnRlcmZhY2VTeW1ib2xCYXNlKCdTeW1ib2xDb25zdHJ1Y3RvcicsIHRoaXMuZ2V0R2xvYmFscygpKTtcblxuICAgICAgcmV0dXJuIHRzVXRpbHMuc3ltYm9sLmdldE1lbWJlcihzeW1ib2xTeW1ib2wsIGtleSkgIT09IHN5bWJvbDtcbiAgICB9O1xuICAgIGNvbnN0IGlzU3ltYm9sS2V5ID0gKGtleTogc3RyaW5nKSA9PiBrZXkuc3RhcnRzV2l0aCgnX19AJyk7XG5cbiAgICBsZXQgdGVzdEtleSA9IChrZXk6IHN0cmluZykgPT4gIWlzU3ltYm9sS2V5KGtleSk7XG4gICAgbGV0IG1vZGlmeUtleSA9IChrZXk6IHN0cmluZykgPT4ga2V5O1xuICAgIGlmIChzeW1ib2xNZW1iZXJzKSB7XG4gICAgICB0ZXN0S2V5ID0gaXNTeW1ib2xLZXk7XG4gICAgICBtb2RpZnlLZXkgPSAoa2V5KSA9PiBrZXkuc2xpY2UoMyk7XG4gICAgfVxuXG4gICAgY29uc3QgbWVtYmVycyA9IHRoaXMuZ2V0QWxsTWVtYmVycyh0aGlzLmdldEFueUludGVyZmFjZVN5bWJvbChuYW1lKSk7XG5cbiAgICBjb25zdCBtdXRhYmxlTWVtYmVyczogQXJyYXk8W3N0cmluZywgVF0+ID0gW107XG4gICAgbWVtYmVycy5mb3JFYWNoKChidWlsdGluLCBtZW1iZXJTeW1ib2wpID0+IHtcbiAgICAgIGNvbnN0IG1lbWJlck5hbWUgPSB0c1V0aWxzLnN5bWJvbC5nZXROYW1lKG1lbWJlclN5bWJvbCk7XG4gICAgICBpZiAoXG4gICAgICAgIGlzTWVtYmVyKGJ1aWx0aW4pICYmXG4gICAgICAgIGZpbHRlclBzZXVkb1N5bWJvbChtZW1iZXJTeW1ib2wsIG1lbWJlck5hbWUpICYmXG4gICAgICAgIHRlc3RLZXkobWVtYmVyTmFtZSkgJiZcbiAgICAgICAgaXNFbGlnaWJsZShidWlsdGluKVxuICAgICAgKSB7XG4gICAgICAgIG11dGFibGVNZW1iZXJzLnB1c2goW21vZGlmeUtleShtZW1iZXJOYW1lKSwgYnVpbHRpbl0pO1xuICAgICAgfVxuICAgIH0pO1xuXG4gICAgcmV0dXJuIG11dGFibGVNZW1iZXJzO1xuICB9XG5cbiAgcHVibGljIGdldEludGVyZmFjZSh2YWx1ZTogdHMuTm9kZSk6IEJ1aWx0aW4gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHZhbHVlU3ltYm9sID0gdGhpcy5jb250ZXh0LmFuYWx5c2lzLmdldFN5bWJvbCh2YWx1ZSk7XG4gICAgaWYgKHZhbHVlU3ltYm9sID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYnVpbHRpbkludGVyZmFjZXMuZ2V0KHZhbHVlU3ltYm9sKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRJbnRlcmZhY2VTeW1ib2wodmFsdWU6IHN0cmluZyk6IHRzLlN5bWJvbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QW55SW50ZXJmYWNlU3ltYm9sKHZhbHVlKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRWYWx1ZSh2YWx1ZTogdHMuTm9kZSk6IEJ1aWx0aW4gfCB1bmRlZmluZWQge1xuICAgIGNvbnN0IHZhbHVlU3ltYm9sID0gdGhpcy5jb250ZXh0LmFuYWx5c2lzLmdldFN5bWJvbCh2YWx1ZSk7XG4gICAgaWYgKHZhbHVlU3ltYm9sID09PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgfVxuXG4gICAgcmV0dXJuIHRoaXMuYnVpbHRpblZhbHVlcy5nZXQodmFsdWVTeW1ib2wpO1xuICB9XG5cbiAgcHVibGljIGdldFZhbHVlSW50ZXJmYWNlKHZhbHVlOiB0cy5Ob2RlKTogc3RyaW5nIHwgdW5kZWZpbmVkIHtcbiAgICBjb25zdCBidWlsdGluVmFsdWUgPSB0aGlzLmdldFZhbHVlKHZhbHVlKTtcblxuICAgIHJldHVybiBidWlsdGluVmFsdWUgPT09IHVuZGVmaW5lZCB8fCAhaXNCdWlsdGluVmFsdWVPYmplY3QoYnVpbHRpblZhbHVlKSA/IHVuZGVmaW5lZCA6IGJ1aWx0aW5WYWx1ZS50eXBlO1xuICB9XG5cbiAgcHVibGljIGdldFZhbHVlU3ltYm9sKHZhbHVlOiBzdHJpbmcpOiB0cy5TeW1ib2wge1xuICAgIHJldHVybiB0aGlzLmdldEFueVZhbHVlU3ltYm9sKHZhbHVlKTtcbiAgfVxuXG4gIHB1YmxpYyBnZXRUeXBlU3ltYm9sKG5hbWU6IHN0cmluZyk6IHRzLlN5bWJvbCB7XG4gICAgcmV0dXJuIHRoaXMuZ2V0QW55VHlwZVN5bWJvbChuYW1lKTtcbiAgfVxuXG4gIHB1YmxpYyBpc0ludGVyZmFjZShub2RlOiB0cy5Ob2RlLCB0ZXN0VHlwZTogdHMuVHlwZSwgbmFtZTogc3RyaW5nKTogYm9vbGVhbiB7XG4gICAgcmV0dXJuIHRoaXMubWVtb2l6ZWQoJ2lzLWludGVyZmFjZScsIGAke3R5cGVLZXkodGVzdFR5cGUpfToke25hbWV9YCwgKCkgPT4ge1xuICAgICAgY29uc3Qgc3ltYm9sID0gdGhpcy5jb250ZXh0LmFuYWx5c2lzLmdldFN5bWJvbEZvclR5cGUobm9kZSwgdGVzdFR5cGUpO1xuICAgICAgaWYgKHN5bWJvbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgaW50ZXJmYWNlU3ltYm9sID0gdGhpcy5nZXRBbnlJbnRlcmZhY2VTeW1ib2wobmFtZSk7XG5cbiAgICAgIHJldHVybiBzeW1ib2wgPT09IGludGVyZmFjZVN5bWJvbDtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBpc1R5cGUobm9kZTogdHMuTm9kZSwgdGVzdFR5cGU6IHRzLlR5cGUsIG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm1lbW9pemVkKCdpcy10eXBlJywgYCR7dHlwZUtleSh0ZXN0VHlwZSl9OiR7bmFtZX1gLCAoKSA9PiB7XG4gICAgICBjb25zdCBzeW1ib2wgPSB0aGlzLmNvbnRleHQuYW5hbHlzaXMuZ2V0U3ltYm9sRm9yVHlwZShub2RlLCB0ZXN0VHlwZSk7XG4gICAgICBpZiAoc3ltYm9sID09PSB1bmRlZmluZWQpIHtcbiAgICAgICAgcmV0dXJuIGZhbHNlO1xuICAgICAgfVxuXG4gICAgICBpZiAobmFtZSA9PT0gJ0ZpeGVkJykge1xuICAgICAgICBjb25zdCBmaXhlZFRhZ1N5bWJvbCA9IHRoaXMuZ2V0QW55SW50ZXJmYWNlU3ltYm9sKCdGaXhlZFRhZycpO1xuICAgICAgICBpZiAoc3ltYm9sID09PSBmaXhlZFRhZ1N5bWJvbCkge1xuICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChuYW1lID09PSAnRm9yd2FyZGVkVmFsdWUnKSB7XG4gICAgICAgIGNvbnN0IGZvcndhcmRlZFZhbHVlVGFnU3ltYm9sID0gdGhpcy5nZXRBbnlJbnRlcmZhY2VTeW1ib2woJ0ZvcndhcmRlZFZhbHVlVGFnJyk7XG4gICAgICAgIGlmIChzeW1ib2wgPT09IGZvcndhcmRlZFZhbHVlVGFnU3ltYm9sKSB7XG4gICAgICAgICAgcmV0dXJuIHRydWU7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgY29uc3QgdHlwZVN5bWJvbCA9IHRoaXMuZ2V0QW55VHlwZVN5bWJvbChuYW1lKTtcblxuICAgICAgcmV0dXJuIHN5bWJvbCA9PT0gdHlwZVN5bWJvbDtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBpc1ZhbHVlKG5vZGU6IHRzLk5vZGUsIG5hbWU6IHN0cmluZyk6IGJvb2xlYW4ge1xuICAgIHJldHVybiB0aGlzLm1lbW9pemVkKCdpcy12YWx1ZScsIGAke25vZGVLZXkobm9kZSl9OiR7bmFtZX1gLCAoKSA9PiB7XG4gICAgICBjb25zdCBzeW1ib2wgPSB0aGlzLmNvbnRleHQuYW5hbHlzaXMuZ2V0U3ltYm9sKG5vZGUpO1xuICAgICAgaWYgKHN5bWJvbCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgIH1cblxuICAgICAgY29uc3QgdmFsdWVTeW1ib2wgPSB0aGlzLmdldEFueVZhbHVlU3ltYm9sKG5hbWUpO1xuXG4gICAgICByZXR1cm4gc3ltYm9sID09PSB2YWx1ZVN5bWJvbDtcbiAgICB9KTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRNZW1iZXIodmFsdWVTeW1ib2w6IHRzLlN5bWJvbCwgbWVtYmVyU3ltYm9sOiB0cy5TeW1ib2wsIGJ1aWx0aW46IEJ1aWx0aW4pOiB2b2lkIHtcbiAgICBsZXQgbWVtYmVycyA9IHRoaXMuYnVpbHRpbk1lbWJlcnMuZ2V0KHZhbHVlU3ltYm9sKTtcbiAgICBpZiAobWVtYmVycyA9PT0gdW5kZWZpbmVkKSB7XG4gICAgICBtZW1iZXJzID0gbmV3IE1hcCgpO1xuICAgICAgdGhpcy5idWlsdGluTWVtYmVycy5zZXQodmFsdWVTeW1ib2wsIG1lbWJlcnMpO1xuICAgIH1cblxuICAgIG1lbWJlcnMuc2V0KG1lbWJlclN5bWJvbCwgYnVpbHRpbik7XG4gICAgdGhpcy5hbGxCdWlsdGluTWVtYmVycy5zZXQobWVtYmVyU3ltYm9sLCBidWlsdGluKTtcbiAgICBjb25zdCBtZW1iZXJTeW1ib2xOYW1lID0gdHNVdGlscy5zeW1ib2wuZ2V0TmFtZShtZW1iZXJTeW1ib2wpO1xuICAgIGlmIChtZW1iZXJTeW1ib2xOYW1lLnN0YXJ0c1dpdGgoJ19fQCcpKSB7XG4gICAgICBjb25zdCBzeW1ib2xTeW1ib2wgPSB0aGlzLmdldEludGVyZmFjZVN5bWJvbEJhc2UoJ1N5bWJvbENvbnN0cnVjdG9yJywgdGhpcy5nZXRHbG9iYWxzKCkpO1xuICAgICAgY29uc3QgbWVtYmVyU3ltYm9sU3ltYm9sID0gZ2V0TWVtYmVyKHN5bWJvbFN5bWJvbCwgbWVtYmVyU3ltYm9sTmFtZS5zbGljZSgzKSk7XG4gICAgICBtZW1iZXJzLnNldChtZW1iZXJTeW1ib2xTeW1ib2wsIGJ1aWx0aW4pO1xuICAgICAgdGhpcy5hbGxCdWlsdGluTWVtYmVycy5zZXQobWVtYmVyU3ltYm9sU3ltYm9sLCBidWlsdGluKTtcbiAgICB9XG4gIH1cblxuICBwdWJsaWMgYWRkT3ZlcnJpZGUoc3VwZXJTeW1ib2w6IHRzLlN5bWJvbCwgb3ZlcnJpZGVTeW1ib2w6IHRzLlN5bWJvbCk6IHZvaWQge1xuICAgIHRoaXMuYnVpbHRpbk92ZXJyaWRlcy5zZXQoc3VwZXJTeW1ib2wsIG92ZXJyaWRlU3ltYm9sKTtcbiAgfVxuXG4gIHB1YmxpYyBhZGRHbG9iYWxNZW1iZXIodmFsdWU6IHN0cmluZywgbWVtYmVyOiBzdHJpbmcsIGJ1aWx0aW46IEJ1aWx0aW4pOiB2b2lkIHtcbiAgICB0aGlzLmFkZE1lbWJlckJhc2UodmFsdWUsIG1lbWJlciwgYnVpbHRpbiwgdGhpcy5nZXRHbG9iYWxzKCkpO1xuICB9XG5cbiAgcHVibGljIGFkZENvbnRyYWN0TWVtYmVyKHZhbHVlOiBzdHJpbmcsIG1lbWJlcjogc3RyaW5nLCBidWlsdGluOiBCdWlsdGluKTogdm9pZCB7XG4gICAgdGhpcy5hZGRNZW1iZXJCYXNlKHZhbHVlLCBtZW1iZXIsIGJ1aWx0aW4sIHRoaXMuZ2V0Q29udHJhY3QoKSk7XG4gIH1cblxuICBwdWJsaWMgYWRkSW50ZXJmYWNlKHZhbHVlOiBzdHJpbmcsIG