UNPKG

13.4 kBJavaScriptView Raw
1"use strict";
2Object.defineProperty(exports, "__esModule", { value: true });
3const ts = require("typescript");
4const os = require("os");
5const fs = require("fs-extra");
6const path = require("path");
7const simplr_logger_1 = require("simplr-logger");
8const logger_1 = require("./utils/logger");
9const api_source_file_1 = require("./definitions/api-source-file");
10const api_registry_1 = require("./api-registry");
11class Extractor {
12 constructor(options) {
13 this.Options = Object.assign({}, options, { ProjectDirectory: fs.realpathSync(options.ProjectDirectory), OutputPathSeparator: options.OutputPathSeparator || "/" });
14 }
15 Extract(files) {
16 const rootNames = files.map(file => {
17 if (path.isAbsolute(file)) {
18 return file;
19 }
20 return path.join(this.Options.ProjectDirectory, file);
21 });
22 // Check whether files exist and are in project directory.
23 rootNames.forEach(filePath => {
24 if (!fs.existsSync(filePath)) {
25 throw new Error(`Given file "${filePath}", does not exist.`);
26 }
27 if (fs.realpathSync(filePath).indexOf(this.Options.ProjectDirectory) === -1) {
28 throw new Error(`Given file "${filePath}", is not in project directory "${this.Options.ProjectDirectory}".`);
29 }
30 });
31 const program = ts.createProgram(rootNames, this.Options.CompilerOptions);
32 const apiRegistry = new api_registry_1.ApiRegistry();
33 // This runs a full type analysis, and augments the Abstract Syntax Tree (i.e. declarations)
34 // with semantic information (i.e. symbols). The "diagnostics" are a subset of everyday
35 // compile errors that would result from a full compilation.
36 const diagnostics = program.getSemanticDiagnostics();
37 if (diagnostics.length > 0) {
38 const str = ts.formatDiagnosticsWithColorAndContext(program.getSemanticDiagnostics(), {
39 getCanonicalFileName: () => __filename,
40 getCurrentDirectory: () => this.Options.ProjectDirectory,
41 getNewLine: () => os.EOL
42 });
43 logger_1.Logger.Log(simplr_logger_1.LogLevel.Error, str);
44 throw new Error("TypeScript compilation errors. Please fix them before using extractor.");
45 }
46 const typeChecker = program.getTypeChecker();
47 const apiSourceFiles = [];
48 // Go through all given files.
49 const rootFiles = program.getRootFileNames();
50 rootFiles.forEach(fileName => {
51 const sourceFile = program.getSourceFile(fileName);
52 const symbol = typeChecker.getSymbolAtLocation(sourceFile);
53 if (symbol == null) {
54 logger_1.Logger.Log(simplr_logger_1.LogLevel.Warning, `Source file "${fileName}" is skipped, because no exported members were found.`);
55 return;
56 }
57 const apiSourceFile = new api_source_file_1.ApiSourceFile(sourceFile, symbol, {
58 Program: program,
59 ExtractorOptions: this.Options,
60 // ApiSourceFile populates given apiItemsRegistry by adding items into it
61 Registry: apiRegistry,
62 AddItemToRegistry: (apiItem) => apiRegistry.AddItem(apiItem)
63 });
64 apiSourceFiles.push(apiSourceFile);
65 apiSourceFile.GatherData();
66 });
67 const extractedApiRegistry = apiRegistry.Extract();
68 // Extracts every source file
69 const extractedEntryFiles = apiSourceFiles.map(x => x.Extract());
70 return {
71 Registry: extractedApiRegistry,
72 EntryFiles: extractedEntryFiles
73 };
74 }
75}
76exports.Extractor = Extractor;
77//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZXh0cmFjdG9yLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vc3JjL2V4dHJhY3Rvci50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOztBQUFBLGlDQUFpQztBQUNqQyx5QkFBeUI7QUFDekIsK0JBQStCO0FBQy9CLDZCQUE2QjtBQUM3QixpREFBeUM7QUFFekMsMkNBQXdDO0FBQ3hDLG1FQUE4RDtBQUs5RCxpREFBbUU7QUFPbkU7SUFDSSxZQUFZLE9BQXlCO1FBQ2pDLElBQUksQ0FBQyxPQUFPLHFCQUNMLE9BQU8sSUFDVixnQkFBZ0IsRUFBRSxFQUFFLENBQUMsWUFBWSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsQ0FBQyxFQUMzRCxtQkFBbUIsRUFBRSxPQUFPLENBQUMsbUJBQW1CLElBQUksR0FBRyxHQUMxRCxDQUFDO0lBQ04sQ0FBQztJQUlNLE9BQU8sQ0FBQyxLQUFlO1FBQzFCLE1BQU0sU0FBUyxHQUFHLEtBQUssQ0FBQyxHQUFHLENBQUMsSUFBSSxDQUFDLEVBQUU7WUFDL0IsRUFBRSxDQUFDLENBQUMsSUFBSSxDQUFDLFVBQVUsQ0FBQyxJQUFJLENBQUMsQ0FBQyxDQUFDLENBQUM7Z0JBQ3hCLE1BQU0sQ0FBQyxJQUFJLENBQUM7WUFDaEIsQ0FBQztZQUVELE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLENBQUM7UUFDMUQsQ0FBQyxDQUFDLENBQUM7UUFFSCwwREFBMEQ7UUFDMUQsU0FBUyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUN6QixFQUFFLENBQUMsQ0FBQyxDQUFDLEVBQUUsQ0FBQyxVQUFVLENBQUMsUUFBUSxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMzQixNQUFNLElBQUksS0FBSyxDQUFDLGVBQWUsUUFBUSxvQkFBb0IsQ0FBQyxDQUFDO1lBQ2pFLENBQUM7WUFFRCxFQUFFLENBQUMsQ0FBQyxFQUFFLENBQUMsWUFBWSxDQUFDLFFBQVEsQ0FBQyxDQUFDLE9BQU8sQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsQ0FBQyxDQUFDO2dCQUMxRSxNQUFNLElBQUksS0FBSyxDQUFDLGVBQWUsUUFBUSxtQ0FBbUMsSUFBSSxDQUFDLE9BQU8sQ0FBQyxnQkFBZ0IsSUFBSSxDQUFDLENBQUM7WUFDakgsQ0FBQztRQUNMLENBQUMsQ0FBQyxDQUFDO1FBRUgsTUFBTSxPQUFPLEdBQUcsRUFBRSxDQUFDLGFBQWEsQ0FBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUMsQ0FBQztRQUMxRSxNQUFNLFdBQVcsR0FBRyxJQUFJLDBCQUFXLEVBQUUsQ0FBQztRQUV0Qyw0RkFBNEY7UUFDNUYsdUZBQXVGO1FBQ3ZGLDREQUE0RDtRQUM1RCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsc0JBQXNCLEVBQUUsQ0FBQztRQUNyRCxFQUFFLENBQUMsQ0FBQyxXQUFXLENBQUMsTUFBTSxHQUFHLENBQUMsQ0FBQyxDQUFDLENBQUM7WUFDekIsTUFBTSxHQUFHLEdBQUcsRUFBRSxDQUFDLG9DQUFvQyxDQUFDLE9BQU8sQ0FBQyxzQkFBc0IsRUFBRSxFQUFFO2dCQUNsRixvQkFBb0IsRUFBRSxHQUFHLEVBQUUsQ0FBQyxVQUFVO2dCQUN0QyxtQkFBbUIsRUFBRSxHQUFHLEVBQUUsQ0FBQyxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQjtnQkFDeEQsVUFBVSxFQUFFLEdBQUcsRUFBRSxDQUFDLEVBQUUsQ0FBQyxHQUFHO2FBQzNCLENBQUMsQ0FBQztZQUNILGVBQU0sQ0FBQyxHQUFHLENBQUMsd0JBQVEsQ0FBQyxLQUFLLEVBQUUsR0FBRyxDQUFDLENBQUM7WUFDaEMsTUFBTSxJQUFJLEtBQUssQ0FBQyx3RUFBd0UsQ0FBQyxDQUFDO1FBQzlGLENBQUM7UUFFRCxNQUFNLFdBQVcsR0FBRyxPQUFPLENBQUMsY0FBYyxFQUFFLENBQUM7UUFDN0MsTUFBTSxjQUFjLEdBQW9CLEVBQUUsQ0FBQztRQUUzQyw4QkFBOEI7UUFDOUIsTUFBTSxTQUFTLEdBQUcsT0FBTyxDQUFDLGdCQUFnQixFQUFFLENBQUM7UUFDN0MsU0FBUyxDQUFDLE9BQU8sQ0FBQyxRQUFRLENBQUMsRUFBRTtZQUN6QixNQUFNLFVBQVUsR0FBa0IsT0FBTyxDQUFDLGFBQWEsQ0FBQyxRQUFRLENBQUMsQ0FBQztZQUNsRSxNQUFNLE1BQU0sR0FBRyxXQUFXLENBQUMsbUJBQW1CLENBQUMsVUFBVSxDQUFDLENBQUM7WUFFM0QsRUFBRSxDQUFDLENBQUMsTUFBTSxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUM7Z0JBQ2pCLGVBQU0sQ0FBQyxHQUFHLENBQUMsd0JBQVEsQ0FBQyxPQUFPLEVBQUUsZ0JBQWdCLFFBQVEsdURBQXVELENBQUMsQ0FBQztnQkFDOUcsTUFBTSxDQUFDO1lBQ1gsQ0FBQztZQUVELE1BQU0sYUFBYSxHQUFHLElBQUksK0JBQWEsQ0FBQyxVQUFVLEVBQUUsTUFBTSxFQUFFO2dCQUN4RCxPQUFPLEVBQUUsT0FBTztnQkFDaEIsZ0JBQWdCLEVBQUUsSUFBSSxDQUFDLE9BQU87Z0JBQzlCLHlFQUF5RTtnQkFDekUsUUFBUSxFQUFFLFdBQVc7Z0JBQ3JCLGlCQUFpQixFQUFFLENBQUMsT0FBZ0IsRUFBRSxFQUFFLENBQUMsV0FBVyxDQUFDLE9BQU8sQ0FBQyxPQUFPLENBQUM7YUFDeEUsQ0FBQyxDQUFDO1lBRUgsY0FBYyxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsQ0FBQztZQUNuQyxhQUFhLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDL0IsQ0FBQyxDQUFDLENBQUM7UUFFSCxNQUFNLG9CQUFvQixHQUFHLFdBQVcsQ0FBQyxPQUFPLEVBQUUsQ0FBQztRQUVuRCw2QkFBNkI7UUFDN0IsTUFBTSxtQkFBbUIsR0FBRyxjQUFjLENBQUMsR0FBRyxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUMsQ0FBQyxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUM7UUFFakUsTUFBTSxDQUFDO1lBQ0gsUUFBUSxFQUFFLG9CQUFvQjtZQUM5QixVQUFVLEVBQUUsbUJBQW1CO1NBQ2xDLENBQUM7SUFDTixDQUFDO0NBQ0o7QUFwRkQsOEJBb0ZDIiwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0ICogYXMgdHMgZnJvbSBcInR5cGVzY3JpcHRcIjtcclxuaW1wb3J0ICogYXMgb3MgZnJvbSBcIm9zXCI7XHJcbmltcG9ydCAqIGFzIGZzIGZyb20gXCJmcy1leHRyYVwiO1xyXG5pbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XHJcbmltcG9ydCB7IExvZ0xldmVsIH0gZnJvbSBcInNpbXBsci1sb2dnZXJcIjtcclxuXHJcbmltcG9ydCB7IExvZ2dlciB9IGZyb20gXCIuL3V0aWxzL2xvZ2dlclwiO1xyXG5pbXBvcnQgeyBBcGlTb3VyY2VGaWxlIH0gZnJvbSBcIi4vZGVmaW5pdGlvbnMvYXBpLXNvdXJjZS1maWxlXCI7XHJcbmltcG9ydCB7IEFwaUl0ZW0gfSBmcm9tIFwiLi9hYnN0cmFjdGlvbnMvYXBpLWl0ZW1cIjtcclxuaW1wb3J0IHsgQXBpU291cmNlRmlsZUR0byB9IGZyb20gXCIuL2NvbnRyYWN0cy9kZWZpbml0aW9ucy9hcGktc291cmNlLWZpbGUtZHRvXCI7XHJcbmltcG9ydCB7IEFwaUJhc2VJdGVtRHRvIH0gZnJvbSBcIi4vY29udHJhY3RzL2FwaS1iYXNlLWl0ZW0tZHRvXCI7XHJcbmltcG9ydCB7IEV4dHJhY3Rvck9wdGlvbnMgfSBmcm9tIFwiLi9jb250cmFjdHMvZXh0cmFjdG9yLW9wdGlvbnNcIjtcclxuaW1wb3J0IHsgQXBpUmVnaXN0cnksIEV4dHJhY3RlZEFwaVJlZ2lzdHJ5IH0gZnJvbSBcIi4vYXBpLXJlZ2lzdHJ5XCI7XHJcblxyXG5leHBvcnQgaW50ZXJmYWNlIEV4dHJhY3REdG8ge1xyXG4gICAgUmVnaXN0cnk6IEV4dHJhY3RlZEFwaVJlZ2lzdHJ5O1xyXG4gICAgRW50cnlGaWxlczogQXBpU291cmNlRmlsZUR0b1tdO1xyXG59XHJcblxyXG5leHBvcnQgY2xhc3MgRXh0cmFjdG9yIHtcclxuICAgIGNvbnN0cnVjdG9yKG9wdGlvbnM6IEV4dHJhY3Rvck9wdGlvbnMpIHtcclxuICAgICAgICB0aGlzLk9wdGlvbnMgPSB7XHJcbiAgICAgICAgICAgIC4uLm9wdGlvbnMsXHJcbiAgICAgICAgICAgIFByb2plY3REaXJlY3Rvcnk6IGZzLnJlYWxwYXRoU3luYyhvcHRpb25zLlByb2plY3REaXJlY3RvcnkpLFxyXG4gICAgICAgICAgICBPdXRwdXRQYXRoU2VwYXJhdG9yOiBvcHRpb25zLk91dHB1dFBhdGhTZXBhcmF0b3IgfHwgXCIvXCJcclxuICAgICAgICB9O1xyXG4gICAgfVxyXG5cclxuICAgIHByb3RlY3RlZCBPcHRpb25zOiBFeHRyYWN0b3JPcHRpb25zO1xyXG5cclxuICAgIHB1YmxpYyBFeHRyYWN0KGZpbGVzOiBzdHJpbmdbXSk6IEV4dHJhY3REdG8ge1xyXG4gICAgICAgIGNvbnN0IHJvb3ROYW1lcyA9IGZpbGVzLm1hcChmaWxlID0+IHtcclxuICAgICAgICAgICAgaWYgKHBhdGguaXNBYnNvbHV0ZShmaWxlKSkge1xyXG4gICAgICAgICAgICAgICAgcmV0dXJuIGZpbGU7XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIHJldHVybiBwYXRoLmpvaW4odGhpcy5PcHRpb25zLlByb2plY3REaXJlY3RvcnksIGZpbGUpO1xyXG4gICAgICAgIH0pO1xyXG5cclxuICAgICAgICAvLyBDaGVjayB3aGV0aGVyIGZpbGVzIGV4aXN0IGFuZCBhcmUgaW4gcHJvamVjdCBkaXJlY3RvcnkuXHJcbiAgICAgICAgcm9vdE5hbWVzLmZvckVhY2goZmlsZVBhdGggPT4ge1xyXG4gICAgICAgICAgICBpZiAoIWZzLmV4aXN0c1N5bmMoZmlsZVBhdGgpKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEdpdmVuIGZpbGUgXCIke2ZpbGVQYXRofVwiLCBkb2VzIG5vdCBleGlzdC5gKTtcclxuICAgICAgICAgICAgfVxyXG5cclxuICAgICAgICAgICAgaWYgKGZzLnJlYWxwYXRoU3luYyhmaWxlUGF0aCkuaW5kZXhPZih0aGlzLk9wdGlvbnMuUHJvamVjdERpcmVjdG9yeSkgPT09IC0xKSB7XHJcbiAgICAgICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoYEdpdmVuIGZpbGUgXCIke2ZpbGVQYXRofVwiLCBpcyBub3QgaW4gcHJvamVjdCBkaXJlY3RvcnkgXCIke3RoaXMuT3B0aW9ucy5Qcm9qZWN0RGlyZWN0b3J5fVwiLmApO1xyXG4gICAgICAgICAgICB9XHJcbiAgICAgICAgfSk7XHJcblxyXG4gICAgICAgIGNvbnN0IHByb2dyYW0gPSB0cy5jcmVhdGVQcm9ncmFtKHJvb3ROYW1lcywgdGhpcy5PcHRpb25zLkNvbXBpbGVyT3B0aW9ucyk7XHJcbiAgICAgICAgY29uc3QgYXBpUmVnaXN0cnkgPSBuZXcgQXBpUmVnaXN0cnkoKTtcclxuXHJcbiAgICAgICAgLy8gVGhpcyBydW5zIGEgZnVsbCB0eXBlIGFuYWx5c2lzLCBhbmQgYXVnbWVudHMgdGhlIEFic3RyYWN0IFN5bnRheCBUcmVlIChpLmUuIGRlY2xhcmF0aW9ucylcclxuICAgICAgICAvLyB3aXRoIHNlbWFudGljIGluZm9ybWF0aW9uIChpLmUuIHN5bWJvbHMpLiBUaGUgXCJkaWFnbm9zdGljc1wiIGFyZSBhIHN1YnNldCBvZiBldmVyeWRheVxyXG4gICAgICAgIC8vIGNvbXBpbGUgZXJyb3JzIHRoYXQgd291bGQgcmVzdWx0IGZyb20gYSBmdWxsIGNvbXBpbGF0aW9uLlxyXG4gICAgICAgIGNvbnN0IGRpYWdub3N0aWNzID0gcHJvZ3JhbS5nZXRTZW1hbnRpY0RpYWdub3N0aWNzKCk7XHJcbiAgICAgICAgaWYgKGRpYWdub3N0aWNzLmxlbmd0aCA+IDApIHtcclxuICAgICAgICAgICAgY29uc3Qgc3RyID0gdHMuZm9ybWF0RGlhZ25vc3RpY3NXaXRoQ29sb3JBbmRDb250ZXh0KHByb2dyYW0uZ2V0U2VtYW50aWNEaWFnbm9zdGljcygpLCB7XHJcbiAgICAgICAgICAgICAgICBnZXRDYW5vbmljYWxGaWxlTmFtZTogKCkgPT4gX19maWxlbmFtZSxcclxuICAgICAgICAgICAgICAgIGdldEN1cnJlbnREaXJlY3Rvcnk6ICgpID0+IHRoaXMuT3B0aW9ucy5Qcm9qZWN0RGlyZWN0b3J5LFxyXG4gICAgICAgICAgICAgICAgZ2V0TmV3TGluZTogKCkgPT4gb3MuRU9MXHJcbiAgICAgICAgICAgIH0pO1xyXG4gICAgICAgICAgICBMb2dnZXIuTG9nKExvZ0xldmVsLkVycm9yLCBzdHIpO1xyXG4gICAgICAgICAgICB0aHJvdyBuZXcgRXJyb3IoXCJUeXBlU2NyaXB0IGNvbXBpbGF0aW9uIGVycm9ycy4gUGxlYXNlIGZpeCB0aGVtIGJlZm9yZSB1c2luZyBleHRyYWN0b3IuXCIpO1xyXG4gICAgICAgIH1cclxuXHJcbiAgICAgICAgY29uc3QgdHlwZUNoZWNrZXIgPSBwcm9ncmFtLmdldFR5cGVDaGVja2VyKCk7XHJcbiAgICAgICAgY29uc3QgYXBpU291cmNlRmlsZXM6IEFwaVNvdXJjZUZpbGVbXSA9IFtdO1xyXG5cclxuICAgICAgICAvLyBHbyB0aHJvdWdoIGFsbCBnaXZlbiBmaWxlcy5cclxuICAgICAgICBjb25zdCByb290RmlsZXMgPSBwcm9ncmFtLmdldFJvb3RGaWxlTmFtZXMoKTtcclxuICAgICAgICByb290RmlsZXMuZm9yRWFjaChmaWxlTmFtZSA9PiB7XHJcbiAgICAgICAgICAgIGNvbnN0IHNvdXJjZUZpbGU6IHRzLlNvdXJjZUZpbGUgPSBwcm9ncmFtLmdldFNvdXJjZUZpbGUoZmlsZU5hbWUpO1xyXG4gICAgICAgICAgICBjb25zdCBzeW1ib2wgPSB0eXBlQ2hlY2tlci5nZXRTeW1ib2xBdExvY2F0aW9uKHNvdXJjZUZpbGUpO1xyXG5cclxuICAgICAgICAgICAgaWYgKHN5bWJvbCA9PSBudWxsKSB7XHJcbiAgICAgICAgICAgICAgICBMb2dnZXIuTG9nKExvZ0xldmVsLldhcm5pbmcsIGBTb3VyY2UgZmlsZSBcIiR7ZmlsZU5hbWV9XCIgaXMgc2tpcHBlZCwgYmVjYXVzZSBubyBleHBvcnRlZCBtZW1iZXJzIHdlcmUgZm91bmQuYCk7XHJcbiAgICAgICAgICAgICAgICByZXR1cm47XHJcbiAgICAgICAgICAgIH1cclxuXHJcbiAgICAgICAgICAgIGNvbnN0IGFwaVNvdXJjZUZpbGUgPSBuZXcgQXBpU291cmNlRmlsZShzb3VyY2VGaWxlLCBzeW1ib2wsIHtcclxuICAgICAgICAgICAgICAgIFByb2dyYW06IHByb2dyYW0sXHJcbiAgICAgICAgICAgICAgICBFeHRyYWN0b3JPcHRpb25zOiB0aGlzLk9wdGlvbnMsXHJcbiAgICAgICAgICAgICAgICAvLyBBcGlTb3VyY2VGaWxlIHBvcHVsYXRlcyBnaXZlbiBhcGlJdGVtc1JlZ2lzdHJ5IGJ5IGFkZGluZyBpdGVtcyBpbnRvIGl0XHJcbiAgICAgICAgICAgICAgICBSZWdpc3RyeTogYXBpUmVnaXN0cnksXHJcbiAgICAgICAgICAgICAgICBBZGRJdGVtVG9SZWdpc3RyeTogKGFwaUl0ZW06IEFwaUl0ZW0pID0+IGFwaVJlZ2lzdHJ5LkFkZEl0ZW0oYXBpSXRlbSlcclxuICAgICAgICAgICAgfSk7XHJcblxyXG4gICAgICAgICAgICBhcGlTb3VyY2VGaWxlcy5wdXNoKGFwaVNvdXJjZUZpbGUpO1xyXG4gICAgICAgICAgICBhcGlTb3VyY2VGaWxlLkdhdGhlckRhdGEoKTtcclxuICAgICAgICB9KTtcclxuXHJcbiAgICAgICAgY29uc3QgZXh0cmFjdGVkQXBpUmVnaXN0cnkgPSBhcGlSZWdpc3RyeS5FeHRyYWN0KCk7XHJcblxyXG4gICAgICAgIC8vIEV4dHJhY3RzIGV2ZXJ5IHNvdXJjZSBmaWxlXHJcbiAgICAgICAgY29uc3QgZXh0cmFjdGVkRW50cnlGaWxlcyA9IGFwaVNvdXJjZUZpbGVzLm1hcCh4ID0+IHguRXh0cmFjdCgpKTtcclxuXHJcbiAgICAgICAgcmV0dXJuIHtcclxuICAgICAgICAgICAgUmVnaXN0cnk6IGV4dHJhY3RlZEFwaVJlZ2lzdHJ5LFxyXG4gICAgICAgICAgICBFbnRyeUZpbGVzOiBleHRyYWN0ZWRFbnRyeUZpbGVzXHJcbiAgICAgICAgfTtcclxuICAgIH1cclxufVxyXG4iXX0=
\No newline at end of file