@angular-devkit/build-angular
Version:
Angular Webpack Build Facade
420 lines • 57.3 kB
JavaScript
"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