UNPKG

@angular-devkit/core

Version:

Angular DevKit - Core Utility Library

133 lines • 15.5 kB
"use strict"; /** * @license * Copyright Google LLC All Rights Reserved. * * Use of this source code is governed by an MIT-style license that can be * found in the LICENSE file at https://angular.io/license */ Object.defineProperty(exports, "__esModule", { value: true }); exports.writeWorkspace = exports.readWorkspace = exports._test_removeWorkspaceFile = exports._test_addWorkspaceFile = exports.WorkspaceFormat = void 0; const virtual_fs_1 = require("../virtual-fs"); const reader_1 = require("./json/reader"); const writer_1 = require("./json/writer"); const formatLookup = new WeakMap(); /** * Supported workspace formats */ var WorkspaceFormat; (function (WorkspaceFormat) { WorkspaceFormat[WorkspaceFormat["JSON"] = 0] = "JSON"; })(WorkspaceFormat = exports.WorkspaceFormat || (exports.WorkspaceFormat = {})); /** * @private */ function _test_addWorkspaceFile(name, format) { workspaceFiles[name] = format; } exports._test_addWorkspaceFile = _test_addWorkspaceFile; /** * @private */ function _test_removeWorkspaceFile(name) { delete workspaceFiles[name]; } exports._test_removeWorkspaceFile = _test_removeWorkspaceFile; // NOTE: future additions could also perform content analysis to determine format/version const workspaceFiles = { 'angular.json': WorkspaceFormat.JSON, '.angular.json': WorkspaceFormat.JSON, }; /** * Reads and constructs a `WorkspaceDefinition`. If the function is provided with a path to a * directory instead of a file, a search of the directory's files will commence to attempt to * locate a known workspace file. Currently the following are considered known workspace files: * - `angular.json` * - `.angular.json` * * @param path The path to either a workspace file or a directory containing a workspace file. * @param host The `WorkspaceHost` to use to access the file and directory data. * @param format An optional `WorkspaceFormat` value. Used if the path specifies a non-standard * file name that would prevent automatically discovering the format. * * * @return An `Promise` of the read result object with the `WorkspaceDefinition` contained within * the `workspace` property. */ async function readWorkspace(path, host, format) { if (await host.isDirectory(path)) { // TODO: Warn if multiple found (requires diagnostics support) const directory = (0, virtual_fs_1.normalize)(path); let found = false; for (const [name, nameFormat] of Object.entries(workspaceFiles)) { if (format !== undefined && format !== nameFormat) { continue; } const potential = (0, virtual_fs_1.getSystemPath)((0, virtual_fs_1.join)(directory, name)); if (await host.isFile(potential)) { path = potential; format = nameFormat; found = true; break; } } if (!found) { throw new Error('Unable to locate a workspace file for workspace path. Are you missing an `angular.json`' + ' or `.angular.json` file?'); } } else if (format === undefined) { const filename = (0, virtual_fs_1.basename)((0, virtual_fs_1.normalize)(path)); if (filename in workspaceFiles) { format = workspaceFiles[filename]; } } if (format === undefined) { throw new Error('Unable to determine format for workspace path.'); } let workspace; switch (format) { case WorkspaceFormat.JSON: workspace = await (0, reader_1.readJsonWorkspace)(path, host); break; default: throw new Error('Unsupported workspace format.'); } formatLookup.set(workspace, WorkspaceFormat.JSON); return { workspace }; } exports.readWorkspace = readWorkspace; /** * Writes a `WorkspaceDefinition` to the underlying storage via the provided `WorkspaceHost`. * If the `WorkspaceDefinition` was created via the `readWorkspace` function, metadata will be * used to determine the path and format of the Workspace. In all other cases, the `path` and * `format` options must be specified as they would be otherwise unknown. * * @param workspace The `WorkspaceDefinition` that will be written. * @param host The `WorkspaceHost` to use to access/write the file and directory data. * @param path The path to a file location for the output. Required if `readWorkspace` was not * used to create the `WorkspaceDefinition`. Optional otherwise; will override the * `WorkspaceDefinition` metadata if provided. * @param format The `WorkspaceFormat` to use for output. Required if `readWorkspace` was not * used to create the `WorkspaceDefinition`. Optional otherwise; will override the * `WorkspaceDefinition` metadata if provided. * * * @return An `Promise` of type `void`. */ async function writeWorkspace(workspace, host, path, format) { if (format === undefined) { format = formatLookup.get(workspace); if (format === undefined) { throw new Error('A format is required for custom workspace objects.'); } } switch (format) { case WorkspaceFormat.JSON: return (0, writer_1.writeJsonWorkspace)(workspace, host, path); default: throw new Error('Unsupported workspace format.'); } } exports.writeWorkspace = writeWorkspace; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29yZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uLy4uLy4uLy4uLy4uLy4uLy4uL3BhY2thZ2VzL2FuZ3VsYXJfZGV2a2l0L2NvcmUvc3JjL3dvcmtzcGFjZS9jb3JlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7QUFBQTs7Ozs7O0dBTUc7OztBQUVILDhDQUF5RTtBQUd6RSwwQ0FBa0Q7QUFDbEQsMENBQW1EO0FBRW5ELE1BQU0sWUFBWSxHQUFHLElBQUksT0FBTyxFQUF3QyxDQUFDO0FBRXpFOztHQUVHO0FBQ0gsSUFBWSxlQUVYO0FBRkQsV0FBWSxlQUFlO0lBQ3pCLHFEQUFJLENBQUE7QUFDTixDQUFDLEVBRlcsZUFBZSxHQUFmLHVCQUFlLEtBQWYsdUJBQWUsUUFFMUI7QUFFRDs7R0FFRztBQUNILFNBQWdCLHNCQUFzQixDQUFDLElBQVksRUFBRSxNQUF1QjtJQUMxRSxjQUFjLENBQUMsSUFBSSxDQUFDLEdBQUcsTUFBTSxDQUFDO0FBQ2hDLENBQUM7QUFGRCx3REFFQztBQUVEOztHQUVHO0FBQ0gsU0FBZ0IseUJBQXlCLENBQUMsSUFBWTtJQUNwRCxPQUFPLGNBQWMsQ0FBQyxJQUFJLENBQUMsQ0FBQztBQUM5QixDQUFDO0FBRkQsOERBRUM7QUFFRCx5RkFBeUY7QUFDekYsTUFBTSxjQUFjLEdBQW9DO0lBQ3RELGNBQWMsRUFBRSxlQUFlLENBQUMsSUFBSTtJQUNwQyxlQUFlLEVBQUUsZUFBZSxDQUFDLElBQUk7Q0FDdEMsQ0FBQztBQUVGOzs7Ozs7Ozs7Ozs7Ozs7R0FlRztBQUNJLEtBQUssVUFBVSxhQUFhLENBQ2pDLElBQVksRUFDWixJQUFtQixFQUNuQixNQUF3QjtJQUd4QixJQUFJLE1BQU0sSUFBSSxDQUFDLFdBQVcsQ0FBQyxJQUFJLENBQUMsRUFBRTtRQUNoQyw4REFBOEQ7UUFDOUQsTUFBTSxTQUFTLEdBQUcsSUFBQSxzQkFBUyxFQUFDLElBQUksQ0FBQyxDQUFDO1FBQ2xDLElBQUksS0FBSyxHQUFHLEtBQUssQ0FBQztRQUNsQixLQUFLLE1BQU0sQ0FBQyxJQUFJLEVBQUUsVUFBVSxDQUFDLElBQUksTUFBTSxDQUFDLE9BQU8sQ0FBQyxjQUFjLENBQUMsRUFBRTtZQUMvRCxJQUFJLE1BQU0sS0FBSyxTQUFTLElBQUksTUFBTSxLQUFLLFVBQVUsRUFBRTtnQkFDakQsU0FBUzthQUNWO1lBRUQsTUFBTSxTQUFTLEdBQUcsSUFBQSwwQkFBYSxFQUFDLElBQUEsaUJBQUksRUFBQyxTQUFTLEVBQUUsSUFBSSxDQUFDLENBQUMsQ0FBQztZQUN2RCxJQUFJLE1BQU0sSUFBSSxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUMsRUFBRTtnQkFDaEMsSUFBSSxHQUFHLFNBQVMsQ0FBQztnQkFDakIsTUFBTSxHQUFHLFVBQVUsQ0FBQztnQkFDcEIsS0FBSyxHQUFHLElBQUksQ0FBQztnQkFDYixNQUFNO2FBQ1A7U0FDRjtRQUNELElBQUksQ0FBQyxLQUFLLEVBQUU7WUFDVixNQUFNLElBQUksS0FBSyxDQUNiLHlGQUF5RjtnQkFDdkYsMkJBQTJCLENBQzlCLENBQUM7U0FDSDtLQUNGO1NBQU0sSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFO1FBQy9CLE1BQU0sUUFBUSxHQUFHLElBQUEscUJBQVEsRUFBQyxJQUFBLHNCQUFTLEVBQUMsSUFBSSxDQUFDLENBQUMsQ0FBQztRQUMzQyxJQUFJLFFBQVEsSUFBSSxjQUFjLEVBQUU7WUFDOUIsTUFBTSxHQUFHLGNBQWMsQ0FBQyxRQUFRLENBQUMsQ0FBQztTQUNuQztLQUNGO0lBRUQsSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFO1FBQ3hCLE1BQU0sSUFBSSxLQUFLLENBQUMsZ0RBQWdELENBQUMsQ0FBQztLQUNuRTtJQUVELElBQUksU0FBUyxDQUFDO0lBQ2QsUUFBUSxNQUFNLEVBQUU7UUFDZCxLQUFLLGVBQWUsQ0FBQyxJQUFJO1lBQ3ZCLFNBQVMsR0FBRyxNQUFNLElBQUEsMEJBQWlCLEVBQUMsSUFBSSxFQUFFLElBQUksQ0FBQyxDQUFDO1lBQ2hELE1BQU07UUFDUjtZQUNFLE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztLQUNwRDtJQUVELFlBQVksQ0FBQyxHQUFHLENBQUMsU0FBUyxFQUFFLGVBQWUsQ0FBQyxJQUFJLENBQUMsQ0FBQztJQUVsRCxPQUFPLEVBQUUsU0FBUyxFQUFFLENBQUM7QUFDdkIsQ0FBQztBQXBERCxzQ0FvREM7QUFFRDs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FpQkc7QUFDSSxLQUFLLFVBQVUsY0FBYyxDQUNsQyxTQUE4QixFQUM5QixJQUFtQixFQUNuQixJQUFhLEVBQ2IsTUFBd0I7SUFFeEIsSUFBSSxNQUFNLEtBQUssU0FBUyxFQUFFO1FBQ3hCLE1BQU0sR0FBRyxZQUFZLENBQUMsR0FBRyxDQUFDLFNBQVMsQ0FBQyxDQUFDO1FBQ3JDLElBQUksTUFBTSxLQUFLLFNBQVMsRUFBRTtZQUN4QixNQUFNLElBQUksS0FBSyxDQUFDLG9EQUFvRCxDQUFDLENBQUM7U0FDdkU7S0FDRjtJQUVELFFBQVEsTUFBTSxFQUFFO1FBQ2QsS0FBSyxlQUFlLENBQUMsSUFBSTtZQUN2QixPQUFPLElBQUEsMkJBQWtCLEVBQUMsU0FBUyxFQUFFLElBQUksRUFBRSxJQUFJLENBQUMsQ0FBQztRQUNuRDtZQUNFLE1BQU0sSUFBSSxLQUFLLENBQUMsK0JBQStCLENBQUMsQ0FBQztLQUNwRDtBQUNILENBQUM7QUFuQkQsd0NBbUJDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7IGJhc2VuYW1lLCBnZXRTeXN0ZW1QYXRoLCBqb2luLCBub3JtYWxpemUgfSBmcm9tICcuLi92aXJ0dWFsLWZzJztcbmltcG9ydCB7IFdvcmtzcGFjZURlZmluaXRpb24gfSBmcm9tICcuL2RlZmluaXRpb25zJztcbmltcG9ydCB7IFdvcmtzcGFjZUhvc3QgfSBmcm9tICcuL2hvc3QnO1xuaW1wb3J0IHsgcmVhZEpzb25Xb3Jrc3BhY2UgfSBmcm9tICcuL2pzb24vcmVhZGVyJztcbmltcG9ydCB7IHdyaXRlSnNvbldvcmtzcGFjZSB9IGZyb20gJy4vanNvbi93cml0ZXInO1xuXG5jb25zdCBmb3JtYXRMb29rdXAgPSBuZXcgV2Vha01hcDxXb3Jrc3BhY2VEZWZpbml0aW9uLCBXb3Jrc3BhY2VGb3JtYXQ+KCk7XG5cbi8qKlxuICogU3VwcG9ydGVkIHdvcmtzcGFjZSBmb3JtYXRzXG4gKi9cbmV4cG9ydCBlbnVtIFdvcmtzcGFjZUZvcm1hdCB7XG4gIEpTT04sXG59XG5cbi8qKlxuICogQHByaXZhdGVcbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIF90ZXN0X2FkZFdvcmtzcGFjZUZpbGUobmFtZTogc3RyaW5nLCBmb3JtYXQ6IFdvcmtzcGFjZUZvcm1hdCk6IHZvaWQge1xuICB3b3Jrc3BhY2VGaWxlc1tuYW1lXSA9IGZvcm1hdDtcbn1cblxuLyoqXG4gKiBAcHJpdmF0ZVxuICovXG5leHBvcnQgZnVuY3Rpb24gX3Rlc3RfcmVtb3ZlV29ya3NwYWNlRmlsZShuYW1lOiBzdHJpbmcpOiB2b2lkIHtcbiAgZGVsZXRlIHdvcmtzcGFjZUZpbGVzW25hbWVdO1xufVxuXG4vLyBOT1RFOiBmdXR1cmUgYWRkaXRpb25zIGNvdWxkIGFsc28gcGVyZm9ybSBjb250ZW50IGFuYWx5c2lzIHRvIGRldGVybWluZSBmb3JtYXQvdmVyc2lvblxuY29uc3Qgd29ya3NwYWNlRmlsZXM6IFJlY29yZDxzdHJpbmcsIFdvcmtzcGFjZUZvcm1hdD4gPSB7XG4gICdhbmd1bGFyLmpzb24nOiBXb3Jrc3BhY2VGb3JtYXQuSlNPTixcbiAgJy5hbmd1bGFyLmpzb24nOiBXb3Jrc3BhY2VGb3JtYXQuSlNPTixcbn07XG5cbi8qKlxuICogUmVhZHMgYW5kIGNvbnN0cnVjdHMgYSBgV29ya3NwYWNlRGVmaW5pdGlvbmAuICBJZiB0aGUgZnVuY3Rpb24gaXMgcHJvdmlkZWQgd2l0aCBhIHBhdGggdG8gYVxuICogZGlyZWN0b3J5IGluc3RlYWQgb2YgYSBmaWxlLCBhIHNlYXJjaCBvZiB0aGUgZGlyZWN0b3J5J3MgZmlsZXMgd2lsbCBjb21tZW5jZSB0byBhdHRlbXB0IHRvXG4gKiBsb2NhdGUgYSBrbm93biB3b3Jrc3BhY2UgZmlsZS4gIEN1cnJlbnRseSB0aGUgZm9sbG93aW5nIGFyZSBjb25zaWRlcmVkIGtub3duIHdvcmtzcGFjZSBmaWxlczpcbiAqIC0gYGFuZ3VsYXIuanNvbmBcbiAqIC0gYC5hbmd1bGFyLmpzb25gXG4gKlxuICogQHBhcmFtIHBhdGggVGhlIHBhdGggdG8gZWl0aGVyIGEgd29ya3NwYWNlIGZpbGUgb3IgYSBkaXJlY3RvcnkgY29udGFpbmluZyBhIHdvcmtzcGFjZSBmaWxlLlxuICogQHBhcmFtIGhvc3QgVGhlIGBXb3Jrc3BhY2VIb3N0YCB0byB1c2UgdG8gYWNjZXNzIHRoZSBmaWxlIGFuZCBkaXJlY3RvcnkgZGF0YS5cbiAqIEBwYXJhbSBmb3JtYXQgQW4gb3B0aW9uYWwgYFdvcmtzcGFjZUZvcm1hdGAgdmFsdWUuIFVzZWQgaWYgdGhlIHBhdGggc3BlY2lmaWVzIGEgbm9uLXN0YW5kYXJkXG4gKiBmaWxlIG5hbWUgdGhhdCB3b3VsZCBwcmV2ZW50IGF1dG9tYXRpY2FsbHkgZGlzY292ZXJpbmcgdGhlIGZvcm1hdC5cbiAqXG4gKlxuICogQHJldHVybiBBbiBgUHJvbWlzZWAgb2YgdGhlIHJlYWQgcmVzdWx0IG9iamVjdCB3aXRoIHRoZSBgV29ya3NwYWNlRGVmaW5pdGlvbmAgY29udGFpbmVkIHdpdGhpblxuICogdGhlIGB3b3Jrc3BhY2VgIHByb3BlcnR5LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVhZFdvcmtzcGFjZShcbiAgcGF0aDogc3RyaW5nLFxuICBob3N0OiBXb3Jrc3BhY2VIb3N0LFxuICBmb3JtYXQ/OiBXb3Jrc3BhY2VGb3JtYXQsXG4gIC8vIHJldHVybiB0eXBlIHdpbGwgZXZlbnR1YWxseSBoYXZlIGEgYGRpYWdub3N0aWNzYCBwcm9wZXJ0eSBhcyB3ZWxsXG4pOiBQcm9taXNlPHsgd29ya3NwYWNlOiBXb3Jrc3BhY2VEZWZpbml0aW9uIH0+IHtcbiAgaWYgKGF3YWl0IGhvc3QuaXNEaXJlY3RvcnkocGF0aCkpIHtcbiAgICAvLyBUT0RPOiBXYXJuIGlmIG11bHRpcGxlIGZvdW5kIChyZXF1aXJlcyBkaWFnbm9zdGljcyBzdXBwb3J0KVxuICAgIGNvbnN0IGRpcmVjdG9yeSA9IG5vcm1hbGl6ZShwYXRoKTtcbiAgICBsZXQgZm91bmQgPSBmYWxzZTtcbiAgICBmb3IgKGNvbnN0IFtuYW1lLCBuYW1lRm9ybWF0XSBvZiBPYmplY3QuZW50cmllcyh3b3Jrc3BhY2VGaWxlcykpIHtcbiAgICAgIGlmIChmb3JtYXQgIT09IHVuZGVmaW5lZCAmJiBmb3JtYXQgIT09IG5hbWVGb3JtYXQpIHtcbiAgICAgICAgY29udGludWU7XG4gICAgICB9XG5cbiAgICAgIGNvbnN0IHBvdGVudGlhbCA9IGdldFN5c3RlbVBhdGgoam9pbihkaXJlY3RvcnksIG5hbWUpKTtcbiAgICAgIGlmIChhd2FpdCBob3N0LmlzRmlsZShwb3RlbnRpYWwpKSB7XG4gICAgICAgIHBhdGggPSBwb3RlbnRpYWw7XG4gICAgICAgIGZvcm1hdCA9IG5hbWVGb3JtYXQ7XG4gICAgICAgIGZvdW5kID0gdHJ1ZTtcbiAgICAgICAgYnJlYWs7XG4gICAgICB9XG4gICAgfVxuICAgIGlmICghZm91bmQpIHtcbiAgICAgIHRocm93IG5ldyBFcnJvcihcbiAgICAgICAgJ1VuYWJsZSB0byBsb2NhdGUgYSB3b3Jrc3BhY2UgZmlsZSBmb3Igd29ya3NwYWNlIHBhdGguIEFyZSB5b3UgbWlzc2luZyBhbiBgYW5ndWxhci5qc29uYCcgK1xuICAgICAgICAgICcgb3IgYC5hbmd1bGFyLmpzb25gIGZpbGU/JyxcbiAgICAgICk7XG4gICAgfVxuICB9IGVsc2UgaWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgY29uc3QgZmlsZW5hbWUgPSBiYXNlbmFtZShub3JtYWxpemUocGF0aCkpO1xuICAgIGlmIChmaWxlbmFtZSBpbiB3b3Jrc3BhY2VGaWxlcykge1xuICAgICAgZm9ybWF0ID0gd29ya3NwYWNlRmlsZXNbZmlsZW5hbWVdO1xuICAgIH1cbiAgfVxuXG4gIGlmIChmb3JtYXQgPT09IHVuZGVmaW5lZCkge1xuICAgIHRocm93IG5ldyBFcnJvcignVW5hYmxlIHRvIGRldGVybWluZSBmb3JtYXQgZm9yIHdvcmtzcGFjZSBwYXRoLicpO1xuICB9XG5cbiAgbGV0IHdvcmtzcGFjZTtcbiAgc3dpdGNoIChmb3JtYXQpIHtcbiAgICBjYXNlIFdvcmtzcGFjZUZvcm1hdC5KU09OOlxuICAgICAgd29ya3NwYWNlID0gYXdhaXQgcmVhZEpzb25Xb3Jrc3BhY2UocGF0aCwgaG9zdCk7XG4gICAgICBicmVhaztcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCB3b3Jrc3BhY2UgZm9ybWF0LicpO1xuICB9XG5cbiAgZm9ybWF0TG9va3VwLnNldCh3b3Jrc3BhY2UsIFdvcmtzcGFjZUZvcm1hdC5KU09OKTtcblxuICByZXR1cm4geyB3b3Jrc3BhY2UgfTtcbn1cblxuLyoqXG4gKiBXcml0ZXMgYSBgV29ya3NwYWNlRGVmaW5pdGlvbmAgdG8gdGhlIHVuZGVybHlpbmcgc3RvcmFnZSB2aWEgdGhlIHByb3ZpZGVkIGBXb3Jrc3BhY2VIb3N0YC5cbiAqIElmIHRoZSBgV29ya3NwYWNlRGVmaW5pdGlvbmAgd2FzIGNyZWF0ZWQgdmlhIHRoZSBgcmVhZFdvcmtzcGFjZWAgZnVuY3Rpb24sIG1ldGFkYXRhIHdpbGwgYmVcbiAqIHVzZWQgdG8gZGV0ZXJtaW5lIHRoZSBwYXRoIGFuZCBmb3JtYXQgb2YgdGhlIFdvcmtzcGFjZS4gIEluIGFsbCBvdGhlciBjYXNlcywgdGhlIGBwYXRoYCBhbmRcbiAqIGBmb3JtYXRgIG9wdGlvbnMgbXVzdCBiZSBzcGVjaWZpZWQgYXMgdGhleSB3b3VsZCBiZSBvdGhlcndpc2UgdW5rbm93bi5cbiAqXG4gKiBAcGFyYW0gd29ya3NwYWNlIFRoZSBgV29ya3NwYWNlRGVmaW5pdGlvbmAgdGhhdCB3aWxsIGJlIHdyaXR0ZW4uXG4gKiBAcGFyYW0gaG9zdCBUaGUgYFdvcmtzcGFjZUhvc3RgIHRvIHVzZSB0byBhY2Nlc3Mvd3JpdGUgdGhlIGZpbGUgYW5kIGRpcmVjdG9yeSBkYXRhLlxuICogQHBhcmFtIHBhdGggVGhlIHBhdGggdG8gYSBmaWxlIGxvY2F0aW9uIGZvciB0aGUgb3V0cHV0LiBSZXF1aXJlZCBpZiBgcmVhZFdvcmtzcGFjZWAgd2FzIG5vdFxuICogdXNlZCB0byBjcmVhdGUgdGhlIGBXb3Jrc3BhY2VEZWZpbml0aW9uYC4gIE9wdGlvbmFsIG90aGVyd2lzZTsgd2lsbCBvdmVycmlkZSB0aGVcbiAqIGBXb3Jrc3BhY2VEZWZpbml0aW9uYCBtZXRhZGF0YSBpZiBwcm92aWRlZC5cbiAqIEBwYXJhbSBmb3JtYXQgVGhlIGBXb3Jrc3BhY2VGb3JtYXRgIHRvIHVzZSBmb3Igb3V0cHV0LiBSZXF1aXJlZCBpZiBgcmVhZFdvcmtzcGFjZWAgd2FzIG5vdFxuICogdXNlZCB0byBjcmVhdGUgdGhlIGBXb3Jrc3BhY2VEZWZpbml0aW9uYC4gIE9wdGlvbmFsIG90aGVyd2lzZTsgd2lsbCBvdmVycmlkZSB0aGVcbiAqIGBXb3Jrc3BhY2VEZWZpbml0aW9uYCBtZXRhZGF0YSBpZiBwcm92aWRlZC5cbiAqXG4gKlxuICogQHJldHVybiBBbiBgUHJvbWlzZWAgb2YgdHlwZSBgdm9pZGAuXG4gKi9cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiB3cml0ZVdvcmtzcGFjZShcbiAgd29ya3NwYWNlOiBXb3Jrc3BhY2VEZWZpbml0aW9uLFxuICBob3N0OiBXb3Jrc3BhY2VIb3N0LFxuICBwYXRoPzogc3RyaW5nLFxuICBmb3JtYXQ/OiBXb3Jrc3BhY2VGb3JtYXQsXG4pOiBQcm9taXNlPHZvaWQ+IHtcbiAgaWYgKGZvcm1hdCA9PT0gdW5kZWZpbmVkKSB7XG4gICAgZm9ybWF0ID0gZm9ybWF0TG9va3VwLmdldCh3b3Jrc3BhY2UpO1xuICAgIGlmIChmb3JtYXQgPT09IHVuZGVmaW5lZCkge1xuICAgICAgdGhyb3cgbmV3IEVycm9yKCdBIGZvcm1hdCBpcyByZXF1aXJlZCBmb3IgY3VzdG9tIHdvcmtzcGFjZSBvYmplY3RzLicpO1xuICAgIH1cbiAgfVxuXG4gIHN3aXRjaCAoZm9ybWF0KSB7XG4gICAgY2FzZSBXb3Jrc3BhY2VGb3JtYXQuSlNPTjpcbiAgICAgIHJldHVybiB3cml0ZUpzb25Xb3Jrc3BhY2Uod29ya3NwYWNlLCBob3N0LCBwYXRoKTtcbiAgICBkZWZhdWx0OlxuICAgICAgdGhyb3cgbmV3IEVycm9yKCdVbnN1cHBvcnRlZCB3b3Jrc3BhY2UgZm9ybWF0LicpO1xuICB9XG59XG4iXX0=