UNPKG

32.6 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const tslib_1 = require("tslib");
4const ts_utils_1 = require("@neo-one/ts-utils");
5const utils_1 = require("@neo-one/utils");
6const appRootDir = tslib_1.__importStar(require("app-root-dir"));
7const fs = tslib_1.__importStar(require("fs-extra")); // tslint:disable-next-line match-default-export-name
8const glob_1 = tslib_1.__importDefault(require("glob"));
9const path = tslib_1.__importStar(require("path"));
10const typescript_1 = tslib_1.__importDefault(require("typescript"));
11const Context_1 = require("./Context");
12const utils_2 = require("./utils");
13function createContext(program, typeChecker, languageService, smartContractDir) {
14 return new Context_1.Context(program, typeChecker, languageService, smartContractDir);
15}
16function updateContext(context, files) {
17 const { program, typeChecker, languageService, smartContractDir } = createProgram(context.program.getCompilerOptions(), Object.keys(files), {
18 modifyHost: createModifyHostFiles(files),
19 // tslint:disable-next-line no-any
20 withTestHarness: context.program.__withTestHarness
21 });
22 return context.update(program, typeChecker, languageService, smartContractDir);
23}
24exports.updateContext = updateContext;
25const doGlob = async (value) => new Promise((resolve, reject) => glob_1.default(value, (error, matches) => {
26 if (error) {
27 reject(error);
28 }
29 else {
30 resolve(matches);
31 }
32}));
33const CREATE_CONTEXT_OPTIONS_DEFAULT = {
34 withTestHarness: false
35};
36const defaultModifyHost = () => {
37};
38const DEFAULT_MAKE_CONTEXT_OPTIONS = Object.assign({}, CREATE_CONTEXT_OPTIONS_DEFAULT, { modifyHost: defaultModifyHost });
39const makeContext = (rootNames, options = DEFAULT_MAKE_CONTEXT_OPTIONS) => {
40 const tsConfigFilePath = utils_2.pathResolve(require.resolve('@neo-one/smart-contract'), '..', '..', 'tsconfig.json');
41 const res = typescript_1.default.readConfigFile(tsConfigFilePath, value => fs.readFileSync(value, 'utf8'));
42 const parseConfigHost = {
43 fileExists: fs.existsSync,
44 readDirectory: typescript_1.default.sys.readDirectory,
45 readFile: typescript_1.default.sys.readFile,
46 useCaseSensitiveFileNames: true
47 };
48 const parsed = typescript_1.default.parseJsonConfigFileContent(res.config, parseConfigHost, path.dirname(tsConfigFilePath));
49 const { program, typeChecker, languageService, smartContractDir } = createProgram(parsed.options, rootNames, options);
50 return createContext(program, typeChecker, languageService, smartContractDir);
51};
52const createModifyHostFiles = (files) => (host) => {
53 const originalFileExists = host.fileExists === undefined ? typescript_1.default.sys.fileExists : host.fileExists.bind(host); // tslint:disable-next-line no-object-mutation no-any
54 host.fileExists = file => {
55 if (files[file] !== undefined) {
56 return true;
57 }
58 return originalFileExists(file);
59 };
60 const originalReadFile = host.readFile === undefined ? typescript_1.default.sys.readFile : host.readFile.bind(host); // tslint:disable-next-line no-object-mutation no-any
61 host.readFile = (file, ...args) => {
62 const foundFile = files[file];
63 if (foundFile !== undefined) {
64 return foundFile;
65 }
66 return originalReadFile(file, ...args);
67 };
68};
69const createProgram = (options, rootNamesIn, { modifyHost = defaultModifyHost, withTestHarness = false } = DEFAULT_MAKE_CONTEXT_OPTIONS) => {
70 const smartContractDir = path.dirname(require.resolve('@neo-one/smart-contract'));
71 const smartContractModule = utils_2.pathResolve(smartContractDir, 'index.d.ts');
72 const smartContractInternalModule = utils_2.pathResolve(smartContractDir, 'internal.d.ts');
73 const smartContractFiles = [utils_2.pathResolve(smartContractDir, 'global.d.ts'), smartContractInternalModule, smartContractModule, withTestHarness ? utils_2.pathResolve(smartContractDir, 'harness.d.ts') : undefined].filter(utils_1.utils.notNull);
74 const rootNames = [...new Set(rootNamesIn.concat(smartContractFiles))].map(utils_2.normalizePath);
75 const mutableFiles = {}; // initialize the list of files
76 rootNames.forEach(fileName => {
77 mutableFiles[fileName] = {
78 version: 0
79 };
80 });
81 const servicesHost = {
82 getScriptFileNames: () => [...rootNames],
83 getScriptVersion: fileName => {
84 const file = mutableFiles[fileName];
85 return file === undefined ? '' : file.version.toString();
86 },
87 getScriptSnapshot: fileName => {
88 // tslint:disable-next-line no-non-null-assertion
89 if (!servicesHost.fileExists(fileName)) {
90 return undefined;
91 } // tslint:disable-next-line no-non-null-assertion
92 return typescript_1.default.ScriptSnapshot.fromString(servicesHost.readFile(fileName));
93 },
94 getCurrentDirectory: () => process.cwd(),
95 getCompilationSettings: () => options,
96 getDefaultLibFileName: opts => typescript_1.default.getDefaultLibFilePath(opts),
97 useCaseSensitiveFileNames: () => typescript_1.default.sys.useCaseSensitiveFileNames,
98 getNewLine: () => typescript_1.default.sys.newLine,
99 fileExists: typescript_1.default.sys.fileExists,
100 readFile: typescript_1.default.sys.readFile,
101 readDirectory: typescript_1.default.sys.readDirectory,
102 resolveModuleNames
103 };
104 const smartContractLibModule = utils_2.pathResolve(path.dirname(require.resolve('@neo-one/smart-contract-lib')), 'index.ts');
105 function resolveModuleNames(moduleNames, containingFile) {
106 const mutableResolvedModules = []; // tslint:disable-next-line no-loop-statement
107 for (const moduleName of moduleNames) {
108 // tslint:disable-next-line prefer-switch
109 if (moduleName === '@neo-one/smart-contract-internal') {
110 mutableResolvedModules.push({
111 resolvedFileName: smartContractInternalModule
112 });
113 }
114 else if (moduleName === '@neo-one/smart-contract') {
115 mutableResolvedModules.push({
116 resolvedFileName: smartContractModule
117 });
118 }
119 else if (moduleName === '@neo-one/smart-contract-lib') {
120 mutableResolvedModules.push({
121 resolvedFileName: smartContractLibModule
122 });
123 }
124 else {
125 const result = typescript_1.default.resolveModuleName(moduleName, containingFile, options, {
126 fileExists: typescript_1.default.sys.fileExists,
127 readFile: typescript_1.default.sys.readFile
128 }); // tslint:disable-next-line no-non-null-assertion
129 mutableResolvedModules.push(result.resolvedModule);
130 }
131 }
132 return mutableResolvedModules;
133 }
134 modifyHost(servicesHost);
135 const languageService = typescript_1.default.createLanguageService(servicesHost);
136 const program = languageService.getProgram();
137 if (program === undefined) {
138 throw new Error('Something went wrong');
139 } // tslint:disable-next-line no-any no-object-mutation
140 program.__withTestHarness = withTestHarness;
141 return {
142 program,
143 typeChecker: program.getTypeChecker(),
144 languageService,
145 smartContractDir
146 };
147};
148exports.createContextForDir = async (dir, options = CREATE_CONTEXT_OPTIONS_DEFAULT) => {
149 const files = await doGlob(path.join(dir, '**', '*.ts'));
150 return makeContext(files, options);
151};
152exports.createContextForPath = (filePath, options = CREATE_CONTEXT_OPTIONS_DEFAULT) => makeContext([filePath], options);
153exports.createContextForSnippet = (code, options = CREATE_CONTEXT_OPTIONS_DEFAULT) => {
154 const dir = appRootDir.get();
155 const fileName = utils_2.pathResolve(dir, 'snippetCode.ts');
156 const context = makeContext([fileName], Object.assign({}, options, { modifyHost: createModifyHostFiles({
157 [fileName]: code
158 }) }));
159 const sourceFile = ts_utils_1.tsUtils.file.getSourceFileOrThrow(context.program, fileName);
160 return {
161 context,
162 sourceFile
163 };
164};
165exports.createContextForLanguageService = (languageService, smartContractDir) => {
166 const program = languageService.getProgram();
167 if (program === undefined) {
168 throw new Error('Something went wrong');
169 }
170 return createContext(program, program.getTypeChecker(), languageService, smartContractDir);
171};
172
173//# sourceMappingURL=data:application/json;charset=utf8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbImNyZWF0ZUNvbnRleHQudHMiXSwibmFtZXMiOlsiY3JlYXRlQ29udGV4dCIsInByb2dyYW0iLCJ0eXBlQ2hlY2tlciIsImxhbmd1YWdlU2VydmljZSIsInNtYXJ0Q29udHJhY3REaXIiLCJDb250ZXh0IiwidXBkYXRlQ29udGV4dCIsImNvbnRleHQiLCJmaWxlcyIsImNyZWF0ZVByb2dyYW0iLCJnZXRDb21waWxlck9wdGlvbnMiLCJPYmplY3QiLCJrZXlzIiwibW9kaWZ5SG9zdCIsImNyZWF0ZU1vZGlmeUhvc3RGaWxlcyIsIndpdGhUZXN0SGFybmVzcyIsIl9fd2l0aFRlc3RIYXJuZXNzIiwidXBkYXRlIiwiZG9HbG9iIiwidmFsdWUiLCJQcm9taXNlIiwicmVzb2x2ZSIsInJlamVjdCIsImdsb2IiLCJlcnJvciIsIm1hdGNoZXMiLCJDUkVBVEVfQ09OVEVYVF9PUFRJT05TX0RFRkFVTFQiLCJkZWZhdWx0TW9kaWZ5SG9zdCIsIkRFRkFVTFRfTUFLRV9DT05URVhUX09QVElPTlMiLCJtYWtlQ29udGV4dCIsInJvb3ROYW1lcyIsIm9wdGlvbnMiLCJ0c0NvbmZpZ0ZpbGVQYXRoIiwicGF0aFJlc29sdmUiLCJyZXF1aXJlIiwicmVzIiwidHMiLCJyZWFkQ29uZmlnRmlsZSIsImZzIiwicmVhZEZpbGVTeW5jIiwicGFyc2VDb25maWdIb3N0IiwiZmlsZUV4aXN0cyIsImV4aXN0c1N5bmMiLCJyZWFkRGlyZWN0b3J5Iiwic3lzIiwicmVhZEZpbGUiLCJ1c2VDYXNlU2Vuc2l0aXZlRmlsZU5hbWVzIiwicGFyc2VkIiwicGFyc2VKc29uQ29uZmlnRmlsZUNvbnRlbnQiLCJjb25maWciLCJwYXRoIiwiZGlybmFtZSIsImhvc3QiLCJvcmlnaW5hbEZpbGVFeGlzdHMiLCJ1bmRlZmluZWQiLCJiaW5kIiwiZmlsZSIsIm9yaWdpbmFsUmVhZEZpbGUiLCJhcmdzIiwiZm91bmRGaWxlIiwicm9vdE5hbWVzSW4iLCJzbWFydENvbnRyYWN0TW9kdWxlIiwic21hcnRDb250cmFjdEludGVybmFsTW9kdWxlIiwic21hcnRDb250cmFjdEZpbGVzIiwiZmlsdGVyIiwidXRpbHMiLCJub3ROdWxsIiwiU2V0IiwiY29uY2F0IiwibWFwIiwibm9ybWFsaXplUGF0aCIsIm11dGFibGVGaWxlcyIsImZvckVhY2giLCJmaWxlTmFtZSIsInZlcnNpb24iLCJzZXJ2aWNlc0hvc3QiLCJnZXRTY3JpcHRGaWxlTmFtZXMiLCJnZXRTY3JpcHRWZXJzaW9uIiwidG9TdHJpbmciLCJnZXRTY3JpcHRTbmFwc2hvdCIsIlNjcmlwdFNuYXBzaG90IiwiZnJvbVN0cmluZyIsImdldEN1cnJlbnREaXJlY3RvcnkiLCJwcm9jZXNzIiwiY3dkIiwiZ2V0Q29tcGlsYXRpb25TZXR0aW5ncyIsImdldERlZmF1bHRMaWJGaWxlTmFtZSIsIm9wdHMiLCJnZXREZWZhdWx0TGliRmlsZVBhdGgiLCJnZXROZXdMaW5lIiwibmV3TGluZSIsInJlc29sdmVNb2R1bGVOYW1lcyIsInNtYXJ0Q29udHJhY3RMaWJNb2R1bGUiLCJtb2R1bGVOYW1lcyIsImNvbnRhaW5pbmdGaWxlIiwibXV0YWJsZVJlc29sdmVkTW9kdWxlcyIsIm1vZHVsZU5hbWUiLCJwdXNoIiwicmVzb2x2ZWRGaWxlTmFtZSIsInJlc3VsdCIsInJlc29sdmVNb2R1bGVOYW1lIiwicmVzb2x2ZWRNb2R1bGUiLCJjcmVhdGVMYW5ndWFnZVNlcnZpY2UiLCJnZXRQcm9ncmFtIiwiRXJyb3IiLCJnZXRUeXBlQ2hlY2tlciIsImNyZWF0ZUNvbnRleHRGb3JEaXIiLCJkaXIiLCJqb2luIiwiY3JlYXRlQ29udGV4dEZvclBhdGgiLCJmaWxlUGF0aCIsImNyZWF0ZUNvbnRleHRGb3JTbmlwcGV0IiwiY29kZSIsImFwcFJvb3REaXIiLCJnZXQiLCJzb3VyY2VGaWxlIiwidHNVdGlscyIsImdldFNvdXJjZUZpbGVPclRocm93IiwiY3JlYXRlQ29udGV4dEZvckxhbmd1YWdlU2VydmljZSJdLCJtYXBwaW5ncyI6Ijs7O0FBQUEsZ0RBQUE7QUFDQSwwQ0FBQTtBQUNB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QU0sSUFBSWtELEtBQUosQ0FBVSxzQkFBVixDQUFOLENBQUE7S0FDRDtJQUVELE9BQU94RyxhQUFhLENBQUNDLE9BQUQsRUFBVUEsT0FBTyxDQUFDd0csY0FBUixFQUFWLEVBQW9DdEcsZUFBcEMsRUFBcURDLGdCQUFyRCxDQUFwQixDQUFBO0FBQ0QsQ0FWTSxDQUFBIiwiZmlsZSI6Im5lby1vbmUtc21hcnQtY29udHJhY3QtY29tcGlsZXIvc3JjL2NyZWF0ZUNvbnRleHQuanMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyB0c1V0aWxzIH0gZnJvbSAnQG5lby1vbmUvdHMtdXRpbHMnO1xuaW1wb3J0IHsgdXRpbHMgfSBmcm9tICdAbmVvLW9uZS91dGlscyc7XG5pbXBvcnQgKiBhcyBhcHBSb290RGlyIGZyb20gJ2FwcC1yb290LWRpcic7XG5pbXBvcnQgKiBhcyBmcyBmcm9tICdmcy1leHRyYSc7XG4vLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbWF0Y2gtZGVmYXVsdC1leHBvcnQtbmFtZVxuaW1wb3J0IGdsb2IgZnJvbSAnZ2xvYic7XG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gJ3BhdGgnO1xuaW1wb3J0IHRzIGZyb20gJ3R5cGVzY3JpcHQnO1xuaW1wb3J0IHsgQ29udGV4dCB9IGZyb20gJy4vQ29udGV4dCc7XG5pbXBvcnQgeyBub3JtYWxpemVQYXRoLCBwYXRoUmVzb2x2ZSB9IGZyb20gJy4vdXRpbHMnO1xuXG5mdW5jdGlvbiBjcmVhdGVDb250ZXh0KFxuICBwcm9ncmFtOiB0cy5Qcm9ncmFtLFxuICB0eXBlQ2hlY2tlcjogdHMuVHlwZUNoZWNrZXIsXG4gIGxhbmd1YWdlU2VydmljZTogdHMuTGFuZ3VhZ2VTZXJ2aWNlLFxuICBzbWFydENvbnRyYWN0RGlyOiBzdHJpbmcsXG4pOiBDb250ZXh0IHtcbiAgcmV0dXJuIG5ldyBDb250ZXh0KHByb2dyYW0sIHR5cGVDaGVja2VyLCBsYW5ndWFnZVNlcnZpY2UsIHNtYXJ0Q29udHJhY3REaXIpO1xufVxuXG5leHBvcnQgZnVuY3Rpb24gdXBkYXRlQ29udGV4dChjb250ZXh0OiBDb250ZXh0LCBmaWxlczogeyByZWFkb25seSBbZmlsZU5hbWU6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZCB9KTogQ29udGV4dCB7XG4gIGNvbnN0IHsgcHJvZ3JhbSwgdHlwZUNoZWNrZXIsIGxhbmd1YWdlU2VydmljZSwgc21hcnRDb250cmFjdERpciB9ID0gY3JlYXRlUHJvZ3JhbShcbiAgICBjb250ZXh0LnByb2dyYW0uZ2V0Q29tcGlsZXJPcHRpb25zKCksXG4gICAgT2JqZWN0LmtleXMoZmlsZXMpLFxuICAgIHtcbiAgICAgIG1vZGlmeUhvc3Q6IGNyZWF0ZU1vZGlmeUhvc3RGaWxlcyhmaWxlcyksXG4gICAgICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tYW55XG4gICAgICB3aXRoVGVzdEhhcm5lc3M6IChjb250ZXh0LnByb2dyYW0gYXMgYW55KS5fX3dpdGhUZXN0SGFybmVzcyxcbiAgICB9LFxuICApO1xuXG4gIHJldHVybiBjb250ZXh0LnVwZGF0ZShwcm9ncmFtLCB0eXBlQ2hlY2tlciwgbGFuZ3VhZ2VTZXJ2aWNlLCBzbWFydENvbnRyYWN0RGlyKTtcbn1cblxuY29uc3QgZG9HbG9iID0gYXN5bmMgKHZhbHVlOiBzdHJpbmcpID0+XG4gIG5ldyBQcm9taXNlPFJlYWRvbmx5QXJyYXk8c3RyaW5nPj4oKHJlc29sdmUsIHJlamVjdCkgPT5cbiAgICBnbG9iKHZhbHVlLCAoZXJyb3IsIG1hdGNoZXMpID0+IHtcbiAgICAgIGlmIChlcnJvcikge1xuICAgICAgICByZWplY3QoZXJyb3IpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgcmVzb2x2ZShtYXRjaGVzKTtcbiAgICAgIH1cbiAgICB9KSxcbiAgKTtcblxuZXhwb3J0IGludGVyZmFjZSBDcmVhdGVDb250ZXh0T3B0aW9ucyB7XG4gIHJlYWRvbmx5IHdpdGhUZXN0SGFybmVzcz86IGJvb2xlYW47XG59XG5cbmNvbnN0IENSRUFURV9DT05URVhUX09QVElPTlNfREVGQVVMVCA9IHtcbiAgd2l0aFRlc3RIYXJuZXNzOiBmYWxzZSxcbn07XG5cbmNvbnN0IGRlZmF1bHRNb2RpZnlIb3N0ID0gKCkgPT4ge1xuICAvLyBkbyBub3RoaW5nXG59O1xuXG5pbnRlcmZhY2UgTWFrZUNvbnRleHRPcHRpb25zIGV4dGVuZHMgQ3JlYXRlQ29udGV4dE9wdGlvbnMge1xuICByZWFkb25seSBtb2RpZnlIb3N0PzogKGhvc3Q6IHRzLkxhbmd1YWdlU2VydmljZUhvc3QpID0+IHZvaWQ7XG59XG5cbmNvbnN0IERFRkFVTFRfTUFLRV9DT05URVhUX09QVElPTlMgPSB7XG4gIC4uLkNSRUFURV9DT05URVhUX09QVElPTlNfREVGQVVMVCxcbiAgbW9kaWZ5SG9zdDogZGVmYXVsdE1vZGlmeUhvc3QsXG59O1xuXG5jb25zdCBtYWtlQ29udGV4dCA9IChcbiAgcm9vdE5hbWVzOiBSZWFkb25seUFycmF5PHN0cmluZz4sXG4gIG9wdGlvbnM6IE1ha2VDb250ZXh0T3B0aW9ucyA9IERFRkFVTFRfTUFLRV9DT05URVhUX09QVElPTlMsXG4pOiBDb250ZXh0ID0+IHtcbiAgY29uc3QgdHNDb25maWdGaWxlUGF0aCA9IHBhdGhSZXNvbHZlKHJlcXVpcmUucmVzb2x2ZSgnQG5lby1vbmUvc21hcnQtY29udHJhY3QnKSwgJy4uJywgJy4uJywgJ3RzY29uZmlnLmpzb24nKTtcblxuICBjb25zdCByZXMgPSB0cy5yZWFkQ29uZmlnRmlsZSh0c0NvbmZpZ0ZpbGVQYXRoLCAodmFsdWUpID0+IGZzLnJlYWRGaWxlU3luYyh2YWx1ZSwgJ3V0ZjgnKSk7XG4gIGNvbnN0IHBhcnNlQ29uZmlnSG9zdCA9IHtcbiAgICBmaWxlRXhpc3RzOiBmcy5leGlzdHNTeW5jLFxuICAgIHJlYWREaXJlY3Rvcnk6IHRzLnN5cy5yZWFkRGlyZWN0b3J5LFxuICAgIHJlYWRGaWxlOiB0cy5zeXMucmVhZEZpbGUsXG4gICAgdXNlQ2FzZVNlbnNpdGl2ZUZpbGVOYW1lczogdHJ1ZSxcbiAgfTtcbiAgY29uc3QgcGFyc2VkID0gdHMucGFyc2VKc29uQ29uZmlnRmlsZUNvbnRlbnQocmVzLmNvbmZpZywgcGFyc2VDb25maWdIb3N0LCBwYXRoLmRpcm5hbWUodHNDb25maWdGaWxlUGF0aCkpO1xuXG4gIGNvbnN0IHsgcHJvZ3JhbSwgdHlwZUNoZWNrZXIsIGxhbmd1YWdlU2VydmljZSwgc21hcnRDb250cmFjdERpciB9ID0gY3JlYXRlUHJvZ3JhbShwYXJzZWQub3B0aW9ucywgcm9vdE5hbWVzLCBvcHRpb25zKTtcblxuICByZXR1cm4gY3JlYXRlQ29udGV4dChwcm9ncmFtLCB0eXBlQ2hlY2tlciwgbGFuZ3VhZ2VTZXJ2aWNlLCBzbWFydENvbnRyYWN0RGlyKTtcbn07XG5cbmNvbnN0IGNyZWF0ZU1vZGlmeUhvc3RGaWxlcyA9IChmaWxlczogeyByZWFkb25seSBbZmlsZU5hbWU6IHN0cmluZ106IHN0cmluZyB8IHVuZGVmaW5lZCB9KSA9PiAoXG4gIGhvc3Q6IHRzLkxhbmd1YWdlU2VydmljZUhvc3QsXG4pID0+IHtcbiAgY29uc3Qgb3JpZ2luYWxGaWxlRXhpc3RzID0gaG9zdC5maWxlRXhpc3RzID09PSB1bmRlZmluZWQgPyB0cy5zeXMuZmlsZUV4aXN0cyA6IGhvc3QuZmlsZUV4aXN0cy5iaW5kKGhvc3QpO1xuICAvLyB0c2xpbnQ6ZGlzYWJsZS1uZXh0LWxpbmUgbm8tb2JqZWN0LW11dGF0aW9uIG5vLWFueVxuICBob3N0LmZpbGVFeGlzdHMgPSAoZmlsZSkgPT4ge1xuICAgIGlmIChmaWxlc1tmaWxlXSAhPT0gdW5kZWZpbmVkKSB7XG4gICAgICByZXR1cm4gdHJ1ZTtcbiAgICB9XG5cbiAgICByZXR1cm4gb3JpZ2luYWxGaWxlRXhpc3RzKGZpbGUpO1xuICB9O1xuXG4gIGNvbnN0IG9yaWdpbmFsUmVhZEZpbGUgPSBob3N0LnJlYWRGaWxlID09PSB1bmRlZmluZWQgPyB0cy5zeXMucmVhZEZpbGUgOiBob3N0LnJlYWRGaWxlLmJpbmQoaG9zdCk7XG4gIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1vYmplY3QtbXV0YXRpb24gbm8tYW55XG4gIGhvc3QucmVhZEZpbGUgPSAoZmlsZSwgLi4uYXJnczogYW55W10pID0+IHtcbiAgICBjb25zdCBmb3VuZEZpbGUgPSBmaWxlc1tmaWxlXTtcbiAgICBpZiAoZm91bmRGaWxlICE9PSB1bmRlZmluZWQpIHtcbiAgICAgIHJldHVybiBmb3VuZEZpbGU7XG4gICAgfVxuXG4gICAgcmV0dXJuIG9yaWdpbmFsUmVhZEZpbGUoZmlsZSwgLi4uYXJncyk7XG4gIH07XG59O1xuXG5jb25zdCBjcmVhdGVQcm9ncmFtID0gKFxuICBvcHRpb25zOiB0cy5Db21waWxlck9wdGlvbnMsXG4gIHJvb3ROYW1lc0luOiBSZWFkb25seUFycmF5PHN0cmluZz4sXG4gIHsgbW9kaWZ5SG9zdCA9IGRlZmF1bHRNb2RpZnlIb3N0LCB3aXRoVGVzdEhhcm5lc3MgPSBmYWxzZSB9OiBNYWtlQ29udGV4dE9wdGlvbnMgPSBERUZBVUxUX01BS0VfQ09OVEVYVF9PUFRJT05TLFxuKSA9PiB7XG4gIGNvbnN0IHNtYXJ0Q29udHJhY3REaXIgPSBwYXRoLmRpcm5hbWUocmVxdWlyZS5yZXNvbHZlKCdAbmVvLW9uZS9zbWFydC1jb250cmFjdCcpKTtcbiAgY29uc3Qgc21hcnRDb250cmFjdE1vZHVsZSA9IHBhdGhSZXNvbHZlKHNtYXJ0Q29udHJhY3REaXIsICdpbmRleC5kLnRzJyk7XG4gIGNvbnN0IHNtYXJ0Q29udHJhY3RJbnRlcm5hbE1vZHVsZSA9IHBhdGhSZXNvbHZlKHNtYXJ0Q29udHJhY3REaXIsICdpbnRlcm5hbC5kLnRzJyk7XG4gIGNvbnN0IHNtYXJ0Q29udHJhY3RGaWxlcyA9IFtcbiAgICBwYXRoUmVzb2x2ZShzbWFydENvbnRyYWN0RGlyLCAnZ2xvYmFsLmQudHMnKSxcbiAgICBzbWFydENvbnRyYWN0SW50ZXJuYWxNb2R1bGUsXG4gICAgc21hcnRDb250cmFjdE1vZHVsZSxcbiAgICB3aXRoVGVzdEhhcm5lc3MgPyBwYXRoUmVzb2x2ZShzbWFydENvbnRyYWN0RGlyLCAnaGFybmVzcy5kLnRzJykgOiB1bmRlZmluZWQsXG4gIF0uZmlsdGVyKHV0aWxzLm5vdE51bGwpO1xuXG4gIGNvbnN0IHJvb3ROYW1lcyA9IFsuLi5uZXcgU2V0KHJvb3ROYW1lc0luLmNvbmNhdChzbWFydENvbnRyYWN0RmlsZXMpKV0ubWFwKG5vcm1hbGl6ZVBhdGgpO1xuXG4gIGNvbnN0IG11dGFibGVGaWxlczogdHMuTWFwTGlrZTx7IHZlcnNpb246IG51bWJlciB9IHwgdW5kZWZpbmVkPiA9IHt9O1xuICAvLyBpbml0aWFsaXplIHRoZSBsaXN0IG9mIGZpbGVzXG4gIHJvb3ROYW1lcy5mb3JFYWNoKChmaWxlTmFtZSkgPT4ge1xuICAgIG11dGFibGVGaWxlc1tmaWxlTmFtZV0gPSB7IHZlcnNpb246IDAgfTtcbiAgfSk7XG4gIGNvbnN0IHNlcnZpY2VzSG9zdDogdHMuTGFuZ3VhZ2VTZXJ2aWNlSG9zdCA9IHtcbiAgICBnZXRTY3JpcHRGaWxlTmFtZXM6ICgpID0+IFsuLi5yb290TmFtZXNdLFxuICAgIGdldFNjcmlwdFZlcnNpb246IChmaWxlTmFtZSkgPT4ge1xuICAgICAgY29uc3QgZmlsZSA9IG11dGFibGVGaWxlc1tmaWxlTmFtZV07XG5cbiAgICAgIHJldHVybiBmaWxlID09PSB1bmRlZmluZWQgPyAnJyA6IGZpbGUudmVyc2lvbi50b1N0cmluZygpO1xuICAgIH0sXG4gICAgZ2V0U2NyaXB0U25hcHNob3Q6IChmaWxlTmFtZSkgPT4ge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgaWYgKCFzZXJ2aWNlc0hvc3QuZmlsZUV4aXN0cyEoZmlsZU5hbWUpKSB7XG4gICAgICAgIHJldHVybiB1bmRlZmluZWQ7XG4gICAgICB9XG5cbiAgICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1ub24tbnVsbC1hc3NlcnRpb25cbiAgICAgIHJldHVybiB0cy5TY3JpcHRTbmFwc2hvdC5mcm9tU3RyaW5nKHNlcnZpY2VzSG9zdC5yZWFkRmlsZSEoZmlsZU5hbWUpISk7XG4gICAgfSxcbiAgICBnZXRDdXJyZW50RGlyZWN0b3J5OiAoKSA9PiBwcm9jZXNzLmN3ZCgpLFxuICAgIGdldENvbXBpbGF0aW9uU2V0dGluZ3M6ICgpID0+IG9wdGlvbnMsXG4gICAgZ2V0RGVmYXVsdExpYkZpbGVOYW1lOiAob3B0cykgPT4gdHMuZ2V0RGVmYXVsdExpYkZpbGVQYXRoKG9wdHMpLFxuICAgIHVzZUNhc2VTZW5zaXRpdmVGaWxlTmFtZXM6ICgpID0+IHRzLnN5cy51c2VDYXNlU2Vuc2l0aXZlRmlsZU5hbWVzLFxuICAgIGdldE5ld0xpbmU6ICgpID0+IHRzLnN5cy5uZXdMaW5lLFxuICAgIGZpbGVFeGlzdHM6IHRzLnN5cy5maWxlRXhpc3RzLFxuICAgIHJlYWRGaWxlOiB0cy5zeXMucmVhZEZpbGUsXG4gICAgcmVhZERpcmVjdG9yeTogdHMuc3lzLnJlYWREaXJlY3RvcnksXG4gICAgcmVzb2x2ZU1vZHVsZU5hbWVzLFxuICB9O1xuXG4gIGNvbnN0IHNtYXJ0Q29udHJhY3RMaWJNb2R1bGUgPSBwYXRoUmVzb2x2ZShwYXRoLmRpcm5hbWUocmVxdWlyZS5yZXNvbHZlKCdAbmVvLW9uZS9zbWFydC1jb250cmFjdC1saWInKSksICdpbmRleC50cycpO1xuICBmdW5jdGlvbiByZXNvbHZlTW9kdWxlTmFtZXMobW9kdWxlTmFtZXM6IHN0cmluZ1tdLCBjb250YWluaW5nRmlsZTogc3RyaW5nKTogdHMuUmVzb2x2ZWRNb2R1bGVbXSB7XG4gICAgY29uc3QgbXV0YWJsZVJlc29sdmVkTW9kdWxlczogdHMuUmVzb2x2ZWRNb2R1bGVbXSA9IFtdO1xuICAgIC8vIHRzbGludDpkaXNhYmxlLW5leHQtbGluZSBuby1sb29wLXN0YXRlbWVudFxuICAgIGZvciAoY29uc3QgbW9kdWxlTmFtZSBvZiBtb2R1bGVOYW1lcykge1xuICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIHByZWZlci1zd2l0Y2hcbiAgICAgIGlmIChtb2R1bGVOYW1lID09PSAnQG5lby1vbmUvc21hcnQtY29udHJhY3QtaW50ZXJuYWwnKSB7XG4gICAgICAgIG11dGFibGVSZXNvbHZlZE1vZHVsZXMucHVzaCh7IHJlc29sdmVkRmlsZU5hbWU6IHNtYXJ0Q29udHJhY3RJbnRlcm5hbE1vZHVsZSB9KTtcbiAgICAgIH0gZWxzZSBpZiAobW9kdWxlTmFtZSA9PT0gJ0BuZW8tb25lL3NtYXJ0LWNvbnRyYWN0Jykge1xuICAgICAgICBtdXRhYmxlUmVzb2x2ZWRNb2R1bGVzLnB1c2goeyByZXNvbHZlZEZpbGVOYW1lOiBzbWFydENvbnRyYWN0TW9kdWxlIH0pO1xuICAgICAgfSBlbHNlIGlmIChtb2R1bGVOYW1lID09PSAnQG5lby1vbmUvc21hcnQtY29udHJhY3QtbGliJykge1xuICAgICAgICBtdXRhYmxlUmVzb2x2ZWRNb2R1bGVzLnB1c2goeyByZXNvbHZlZEZpbGVOYW1lOiBzbWFydENvbnRyYWN0TGliTW9kdWxlIH0pO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgY29uc3QgcmVzdWx0ID0gdHMucmVzb2x2ZU1vZHVsZU5hbWUobW9kdWxlTmFtZSwgY29udGFpbmluZ0ZpbGUsIG9wdGlvbnMsIHtcbiAgICAgICAgICBmaWxlRXhpc3RzOiB0cy5zeXMuZmlsZUV4aXN0cyxcbiAgICAgICAgICByZWFkRmlsZTogdHMuc3lzLnJlYWRGaWxlLFxuICAgICAgICB9KTtcbiAgICAgICAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLW5vbi1udWxsLWFzc2VydGlvblxuICAgICAgICBtdXRhYmxlUmVzb2x2ZWRNb2R1bGVzLnB1c2gocmVzdWx0LnJlc29sdmVkTW9kdWxlISk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgcmV0dXJuIG11dGFibGVSZXNvbHZlZE1vZHVsZXM7XG4gIH1cblxuICBtb2RpZnlIb3N0KHNlcnZpY2VzSG9zdCk7XG5cbiAgY29uc3QgbGFuZ3VhZ2VTZXJ2aWNlID0gdHMuY3JlYXRlTGFuZ3VhZ2VTZXJ2aWNlKHNlcnZpY2VzSG9zdCk7XG4gIGNvbnN0IHByb2dyYW0gPSBsYW5ndWFnZVNlcnZpY2UuZ2V0UHJvZ3JhbSgpO1xuICBpZiAocHJvZ3JhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTb21ldGhpbmcgd2VudCB3cm9uZycpO1xuICB9XG5cbiAgLy8gdHNsaW50OmRpc2FibGUtbmV4dC1saW5lIG5vLWFueSBuby1vYmplY3QtbXV0YXRpb25cbiAgKHByb2dyYW0gYXMgYW55KS5fX3dpdGhUZXN0SGFybmVzcyA9IHdpdGhUZXN0SGFybmVzcztcblxuICByZXR1cm4ge1xuICAgIHByb2dyYW0sXG4gICAgdHlwZUNoZWNrZXI6IHByb2dyYW0uZ2V0VHlwZUNoZWNrZXIoKSxcbiAgICBsYW5ndWFnZVNlcnZpY2UsXG4gICAgc21hcnRDb250cmFjdERpcixcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVDb250ZXh0Rm9yRGlyID0gYXN5bmMgKFxuICBkaXI6IHN0cmluZyxcbiAgb3B0aW9uczogQ3JlYXRlQ29udGV4dE9wdGlvbnMgPSBDUkVBVEVfQ09OVEVYVF9PUFRJT05TX0RFRkFVTFQsXG4pOiBQcm9taXNlPENvbnRleHQ+ID0+IHtcbiAgY29uc3QgZmlsZXMgPSBhd2FpdCBkb0dsb2IocGF0aC5qb2luKGRpciwgJyoqJywgJyoudHMnKSk7XG5cbiAgcmV0dXJuIG1ha2VDb250ZXh0KGZpbGVzLCBvcHRpb25zKTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVDb250ZXh0Rm9yUGF0aCA9IChcbiAgZmlsZVBhdGg6IHN0cmluZyxcbiAgb3B0aW9uczogQ3JlYXRlQ29udGV4dE9wdGlvbnMgPSBDUkVBVEVfQ09OVEVYVF9PUFRJT05TX0RFRkFVTFQsXG4pOiBDb250ZXh0ID0+IG1ha2VDb250ZXh0KFtmaWxlUGF0aF0sIG9wdGlvbnMpO1xuXG5leHBvcnQgaW50ZXJmYWNlIFNuaXBwZXRSZXN1bHQge1xuICByZWFkb25seSBjb250ZXh0OiBDb250ZXh0O1xuICByZWFkb25seSBzb3VyY2VGaWxlOiB0cy5Tb3VyY2VGaWxlO1xufVxuXG5leHBvcnQgY29uc3QgY3JlYXRlQ29udGV4dEZvclNuaXBwZXQgPSAoXG4gIGNvZGU6IHN0cmluZyxcbiAgb3B0aW9uczogQ3JlYXRlQ29udGV4dE9wdGlvbnMgPSBDUkVBVEVfQ09OVEVYVF9PUFRJT05TX0RFRkFVTFQsXG4pOiBTbmlwcGV0UmVzdWx0ID0+IHtcbiAgY29uc3QgZGlyID0gYXBwUm9vdERpci5nZXQoKTtcbiAgY29uc3QgZmlsZU5hbWUgPSBwYXRoUmVzb2x2ZShkaXIsICdzbmlwcGV0Q29kZS50cycpO1xuXG4gIGNvbnN0IGNvbnRleHQgPSBtYWtlQ29udGV4dChbZmlsZU5hbWVdLCB7XG4gICAgLi4ub3B0aW9ucyxcbiAgICBtb2RpZnlIb3N0OiBjcmVhdGVNb2RpZnlIb3N0RmlsZXMoeyBbZmlsZU5hbWVdOiBjb2RlIH0pLFxuICB9KTtcbiAgY29uc3Qgc291cmNlRmlsZSA9IHRzVXRpbHMuZmlsZS5nZXRTb3VyY2VGaWxlT3JUaHJvdyhjb250ZXh0LnByb2dyYW0sIGZpbGVOYW1lKTtcblxuICByZXR1cm4ge1xuICAgIGNvbnRleHQsXG4gICAgc291cmNlRmlsZSxcbiAgfTtcbn07XG5cbmV4cG9ydCBjb25zdCBjcmVhdGVDb250ZXh0Rm9yTGFuZ3VhZ2VTZXJ2aWNlID0gKFxuICBsYW5ndWFnZVNlcnZpY2U6IHRzLkxhbmd1YWdlU2VydmljZSxcbiAgc21hcnRDb250cmFjdERpcjogc3RyaW5nLFxuKTogQ29udGV4dCA9PiB7XG4gIGNvbnN0IHByb2dyYW0gPSBsYW5ndWFnZVNlcnZpY2UuZ2V0UHJvZ3JhbSgpO1xuICBpZiAocHJvZ3JhbSA9PT0gdW5kZWZpbmVkKSB7XG4gICAgdGhyb3cgbmV3IEVycm9yKCdTb21ldGhpbmcgd2VudCB3cm9uZycpO1xuICB9XG5cbiAgcmV0dXJuIGNyZWF0ZUNvbnRleHQocHJvZ3JhbSwgcHJvZ3JhbS5nZXRUeXBlQ2hlY2tlcigpLCBsYW5ndWFnZVNlcnZpY2UsIHNtYXJ0Q29udHJhY3REaXIpO1xufTtcbiJdfQ==