UNPKG

@angular-devkit/build-angular

Version:
420 lines • 57.3 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 */ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) { if (k2 === undefined) k2 = k; var desc = Object.getOwnPropertyDescriptor(m, k); if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) { desc = { enumerable: true, get: function() { return m[k]; } }; } Object.defineProperty(o, k2, desc); }) : (function(o, m, k, k2) { if (k2 === undefined) k2 = k; o[k2] = m[k]; })); var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) { Object.defineProperty(o, "default", { enumerable: true, value: v }); }) : function(o, v) { o["default"] = v; }); var __importStar = (this && this.__importStar) || function (mod) { if (mod && mod.__esModule) return mod; var result = {}; if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k); __setModuleDefault(result, mod); return result; }; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.getCommonConfig = void 0; const webpack_1 = require("@ngtools/webpack"); const copy_webpack_plugin_1 = __importDefault(require("copy-webpack-plugin")); const path = __importStar(require("path")); const webpack_2 = require("webpack"); const webpack_subresource_integrity_1 = require("webpack-subresource-integrity"); const environment_options_1 = require("../../../utils/environment-options"); const load_esm_1 = require("../../../utils/load-esm"); const plugins_1 = require("../plugins"); const devtools_ignore_plugin_1 = require("../plugins/devtools-ignore-plugin"); const named_chunks_plugin_1 = require("../plugins/named-chunks-plugin"); const occurrences_plugin_1 = require("../plugins/occurrences-plugin"); const progress_plugin_1 = require("../plugins/progress-plugin"); const transfer_size_plugin_1 = require("../plugins/transfer-size-plugin"); const typescript_1 = require("../plugins/typescript"); const watch_files_logs_plugin_1 = require("../plugins/watch-files-logs-plugin"); const helpers_1 = require("../utils/helpers"); const VENDORS_TEST = /[\\/]node_modules[\\/]/; // eslint-disable-next-line max-lines-per-function async function getCommonConfig(wco) { const { root, projectRoot, buildOptions, tsConfig, projectName, sourceRoot, tsConfigPath } = wco; const { cache, codeCoverage, crossOrigin = 'none', platform = 'browser', aot = true, codeCoverageExclude = [], main, sourceMap: { styles: stylesSourceMap, scripts: scriptsSourceMap, vendor: vendorSourceMap, hidden: hiddenSourceMap, }, optimization: { styles: stylesOptimization, scripts: scriptsOptimization }, commonChunk, vendorChunk, subresourceIntegrity, verbose, poll, webWorkerTsConfig, externalDependencies = [], allowedCommonJsDependencies, } = buildOptions; const isPlatformServer = buildOptions.platform === 'server'; const extraPlugins = []; const extraRules = []; const entryPoints = {}; // Load ESM `@angular/compiler-cli` using the TypeScript dynamic import workaround. // Once TypeScript provides support for keeping the dynamic import this workaround can be // changed to a direct dynamic import. const { GLOBAL_DEFS_FOR_TERSER, GLOBAL_DEFS_FOR_TERSER_WITH_AOT, VERSION: NG_VERSION, } = await (0, load_esm_1.loadEsmModule)('@angular/compiler-cli'); // determine hashing format const hashFormat = (0, helpers_1.getOutputHashFormat)(buildOptions.outputHashing); if (buildOptions.progress) { extraPlugins.push(new progress_plugin_1.ProgressPlugin(platform)); } const localizePackageInitEntryPoint = '@angular/localize/init'; const hasLocalizeType = tsConfig.options.types?.some((t) => t === '@angular/localize' || t === localizePackageInitEntryPoint); if (hasLocalizeType) { entryPoints['main'] = [localizePackageInitEntryPoint]; } if (buildOptions.main) { const mainPath = path.resolve(root, buildOptions.main); if (Array.isArray(entryPoints['main'])) { entryPoints['main'].push(mainPath); } else { entryPoints['main'] = [mainPath]; } } if (isPlatformServer) { // Fixes Critical dependency: the request of a dependency is an expression extraPlugins.push(new webpack_2.ContextReplacementPlugin(/@?hapi|express[\\/]/)); if ((0, helpers_1.isPlatformServerInstalled)(wco.root) && Array.isArray(entryPoints['main'])) { // This import must come before any imports (direct or transitive) that rely on DOM built-ins being // available, such as `@angular/elements`. entryPoints['main'].unshift('@angular/platform-server/init'); } } const polyfills = [...buildOptions.polyfills]; if (!aot) { polyfills.push('@angular/compiler'); } if (polyfills.length) { // `zone.js/testing` is a **special** polyfill because when not imported in the main it fails with the below errors: // `Error: Expected to be running in 'ProxyZone', but it was not found.` // This was also the reason why previously it was imported in `test.ts` as the first module. // From Jia li: // This is because the jasmine functions such as beforeEach/it will not be patched by zone.js since // jasmine will not be loaded yet, so the ProxyZone will not be there. We have to load zone-testing.js after // jasmine is ready. // We could force loading 'zone.js/testing' prior to jasmine by changing the order of scripts in 'karma-context.html'. // But this has it's own problems as zone.js needs to be loaded prior to jasmine due to patching of timing functions // See: https://github.com/jasmine/jasmine/issues/1944 // Thus the correct order is zone.js -> jasmine -> zone.js/testing. const zoneTestingEntryPoint = 'zone.js/testing'; const polyfillsExludingZoneTesting = polyfills.filter((p) => p !== zoneTestingEntryPoint); if (Array.isArray(entryPoints['polyfills'])) { entryPoints['polyfills'].push(...polyfillsExludingZoneTesting); } else { entryPoints['polyfills'] = polyfillsExludingZoneTesting; } if (polyfillsExludingZoneTesting.length !== polyfills.length) { if (Array.isArray(entryPoints['main'])) { entryPoints['main'].unshift(zoneTestingEntryPoint); } else { entryPoints['main'] = [zoneTestingEntryPoint]; } } } if (allowedCommonJsDependencies) { // When this is not defined it means the builder doesn't support showing common js usages. // When it does it will be an array. extraPlugins.push(new plugins_1.CommonJsUsageWarnPlugin({ allowedDependencies: allowedCommonJsDependencies, })); } // process global scripts // Add a new asset for each entry. for (const { bundleName, inject, paths } of (0, helpers_1.globalScriptsByBundleName)(buildOptions.scripts)) { // Lazy scripts don't get a hash, otherwise they can't be loaded by name. const hash = inject ? hashFormat.script : ''; extraPlugins.push(new plugins_1.ScriptsWebpackPlugin({ name: bundleName, sourceMap: scriptsSourceMap, scripts: paths, filename: `${path.basename(bundleName)}${hash}.js`, basePath: root, })); } // process asset entries if (buildOptions.assets.length) { extraPlugins.push(new copy_webpack_plugin_1.default({ patterns: (0, helpers_1.assetPatterns)(root, buildOptions.assets), })); } if (buildOptions.extractLicenses) { const LicenseWebpackPlugin = require('license-webpack-plugin').LicenseWebpackPlugin; extraPlugins.push(new LicenseWebpackPlugin({ stats: { warnings: false, errors: false, }, perChunkOutput: false, outputFilename: '3rdpartylicenses.txt', skipChildCompilers: true, })); } if (scriptsSourceMap || stylesSourceMap) { const include = []; if (scriptsSourceMap) { include.push(/js$/); } if (stylesSourceMap) { include.push(/css$/); } extraPlugins.push(new devtools_ignore_plugin_1.DevToolsIgnorePlugin()); extraPlugins.push(new webpack_2.SourceMapDevToolPlugin({ filename: '[file].map', include, // We want to set sourceRoot to `webpack:///` for non // inline sourcemaps as otherwise paths to sourcemaps will be broken in browser // `webpack:///` is needed for Visual Studio breakpoints to work properly as currently // there is no way to set the 'webRoot' sourceRoot: 'webpack:///', moduleFilenameTemplate: '[resource-path]', append: hiddenSourceMap ? false : undefined, })); } if (verbose) { extraPlugins.push(new watch_files_logs_plugin_1.WatchFilesLogsPlugin()); } if (buildOptions.statsJson) { extraPlugins.push(new plugins_1.JsonStatsPlugin(path.resolve(root, buildOptions.outputPath, 'stats.json'))); } if (subresourceIntegrity) { extraPlugins.push(new webpack_subresource_integrity_1.SubresourceIntegrityPlugin({ hashFuncNames: ['sha384'], })); } if (scriptsSourceMap || stylesSourceMap) { extraRules.push({ test: /\.[cm]?jsx?$/, enforce: 'pre', loader: require.resolve('source-map-loader'), options: { filterSourceMappingUrl: (_mapUri, resourcePath) => { if (vendorSourceMap) { // Consume all sourcemaps when vendor option is enabled. return true; } // Don't consume sourcemaps in node_modules when vendor is disabled. // But, do consume local libraries sourcemaps. return !resourcePath.includes('node_modules'); }, }, }); } if (main || polyfills) { extraRules.push({ test: tsConfig.options.allowJs ? /\.[cm]?[tj]sx?$/ : /\.[cm]?tsx?$/, loader: webpack_1.AngularWebpackLoaderPath, // The below are known paths that are not part of the TypeScript compilation even when allowJs is enabled. exclude: [ /[\\/]node_modules[/\\](?:css-loader|mini-css-extract-plugin|webpack-dev-server|webpack)[/\\]/, ], }); extraPlugins.push((0, typescript_1.createIvyPlugin)(wco, aot, tsConfigPath)); } if (webWorkerTsConfig) { extraPlugins.push((0, typescript_1.createIvyPlugin)(wco, false, path.resolve(wco.root, webWorkerTsConfig))); } const extraMinimizers = []; if (scriptsOptimization) { extraMinimizers.push(new plugins_1.JavaScriptOptimizerPlugin({ define: buildOptions.aot ? GLOBAL_DEFS_FOR_TERSER_WITH_AOT : GLOBAL_DEFS_FOR_TERSER, sourcemap: scriptsSourceMap, supportedBrowsers: buildOptions.supportedBrowsers, keepIdentifierNames: !environment_options_1.allowMangle || isPlatformServer, removeLicenses: buildOptions.extractLicenses, advanced: buildOptions.buildOptimizer, })); } if (platform === 'browser' && (scriptsOptimization || stylesOptimization.minify)) { extraMinimizers.push(new transfer_size_plugin_1.TransferSizePlugin()); } let crossOriginLoading = false; if (subresourceIntegrity && crossOrigin === 'none') { crossOriginLoading = 'anonymous'; } else if (crossOrigin !== 'none') { crossOriginLoading = crossOrigin; } return { mode: scriptsOptimization || stylesOptimization.minify ? 'production' : 'development', devtool: false, target: [isPlatformServer ? 'node' : 'web', 'es2015'], profile: buildOptions.statsJson, resolve: { roots: [projectRoot], extensions: ['.ts', '.tsx', '.mjs', '.js'], symlinks: !buildOptions.preserveSymlinks, modules: [tsConfig.options.baseUrl || projectRoot, 'node_modules'], mainFields: isPlatformServer ? ['es2020', 'es2015', 'module', 'main'] : ['es2020', 'es2015', 'browser', 'module', 'main'], conditionNames: ['es2020', 'es2015', '...'], }, resolveLoader: { symlinks: !buildOptions.preserveSymlinks, }, context: root, entry: entryPoints, externals: externalDependencies, output: { uniqueName: projectName, hashFunction: 'xxhash64', clean: buildOptions.deleteOutputPath ?? true, path: path.resolve(root, buildOptions.outputPath), publicPath: buildOptions.deployUrl ?? '', filename: `[name]${hashFormat.chunk}.js`, chunkFilename: `[name]${hashFormat.chunk}.js`, libraryTarget: isPlatformServer ? 'commonjs' : undefined, crossOriginLoading, trustedTypes: 'angular#bundler', scriptType: 'module', }, watch: buildOptions.watch, watchOptions: { poll, // The below is needed as when preserveSymlinks is enabled we disable `resolve.symlinks`. followSymlinks: buildOptions.preserveSymlinks, ignored: poll === undefined ? undefined : '**/node_modules/**', }, snapshot: { module: { // Use hash of content instead of timestamp because the timestamp of the symlink will be used // instead of the referenced files which causes changes in symlinks not to be picked up. hash: buildOptions.preserveSymlinks, }, }, performance: { hints: false, }, ignoreWarnings: [ // https://github.com/webpack-contrib/source-map-loader/blob/b2de4249c7431dd8432da607e08f0f65e9d64219/src/index.js#L83 /Failed to parse source map from/, // https://github.com/webpack-contrib/postcss-loader/blob/bd261875fdf9c596af4ffb3a1a73fe3c549befda/src/index.js#L153-L158 /Add postcss as project dependency/, // esbuild will issue a warning, while still hoists the @charset at the very top. // This is caused by a bug in css-loader https://github.com/webpack-contrib/css-loader/issues/1212 /"@charset" must be the first rule in the file/, ], module: { // Show an error for missing exports instead of a warning. strictExportPresence: true, parser: { javascript: { requireContext: false, // Disable auto URL asset module creation. This doesn't effect `new Worker(new URL(...))` // https://webpack.js.org/guides/asset-modules/#url-assets url: false, worker: !!webWorkerTsConfig, }, }, rules: [ { test: /\.?(svg|html)$/, // Only process HTML and SVG which are known Angular component resources. resourceQuery: /\?ngResource/, type: 'asset/source', }, { // Mark files inside `rxjs/add` as containing side effects. // If this is fixed upstream and the fixed version becomes the minimum // supported version, this can be removed. test: /[/\\]rxjs[/\\]add[/\\].+\.js$/, sideEffects: true, }, { test: /\.[cm]?[tj]sx?$/, // The below is needed due to a bug in `@babel/runtime`. See: https://github.com/babel/babel/issues/12824 resolve: { fullySpecified: false }, exclude: [ /[\\/]node_modules[/\\](?:core-js|@babel|tslib|web-animations-js|web-streams-polyfill|whatwg-url)[/\\]/, ], use: [ { loader: require.resolve('../../babel/webpack-loader'), options: { cacheDirectory: (cache.enabled && path.join(cache.path, 'babel-webpack')) || false, aot: buildOptions.aot, optimize: buildOptions.buildOptimizer, supportedBrowsers: buildOptions.supportedBrowsers, instrumentCode: codeCoverage ? { includedBasePath: sourceRoot ?? projectRoot, excludedPaths: (0, helpers_1.getInstrumentationExcludedPaths)(root, codeCoverageExclude), } : undefined, }, }, ], }, ...extraRules, ], }, experiments: { backCompat: false, syncWebAssembly: true, asyncWebAssembly: true, topLevelAwait: false, }, infrastructureLogging: { debug: verbose, level: verbose ? 'verbose' : 'error', }, stats: (0, helpers_1.getStatsOptions)(verbose), cache: (0, helpers_1.getCacheSettings)(wco, NG_VERSION.full), optimization: { minimizer: extraMinimizers, moduleIds: 'deterministic', chunkIds: buildOptions.namedChunks ? 'named' : 'deterministic', emitOnErrors: false, runtimeChunk: isPlatformServer ? false : 'single', splitChunks: { maxAsyncRequests: Infinity, cacheGroups: { default: !!commonChunk && { chunks: 'async', minChunks: 2, priority: 10, }, common: !!commonChunk && { name: 'common', chunks: 'async', minChunks: 2, enforce: true, priority: 5, }, vendors: false, defaultVendors: !!vendorChunk && { name: 'vendor', chunks: (chunk) => chunk.name === 'main', enforce: true, test: VENDORS_TEST, }, }, }, }, plugins: [ new named_chunks_plugin_1.NamedChunksPlugin(), new occurrences_plugin_1.OccurrencesPlugin({ aot, scriptsOptimization, }), new plugins_1.DedupeModuleResolvePlugin({ verbose }), ...extraPlugins, ], node: false, }; } exports.getCommonConfig = getCommonConfig; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiY29tbW9uLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vLi4vcGFja2FnZXMvYW5ndWxhcl9kZXZraXQvYnVpbGRfYW5ndWxhci9zcmMvdG9vbHMvd2VicGFjay9jb25maWdzL2NvbW1vbi50cyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiO0FBQUE7Ozs7OztHQU1HOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQUVILDhDQUE0RDtBQUM1RCw4RUFBb0Q7QUFDcEQsMkNBQTZCO0FBQzdCLHFDQU1pQjtBQUNqQixpRkFBMkU7QUFFM0UsNEVBQWlFO0FBQ2pFLHNEQUF3RDtBQUV4RCx3Q0FNb0I7QUFDcEIsOEVBQXlFO0FBQ3pFLHdFQUFtRTtBQUNuRSxzRUFBa0U7QUFDbEUsZ0VBQTREO0FBQzVELDBFQUFxRTtBQUNyRSxzREFBd0Q7QUFDeEQsZ0ZBQTBFO0FBQzFFLDhDQVEwQjtBQUUxQixNQUFNLFlBQVksR0FBRyx3QkFBd0IsQ0FBQztBQUU5QyxrREFBa0Q7QUFDM0MsS0FBSyxVQUFVLGVBQWUsQ0FBQyxHQUF5QjtJQUM3RCxNQUFNLEVBQUUsSUFBSSxFQUFFLFdBQVcsRUFBRSxZQUFZLEVBQUUsUUFBUSxFQUFFLFdBQVcsRUFBRSxVQUFVLEVBQUUsWUFBWSxFQUFFLEdBQUcsR0FBRyxDQUFDO0lBQ2pHLE1BQU0sRUFDSixLQUFLLEVBQ0wsWUFBWSxFQUNaLFdBQVcsR0FBRyxNQUFNLEVBQ3BCLFFBQVEsR0FBRyxTQUFTLEVBQ3BCLEdBQUcsR0FBRyxJQUFJLEVBQ1YsbUJBQW1CLEdBQUcsRUFBRSxFQUN4QixJQUFJLEVBQ0osU0FBUyxFQUFFLEVBQ1QsTUFBTSxFQUFFLGVBQWUsRUFDdkIsT0FBTyxFQUFFLGdCQUFnQixFQUN6QixNQUFNLEVBQUUsZUFBZSxFQUN2QixNQUFNLEVBQUUsZUFBZSxHQUN4QixFQUNELFlBQVksRUFBRSxFQUFFLE1BQU0sRUFBRSxrQkFBa0IsRUFBRSxPQUFPLEVB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LE9BQU8sRUFBRSxDQUFDLENBQUMsV0FBVyxJQUFJO3dCQUN4QixNQUFNLEVBQUUsT0FBTzt3QkFDZixTQUFTLEVBQUUsQ0FBQzt3QkFDWixRQUFRLEVBQUUsRUFBRTtxQkFDYjtvQkFDRCxNQUFNLEVBQUUsQ0FBQyxDQUFDLFdBQVcsSUFBSTt3QkFDdkIsSUFBSSxFQUFFLFFBQVE7d0JBQ2QsTUFBTSxFQUFFLE9BQU87d0JBQ2YsU0FBUyxFQUFFLENBQUM7d0JBQ1osT0FBTyxFQUFFLElBQUk7d0JBQ2IsUUFBUSxFQUFFLENBQUM7cUJBQ1o7b0JBQ0QsT0FBTyxFQUFFLEtBQUs7b0JBQ2QsY0FBYyxFQUFFLENBQUMsQ0FBQyxXQUFXLElBQUk7d0JBQy9CLElBQUksRUFBRSxRQUFRO3dCQUNkLE1BQU0sRUFBRSxDQUFDLEtBQUssRUFBRSxFQUFFLENBQUMsS0FBSyxDQUFDLElBQUksS0FBSyxNQUFNO3dCQUN4QyxPQUFPLEVBQUUsSUFBSTt3QkFDYixJQUFJLEVBQUUsWUFBWTtxQkFDbkI7aUJBQ0Y7YUFDRjtTQUNGO1FBQ0QsT0FBTyxFQUFFO1lBQ1AsSUFBSSx1Q0FBaUIsRUFBRTtZQUN2QixJQUFJLHNDQUFpQixDQUFDO2dCQUNwQixHQUFHO2dCQUNILG1CQUFtQjthQUNwQixDQUFDO1lBQ0YsSUFBSSxtQ0FBeUIsQ0FBQyxFQUFFLE9BQU8sRUFBRSxDQUFDO1lBQzFDLEdBQUcsWUFBWTtTQUNoQjtRQUNELElBQUksRUFBRSxLQUFLO0tBQ1osQ0FBQztBQUNKLENBQUM7QUFyYkQsMENBcWJDIiwic291cmNlc0NvbnRlbnQiOlsiLyoqXG4gKiBAbGljZW5zZVxuICogQ29weXJpZ2h0IEdvb2dsZSBMTEMgQWxsIFJpZ2h0cyBSZXNlcnZlZC5cbiAqXG4gKiBVc2Ugb2YgdGhpcyBzb3VyY2UgY29kZSBpcyBnb3Zlcm5lZCBieSBhbiBNSVQtc3R5bGUgbGljZW5zZSB0aGF0IGNhbiBiZVxuICogZm91bmQgaW4gdGhlIExJQ0VOU0UgZmlsZSBhdCBodHRwczovL2FuZ3VsYXIuaW8vbGljZW5zZVxuICovXG5cbmltcG9ydCB7IEFuZ3VsYXJXZWJwYWNrTG9hZGVyUGF0aCB9IGZyb20gJ0BuZ3Rvb2xzL3dlYnBhY2snO1xuaW1wb3J0IENvcHlXZWJwYWNrUGx1Z2luIGZyb20gJ2NvcHktd2VicGFjay1wbHVnaW4nO1xuaW1wb3J0ICogYXMgcGF0aCBmcm9tICdwYXRoJztcbmltcG9ydCB7XG4gIENvbXBpbGVyLFxuICBDb25maWd1cmF0aW9uLFxuICBDb250ZXh0UmVwbGFjZW1lbnRQbHVnaW4sXG4gIFJ1bGVTZXRSdWxlLFxuICBTb3VyY2VNYXBEZXZUb29sUGx1Z2luLFxufSBmcm9tICd3ZWJwYWNrJztcbmltcG9ydCB7IFN1YnJlc291cmNlSW50ZWdyaXR5UGx1Z2luIH0gZnJvbSAnd2VicGFjay1zdWJyZXNvdXJjZS1pbnRlZ3JpdHknO1xuaW1wb3J0IHsgV2VicGFja0NvbmZpZ09wdGlvbnMgfSBmcm9tICcuLi8uLi8uLi91dGlscy9idWlsZC1vcHRpb25zJztcbmltcG9ydCB7IGFsbG93TWFuZ2xlIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvZW52aXJvbm1lbnQtb3B0aW9ucyc7XG5pbXBvcnQgeyBsb2FkRXNtTW9kdWxlIH0gZnJvbSAnLi4vLi4vLi4vdXRpbHMvbG9hZC1lc20nO1xuaW1wb3J0IHsgQW5ndWxhckJhYmVsTG9hZGVyT3B0aW9ucyB9IGZyb20gJy4uLy4uL2JhYmVsL3dlYnBhY2stbG9hZGVyJztcbmltcG9ydCB7XG4gIENvbW1vbkpzVXNhZ2VXYXJuUGx1Z2luLFxuICBEZWR1cGVNb2R1bGVSZXNvbHZlUGx1Z2luLFxuICBKYXZhU2NyaXB0T3B0aW1pemVyUGx1Z2luLFxuICBKc29uU3RhdHNQbHVnaW4sXG4gIFNjcmlwdHNXZWJwYWNrUGx1Z2luLFxufSBmcm9tICcuLi9wbHVnaW5zJztcbmltcG9ydCB7IERldlRvb2xzSWdub3JlUGx1Z2luIH0gZnJvbSAnLi4vcGx1Z2lucy9kZXZ0b29scy1pZ25vcmUtcGx1Z2luJztcbmltcG9ydCB7IE5hbWVkQ2h1bmtzUGx1Z2luIH0gZnJvbSAnLi4vcGx1Z2lucy9uYW1lZC1jaHVua3MtcGx1Z2luJztcbmltcG9ydCB7IE9jY3VycmVuY2VzUGx1Z2luIH0gZnJvbSAnLi4vcGx1Z2lucy9vY2N1cnJlbmNlcy1wbHVnaW4nO1xuaW1wb3J0IHsgUHJvZ3Jlc3NQbHVnaW4gfSBmcm9tICcuLi9wbHVnaW5zL3Byb2dyZXNzLXBsdWdpbic7XG5pbXBvcnQgeyBUcmFuc2ZlclNpemVQbHVnaW4gfSBmcm9tICcuLi9wbHVnaW5zL3RyYW5zZmVyLXNpemUtcGx1Z2luJztcbmltcG9ydCB7IGNyZWF0ZUl2eVBsdWdpbiB9IGZyb20gJy4uL3BsdWdpbnMvdHlwZXNjcmlwdCc7XG5pbXBvcnQgeyBXYXRjaEZpbGVzTG9nc1BsdWdpbiB9IGZyb20gJy4uL3BsdWdpbnMvd2F0Y2gtZmlsZXMtbG9ncy1wbHVnaW4nO1xuaW1wb3J0IHtcbiAgYXNzZXRQYXR0ZXJucyxcbiAgZ2V0Q2FjaGVTZXR0aW5ncyxcbiAgZ2V0SW5zdHJ1bWVudGF0aW9uRXhjbHVkZWRQYXRocyxcbiAgZ2V0T3V0cHV0SGFzaEZvcm1hdCxcbiAgZ2V0U3RhdHNPcHRpb25zLFxuICBnbG9iYWxTY3JpcHRzQnlCdW5kbGVOYW1lLFxuICBpc1BsYXRmb3JtU2VydmVySW5zdGFsbGVkLFxufSBmcm9tICcuLi91dGlscy9oZWxwZXJzJztcblxuY29uc3QgVkVORE9SU19URVNUID0gL1tcXFxcL11ub2RlX21vZHVsZXNbXFxcXC9dLztcblxuLy8gZXNsaW50LWRpc2FibGUtbmV4dC1saW5lIG1heC1saW5lcy1wZXItZnVuY3Rpb25cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBnZXRDb21tb25Db25maWcod2NvOiBXZWJwYWNrQ29uZmlnT3B0aW9ucyk6IFByb21pc2U8Q29uZmlndXJhdGlvbj4ge1xuICBjb25zdCB7IHJvb3QsIHByb2plY3RSb290LCBidWlsZE9wdGlvbnMsIHRzQ29uZmlnLCBwcm9qZWN0TmFtZSwgc291cmNlUm9vdCwgdHNDb25maWdQYXRoIH0gPSB3Y287XG4gIGNvbnN0IHtcbiAgICBjYWNoZSxcbiAgICBjb2RlQ292ZXJhZ2UsXG4gICAgY3Jvc3NPcmlnaW4gPSAnbm9uZScsXG4gICAgcGxhdGZvcm0gPSAnYnJvd3NlcicsXG4gICAgYW90ID0gdHJ1ZSxcbiAgICBjb2RlQ292ZXJhZ2VFeGNsdWRlID0gW10sXG4gICAgbWFpbixcbiAgICBzb3VyY2VNYXA6IHtcbiAgICAgIHN0eWxlczogc3R5bGVzU291cmNlTWFwLFxuICAgICAgc2NyaXB0czogc2NyaXB0c1NvdXJjZU1hcCxcbiAgICAgIHZlbmRvcjogdmVuZG9yU291cmNlTWFwLFxuICAgICAgaGlkZGVuOiBoaWRkZW5Tb3VyY2VNYXAsXG4gICAgfSxcbiAgICBvcHRpbWl6YXRpb246IHsgc3R5bGVzOiBzdHlsZXNPcHRpbWl6YXRpb24sIHNjcmlwdHM6IHNjcmlwdHNPcHRpbWl6YXRpb24gfSxcbiAgICBjb21tb25DaHVuayxcbiAgICB2ZW5kb3JDaHVuayxcbiAgICBzdWJyZXNvdXJjZUludGVncml0eSxcbiAgICB2ZXJib3NlLFxuICAgIHBvbGwsXG4gICAgd2ViV29ya2VyVHNDb25maWcsXG4gICAgZXh0ZXJuYWxEZXBlbmRlbmNpZXMgPSBbXSxcbiAgICBhbGxvd2VkQ29tbW9uSnNEZXBlbmRlbmNpZXMsXG4gIH0gPSBidWlsZE9wdGlvbnM7XG5cbiAgY29uc3QgaXNQbGF0Zm9ybVNlcnZlciA9IGJ1aWxkT3B0aW9ucy5wbGF0Zm9ybSA9PT0gJ3NlcnZlcic7XG4gIGNvbnN0IGV4dHJhUGx1Z2luczogeyBhcHBseShjb21waWxlcjogQ29tcGlsZXIpOiB2b2lkIH1bXSA9IFtdO1xuICBjb25zdCBleHRyYVJ1bGVzOiBSdWxlU2V0UnVsZVtdID0gW107XG4gIGNvbnN0IGVudHJ5UG9pbnRzOiBDb25maWd1cmF0aW9uWydlbnRyeSddID0ge307XG5cbiAgLy8gTG9hZCBFU00gYEBhbmd1bGFyL2NvbXBpbGVyLWNsaWAgdXNpbmcgdGhlIFR5cGVTY3JpcHQgZHluYW1pYyBpbXBvcnQgd29ya2Fyb3VuZC5cbiAgLy8gT25jZSBUeXBlU2NyaXB0IHByb3ZpZGVzIHN1cHBvcnQgZm9yIGtlZXBpbmcgdGhlIGR5bmFtaWMgaW1wb3J0IHRoaXMgd29ya2Fyb3VuZCBjYW4gYmVcbiAgLy8gY2hhbmdlZCB0byBhIGRpcmVjdCBkeW5hbWljIGltcG9ydC5cbiAgY29uc3Qge1xuICAgIEdMT0JBTF9ERUZTX0ZPUl9URVJTRVIsXG4gICAgR0xPQkFMX0RFRlNfRk9SX1RFUlNFUl9XSVRIX0FPVCxcbiAgICBWRVJTSU9OOiBOR19WRVJTSU9OLFxuICB9ID0gYXdhaXQgbG9hZEVzbU1vZHVsZTx0eXBlb2YgaW1wb3J0KCdAYW5ndWxhci9jb21waWxlci1jbGknKT4oJ0Bhbmd1bGFyL2NvbXBpbGVyLWNsaScpO1xuXG4gIC8vIGRldGVybWluZSBoYXNoaW5nIGZvcm1hdFxuICBjb25zdCBoYXNoRm9ybWF0ID0gZ2V0T3V0cHV0SGFzaEZvcm1hdChidWlsZE9wdGlvbnMub3V0cHV0SGFzaGluZyk7XG5cbiAgaWYgKGJ1aWxkT3B0aW9ucy5wcm9ncmVzcykge1xuICAgIGV4dHJhUGx1Z2lucy5wdXNoKG5ldyBQcm9ncmVzc1BsdWdpbihwbGF0Zm9ybSkpO1xuICB9XG5cbiAgY29uc3QgbG9jYWxpemVQYWNrYWdlSW5pdEVudHJ5UG9pbnQgPSAnQGFuZ3VsYXIvbG9jYWxpemUvaW5pdCc7XG4gIGNvbnN0IGhhc0xvY2FsaXplVHlwZSA9IHRzQ29uZmlnLm9wdGlvbnMudHlwZXM/LnNvbWUoXG4gICAgKHQpID0+IHQgPT09ICdAYW5ndWxhci9sb2NhbGl6ZScgfHwgdCA9PT0gbG9jYWxpemVQYWNrYWdlSW5pdEVudHJ5UG9pbnQsXG4gICk7XG5cbiAgaWYgKGhhc0xvY2FsaXplVHlwZSkge1xuICAgIGVudHJ5UG9pbnRzWydtYWluJ10gPSBbbG9jYWxpemVQYWNrYWdlSW5pdEVudHJ5UG9pbnRdO1xuICB9XG5cbiAgaWYgKGJ1aWxkT3B0aW9ucy5tYWluKSB7XG4gICAgY29uc3QgbWFpblBhdGggPSBwYXRoLnJlc29sdmUocm9vdCwgYnVpbGRPcHRpb25zLm1haW4pO1xuICAgIGlmIChBcnJheS5pc0FycmF5KGVudHJ5UG9pbnRzWydtYWluJ10pKSB7XG4gICAgICBlbnRyeVBvaW50c1snbWFpbiddLnB1c2gobWFpblBhdGgpO1xuICAgIH0gZWxzZSB7XG4gICAgICBlbnRyeVBvaW50c1snbWFpbiddID0gW21haW5QYXRoXTtcbiAgICB9XG4gIH1cblxuICBpZiAoaXNQbGF0Zm9ybVNlcnZlcikge1xuICAgIC8vIEZpeGVzIENyaXRpY2FsIGRlcGVuZGVuY3k6IHRoZSByZXF1ZXN0IG9mIGEgZGVwZW5kZW5jeSBpcyBhbiBleHByZXNzaW9uXG4gICAgZXh0cmFQbHVnaW5zLnB1c2gobmV3IENvbnRleHRSZXBsYWNlbWVudFBsdWdpbigvQD9oYXBpfGV4cHJlc3NbXFxcXC9dLykpO1xuXG4gICAgaWYgKGlzUGxhdGZvcm1TZXJ2ZXJJbnN0YWxsZWQod2NvLnJvb3QpICYmIEFycmF5LmlzQXJyYXkoZW50cnlQb2ludHNbJ21haW4nXSkpIHtcbiAgICAgIC8vIFRoaXMgaW1wb3J0IG11c3QgY29tZSBiZWZvcmUgYW55IGltcG9ydHMgKGRpcmVjdCBvciB0cmFuc2l0aXZlKSB0aGF0IHJlbHkgb24gRE9NIGJ1aWx0LWlucyBiZWluZ1xuICAgICAgLy8gYXZhaWxhYmxlLCBzdWNoIGFzIGBAYW5ndWxhci9lbGVtZW50c2AuXG4gICAgICBlbnRyeVBvaW50c1snbWFpbiddLnVuc2hpZnQoJ0Bhbmd1bGFyL3BsYXRmb3JtLXNlcnZlci9pbml0Jyk7XG4gICAgfVxuICB9XG5cbiAgY29uc3QgcG9seWZpbGxzID0gWy4uLmJ1aWxkT3B0aW9ucy5wb2x5ZmlsbHNdO1xuICBpZiAoIWFvdCkge1xuICAgIHBvbHlmaWxscy5wdXNoKCdAYW5ndWxhci9jb21waWxlcicpO1xuICB9XG5cbiAgaWYgKHBvbHlmaWxscy5sZW5ndGgpIHtcbiAgICAvLyBgem9uZS5qcy90ZXN0aW5nYCBpcyBhICoqc3BlY2lhbCoqIHBvbHlmaWxsIGJlY2F1c2Ugd2hlbiBub3QgaW1wb3J0ZWQgaW4gdGhlIG1haW4gaXQgZmFpbHMgd2l0aCB0aGUgYmVsb3cgZXJyb3JzOlxuICAgIC8vIGBFcnJvcjogRXhwZWN0ZWQgdG8gYmUgcnVubmluZyBpbiAnUHJveHlab25lJywgYnV0IGl0IHdhcyBub3QgZm91bmQuYFxuICAgIC8vIFRoaXMgd2FzIGFsc28gdGhlIHJlYXNvbiB3aHkgcHJldmlvdXNseSBpdCB3YXMgaW1wb3J0ZWQgaW4gYHRlc3QudHNgIGFzIHRoZSBmaXJzdCBtb2R1bGUuXG4gICAgLy8gRnJvbSBKaWEgbGk6XG4gICAgLy8gVGhpcyBpcyBiZWNhdXNlIHRoZSBqYXNtaW5lIGZ1bmN0aW9ucyBzdWNoIGFzIGJlZm9yZUVhY2gvaXQgd2lsbCBub3QgYmUgcGF0Y2hlZCBieSB6b25lLmpzIHNpbmNlXG4gICAgLy8gamFzbWluZSB3aWxsIG5vdCBiZSBsb2FkZWQgeWV0LCBzbyB0aGUgUHJveHlab25lIHdpbGwgbm90IGJlIHRoZXJlLiBXZSBoYXZlIHRvIGxvYWQgem9uZS10ZXN0aW5nLmpzIGFmdGVyXG4gICAgLy8gamFzbWluZSBpcyByZWFkeS5cbiAgICAvLyBXZSBjb3VsZCBmb3JjZSBsb2FkaW5nICd6b25lLmpzL3Rlc3RpbmcnIHByaW9yIHRvIGphc21pbmUgYnkgY2hhbmdpbmcgdGhlIG9yZGVyIG9mIHNjcmlwdHMgaW4gJ2thcm1hLWNvbnRleHQuaHRtbCcuXG4gICAgLy8gQnV0IHRoaXMgaGFzIGl0J3Mgb3duIHByb2JsZW1zIGFzIHpvbmUuanMgbmVlZHMgdG8gYmUgbG9hZGVkIHByaW9yIHRvIGphc21pbmUgZHVlIHRvIHBhdGNoaW5nIG9mIHRpbWluZyBmdW5jdGlvbnNcbiAgICAvLyBTZWU6IGh0dHBzOi8vZ2l0aHViLmNvbS9qYXNtaW5lL2phc21pbmUvaXNzdWVzLzE5NDRcbiAgICAvLyBUaHVzIHRoZSBjb3JyZWN0IG9yZGVyIGlzIHpvbmUuanMgLT4gamFzbWluZSAtPiB6b25lLmpzL3Rlc3RpbmcuXG4gICAgY29uc3Qgem9uZVRlc3RpbmdFbnRyeVBvaW50ID0gJ3pvbmUuanMvdGVzdGluZyc7XG4gICAgY29uc3QgcG9seWZpbGxzRXhsdWRpbmdab25lVGVzdGluZyA9IHBvbHlmaWxscy5maWx0ZXIoKHApID0+IHAgIT09IHpvbmVUZXN0aW5nRW50cnlQb2ludCk7XG5cbiAgICBpZiAoQXJyYXkuaXNBcnJheShlbnRyeVBvaW50c1sncG9seWZpbGxzJ10pKSB7XG4gICAgICBlbnRyeVBvaW50c1sncG9seWZpbGxzJ10ucHVzaCguLi5wb2x5ZmlsbHNFeGx1ZGluZ1pvbmVUZXN0aW5nKTtcbiAgICB9IGVsc2Uge1xuICAgICAgZW50cnlQb2ludHNbJ3BvbHlmaWxscyddID0gcG9seWZpbGxzRXhsdWRpbmdab25lVGVzdGluZztcbiAgICB9XG5cbiAgICBpZiAocG9seWZpbGxzRXhsdWRpbmdab25lVGVzdGluZy5sZW5ndGggIT09IHBvbHlmaWxscy5sZW5ndGgpIHtcbiAgICAgIGlmIChBcnJheS5pc0FycmF5KGVudHJ5UG9pbnRzWydtYWluJ10pKSB7XG4gICAgICAgIGVudHJ5UG9pbnRzWydtYWluJ10udW5zaGlmdCh6b25lVGVzdGluZ0VudHJ5UG9pbnQpO1xuICAgICAgfSBlbHNlIHtcbiAgICAgICAgZW50cnlQb2ludHNbJ21haW4nXSA9IFt6b25lVGVzdGluZ0VudHJ5UG9pbnRdO1xuICAgICAgfVxuICAgIH1cbiAgfVxuXG4gIGlmIChhbGxvd2VkQ29tbW9uSnNEZXBlbmRlbmNpZXMpIHtcbiAgICAvLyBXaGVuIHRoaXMgaXMgbm90IGRlZmluZWQgaXQgbWVhbnMgdGhlIGJ1aWxkZXIgZG9lc24ndCBzdXBwb3J0IHNob3dpbmcgY29tbW9uIGpzIHVzYWdlcy5cbiAgICAvLyBXaGVuIGl0IGRvZXMgaXQgd2lsbCBiZSBhbiBhcnJheS5cbiAgICBleHRyYVBsdWdpbnMucHVzaChcbiAgICAgIG5ldyBDb21tb25Kc1VzYWdlV2FyblBsdWdpbih7XG4gICAgICAgIGFsbG93ZWREZXBlbmRlbmNpZXM6IGFsbG93ZWRDb21tb25Kc0RlcGVuZGVuY2llcyxcbiAgICAgIH0pLFxuICAgICk7XG4gIH1cblxuICAvLyBwcm9jZXNzIGdsb2JhbCBzY3JpcHRzXG4gIC8vIEFkZCBhIG5ldyBhc3NldCBmb3IgZWFjaCBlbnRyeS5cbiAgZm9yIChjb25zdCB7IGJ1bmRsZU5hbWUsIGluamVjdCwgcGF0aHMgfSBvZiBnbG9iYWxTY3JpcHRzQnlCdW5kbGVOYW1lKGJ1aWxkT3B0aW9ucy5zY3JpcHRzKSkge1xuICAgIC8vIExhenkgc2NyaXB0cyBkb24ndCBnZXQgYSBoYXNoLCBvdGhlcndpc2UgdGhleSBjYW4ndCBiZSBsb2FkZWQgYnkgbmFtZS5cbiAgICBjb25zdCBoYXNoID0gaW5qZWN0ID8gaGFzaEZvcm1hdC5zY3JpcHQgOiAnJztcblxuICAgIGV4dHJhUGx1Z2lucy5wdXNoKFxuICAgICAgbmV3IFNjcmlwdHNXZWJwYWNrUGx1Z2luKHtcbiAgICAgICAgbmFtZTogYnVuZGxlTmFtZSxcbiAgICAgICAgc291cmNlTWFwOiBzY3JpcHRzU291cmNlTWFwLFxuICAgICAgICBzY3JpcHRzOiBwYXRocyxcbiAgICAgICAgZmlsZW5hbWU6IGAke3BhdGguYmFzZW5hbWUoYnVuZGxlTmFtZSl9JHtoYXNofS5qc2AsXG4gICAgICAgIGJhc2VQYXRoOiByb290LFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIC8vIHByb2Nlc3MgYXNzZXQgZW50cmllc1xuICBpZiAoYnVpbGRPcHRpb25zLmFzc2V0cy5sZW5ndGgpIHtcbiAgICBleHRyYVBsdWdpbnMucHVzaChcbiAgICAgIG5ldyBDb3B5V2VicGFja1BsdWdpbih7XG4gICAgICAgIHBhdHRlcm5zOiBhc3NldFBhdHRlcm5zKHJvb3QsIGJ1aWxkT3B0aW9ucy5hc3NldHMpLFxuICAgICAgfSksXG4gICAgKTtcbiAgfVxuXG4gIGlmIChidWlsZE9wdGlvbnMuZXh0cmFjdExpY2Vuc2VzKSB7XG4gICAgY29uc3QgTGljZW5zZVdlYnBhY2tQbHVnaW4gPSByZXF1aXJlKCdsaWNlbnNlLXdlYnBhY2stcGx1Z2luJykuTGljZW5zZVdlYnBhY2tQbHVnaW47XG4gICAgZXh0cmFQbHVnaW5zLnB1c2goXG4gICAgICBuZXcgTGljZW5zZVdlYnBhY2tQbHVnaW4oe1xuICAgICAgICBzdGF0czoge1xuICAgICAgICAgIHdhcm5pbmdzOiBmYWxzZSxcbiAgICAgICAgICBlcnJvcnM6IGZhbHNlLFxuICAgICAgICB9LFxuICAgICAgICBwZXJDaHVua091dHB1dDogZmFsc2UsXG4gICAgICAgIG91dHB1dEZpbGVuYW1lOiAnM3JkcGFydHlsaWNlbnNlcy50eHQnLFxuICAgICAgICBza2lwQ2hpbGRDb21waWxlcnM6IHRydWUsXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgaWYgKHNjcmlwdHNTb3VyY2VNYXAgfHwgc3R5bGVzU291cmNlTWFwKSB7XG4gICAgY29uc3QgaW5jbHVkZSA9IFtdO1xuICAgIGlmIChzY3JpcHRzU291cmNlTWFwKSB7XG4gICAgICBpbmNsdWRlLnB1c2goL2pzJC8pO1xuICAgIH1cblxuICAgIGlmIChzdHlsZXNTb3VyY2VNYXApIHtcbiAgICAgIGluY2x1ZGUucHVzaCgvY3NzJC8pO1xuICAgIH1cblxuICAgIGV4dHJhUGx1Z2lucy5wdXNoKG5ldyBEZXZUb29sc0lnbm9yZVBsdWdpbigpKTtcblxuICAgIGV4dHJhUGx1Z2lucy5wdXNoKFxuICAgICAgbmV3IFNvdXJjZU1hcERldlRvb2xQbHVnaW4oe1xuICAgICAgICBmaWxlbmFtZTogJ1tmaWxlXS5tYXAnLFxuICAgICAgICBpbmNsdWRlLFxuICAgICAgICAvLyBXZSB3YW50IHRvIHNldCBzb3VyY2VSb290IHRvICBgd2VicGFjazovLy9gIGZvciBub25cbiAgICAgICAgLy8gaW5saW5lIHNvdXJjZW1hcHMgYXMgb3RoZXJ3aXNlIHBhdGhzIHRvIHNvdXJjZW1hcHMgd2lsbCBiZSBicm9rZW4gaW4gYnJvd3NlclxuICAgICAgICAvLyBgd2VicGFjazovLy9gIGlzIG5lZWRlZCBmb3IgVmlzdWFsIFN0dWRpbyBicmVha3BvaW50cyB0byB3b3JrIHByb3Blcmx5IGFzIGN1cnJlbnRseVxuICAgICAgICAvLyB0aGVyZSBpcyBubyB3YXkgdG8gc2V0IHRoZSAnd2ViUm9vdCdcbiAgICAgICAgc291cmNlUm9vdDogJ3dlYnBhY2s6Ly8vJyxcbiAgICAgICAgbW9kdWxlRmlsZW5hbWVUZW1wbGF0ZTogJ1tyZXNvdXJjZS1wYXRoXScsXG4gICAgICAgIGFwcGVuZDogaGlkZGVuU291cmNlTWFwID8gZmFsc2UgOiB1bmRlZmluZWQsXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgaWYgKHZlcmJvc2UpIHtcbiAgICBleHRyYVBsdWdpbnMucHVzaChuZXcgV2F0Y2hGaWxlc0xvZ3NQbHVnaW4oKSk7XG4gIH1cblxuICBpZiAoYnVpbGRPcHRpb25zLnN0YXRzSnNvbikge1xuICAgIGV4dHJhUGx1Z2lucy5wdXNoKFxuICAgICAgbmV3IEpzb25TdGF0c1BsdWdpbihwYXRoLnJlc29sdmUocm9vdCwgYnVpbGRPcHRpb25zLm91dHB1dFBhdGgsICdzdGF0cy5qc29uJykpLFxuICAgICk7XG4gIH1cblxuICBpZiAoc3VicmVzb3VyY2VJbnRlZ3JpdHkpIHtcbiAgICBleHRyYVBsdWdpbnMucHVzaChcbiAgICAgIG5ldyBTdWJyZXNvdXJjZUludGVncml0eVBsdWdpbih7XG4gICAgICAgIGhhc2hGdW5jTmFtZXM6IFsnc2hhMzg0J10sXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgaWYgKHNjcmlwdHNTb3VyY2VNYXAgfHwgc3R5bGVzU291cmNlTWFwKSB7XG4gICAgZXh0cmFSdWxlcy5wdXNoKHtcbiAgICAgIHRlc3Q6IC9cXC5bY21dP2pzeD8kLyxcbiAgICAgIGVuZm9yY2U6ICdwcmUnLFxuICAgICAgbG9hZGVyOiByZXF1aXJlLnJlc29sdmUoJ3NvdXJjZS1tYXAtbG9hZGVyJyksXG4gICAgICBvcHRpb25zOiB7XG4gICAgICAgIGZpbHRlclNvdXJjZU1hcHBpbmdVcmw6IChfbWFwVXJpOiBzdHJpbmcsIHJlc291cmNlUGF0aDogc3RyaW5nKSA9PiB7XG4gICAgICAgICAgaWYgKHZlbmRvclNvdXJjZU1hcCkge1xuICAgICAgICAgICAgLy8gQ29uc3VtZSBhbGwgc291cmNlbWFwcyB3aGVuIHZlbmRvciBvcHRpb24gaXMgZW5hYmxlZC5cbiAgICAgICAgICAgIHJldHVybiB0cnVlO1xuICAgICAgICAgIH1cblxuICAgICAgICAgIC8vIERvbid0IGNvbnN1bWUgc291cmNlbWFwcyBpbiBub2RlX21vZHVsZXMgd2hlbiB2ZW5kb3IgaXMgZGlzYWJsZWQuXG4gICAgICAgICAgLy8gQnV0LCBkbyBjb25zdW1lIGxvY2FsIGxpYnJhcmllcyBzb3VyY2VtYXBzLlxuICAgICAgICAgIHJldHVybiAhcmVzb3VyY2VQYXRoLmluY2x1ZGVzKCdub2RlX21vZHVsZXMnKTtcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgfSk7XG4gIH1cblxuICBpZiAobWFpbiB8fCBwb2x5ZmlsbHMpIHtcbiAgICBleHRyYVJ1bGVzLnB1c2goe1xuICAgICAgdGVzdDogdHNDb25maWcub3B0aW9ucy5hbGxvd0pzID8gL1xcLltjbV0/W3RqXXN4PyQvIDogL1xcLltjbV0/dHN4PyQvLFxuICAgICAgbG9hZGVyOiBBbmd1bGFyV2VicGFja0xvYWRlclBhdGgsXG4gICAgICAvLyBUaGUgYmVsb3cgYXJlIGtub3duIHBhdGhzIHRoYXQgYXJlIG5vdCBwYXJ0IG9mIHRoZSBUeXBlU2NyaXB0IGNvbXBpbGF0aW9uIGV2ZW4gd2hlbiBhbGxvd0pzIGlzIGVuYWJsZWQuXG4gICAgICBleGNsdWRlOiBbXG4gICAgICAgIC9bXFxcXC9dbm9kZV9tb2R1bGVzWy9cXFxcXSg/OmNzcy1sb2FkZXJ8bWluaS1jc3MtZXh0cmFjdC1wbHVnaW58d2VicGFjay1kZXYtc2VydmVyfHdlYnBhY2spWy9cXFxcXS8sXG4gICAgICBdLFxuICAgIH0pO1xuICAgIGV4dHJhUGx1Z2lucy5wdXNoKGNyZWF0ZUl2eVBsdWdpbih3Y28sIGFvdCwgdHNDb25maWdQYXRoKSk7XG4gIH1cblxuICBpZiAod2ViV29ya2VyVHNDb25maWcpIHtcbiAgICBleHRyYVBsdWdpbnMucHVzaChjcmVhdGVJdnlQbHVnaW4od2NvLCBmYWxzZSwgcGF0aC5yZXNvbHZlKHdjby5yb290LCB3ZWJXb3JrZXJUc0NvbmZpZykpKTtcbiAgfVxuXG4gIGNvbnN0IGV4dHJhTWluaW1pemVycyA9IFtdO1xuICBpZiAoc2NyaXB0c09wdGltaXphdGlvbikge1xuICAgIGV4dHJhTWluaW1pemVycy5wdXNoKFxuICAgICAgbmV3IEphdmFTY3JpcHRPcHRpbWl6ZXJQbHVnaW4oe1xuICAgICAgICBkZWZpbmU6IGJ1aWxkT3B0aW9ucy5hb3QgPyBHTE9CQUxfREVGU19GT1JfVEVSU0VSX1dJVEhfQU9UIDogR0xPQkFMX0RFRlNfRk9SX1RFUlNFUixcbiAgICAgICAgc291cmNlbWFwOiBzY3JpcHRzU291cmNlTWFwLFxuICAgICAgICBzdXBwb3J0ZWRCcm93c2VyczogYnVpbGRPcHRpb25zLnN1cHBvcnRlZEJyb3dzZXJzLFxuICAgICAgICBrZWVwSWRlbnRpZmllck5hbWVzOiAhYWxsb3dNYW5nbGUgfHwgaXNQbGF0Zm9ybVNlcnZlcixcbiAgICAgICAgcmVtb3ZlTGljZW5zZXM6IGJ1aWxkT3B0aW9ucy5leHRyYWN0TGljZW5zZXMsXG4gICAgICAgIGFkdmFuY2VkOiBidWlsZE9wdGlvbnMuYnVpbGRPcHRpbWl6ZXIsXG4gICAgICB9KSxcbiAgICApO1xuICB9XG5cbiAgaWYgKHBsYXRmb3JtID09PSAnYnJvd3NlcicgJiYgKHNjcmlwdHNPcHRpbWl6YXRpb24gfHwgc3R5bGVzT3B0aW1pemF0aW9uLm1pbmlmeSkpIHtcbiAgICBleHRyYU1pbmltaXplcnMucHVzaChuZXcgVHJhbnNmZXJTaXplUGx1Z2luKCkpO1xuICB9XG5cbiAgbGV0IGNyb3NzT3JpZ2luTG9hZGluZzogTm9uTnVsbGFibGU8Q29uZmlndXJhdGlvblsnb3V0cHV0J10+Wydjcm9zc09yaWdpbkxvYWRpbmcnXSA9IGZhbHNlO1xuICBpZiAoc3VicmVzb3VyY2VJbnRlZ3JpdHkgJiYgY3Jvc3NPcmlnaW4gPT09ICdub25lJykge1xuICAgIGNyb3NzT3JpZ2luTG9hZGluZyA9ICdhbm9ueW1vdXMnO1xuICB9IGVsc2UgaWYgKGNyb3NzT3JpZ2luICE9PSAnbm9uZScpIHtcbiAgICBjcm9zc09yaWdpbkxvYWRpbmcgPSBjcm9zc09yaWdpbjtcbiAgfVxuXG4gIHJldHVybiB7XG4gICAgbW9kZTogc2NyaXB0c09wdGltaXphdGlvbiB8fCBzdHlsZXNPcHRpbWl6YXRpb24ubWluaWZ5ID8gJ3Byb2R1Y3Rpb24nIDogJ2RldmVsb3BtZW50JyxcbiAgICBkZXZ0b29sOiBmYWxzZSxcbiAgICB0YXJnZXQ6IFtpc1BsYXRmb3JtU2VydmVyID8gJ25vZGUnIDogJ3dlYicsICdlczIwMTUnXSxcbiAgICBwcm9maWxlOiBidWlsZE9wdGlvbnMuc3RhdHNKc29uLFxuICAgIHJlc29sdmU6IHtcbiAgICAgIHJvb3RzOiBbcHJvamVjdFJvb3RdLFxuICAgICAgZXh0ZW5zaW9uczogWycudHMnLCAnLnRzeCcsICcubWpzJywgJy5qcyddLFxuICAgICAgc3ltbGlua3M6ICFidWlsZE9wdGlvbnMucHJlc2VydmVTeW1saW5rcyxcbiAgICAgIG1vZHVsZXM6IFt0c0NvbmZpZy5vcHRpb25zLmJhc2VVcmwgfHwgcHJvamVjdFJvb3QsICdub2RlX21vZHVsZXMnXSxcbiAgICAgIG1haW5GaWVsZHM6IGlzUGxhdGZvcm1TZXJ2ZXJcbiAgICAgICAgPyBbJ2VzMjAyMCcsICdlczIwMTUnLCAnbW9kdWxlJywgJ21haW4nXVxuICAgICAgICA6IFsnZXMyMDIwJywgJ2VzMjAxNScsICdicm93c2VyJywgJ21vZHVsZScsICdtYWluJ10sXG4gICAgICBjb25kaXRpb25OYW1lczogWydlczIwMjAnLCAnZXMyMDE1JywgJy4uLiddLFxuICAgIH0sXG4gICAgcmVzb2x2ZUxvYWRlcjoge1xuICAgICAgc3ltbGlua3M6ICFidWlsZE9wdGlvbnMucHJlc2VydmVTeW1saW5rcyxcbiAgICB9LFxuICAgIGNvbnRleHQ6IHJvb3QsXG4gICAgZW50cnk6IGVudHJ5UG9pbnRzLFxuICAgIGV4dGVybmFsczogZXh0ZXJuYWxEZXBlbmRlbmNpZXMsXG4gICAgb3V0cHV0OiB7XG4gICAgICB1bmlxdWVOYW1lOiBwcm9qZWN0TmFtZSxcbiAgICAgI