UNPKG

@neo-one/server-plugin-project

Version:

NEO•ONE server plugin for project functionality.

254 lines (252 loc) 47.7 kB
"use strict"; Object.defineProperty(exports, "__esModule", { value: true }); const tslib_1 = require("tslib"); const client_common_1 = require("@neo-one/client-common"); const server_plugin_1 = require("@neo-one/server-plugin"); const server_plugin_neotracker_1 = require("@neo-one/server-plugin-neotracker"); const server_plugin_network_1 = require("@neo-one/server-plugin-network"); const server_plugin_wallet_1 = require("@neo-one/server-plugin-wallet"); const utils_1 = require("@neo-one/utils"); const nanoid_1 = tslib_1.__importDefault(require("nanoid")); const operators_1 = require("rxjs/operators"); const typescript_1 = require("typescript"); const constants_1 = require("../constants"); const utils_2 = require("../utils"); const compileContract_1 = require("./compileContract"); const deployContract_1 = require("./deployContract"); const findContracts_1 = require("./findContracts"); const generateCode_1 = require("./generateCode"); const generateCommonCode_1 = require("./generateCommonCode"); const setupWallets_1 = require("./setupWallets"); const getProjectConfig = (ctx) => ctx.projectConfig; const getProjectID = (ctx) => ctx.projectID; const getContractPaths = (ctx) => ctx.contractPaths; const getContracts = (ctx) => ctx.contracts; const getSmartContractNetworksDefinitions = (ctx) => ctx.smartContractNetworkDefinitions; const getNetworkDefinitions = (ctx) => ctx.networkDefinitions; const getWallet = (ctx) => ctx.wallet; const getNetworkMaybe = (ctx) => ctx.networkMaybe; const getNetwork = (ctx) => ctx.network; const getSourceMaps = (ctx) => ctx.sourceMaps; exports.build = (pluginManager, options, { forceTransfer = false } = { forceTransfer: false }) => new server_plugin_1.TaskList({ tasks: [ { title: 'Load project configuration', task: async (ctx) => { const projectConfig = await utils_2.loadProjectConfig(options.rootDir); let projectID = await utils_2.loadProjectID(pluginManager, projectConfig, options); if (projectID === undefined) { projectID = nanoid_1.default(); } ctx.projectConfig = projectConfig; ctx.projectID = projectID; }, }, { title: 'Find contracts', task: async (ctx) => { const config = getProjectConfig(ctx); ctx.contractPaths = await findContracts_1.findContracts(config); if (ctx.contractPaths.length === 0) { throw new Error(`0 compilable smart contracts found in ${config.paths.contracts}`); } }, }, { title: 'Deploy dev contracts', task: () => new server_plugin_1.TaskList({ tasks: [ { title: 'Ensure development network', task: () => new server_plugin_1.TaskList({ tasks: [ { title: 'Check for existing network', task: async (ctx) => { const network = await server_plugin_network_1.getNetworkResourceManager(pluginManager) .getResource$({ name: utils_2.getLocalNetworkName(options.rootDir, getProjectID(ctx)), options: {}, }) .pipe(operators_1.take(1)) .toPromise(); if (network !== undefined) { await server_plugin_network_1.getNetworkResourceManager(pluginManager) .start(utils_2.getLocalNetworkName(options.rootDir, getProjectID(ctx)), {}) .toPromise(); } ctx.networkMaybe = network; }, }, { title: 'Create network', skip: (ctx) => { if (getNetworkMaybe(ctx) !== undefined) { return 'Network exists'; } return false; }, task: (ctx) => server_plugin_network_1.getNetworkResourceManager(pluginManager).create(utils_2.getLocalNetworkName(options.rootDir, getProjectID(ctx)), {}), }, { title: 'Create wallets', skip: (ctx) => { if (getNetworkMaybe(ctx) !== undefined) { return 'Wallets already exist'; } return false; }, task: () => new server_plugin_1.TaskList({ concurrent: true, tasks: setupWallets_1.WALLETS.map((wallet) => ({ title: `Create ${wallet.name} wallet`, task: (ctx) => { const networkName = utils_2.getLocalNetworkName(options.rootDir, getProjectID(ctx)); return server_plugin_wallet_1.getWalletResourceManager(pluginManager).create(server_plugin_wallet_1.constants.makeWallet({ network: networkName, name: wallet.name }), { network: networkName, privateKey: client_common_1.wifToPrivateKey(wallet.privateKey) }); }, })), }), }, { title: 'Gather network information', task: async (ctx) => { const networkName = utils_2.getLocalNetworkName(options.rootDir, getProjectID(ctx)); const [network, wallet] = await Promise.all([ server_plugin_network_1.getNetworkResourceManager(pluginManager) .getResource$({ name: networkName, options: {} }) .pipe(operators_1.filter(utils_1.utils.notNull), operators_1.take(1)) .toPromise(), server_plugin_wallet_1.getWalletResourceManager(pluginManager) .getResource$({ name: server_plugin_wallet_1.constants.makeMasterWallet(networkName), options: { network: networkName }, }) .pipe(operators_1.filter(utils_1.utils.notNull), operators_1.take(1)) .toPromise(), ]); ctx.network = network; ctx.wallet = wallet; ctx.networkDefinitions = [ { name: constants_1.constants.LOCAL_NETWORK_NAME, rpcURL: network.nodes[0].rpcAddress, }, ]; }, }, { title: 'Setup NEO Tracker', task: (ctx) => server_plugin_neotracker_1.getNEOTrackerResourceManager(pluginManager).create(utils_2.getLocalNEOTrackerName(utils_2.getLocalNetworkName(options.rootDir, getProjectID(ctx))), { network: getNetwork(ctx).name, }), }, { title: 'Transfer to wallets', skip: (ctx) => { if (!forceTransfer && getNetworkMaybe(ctx) !== undefined) { return 'Wallets already exist'; } return false; }, task: async (ctx) => { await setupWallets_1.setupWallets(getNetwork(ctx), getWallet(ctx).wif); }, }, ], }), }, { title: 'Deploy', task: (ctx) => { ctx.smartContractNetworkDefinitions = {}; ctx.contracts = []; const mutableLinked = {}; const mutableSourceMaps = {}; ctx.sourceMaps = mutableSourceMaps; return new server_plugin_1.TaskList({ tasks: getContractPaths(ctx).map((contractPath) => ({ title: `Deploy ${contractPath.name}`, task: async () => { const contract = await compileContract_1.compileContract(contractPath.filePath, contractPath.name, mutableLinked); if (contract.diagnostics.some((diagnostic) => diagnostic.category === typescript_1.DiagnosticCategory.Error)) { throw new Error('Compilation error.'); } const network = getNetwork(ctx); const address = client_common_1.scriptHashToAddress(client_common_1.common.uInt160ToString(client_common_1.crypto.toScriptHash(Buffer.from(contract.contract.script, 'hex')))); mutableSourceMaps[address] = contract.sourceMap; const [prodNetworksDefinition] = await Promise.all([ Promise.resolve({}), deployContract_1.deployContract(network, contract, mutableSourceMaps, getWallet(ctx).wif), ]); mutableLinked[contractPath.filePath] = { [contractPath.name]: address }; getContracts(ctx).push(Object.assign({}, contract, { addresses: [address].concat(Object.values(prodNetworksDefinition).map(({ address: value }) => value)) })); getSmartContractNetworksDefinitions(ctx)[contract.name] = Object.assign({}, prodNetworksDefinition, { [constants_1.constants.LOCAL_NETWORK_NAME]: { address } }); }, })), }); }, }, ], }), }, { title: 'Synchronize project', task: () => new server_plugin_1.TaskList({ concurrent: true, tasks: [ { title: 'Save project info', task: async (ctx) => { const projectID = getProjectID(ctx); const sourceMaps = getSourceMaps(ctx); const projectOptions = { rootDir: options.rootDir, sourceMaps, }; await utils_2.getProjectResourceManager(pluginManager) .delete(projectID, projectOptions) .toPromise(); await utils_2.getProjectResourceManager(pluginManager) .create(projectID, projectOptions) .toPromise(); }, }, { title: 'Generate code', task: (ctx) => new server_plugin_1.TaskList({ concurrent: true, tasks: getContracts(ctx) .filter(({ name }) => { const networksDefinition = getSmartContractNetworksDefinitions(ctx)[name]; return networksDefinition !== undefined; }) .map((contract) => ({ title: `Generate ${contract.name} code`, task: async () => { const project = getProjectConfig(ctx); const networksDefinition = getSmartContractNetworksDefinitions(ctx)[contract.name]; await generateCode_1.generateCode(project, contract, networksDefinition, project.codegen.browser); }, })) .concat([ { title: 'Generate common code', task: async () => { const project = getProjectConfig(ctx); await generateCommonCode_1.generateCommonCode(getProjectConfig(ctx), getProjectID(ctx), getContracts(ctx), constants_1.constants.LOCAL_NETWORK_NAME, [ { name: 'master', privateKey: getWallet(ctx).wif, }, ].concat(setupWallets_1.WALLETS), getNetworkDefinitions(ctx), pluginManager.httpServerPort, getSourceMaps(ctx), project.codegen.browser); }, }, ]), }), }, ], }), }, ], }); //# sourceMappingURL=data:application/json;charset=utf8;base64,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QUFnQixDQUFDLEdBQUcsQ0FBQyxDQUFDO3dDQUN0QyxNQUFNLHVDQUFrQixDQUN0QixnQkFBZ0IsQ0FBQyxHQUFHLENBQUMsRUFDckIsWUFBWSxDQUFDLEdBQUcsQ0FBQyxFQUNqQixZQUFZLENBQUMsR0FBRyxDQUFDLEVBQ2pCLHFCQUFTLENBQUMsa0JBQWtCLEVBQzVCOzRDQUNFO2dEQUNFLElBQUksRUFBRSxRQUFRO2dEQUVkLFVBQVUsRUFBRSxTQUFTLENBQUMsR0FBRyxDQUFDLENBQUMsR0FBSTs2Q0FDaEM7eUNBQ0YsQ0FBQyxNQUFNLENBQUMsc0JBQU8sQ0FBQyxFQUNqQixxQkFBcUIsQ0FBQyxHQUFHLENBQUMsRUFDMUIsYUFBYSxDQUFDLGNBQWMsRUFDNUIsYUFBYSxDQUFDLEdBQUcsQ0FBQyxFQUNsQixPQUFPLENBQUMsT0FBTyxDQUFDLE9BQU8sQ0FDeEIsQ0FBQztvQ0FDSixDQUFDO2lDQUNGOzZCQUNGLENBQUM7eUJBQ0wsQ0FBQztxQkFDTDtpQkFDRjthQUNGLENBQUM7U0FDTDtLQUNGO0NBQ0YsQ0FBQyxDQUFDIiwiZmlsZSI6Im5lby1vbmUtc2VydmVyLXBsdWdpbi1wcm9qZWN0L3NyYy9idWlsZC9pbmRleC5qcyIsInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7XG4gIGNvbW1vbixcbiAgY3J5cHRvLFxuICBzY3JpcHRIYXNoVG9BZGRyZXNzLFxuICBTbWFydENvbnRyYWN0TmV0d29ya3NEZWZpbml0aW9uLFxuICBTb3VyY2VNYXBzLFxuICB3aWZUb1ByaXZhdGVLZXksXG59IGZyb20gJ0BuZW8tb25lL2NsaWVudC1jb21tb24nO1xuaW1wb3J0IHsgUGx1Z2luTWFuYWdlciwgVGFzaywgVGFza0xpc3QgfSBmcm9tICdAbmVvLW9uZS9zZXJ2ZXItcGx1Z2luJztcbmltcG9ydCB7IGdldE5FT1RyYWNrZXJSZXNvdXJjZU1hbmFnZXIgfSBmcm9tICdAbmVvLW9uZS9zZXJ2ZXItcGx1Z2luLW5lb3RyYWNrZXInO1xuaW1wb3J0IHsgZ2V0TmV0d29ya1Jlc291cmNlTWFuYWdlciwgTmV0d29yayB9IGZyb20gJ0BuZW8tb25lL3NlcnZlci1wbHVnaW4tbmV0d29yayc7XG5pbXBvcnQgeyBjb25zdGFudHMgYXMgd2FsbGV0Q29uc3RhbnRzLCBnZXRXYWxsZXRSZXNvdXJjZU1hbmFnZXIsIFdhbGxldCB9IGZyb20gJ0BuZW8tb25lL3NlcnZlci1wbHVnaW4td2FsbGV0JztcbmltcG9ydCB7IE5ldHdvcmtEZWZpbml0aW9uIH0gZnJvbSAnQG5lby1vbmUvc21hcnQtY29udHJhY3QtY29kZWdlbic7XG5pbXBvcnQgeyBDb250cmFjdHMgYXMgQ29udHJhY3RQYXRocyB9IGZyb20gJ0BuZW8tb25lL3NtYXJ0LWNvbnRyYWN0LWNvbXBpbGVyJztcbmltcG9ydCB7IE1vZGlmaWFibGUsIHV0aWxzIH0gZnJvbSAnQG5lby1vbmUvdXRpbHMnO1xuaW1wb3J0IG5hbm9pZCBmcm9tICduYW5vaWQnO1xuaW1wb3J0IHsgZmlsdGVyLCB0YWtlIH0gZnJvbSAncnhqcy9vcGVyYXRvcnMnO1xuaW1wb3J0IHsgRGlhZ25vc3RpY0NhdGVnb3J5IH0gZnJvbSAndHlwZXNjcmlwdCc7XG5pbXBvcnQgeyBjb25zdGFudHMgfSBmcm9tICcuLi9jb25zdGFudHMnO1xuaW1wb3J0IHsgQnVpbGRUYXNrTGlzdE9wdGlvbnMsIFByb2plY3RDb25maWcgfSBmcm9tICcuLi90eXBlcyc7XG5pbXBvcnQge1xuICBnZXRMb2NhbE5FT1RyYWNrZXJOYW1lLFxuICBnZXRMb2NhbE5ldHdvcmtOYW1lLFxuICBnZXRQcm9qZWN0UmVzb3VyY2VNYW5hZ2VyLFxuICBsb2FkUHJvamVjdENvbmZpZyxcbiAgbG9hZFByb2plY3RJRCxcbn0gZnJvbSAnLi4vdXRpbHMnO1xuaW1wb3J0IHsgY29tcGlsZUNvbnRyYWN0IH0gZnJvbSAnLi9jb21waWxlQ29udHJhY3QnO1xuaW1wb3J0IHsgZGVwbG95Q29udHJhY3QgfSBmcm9tICcuL2RlcGxveUNvbnRyYWN0JztcbmltcG9ydCB7IGZpbmRDb250cmFjdHMgfSBmcm9tICcuL2ZpbmRDb250cmFjdHMnO1xuaW1wb3J0IHsgZ2VuZXJhdGVDb2RlIH0gZnJvbSAnLi9nZW5lcmF0ZUNvZGUnO1xuaW1wb3J0IHsgQ29tbW9uQ29kZUNvbnRyYWN0LCBnZW5lcmF0ZUNvbW1vbkNvZGUgfSBmcm9tICcuL2dlbmVyYXRlQ29tbW9uQ29kZSc7XG5pbXBvcnQgeyBzZXR1cFdhbGxldHMsIFdBTExFVFMgfSBmcm9tICcuL3NldHVwV2FsbGV0cyc7XG5cbi8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSByZWFkb25seS1hcnJheVxudHlwZSBDb250cmFjdHMgPSBDb21tb25Db2RlQ29udHJhY3RbXTtcbmludGVyZmFjZSBTbWFydENvbnRyYWN0TmV0d29ya3NEZWZpbml0aW9ucyB7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSByZWFkb25seS1rZXl3b3JkXG4gIFtjb250cmFjdE5hbWU6IHN0cmluZ106IFNtYXJ0Q29udHJhY3ROZXR3b3Jrc0RlZmluaXRpb247XG59XG5cbi8vIHRzbGludDpkaXNhYmxlIG5vLWFueVxuY29uc3QgZ2V0UHJvamVjdENvbmZpZyA9IChjdHg6IGFueSk6IFByb2plY3RDb25maWcgPT4gY3R4LnByb2plY3RDb25maWc7XG5jb25zdCBnZXRQcm9qZWN0SUQgPSAoY3R4OiBhbnkpOiBzdHJpbmcgPT4gY3R4LnByb2plY3RJRDtcbmNvbnN0IGdldENvbnRyYWN0UGF0aHMgPSAoY3R4OiBhbnkpOiBDb250cmFjdFBhdGhzID0+IGN0eC5jb250cmFjdFBhdGhzO1xuY29uc3QgZ2V0Q29udHJhY3RzID0gKGN0eDogYW55KTogQ29udHJhY3RzID0+IGN0eC5jb250cmFjdHM7XG5jb25zdCBnZXRTbWFydENvbnRyYWN0TmV0d29ya3NEZWZpbml0aW9ucyA9IChjdHg6IGFueSk6IFNtYXJ0Q29udHJhY3ROZXR3b3Jrc0RlZmluaXRpb25zID0+XG4gIGN0eC5zbWFydENvbnRyYWN0TmV0d29ya0RlZmluaXRpb25zO1xuY29uc3QgZ2V0TmV0d29ya0RlZmluaXRpb25zID0gKGN0eDogYW55KTogcmVhZG9ubHkgTmV0d29ya0RlZmluaXRpb25bXSA9PiBjdHgubmV0d29ya0RlZmluaXRpb25zO1xuY29uc3QgZ2V0V2FsbGV0ID0gKGN0eDogYW55KTogV2FsbGV0ID0+IGN0eC53YWxsZXQ7XG5jb25zdCBnZXROZXR3b3JrTWF5YmUgPSAoY3R4OiBhbnkpOiBOZXR3b3JrIHwgdW5kZWZpbmVkID0+IGN0eC5uZXR3b3JrTWF5YmU7XG5jb25zdCBnZXROZXR3b3JrID0gKGN0eDogYW55KTogTmV0d29yayA9PiBjdHgubmV0d29yaztcbmNvbnN0IGdldFNvdXJjZU1hcHMgPSAoY3R4OiBhbnkpOiBTb3VyY2VNYXBzID0+IGN0eC5zb3VyY2VNYXBzO1xuLy8gdHNsaW50OmVuYWJsZSBuby1hbnlcblxuaW50ZXJmYWNlIE9wdGlvbnMge1xuICByZWFkb25seSBmb3JjZVRyYW5zZmVyPzogYm9vbGVhbjtcbn1cblxuLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIGV4cG9ydC1uYW1lXG5leHBvcnQgY29uc3QgYnVpbGQgPSAoXG4gIHBsdWdpbk1hbmFnZXI6IFBsdWdpbk1hbmFnZXIsXG4gIG9wdGlvbnM6IEJ1aWxkVGFza0xpc3RPcHRpb25zLFxuICB7IGZvcmNlVHJhbnNmZXIgPSBmYWxzZSB9OiBPcHRpb25zID0geyBmb3JjZVRyYW5zZmVyOiBmYWxzZSB9LFxuKTogVGFza0xpc3QgPT5cbiAgbmV3IFRhc2tMaXN0KHtcbiAgICB0YXNrczogW1xuICAgICAge1xuICAgICAgICB0aXRsZTogJ0xvYWQgcHJvamVjdCBjb25maWd1cmF0aW9uJyxcbiAgICAgICAgdGFzazogYXN5bmMgKGN0eCkgPT4ge1xuICAgICAgICAgIGNvbnN0IHByb2plY3RDb25maWcgPSBhd2FpdCBsb2FkUHJvamVjdENvbmZpZyhvcHRpb25zLnJvb3REaXIpO1xuICAgICAgICAgIGxldCBwcm9qZWN0SUQgPSBhd2FpdCBsb2FkUHJvamVjdElEKHBsdWdpbk1hbmFnZXIsIHByb2plY3RDb25maWcsIG9wdGlvbnMpO1xuICAgICAgICAgIGlmIChwcm9qZWN0SUQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgcHJvamVjdElEID0gbmFub2lkKCk7XG4gICAgICAgICAgfVxuXG4gICAgICAgICAgY3R4LnByb2plY3RDb25maWcgPSBwcm9qZWN0Q29uZmlnO1xuICAgICAgICAgIGN0eC5wcm9qZWN0SUQgPSBwcm9qZWN0SUQ7XG4gICAgICAgIH0sXG4gICAgICB9LFxuICAgICAge1xuICAgICAgICB0aXRsZTogJ0ZpbmQgY29udHJhY3RzJyxcbiAgICAgICAgdGFzazogYXN5bmMgKGN0eCkgPT4ge1xuICAgICAgICAgIGNvbnN0IGNvbmZpZyA9IGdldFByb2plY3RDb25maWcoY3R4KTtcbiAgICAgICAgICBjdHguY29udHJhY3RQYXRocyA9IGF3YWl0IGZpbmRDb250cmFjdHMoY29uZmlnKTtcbiAgICAgICAgICBpZiAoY3R4LmNvbnRyYWN0UGF0aHMubGVuZ3RoID09PSAwKSB7XG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYDAgY29tcGlsYWJsZSBzbWFydCBjb250cmFjdHMgZm91bmQgaW4gJHtjb25maWcucGF0aHMuY29udHJhY3RzfWApO1xuICAgICAgICAgIH1cbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHRpdGxlOiAnRGVwbG95IGRldiBjb250cmFjdHMnLFxuICAgICAgICB0YXNrOiAoKSA9PlxuICAgICAgICAgIG5ldyBUYXNrTGlzdCh7XG4gICAgICAgICAgICB0YXNrczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdFbnN1cmUgZGV2ZWxvcG1lbnQgbmV0d29yaycsXG4gICAgICAgICAgICAgICAgdGFzazogKCkgPT5cbiAgICAgICAgICAgICAgICAgIG5ldyBUYXNrTGlzdCh7XG4gICAgICAgICAgICAgICAgICAgIHRhc2tzOiBbXG4gICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdDaGVjayBmb3IgZXhpc3RpbmcgbmV0d29yaycsXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXNrOiBhc3luYyAoY3R4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ldHdvcmsgPSBhd2FpdCBnZXROZXR3b3JrUmVzb3VyY2VNYW5hZ2VyKHBsdWdpbk1hbmFnZXIpXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFJlc291cmNlJCh7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiBnZXRMb2NhbE5ldHdvcmtOYW1lKG9wdGlvbnMucm9vdERpciwgZ2V0UHJvamVjdElEKGN0eCkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgb3B0aW9uczoge30sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAucGlwZSh0YWtlKDEpKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50b1Byb21pc2UoKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAobmV0d29yayAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgZ2V0TmV0d29ya1Jlc291cmNlTWFuYWdlcihwbHVnaW5NYW5hZ2VyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnN0YXJ0KGdldExvY2FsTmV0d29ya05hbWUob3B0aW9ucy5yb290RGlyLCBnZXRQcm9qZWN0SUQoY3R4KSksIHt9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvUHJvbWlzZSgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgY3R4Lm5ldHdvcmtNYXliZSA9IG5ldHdvcms7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdDcmVhdGUgbmV0d29yaycsXG4gICAgICAgICAgICAgICAgICAgICAgICBza2lwOiAoY3R4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGlmIChnZXROZXR3b3JrTWF5YmUoY3R4KSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcmV0dXJuICdOZXR3b3JrIGV4aXN0cyc7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gZmFsc2U7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgdGFzazogKGN0eCkgPT5cbiAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TmV0d29ya1Jlc291cmNlTWFuYWdlcihwbHVnaW5NYW5hZ2VyKS5jcmVhdGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TG9jYWxOZXR3b3JrTmFtZShvcHRpb25zLnJvb3REaXIsIGdldFByb2plY3RJRChjdHgpKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICB7fSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiAnQ3JlYXRlIHdhbGxldHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2tpcDogKGN0eCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoZ2V0TmV0d29ya01heWJlKGN0eCkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnV2FsbGV0cyBhbHJlYWR5IGV4aXN0JztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXNrOiAoKSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICBuZXcgVGFza0xpc3Qoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbmN1cnJlbnQ6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFza3M6IFdBTExFVFMubWFwKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKHdhbGxldCk6IFRhc2sgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6IGBDcmVhdGUgJHt3YWxsZXQubmFtZX0gd2FsbGV0YCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFzazogKGN0eCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ldHdvcmtOYW1lID0gZ2V0TG9jYWxOZXR3b3JrTmFtZShvcHRpb25zLnJvb3REaXIsIGdldFByb2plY3RJRChjdHgpKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBnZXRXYWxsZXRSZXNvdXJjZU1hbmFnZXIocGx1Z2luTWFuYWdlcikuY3JlYXRlKFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgd2FsbGV0Q29uc3RhbnRzLm1ha2VXYWxsZXQoeyBuZXR3b3JrOiBuZXR3b3JrTmFtZSwgbmFtZTogd2FsbGV0Lm5hbWUgfSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7IG5ldHdvcms6IG5ldHdvcmtOYW1lLCBwcml2YXRlS2V5OiB3aWZUb1ByaXZhdGVLZXkod2FsbGV0LnByaXZhdGVLZXkpIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdHYXRoZXIgbmV0d29yayBpbmZvcm1hdGlvbicsXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXNrOiBhc3luYyAoY3R4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ldHdvcmtOYW1lID0gZ2V0TG9jYWxOZXR3b3JrTmFtZShvcHRpb25zLnJvb3REaXIsIGdldFByb2plY3RJRChjdHgpKTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgW25ldHdvcmssIHdhbGxldF0gPSBhd2FpdCBQcm9taXNlLmFsbChbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0TmV0d29ya1Jlc291cmNlTWFuYWdlcihwbHVnaW5NYW5hZ2VyKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLmdldFJlc291cmNlJCh7IG5hbWU6IG5ldHdvcmtOYW1lLCBvcHRpb25zOiB7fSB9KVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnBpcGUoXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGZpbHRlcih1dGlscy5ub3ROdWxsKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgdGFrZSgxKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC50b1Byb21pc2UoKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRXYWxsZXRSZXNvdXJjZU1hbmFnZXIocGx1Z2luTWFuYWdlcilcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIC5nZXRSZXNvdXJjZSQoe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICBuYW1lOiB3YWxsZXRDb25zdGFudHMubWFrZU1hc3RlcldhbGxldChuZXR3b3JrTmFtZSksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG9wdGlvbnM6IHsgbmV0d29yazogbmV0d29ya05hbWUgfSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0pXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAucGlwZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZmlsdGVyKHV0aWxzLm5vdE51bGwpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB0YWtlKDEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLnRvUHJvbWlzZSgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBdKTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICBjdHgubmV0d29yayA9IG5ldHdvcms7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC53YWxsZXQgPSB3YWxsZXQ7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIGN0eC5uZXR3b3JrRGVmaW5pdGlvbnMgPSBbXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogY29uc3RhbnRzLkxPQ0FMX05FVFdPUktfTkFNRSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJwY1VSTDogbmV0d29yay5ub2Rlc1swXS5ycGNBZGRyZXNzLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgIF07XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdTZXR1cCBORU8gVHJhY2tlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXNrOiAoY3R4KSA9PlxuICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRORU9UcmFja2VyUmVzb3VyY2VNYW5hZ2VyKHBsdWdpbk1hbmFnZXIpLmNyZWF0ZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBnZXRMb2NhbE5FT1RyYWNrZXJOYW1lKGdldExvY2FsTmV0d29ya05hbWUob3B0aW9ucy5yb290RGlyLCBnZXRQcm9qZWN0SUQoY3R4KSkpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIG5ldHdvcms6IGdldE5ldHdvcmsoY3R4KS5uYW1lLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICksXG4gICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogJ1RyYW5zZmVyIHRvIHdhbGxldHMnLFxuICAgICAgICAgICAgICAgICAgICAgICAgc2tpcDogKGN0eCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICBpZiAoIWZvcmNlVHJhbnNmZXIgJiYgZ2V0TmV0d29ya01heWJlKGN0eCkgIT09IHVuZGVmaW5lZCkge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiAnV2FsbGV0cyBhbHJlYWR5IGV4aXN0JztcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfVxuXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHJldHVybiBmYWxzZTtcbiAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB0YXNrOiBhc3luYyAoY3R4KSA9PiB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgICAgYXdhaXQgc2V0dXBXYWxsZXRzKGdldE5ldHdvcmsoY3R4KSwgZ2V0V2FsbGV0KGN0eCkud2lmISk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgIHRpdGxlOiAnRGVwbG95JyxcbiAgICAgICAgICAgICAgICB0YXNrOiAoY3R4KSA9PiB7XG4gICAgICAgICAgICAgICAgICBjdHguc21hcnRDb250cmFjdE5ldHdvcmtEZWZpbml0aW9ucyA9IHt9O1xuICAgICAgICAgICAgICAgICAgY3R4LmNvbnRyYWN0cyA9IFtdO1xuICAgICAgICAgICAgICAgICAgY29uc3QgbXV0YWJsZUxpbmtlZDogeyBbZmlsZVBhdGg6IHN0cmluZ106IHsgW25hbWU6IHN0cmluZ106IHN0cmluZyB9IH0gPSB7fTtcbiAgICAgICAgICAgICAgICAgIGNvbnN0IG11dGFibGVTb3VyY2VNYXBzOiBNb2RpZmlhYmxlPFNvdXJjZU1hcHM+ID0ge307XG4gICAgICAgICAgICAgICAgICBjdHguc291cmNlTWFwcyA9IG11dGFibGVTb3VyY2VNYXBzO1xuXG4gICAgICAgICAgICAgICAgICByZXR1cm4gbmV3IFRhc2tMaXN0KHtcbiAgICAgICAgICAgICAgICAgICAgdGFza3M6IGdldENvbnRyYWN0UGF0aHMoY3R4KS5tYXAoKGNvbnRyYWN0UGF0aCkgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgICB0aXRsZTogYERlcGxveSAke2NvbnRyYWN0UGF0aC5uYW1lfWAsXG4gICAgICAgICAgICAgICAgICAgICAgdGFzazogYXN5bmMgKCkgPT4ge1xuICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgY29udHJhY3QgPSBhd2FpdCBjb21waWxlQ29udHJhY3QoY29udHJhY3RQYXRoLmZpbGVQYXRoLCBjb250cmFjdFBhdGgubmFtZSwgbXV0YWJsZUxpbmtlZCk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGlmIChcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29udHJhY3QuZGlhZ25vc3RpY3Muc29tZSgoZGlhZ25vc3RpYykgPT4gZGlhZ25vc3RpYy5jYXRlZ29yeSA9PT0gRGlhZ25vc3RpY0NhdGVnb3J5LkVycm9yKVxuICAgICAgICAgICAgICAgICAgICAgICAgKSB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRocm93IG5ldyBFcnJvcignQ29tcGlsYXRpb24gZXJyb3IuJyk7XG4gICAgICAgICAgICAgICAgICAgICAgICB9XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ldHdvcmsgPSBnZXROZXR3b3JrKGN0eCk7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBhZGRyZXNzID0gc2NyaXB0SGFzaFRvQWRkcmVzcyhcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29tbW9uLnVJbnQxNjBUb1N0cmluZyhjcnlwdG8udG9TY3JpcHRIYXNoKEJ1ZmZlci5mcm9tKGNvbnRyYWN0LmNvbnRyYWN0LnNjcmlwdCwgJ2hleCcpKSksXG4gICAgICAgICAgICAgICAgICAgICAgICApO1xuICAgICAgICAgICAgICAgICAgICAgICAgbXV0YWJsZVNvdXJjZU1hcHNbYWRkcmVzc10gPSBjb250cmFjdC5zb3VyY2VNYXA7XG4gICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBbcHJvZE5ldHdvcmtzRGVmaW5pdGlvbl0gPSBhd2FpdCBQcm9taXNlLmFsbDxTbWFydENvbnRyYWN0TmV0d29ya3NEZWZpbml0aW9uLCBzdHJpbmc+KFtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgUHJvbWlzZS5yZXNvbHZlKHt9KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICBkZXBsb3lDb250cmFjdChuZXR3b3JrLCBjb250cmFjdCwgbXV0YWJsZVNvdXJjZU1hcHMsIGdldFdhbGxldChjdHgpLndpZiEpLFxuICAgICAgICAgICAgICAgICAgICAgICAgXSk7XG5cbiAgICAgICAgICAgICAgICAgICAgICAgIG11dGFibGVMaW5rZWRbY29udHJhY3RQYXRoLmZpbGVQYXRoXSA9IHsgW2NvbnRyYWN0UGF0aC5uYW1lXTogYWRkcmVzcyB9O1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tYXJyYXktbXV0YXRpb25cbiAgICAgICAgICAgICAgICAgICAgICAgIGdldENvbnRyYWN0cyhjdHgpLnB1c2goe1xuICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5jb250cmFjdCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgYWRkcmVzc2VzOiBbYWRkcmVzc10uY29uY2F0KFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIE9iamVjdC52YWx1ZXMocHJvZE5ldHdvcmtzRGVmaW5pdGlvbikubWFwKCh7IGFkZHJlc3M6IHZhbHVlIH0pID0+IHZhbHVlKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tb2JqZWN0LW11dGF0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICBnZXRTbWFydENvbnRyYWN0TmV0d29ya3NEZWZpbml0aW9ucyhjdHgpW2NvbnRyYWN0Lm5hbWVdID0ge1xuICAgICAgICAgICAgICAgICAgICAgICAgICAuLi5wcm9kTmV0d29ya3NEZWZpbml0aW9uLFxuICAgICAgICAgICAgICAgICAgICAgICAgICBbY29uc3RhbnRzLkxPQ0FMX05FVFdPUktfTkFNRV06IHsgYWRkcmVzcyB9LFxuICAgICAgICAgICAgICAgICAgICAgICAgfTtcbiAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICB9KSksXG4gICAgICAgICAgICAgICAgICB9KTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICB9KSxcbiAgICAgIH0sXG4gICAgICB7XG4gICAgICAgIHRpdGxlOiAnU3luY2hyb25pemUgcHJvamVjdCcsXG4gICAgICAgIHRhc2s6ICgpID0+XG4gICAgICAgICAgbmV3IFRhc2tMaXN0KHtcbiAgICAgICAgICAgIGNvbmN1cnJlbnQ6IHRydWUsXG4gICAgICAgICAgICB0YXNrczogW1xuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdTYXZlIHByb2plY3QgaW5mbycsXG4gICAgICAgICAgICAgICAgdGFzazogYXN5bmMgKGN0eCkgPT4ge1xuICAgICAgICAgICAgICAgICAgY29uc3QgcHJvamVjdElEID0gZ2V0UHJvamVjdElEKGN0eCk7XG4gICAgICAgICAgICAgICAgICBjb25zdCBzb3VyY2VNYXBzID0gZ2V0U291cmNlTWFwcyhjdHgpO1xuICAgICAgICAgICAgICAgICAgY29uc3QgcHJvamVjdE9wdGlvbnMgPSB7XG4gICAgICAgICAgICAgICAgICAgIHJvb3REaXI6IG9wdGlvbnMucm9vdERpcixcbiAgICAgICAgICAgICAgICAgICAgc291cmNlTWFwcyxcbiAgICAgICAgICAgICAgICAgIH07XG4gICAgICAgICAgICAgICAgICBhd2FpdCBnZXRQcm9qZWN0UmVzb3VyY2VNYW5hZ2VyKHBsdWdpbk1hbmFnZXIpXG4gICAgICAgICAgICAgICAgICAgIC5kZWxldGUocHJvamVjdElELCBwcm9qZWN0T3B0aW9ucylcbiAgICAgICAgICAgICAgICAgICAgLnRvUHJvbWlzZSgpO1xuICAgICAgICAgICAgICAgICAgYXdhaXQgZ2V0UHJvamVjdFJlc291cmNlTWFuYWdlcihwbHVnaW5NYW5hZ2VyKVxuICAgICAgICAgICAgICAgICAgICAuY3JlYXRlKHByb2plY3RJRCwgcHJvamVjdE9wdGlvbnMpXG4gICAgICAgICAgICAgICAgICAgIC50b1Byb21pc2UoKTtcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgdGl0bGU6ICdHZW5lcmF0ZSBjb2RlJyxcbiAgICAgICAgICAgICAgICB0YXNrOiAoY3R4KSA9PlxuICAgICAgICAgICAgICAgICAgbmV3IFRhc2tMaXN0KHtcbiAgICAgICAgICAgICAgICAgICAgY29uY3VycmVudDogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgdGFza3M6IGdldENvbnRyYWN0cyhjdHgpXG4gICAgICAgICAgICAgICAgICAgICAgLmZpbHRlcigoeyBuYW1lIH0pID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgIGNvbnN0IG5ldHdvcmtzRGVmaW5pdGlvbiA9IGdldFNtYXJ0Q29udHJhY3ROZXR3b3Jrc0RlZmluaXRpb25zKGN0eClbbmFtZV0gYXNcbiAgICAgICAgICAgICAgICAgICAgICAgICAgfCBTbWFydENvbnRyYWN0TmV0d29ya3NEZWZpbml0aW9uXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHwgdW5kZWZpbmVkO1xuXG4gICAgICAgICAgICAgICAgICAgICAgICByZXR1cm4gbmV0d29ya3NEZWZpbml0aW9uICE9PSB1bmRlZmluZWQ7XG4gICAgICAgICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAgICAgICAubWFwKChjb250cmFjdCkgPT4gKHtcbiAgICAgICAgICAgICAgICAgICAgICAgIHRpdGxlOiBgR2VuZXJhdGUgJHtjb250cmFjdC5uYW1lfSBjb2RlYCxcbiAgICAgICAgICAgICAgICAgICAgICAgIHRhc2s6IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgcHJvamVjdCA9IGdldFByb2plY3RDb25maWcoY3R4KTtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgY29uc3QgbmV0d29ya3NEZWZpbml0aW9uID0gZ2V0U21hcnRDb250cmFjdE5ldHdvcmtzRGVmaW5pdGlvbnMoY3R4KVtjb250cmFjdC5uYW1lXTtcblxuICAgICAgICAgICAgICAgICAgICAgICAgICBhd2FpdCBnZW5lcmF0ZUNvZGUocHJvamVjdCwgY29udHJhY3QsIG5ldHdvcmtzRGVmaW5pdGlvbiwgcHJvamVjdC5jb2RlZ2VuLmJyb3dzZXIpO1xuICAgICAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICAgICAgICB9KSlcbiAgICAgICAgICAgICAgICAgICAgICAuY29uY2F0KFtcbiAgICAgICAgICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgdGl0bGU6ICdHZW5lcmF0ZSBjb21tb24gY29kZScsXG4gICAgICAgICAgICAgICAgICAgICAgICAgIHRhc2s6IGFzeW5jICgpID0+IHtcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdCBwcm9qZWN0ID0gZ2V0UHJvamVjdENvbmZpZyhjdHgpO1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGF3YWl0IGdlbmVyYXRlQ29tbW9uQ29kZShcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFByb2plY3RDb25maWcoY3R4KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFByb2plY3RJRChjdHgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgZ2V0Q29udHJhY3RzKGN0eCksXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBjb25zdGFudHMuTE9DQUxfTkVUV09SS19OQU1FLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgW1xuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgbmFtZTogJ21hc3RlcicsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByaXZhdGVLZXk6IGdldFdhbGxldChjdHgpLndpZiEsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgICBdLmNvbmNhdChXQUxMRVRTKSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldE5ldHdvcmtEZWZpbml0aW9ucyhjdHgpLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICAgcGx1Z2luTWFuYWdlci5odHRwU2VydmVyUG9ydCxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdldFNvdXJjZU1hcHMoY3R4KSxcbiAgICAgICAgICAgICAgICAgICAgICAgICAgICAgIHByb2plY3QuY29kZWdlbi5icm93c2VyLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICAgIF0pLFxuICAgICAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICAgIH0pLFxuICAgICAgfSxcbiAgICBdLFxuICB9KTtcbiJdfQ==