UNPKG

dkershner6-projen-typescript

Version:

DKershner's preferred constructs for Projen TypeScript projects.

432 lines 54.1 kB
"use strict"; var __importDefault = (this && this.__importDefault) || function (mod) { return (mod && mod.__esModule) ? mod : { "default": mod }; }; Object.defineProperty(exports, "__esModule", { value: true }); exports.Node20TypeScriptProject = exports.JestTransformer = exports.DKTasks = exports.DKTaskName = exports.DKEslintConfig = exports.DKBugFixes = exports.RECOMMENDED_NODE_20_PROJECT_OPTIONS = exports.RECOMMENDED_PRETTIER_CONFIG = exports.RECOMMENDED_JEST_CONFIG = exports.RECOMMENDED_ESLINT_CONFIG = exports.RECOMMENDED_PNPM_8 = exports.RECOMMENDED_NODE_20 = exports.CONSTRUCTS_VERSION = exports.PROJEN_VERSION = exports.RECOMMENDED_TSCONFIG_NODE_20 = exports.RECOMMENDED_TSCONFIG_COMPILER_OPTIONS = exports.PROJEN_COMPILER_OPTION_DEFAULTS = exports.DEV_FILE_PATTERNS = exports.TEST_FOLDERS = exports.TEST_FILE_SUFFIXES = exports.PUBLISH_FILE_PATTERNS = void 0; const clone_deep_1 = __importDefault(require("clone-deep")); const projen_1 = require("projen"); const awscdk_1 = require("projen/lib/awscdk"); const typescript_1 = require("projen/lib/typescript"); const util_1 = require("projen/lib/util"); exports.PUBLISH_FILE_PATTERNS = ["src/**/*.ts"]; exports.TEST_FILE_SUFFIXES = ["test", "spec"]; exports.TEST_FOLDERS = ["__tests__", "__mocks__"]; exports.DEV_FILE_PATTERNS = [ ...exports.TEST_FOLDERS.map((folder) => `src/**/${folder}/**/*`), ...exports.TEST_FILE_SUFFIXES.map((suffix) => `src/**/*.${suffix}.ts`), ]; exports.PROJEN_COMPILER_OPTION_DEFAULTS = { alwaysStrict: true, declaration: true, esModuleInterop: true, experimentalDecorators: true, inlineSourceMap: true, inlineSources: true, lib: ["es2019"], module: "CommonJS", noEmitOnError: false, noFallthroughCasesInSwitch: true, noImplicitAny: true, noImplicitReturns: true, noImplicitThis: true, noUnusedLocals: true, noUnusedParameters: true, resolveJsonModule: true, strict: true, strictNullChecks: true, strictPropertyInitialization: true, stripInternal: true, target: "ES2019", }; exports.RECOMMENDED_TSCONFIG_COMPILER_OPTIONS = { lib: ["es2023"], target: "es2022", // Let lint handle these noUnusedLocals: false, noUnusedParameters: false, // We don't want to be responsible for external libs errors, change this if TS ever allows checking OUR declaration files but not node_modules skipLibCheck: true, // Opinions noImplicitOverride: true, forceConsistentCasingInFileNames: true, esModuleInterop: true, declaration: true, // Just to state it is different than tsconfigDev types: ["jest", "node"], }; exports.RECOMMENDED_TSCONFIG_NODE_20 = { tsconfig: { fileName: "tsconfig.publish.json", compilerOptions: { ...exports.RECOMMENDED_TSCONFIG_COMPILER_OPTIONS, }, }, tsconfigDev: { fileName: "tsconfig.json", // Shim for VSCode, dev file must be named this compilerOptions: { declaration: false, // This helps with certain type inference issues that more often come up in test and other non-published code }, include: exports.DEV_FILE_PATTERNS, }, }; exports.PROJEN_VERSION = "0.88.0"; exports.CONSTRUCTS_VERSION = "10.3.0"; exports.RECOMMENDED_NODE_20 = { projenVersion: exports.PROJEN_VERSION, minNodeVersion: "20.10.0", maxNodeVersion: "20.10.0", workflowNodeVersion: "20.10.0", projenrcTs: true, sampleCode: false, autoMerge: false, }; exports.RECOMMENDED_PNPM_8 = { packageManager: projen_1.javascript.NodePackageManager.PNPM, pnpmVersion: "8", }; exports.RECOMMENDED_ESLINT_CONFIG = { eslint: true, }; exports.RECOMMENDED_JEST_CONFIG = { jest: true, jestOptions: { jestConfig: { testEnvironment: "node", testTimeout: 15000, }, }, tsJestOptions: { transformOptions: { isolatedModules: true, }, }, }; exports.RECOMMENDED_PRETTIER_CONFIG = { prettier: true, prettierOptions: { settings: { tabWidth: 4, }, }, }; exports.RECOMMENDED_NODE_20_PROJECT_OPTIONS = (0, util_1.deepMerge)([ (0, clone_deep_1.default)(exports.RECOMMENDED_TSCONFIG_NODE_20), exports.RECOMMENDED_PNPM_8, exports.RECOMMENDED_NODE_20, exports.RECOMMENDED_ESLINT_CONFIG, exports.RECOMMENDED_JEST_CONFIG, exports.RECOMMENDED_PRETTIER_CONFIG, ]); class DKBugFixes extends projen_1.Component { constructor(project) { super(project); project.addDevDeps(`constructs@${exports.CONSTRUCTS_VERSION}`); // Why not? Always true. project.package.addField("sideEffects", false); // DevDeps (doesn't work in config) project.addDevDeps("@types/clone-deep", "clone-deep"); project.addGitIgnore(".DS_Store"); project.addPackageIgnore(".DS_Store"); project.addPackageIgnore("/project.json"); project.addPackageIgnore("/docs/"); project.addPackageIgnore("**/*.md"); project.addPackageIgnore("/.jest/"); project.addPackageIgnore("/CONTRIBUTING.md"); project.addPackageIgnore("/README.md"); project.addPackageIgnore("/LICENSE"); if (project.docgen) { project.gitattributes.addAttributes(`/${project.docsDirectory}${project.docsDirectory.endsWith("/") ? "" : "/"}**`, "linguist-generated"); } // TypeScript if (!(project instanceof awscdk_1.AwsCdkConstructLibrary)) { for (const suffix of exports.TEST_FILE_SUFFIXES) { project.tsconfig?.addExclude(`${project.srcdir}/**/*.${suffix}.ts`); } for (const folder of exports.TEST_FOLDERS) { project.tsconfig?.addExclude(`**/${folder}/**/*`); } } } } exports.DKBugFixes = DKBugFixes; class DKEslintConfig extends projen_1.Component { constructor(project) { super(project); project.addDevDeps("eslint-plugin-jest", "eslint-plugin-sonarjs"); project.eslint?.addPlugins("jest", "sonarjs"); project.eslint?.addExtends("eslint:recommended", "plugin:@typescript-eslint/eslint-recommended", "plugin:@typescript-eslint/recommended", "plugin:jest/recommended", "plugin:sonarjs/recommended"); project.eslint?.addRules({ "no-console": [ "error", { allow: ["debug", "info", "warn", "error"] }, ], "no-trailing-spaces": "off", // Conflicts with Prettier "no-multiple-empty-lines": "off", // Conflicts with Prettier "import/no-unresolved": "off", // Handled by TS and it gets confused on @types packages. "import/namespace": "off", "no-duplicate-imports": "off", // Handled by import/no-duplicates "import/no-duplicates": "error", "import/no-named-as-default": "error", "import/no-named-as-default-member": "error", "import/order": [ "error", { groups: [ "builtin", "external", "parent", "sibling", "index", ], "newlines-between": "always", pathGroups: [ { pattern: "react", group: "external", position: "before", }, ], pathGroupsExcludedImportTypes: ["react"], alphabetize: { order: "asc", caseInsensitive: true, }, }, ], "sonarjs/no-redundant-jump": "off", "sonarjs/no-small-switch": "warn", "@typescript-eslint/explicit-function-return-type": [ "error", { allowExpressions: true, allowTypedFunctionExpressions: true, allowHigherOrderFunctions: true, allowDirectConstAssertionInArrowFunctions: true, allowConciseArrowFunctionExpressionsStartingWithVoid: true, }, ], "@typescript-eslint/return-await": ["error", "always"], "@typescript-eslint/no-unused-vars": [ "error", { ignoreRestSiblings: true, }, ], }); project.eslint?.addOverride({ files: ["*.ts", "*.tsx"], excludedFiles: [ // Next.js forced default exports "**/app/**", "**/app/**", "**/pages/**", "**/pages/**", // Storybook Stories have a forced default export "**/.storybook/**", "*.stories.ts", "*.stories.tsx", ], rules: { "import/no-default-export": "warn", // Causes issues when using babel and tsc separately }, }); project.eslint?.addOverride({ files: ["*.js", "*.jsx"], rules: { "import/no-unresolved": "error", "@typescript-eslint/explicit-function-return-type": "off", "@typescript-eslint/explicit-module-boundary-types": "off", "@typescript-eslint/no-var-requires": "off", }, }); for (const pattern of exports.DEV_FILE_PATTERNS) { project.eslint?.allowDevDeps(pattern); } } } exports.DKEslintConfig = DKEslintConfig; var DKTaskName; (function (DKTaskName) { DKTaskName["CLEAN_COMPILE"] = "clean-compile"; DKTaskName["CI"] = "ci"; DKTaskName["DOCGEN_REMOVE"] = "docgen:remove"; DKTaskName["I"] = "i"; DKTaskName["LINT"] = "lint"; DKTaskName["TEST_UNIT"] = "test-unit"; DKTaskName["TYPE_CHECK"] = "type-check"; DKTaskName["UPGRADE_PACKAGE"] = "upgrade:package"; })(DKTaskName || (exports.DKTaskName = DKTaskName = {})); class DKTasks extends projen_1.Component { static IS_NOT_RELEASE_CONDITION = `if [ "$RELEASE" = "true" ] ; then exit 1 ; fi`; constructor(project) { super(project); // Install project.addTask(DKTaskName.CI).spawn(project.package.installCiTask); project.addTask(DKTaskName.I).spawn(project.package.installTask); const typeCheckTask = project.tasks.addTask(DKTaskName.TYPE_CHECK); typeCheckTask.exec("tsc --noEmit"); // Eslint const lintTask = project.eslint?.eslintTask; if (lintTask) { lintTask.addCondition(DKTasks.IS_NOT_RELEASE_CONDITION); project .addTask(DKTaskName.LINT, { condition: DKTasks.IS_NOT_RELEASE_CONDITION, description: "Alternate lint command", receiveArgs: true, }) .spawn(lintTask); const originalTestTaskStep = project.testTask.steps[0]; const { exec, ...restOfTestTaskStep } = originalTestTaskStep; const unitTestTask = project.addTask(DKTaskName.TEST_UNIT, { condition: DKTasks.IS_NOT_RELEASE_CONDITION, receiveArgs: true, }); unitTestTask.exec(exec, { ...restOfTestTaskStep }); project.testTask.reset(); project.testTask.spawn(lintTask); project.testTask.spawn(typeCheckTask); project.testTask.spawn(unitTestTask); } // Compile const cleanCompileTask = project.tasks.tryFind(DKTaskName.CLEAN_COMPILE) ?? project.tasks.addTask(DKTaskName.CLEAN_COMPILE, { description: "Clean up the compiled output", }); cleanCompileTask.exec(`rm -rf ${project.libdir} && rm -rf ${project.artifactsDirectory}`); // Docgen const docgenRemoveTask = project.addTask(DKTaskName.DOCGEN_REMOVE, { description: "Remove the docgen directory", }); docgenRemoveTask.exec(`rm -rf ${project.docsDirectory}`); const docgenTask = project.tasks.tryFind("docgen"); if (docgenTask) { docgenTask.addCondition(DKTasks.IS_NOT_RELEASE_CONDITION); docgenTask.prependSpawn(docgenRemoveTask); } // Upgrade Package project.addTask(DKTaskName.UPGRADE_PACKAGE, { description: "Upgrade a single package (or otherwise use NPM Check Updates). This should be used as 'npx projen upgrade:package -- <package-name>'", exec: "pnpm dlx npm-check-updates@16 --upgrade", receiveArgs: true, }); } preSynthesize() { super.preSynthesize(); } } exports.DKTasks = DKTasks; class JestTransformer extends projen_1.Component { static ESM_MODULES_TO_TRANSFORM = [ "@babel/runtime", "@mui.*", "@panva/hkdf", "@sindresorhus/is", "@szmarczak/http-timer", "bail", "cacheable-lookup", "cacheable-request", "ccount", "character-entities.*", "comma-separated-tokens", "decode-named-character-reference", "devlop", "direction", "dom7", "escape-string-regexp", "file-type", "form-data-encoder", "github-slugger", "got", "hast.*", "html-void-elements", "is-plain-obj", "jose", "longest-streak", "lowercase-keys", "markdown.*", "mdast.*", "micromark.*", "mimic-response", "normalize-url", "p-cancelable", "peek-readable", "property-information", "rehype.*", "remark.*", "responselike", "separated-tokens", "space-separated-tokens", "ssr-window", "stringify-entities", "strip-markdown", "strtok3", "swiper", "swiper/react", "token-types", "trim-lines", "trough", "unified", "unist.*", "util-gfm.*", "uuid", "vfile.*", "web-namespaces", "zwitch", ]; _modulesToTransform = new Set(); constructor(project, options) { super(project); if (options?.modulesToTransform) { this.addModulesToTransform(...options.modulesToTransform); } if (project.jest) { project.addDevDeps("jest-mock"); project.jest.config.transformIgnorePatterns = this.buildTransformIgnorePatterns([ ...(project.jest.config.transformIgnorePatterns ?? new Array()).filter((pattern) => !pattern.includes("node_modules")), ...JestTransformer.ESM_MODULES_TO_TRANSFORM, ...Array.from(this._modulesToTransform), ]); } } get modulesToTransform() { return this._modulesToTransform; } addModulesToTransform(...modules) { for (const module of modules) { this._modulesToTransform.add(module); } } removeModulesToTransform(...modules) { for (const module of modules) { this._modulesToTransform.delete(module); } } buildTransformIgnorePatterns(nodeModulesToTransform) { const modulesRegex = [ ...new Set([...(nodeModulesToTransform ?? [])]), ].join("|"); return [ `/node_modules/(?!.pnpm)(?!(${modulesRegex})/)`, `/node_modules/.pnpm/(?!(${modulesRegex.replace(/\//g, "\\+")})@)`, // default is just `node_modules` "\\.pnp\\.[^\\/]+$", // default ]; } } exports.JestTransformer = JestTransformer; class Node20TypeScriptProject extends typescript_1.TypeScriptProject { jestTransformer; constructor(options) { super((0, util_1.deepMerge)([ (0, clone_deep_1.default)(exports.RECOMMENDED_NODE_20_PROJECT_OPTIONS), options, ])); new DKBugFixes(this); new DKEslintConfig(this); new DKTasks(this); this.jestTransformer = new JestTransformer(this, options.jestOptions); } } exports.Node20TypeScriptProject = Node20TypeScriptProject; //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiaW5kZXguanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi9zcmMvaW5kZXgudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6Ijs7Ozs7O0FBQUEsNERBQW1DO0FBQ25DLG1DQUErRDtBQUMvRCw4Q0FBMkQ7QUFNM0Qsc0RBRytCO0FBQy9CLDBDQUE0QztBQUUvQixRQUFBLHFCQUFxQixHQUFhLENBQUMsYUFBYSxDQUFDLENBQUM7QUFFbEQsUUFBQSxrQkFBa0IsR0FBRyxDQUFDLE1BQU0sRUFBRSxNQUFNLENBQUMsQ0FBQztBQUN0QyxRQUFBLFlBQVksR0FBRyxDQUFDLFdBQVcsRUFBRSxXQUFXLENBQUMsQ0FBQztBQUUxQyxRQUFBLGlCQUFpQixHQUFHO0lBQzdCLEdBQUcsb0JBQVksQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLFVBQVUsTUFBTSxPQUFPLENBQUM7SUFDeEQsR0FBRywwQkFBa0IsQ0FBQyxHQUFHLENBQUMsQ0FBQyxNQUFNLEVBQUUsRUFBRSxDQUFDLFlBQVksTUFBTSxLQUFLLENBQUM7Q0FDakUsQ0FBQztBQUVXLFFBQUEsK0JBQStCLEdBQThCO0lBQ3RFLFlBQVksRUFBRSxJQUFJO0lBQ2xCLFdBQVcsRUFBRSxJQUFJO0lBQ2pCLGVBQWUsRUFBRSxJQUFJO0lBQ3JCLHNCQUFzQixFQUFFLElBQUk7SUFDNUIsZUFBZSxFQUFFLElBQUk7SUFDckIsYUFBYSxFQUFFLElBQUk7SUFDbkIsR0FBRyxFQUFFLENBQUMsUUFBUSxDQUFDO0lBQ2YsTUFBTSxFQUFFLFVBQVU7SUFDbEIsYUFBYSxFQUFFLEtBQUs7SUFDcEIsMEJBQTBCLEVBQUUsSUFBSTtJQUNoQyxhQUFhLEVBQUUsSUFBSTtJQUNuQixpQkFBaUIsRUFBRSxJQUFJO0lBQ3ZCLGNBQWMsRUFBRSxJQUFJO0lBQ3BCLGNBQWMsRUFBRSxJQUFJO0lBQ3BCLGtCQUFrQixFQUFFLElBQUk7SUFDeEIsaUJBQWlCLEVBQUUsSUFBSTtJQUN2QixNQUFNLEVBQUUs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bEMsQ0FBQztJQUNOLENBQUM7O0FBbkhMLDBDQW9IQztBQU9ELE1BQWEsdUJBQXdCLFNBQVEsOEJBQWlCO0lBQzFDLGVBQWUsQ0FBa0I7SUFFakQsWUFBWSxPQUF1QztRQUMvQyxLQUFLLENBQ0QsSUFBQSxnQkFBUyxFQUFDO1lBQ04sSUFBQSxvQkFBUyxFQUFDLDJDQUFtQyxDQUFDO1lBQzlDLE9BQU87U0FDVixDQUE2QixDQUNqQyxDQUFDO1FBRUYsSUFBSSxVQUFVLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDckIsSUFBSSxjQUFjLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDekIsSUFBSSxPQUFPLENBQUMsSUFBSSxDQUFDLENBQUM7UUFDbEIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLGVBQWUsQ0FBQyxJQUFJLEVBQUUsT0FBTyxDQUFDLFdBQVcsQ0FBQyxDQUFDO0lBQzFFLENBQUM7Q0FDSjtBQWhCRCwwREFnQkMiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgZGVlcENsb25lIGZyb20gXCJjbG9uZS1kZWVwXCI7XG5pbXBvcnQgeyBDb21wb25lbnQsIGphdmFzY3JpcHQsIFByb2plY3RPcHRpb25zIH0gZnJvbSBcInByb2plblwiO1xuaW1wb3J0IHsgQXdzQ2RrQ29uc3RydWN0TGlicmFyeSB9IGZyb20gXCJwcm9qZW4vbGliL2F3c2Nka1wiO1xuaW1wb3J0IHtcbiAgICBUeXBlU2NyaXB0Q29tcGlsZXJPcHRpb25zLFxuICAgIE5vZGVQcm9qZWN0T3B0aW9ucyxcbiAgICBKZXN0T3B0aW9ucyxcbn0gZnJvbSBcInByb2plbi9saWIvamF2YXNjcmlwdFwiO1xuaW1wb3J0IHtcbiAgICBUeXBlU2NyaXB0UHJvamVjdE9wdGlvbnMsXG4gICAgVHlwZVNjcmlwdFByb2plY3QsXG59IGZyb20gXCJwcm9qZW4vbGliL3R5cGVzY3JpcHRcIjtcbmltcG9ydCB7IGRlZXBNZXJnZSB9IGZyb20gXCJwcm9qZW4vbGliL3V0aWxcIjtcblxuZXhwb3J0IGNvbnN0IFBVQkxJU0hfRklMRV9QQVRURVJOUzogc3RyaW5nW10gPSBbXCJzcmMvKiovKi50c1wiXTtcblxuZXhwb3J0IGNvbnN0IFRFU1RfRklMRV9TVUZGSVhFUyA9IFtcInRlc3RcIiwgXCJzcGVjXCJdO1xuZXhwb3J0IGNvbnN0IFRFU1RfRk9MREVSUyA9IFtcIl9fdGVzdHNfX1wiLCBcIl9fbW9ja3NfX1wiXTtcblxuZXhwb3J0IGNvbnN0IERFVl9GSUxFX1BBVFRFUk5TID0gW1xuICAgIC4uLlRFU1RfRk9MREVSUy5tYXAoKGZvbGRlcikgPT4gYHNyYy8qKi8ke2ZvbGRlcn0vKiovKmApLFxuICAgIC4uLlRFU1RfRklMRV9TVUZGSVhFUy5tYXAoKHN1ZmZpeCkgPT4gYHNyYy8qKi8qLiR7c3VmZml4fS50c2ApLFxuXTtcblxuZXhwb3J0IGNvbnN0IFBST0pFTl9DT01QSUxFUl9PUFRJT05fREVGQVVMVFM6IFR5cGVTY3JpcHRDb21waWxlck9wdGlvbnMgPSB7XG4gICAgYWx3YXlzU3RyaWN0OiB0cnVlLFxuICAgIGRlY2xhcmF0aW9uOiB0cnVlLFxuICAgIGVzTW9kdWxlSW50ZXJvcDogdHJ1ZSxcbiAgICBleHBlcmltZW50YWxEZWNvcmF0b3JzOiB0cnVlLFxuICAgIGlubGluZVNvdXJjZU1hcDogdHJ1ZSxcbiAgICBpbmxpbmVTb3VyY2VzOiB0cnVlLFxuICAgIGxpYjogW1wiZXMyMDE5XCJdLFxuICAgIG1vZHVsZTogXCJDb21tb25KU1wiLFxuICAgIG5vRW1pdE9uRXJyb3I6IGZhbHNlLFxuICAgIG5vRmFsbHRocm91Z2hDYXNlc0luU3dpdGNoOiB0cnVlLFxuICAgIG5vSW1wbGljaXRBbnk6IHRydWUsXG4gICAgbm9JbXBsaWNpdFJldHVybnM6IHRydWUsXG4gICAgbm9JbXBsaWNpdFRoaXM6IHRydWUsXG4gICAgbm9VbnVzZWRMb2NhbHM6IHRydWUsXG4gICAgbm9VbnVzZWRQYXJhbWV0ZXJzOiB0cnVlLFxuICAgIHJlc29sdmVKc29uTW9kdWxlOiB0cnVlLFxuICAgIHN0cmljdDogdHJ1ZSxcbiAgICBzdHJpY3ROdWxsQ2hlY2tzOiB0cnVlLFxuICAgIHN0cmljdFByb3BlcnR5SW5pdGlhbGl6YXRpb246IHRydWUsXG4gICAgc3RyaXBJbnRlcm5hbDogdHJ1ZSxcbiAgICB0YXJnZXQ6IFwiRVMyMDE5XCIsXG59O1xuXG5leHBvcnQgY29uc3QgUkVDT01NRU5ERURfVFNDT05GSUdfQ09NUElMRVJfT1BUSU9OUzogVHlwZVNjcmlwdENvbXBpbGVyT3B0aW9ucyA9XG4gICAge1xuICAgICAgICBsaWI6IFtcImVzMjAyM1wiXSxcbiAgICAgICAgdGFyZ2V0OiBcImVzMjAyMlwiLFxuICAgICAgICAvLyBMZXQgbGludCBoYW5kbGUgdGhlc2VcbiAgICAgICAgbm9VbnVzZWRMb2NhbHM6IGZhbHNlLFxuICAgICAgICBub1VudXNlZFBhcmFtZXRlcnM6IGZhbHNlLFxuICAgICAgICAvLyBXZSBkb24ndCB3YW50IHRvIGJlIHJlc3BvbnNpYmxlIGZvciBleHRlcm5hbCBsaWJzIGVycm9ycywgY2hhbmdlIHRoaXMgaWYgVFMgZXZlciBhbGxvd3MgY2hlY2tpbmcgT1VSIGRlY2xhcmF0aW9uIGZpbGVzIGJ1dCBub3Qgbm9kZV9tb2R1bGVzXG4gICAgICAgIHNraXBMaWJDaGVjazogdHJ1ZSxcbiAgICAgICAgLy8gT3BpbmlvbnNcbiAgICAgICAgbm9JbXBsaWNpdE92ZXJyaWRlOiB0cnVlLFxuICAgICAgICBmb3JjZUNvbnNpc3RlbnRDYXNpbmdJbkZpbGVOYW1lczogdHJ1ZSxcbiAgICAgICAgZXNNb2R1bGVJbnRlcm9wOiB0cnVlLFxuXG4gICAgICAgIGRlY2xhcmF0aW9uOiB0cnVlLCAvLyBKdXN0IHRvIHN0YXRlIGl0IGlzIGRpZmZlcmVudCB0aGFuIHRzY29uZmlnRGV2XG5cbiAgICAgICAgdHlwZXM6IFtcImplc3RcIiwgXCJub2RlXCJdLFxuICAgIH07XG5cbmV4cG9ydCBjb25zdCBSRUNPTU1FTkRFRF9UU0NPTkZJR19OT0RFXzIwOiBQYXJ0aWFsPFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9ucz4gPSB7XG4gICAgdHNjb25maWc6IHtcbiAgICAgICAgZmlsZU5hbWU6IFwidHNjb25maWcucHVibGlzaC5qc29uXCIsXG4gICAgICAgIGNvbXBpbGVyT3B0aW9uczoge1xuICAgICAgICAgICAgLi4uUkVDT01NRU5ERURfVFNDT05GSUdfQ09NUElMRVJfT1BUSU9OUyxcbiAgICAgICAgfSxcbiAgICB9LFxuICAgIHRzY29uZmlnRGV2OiB7XG4gICAgICAgIGZpbGVOYW1lOiBcInRzY29uZmlnLmpzb25cIiwgLy8gU2hpbSBmb3IgVlNDb2RlLCBkZXYgZmlsZSBtdXN0IGJlIG5hbWVkIHRoaXNcbiAgICAgICAgY29tcGlsZXJPcHRpb25zOiB7XG4gICAgICAgICAgICBkZWNsYXJhdGlvbjogZmFsc2UsIC8vIFRoaXMgaGVscHMgd2l0aCBjZXJ0YWluIHR5cGUgaW5mZXJlbmNlIGlzc3VlcyB0aGF0IG1vcmUgb2Z0ZW4gY29tZSB1cCBpbiB0ZXN0IGFuZCBvdGhlciBub24tcHVibGlzaGVkIGNvZGVcbiAgICAgICAgfSxcbiAgICAgICAgaW5jbHVkZTogREVWX0ZJTEVfUEFUVEVSTlMsXG4gICAgfSxcbn07XG5cbmV4cG9ydCBjb25zdCBQUk9KRU5fVkVSU0lPTiA9IFwiMC44OC4wXCI7XG5leHBvcnQgY29uc3QgQ09OU1RSVUNUU19WRVJTSU9OID0gXCIxMC4zLjBcIjtcblxuZXhwb3J0IGNvbnN0IFJFQ09NTUVOREVEX05PREVfMjA6IFBhcnRpYWw8VHlwZVNjcmlwdFByb2plY3RPcHRpb25zPiA9IHtcbiAgICBwcm9qZW5WZXJzaW9uOiBQUk9KRU5fVkVSU0lPTixcbiAgICBtaW5Ob2RlVmVyc2lvbjogXCIyMC4xMC4wXCIsXG4gICAgbWF4Tm9kZVZlcnNpb246IFwiMjAuMTAuMFwiLFxuICAgIHdvcmtmbG93Tm9kZVZlcnNpb246IFwiMjAuMTAuMFwiLFxuXG4gICAgcHJvamVucmNUczogdHJ1ZSxcbiAgICBzYW1wbGVDb2RlOiBmYWxzZSxcbiAgICBhdXRvTWVyZ2U6IGZhbHNlLFxufTtcblxuZXhwb3J0IGNvbnN0IFJFQ09NTUVOREVEX1BOUE1fODogUGFydGlhbDxUeXBlU2NyaXB0UHJvamVjdE9wdGlvbnM+ID0ge1xuICAgIHBhY2thZ2VNYW5hZ2VyOiBqYXZhc2NyaXB0Lk5vZGVQYWNrYWdlTWFuYWdlci5QTlBNLFxuICAgIHBucG1WZXJzaW9uOiBcIjhcIixcbn07XG5cbmV4cG9ydCBjb25zdCBSRUNPTU1FTkRFRF9FU0xJTlRfQ09ORklHOiBQYXJ0aWFsPFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9ucz4gPSB7XG4gICAgZXNsaW50OiB0cnVlLFxufTtcblxuZXhwb3J0IGNvbnN0IFJFQ09NTUVOREVEX0pFU1RfQ09ORklHOiBQYXJ0aWFsPFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9ucz4gPSB7XG4gICAgamVzdDogdHJ1ZSxcbiAgICBqZXN0T3B0aW9uczoge1xuICAgICAgICBqZXN0Q29uZmlnOiB7XG4gICAgICAgICAgICB0ZXN0RW52aXJvbm1lbnQ6IFwibm9kZVwiLFxuICAgICAgICAgICAgdGVzdFRpbWVvdXQ6IDE1MDAwLFxuICAgICAgICB9LFxuICAgIH0sXG4gICAgdHNKZXN0T3B0aW9uczoge1xuICAgICAgICB0cmFuc2Zvcm1PcHRpb25zOiB7XG4gICAgICAgICAgICBpc29sYXRlZE1vZHVsZXM6IHRydWUsXG4gICAgICAgIH0sXG4gICAgfSxcbn07XG5cbmV4cG9ydCBjb25zdCBSRUNPTU1FTkRFRF9QUkVUVElFUl9DT05GSUc6IFBhcnRpYWw8Tm9kZVByb2plY3RPcHRpb25zPiA9IHtcbiAgICBwcmV0dGllcjogdHJ1ZSxcbiAgICBwcmV0dGllck9wdGlvbnM6IHtcbiAgICAgICAgc2V0dGluZ3M6IHtcbiAgICAgICAgICAgIHRhYldpZHRoOiA0LFxuICAgICAgICB9LFxuICAgIH0sXG59O1xuZXhwb3J0IGNvbnN0IFJFQ09NTUVOREVEX05PREVfMjBfUFJPSkVDVF9PUFRJT05TOiBPbWl0PFxuICAgIFByb2plY3RPcHRpb25zICYgTm9kZVByb2plY3RPcHRpb25zICYgVHlwZVNjcmlwdFByb2plY3RPcHRpb25zLFxuICAgIFwiZGVmYXVsdFJlbGVhc2VCcmFuY2hcIiB8IFwibmFtZVwiXG4+ID0gZGVlcE1lcmdlKFtcbiAgICBkZWVwQ2xvbmUoUkVDT01NRU5ERURfVFNDT05GSUdfTk9ERV8yMCksXG4gICAgUkVDT01NRU5ERURfUE5QTV84LFxuICAgIFJFQ09NTUVOREVEX05PREVfMjAsXG4gICAgUkVDT01NRU5ERURfRVNMSU5UX0NPTkZJRyxcbiAgICBSRUNPTU1FTkRFRF9KRVNUX0NPTkZJRyxcbiAgICBSRUNPTU1FTkRFRF9QUkVUVElFUl9DT05GSUcsXG5dKTtcblxuZXhwb3J0IGNsYXNzIERLQnVnRml4ZXMgZXh0ZW5kcyBDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKHByb2plY3Q6IFR5cGVTY3JpcHRQcm9qZWN0KSB7XG4gICAgICAgIHN1cGVyKHByb2plY3QpO1xuXG4gICAgICAgIHByb2plY3QuYWRkRGV2RGVwcyhgY29uc3RydWN0c0Ake0NPTlNUUlVDVFNfVkVSU0lPTn1gKTtcblxuICAgICAgICAvLyBXaHkgbm90PyBBbHdheXMgdHJ1ZS5cbiAgICAgICAgcHJvamVjdC5wYWNrYWdlLmFkZEZpZWxkKFwic2lkZUVmZmVjdHNcIiwgZmFsc2UpO1xuXG4gICAgICAgIC8vIERldkRlcHMgKGRvZXNuJ3Qgd29yayBpbiBjb25maWcpXG4gICAgICAgIHByb2plY3QuYWRkRGV2RGVwcyhcIkB0eXBlcy9jbG9uZS1kZWVwXCIsIFwiY2xvbmUtZGVlcFwiKTtcblxuICAgICAgICBwcm9qZWN0LmFkZEdpdElnbm9yZShcIi5EU19TdG9yZVwiKTtcbiAgICAgICAgcHJvamVjdC5hZGRQYWNrYWdlSWdub3JlKFwiLkRTX1N0b3JlXCIpO1xuXG4gICAgICAgIHByb2plY3QuYWRkUGFja2FnZUlnbm9yZShcIi9wcm9qZWN0Lmpzb25cIik7XG4gICAgICAgIHByb2plY3QuYWRkUGFja2FnZUlnbm9yZShcIi9kb2NzL1wiKTtcbiAgICAgICAgcHJvamVjdC5hZGRQYWNrYWdlSWdub3JlKFwiKiovKi5tZFwiKTtcbiAgICAgICAgcHJvamVjdC5hZGRQYWNrYWdlSWdub3JlKFwiLy5qZXN0L1wiKTtcblxuICAgICAgICBwcm9qZWN0LmFkZFBhY2thZ2VJZ25vcmUoXCIvQ09OVFJJQlVUSU5HLm1kXCIpO1xuICAgICAgICBwcm9qZWN0LmFkZFBhY2thZ2VJZ25vcmUoXCIvUkVBRE1FLm1kXCIpO1xuICAgICAgICBwcm9qZWN0LmFkZFBhY2thZ2VJZ25vcmUoXCIvTElDRU5TRVwiKTtcblxuICAgICAgICBpZiAocHJvamVjdC5kb2NnZW4pIHtcbiAgICAgICAgICAgIHByb2plY3QuZ2l0YXR0cmlidXRlcy5hZGRBdHRyaWJ1dGVzKFxuICAgICAgICAgICAgICAgIGAvJHtwcm9qZWN0LmRvY3NEaXJlY3Rvcnl9JHtwcm9qZWN0LmRvY3NEaXJlY3RvcnkuZW5kc1dpdGgoXCIvXCIpID8gXCJcIiA6IFwiL1wifSoqYCxcbiAgICAgICAgICAgICAgICBcImxpbmd1aXN0LWdlbmVyYXRlZFwiLFxuICAgICAgICAgICAgKTtcbiAgICAgICAgfVxuXG4gICAgICAgIC8vIFR5cGVTY3JpcHRcbiAgICAgICAgaWYgKCEocHJvamVjdCBpbnN0YW5jZW9mIEF3c0Nka0NvbnN0cnVjdExpYnJhcnkpKSB7XG4gICAgICAgICAgICBmb3IgKGNvbnN0IHN1ZmZpeCBvZiBURVNUX0ZJTEVfU1VGRklYRVMpIHtcbiAgICAgICAgICAgICAgICBwcm9qZWN0LnRzY29uZmlnPy5hZGRFeGNsdWRlKFxuICAgICAgICAgICAgICAgICAgICBgJHtwcm9qZWN0LnNyY2Rpcn0vKiovKi4ke3N1ZmZpeH0udHNgLFxuICAgICAgICAgICAgICAgICk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgICBmb3IgKGNvbnN0IGZvbGRlciBvZiBURVNUX0ZPTERFUlMpIHtcbiAgICAgICAgICAgICAgICBwcm9qZWN0LnRzY29uZmlnPy5hZGRFeGNsdWRlKGAqKi8ke2ZvbGRlcn0vKiovKmApO1xuICAgICAgICAgICAgfVxuICAgICAgICB9XG4gICAgfVxufVxuXG5leHBvcnQgY2xhc3MgREtFc2xpbnRDb25maWcgZXh0ZW5kcyBDb21wb25lbnQge1xuICAgIGNvbnN0cnVjdG9yKHByb2plY3Q6IFR5cGVTY3JpcHRQcm9qZWN0KSB7XG4gICAgICAgIHN1cGVyKHByb2plY3QpO1xuXG4gICAgICAgIHByb2plY3QuYWRkRGV2RGVwcyhcImVzbGludC1wbHVnaW4tamVzdFwiLCBcImVzbGludC1wbHVnaW4tc29uYXJqc1wiKTtcbiAgICAgICAgcHJvamVjdC5lc2xpbnQ/LmFkZFBsdWdpbnMoXCJqZXN0XCIsIFwic29uYXJqc1wiKTtcbiAgICAgICAgcHJvamVjdC5lc2xpbnQ/LmFkZEV4dGVuZHMoXG4gICAgICAgICAgICBcImVzbGludDpyZWNvbW1lbmRlZFwiLFxuICAgICAgICAgICAgXCJwbHVnaW46QHR5cGVzY3JpcHQtZXNsaW50L2VzbGludC1yZWNvbW1lbmRlZFwiLFxuICAgICAgICAgICAgXCJwbHVnaW46QHR5cGVzY3JpcHQtZXNsaW50L3JlY29tbWVuZGVkXCIsXG4gICAgICAgICAgICBcInBsdWdpbjpqZXN0L3JlY29tbWVuZGVkXCIsXG4gICAgICAgICAgICBcInBsdWdpbjpzb25hcmpzL3JlY29tbWVuZGVkXCIsXG4gICAgICAgICk7XG4gICAgICAgIHByb2plY3QuZXNsaW50Py5hZGRSdWxlcyh7XG4gICAgICAgICAgICBcIm5vLWNvbnNvbGVcIjogW1xuICAgICAgICAgICAgICAgIFwiZXJyb3JcIixcbiAgICAgICAgICAgICAgICB7IGFsbG93OiBbXCJkZWJ1Z1wiLCBcImluZm9cIiwgXCJ3YXJuXCIsIFwiZXJyb3JcIl0gfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBcIm5vLXRyYWlsaW5nLXNwYWNlc1wiOiBcIm9mZlwiLCAvLyBDb25mbGljdHMgd2l0aCBQcmV0dGllclxuICAgICAgICAgICAgXCJuby1tdWx0aXBsZS1lbXB0eS1saW5lc1wiOiBcIm9mZlwiLCAvLyBDb25mbGljdHMgd2l0aCBQcmV0dGllclxuICAgICAgICAgICAgXCJpbXBvcnQvbm8tdW5yZXNvbHZlZFwiOiBcIm9mZlwiLCAvLyBIYW5kbGVkIGJ5IFRTIGFuZCBpdCBnZXRzIGNvbmZ1c2VkIG9uIEB0eXBlcyBwYWNrYWdlcy5cbiAgICAgICAgICAgIFwiaW1wb3J0L25hbWVzcGFjZVwiOiBcIm9mZlwiLFxuICAgICAgICAgICAgXCJuby1kdXBsaWNhdGUtaW1wb3J0c1wiOiBcIm9mZlwiLCAvLyBIYW5kbGVkIGJ5IGltcG9ydC9uby1kdXBsaWNhdGVzXG4gICAgICAgICAgICBcImltcG9ydC9uby1kdXBsaWNhdGVzXCI6IFwiZXJyb3JcIixcbiAgICAgICAgICAgIFwiaW1wb3J0L25vLW5hbWVkLWFzLWRlZmF1bHRcIjogXCJlcnJvclwiLFxuICAgICAgICAgICAgXCJpbXBvcnQvbm8tbmFtZWQtYXMtZGVmYXVsdC1tZW1iZXJcIjogXCJlcnJvclwiLFxuICAgICAgICAgICAgXCJpbXBvcnQvb3JkZXJcIjogW1xuICAgICAgICAgICAgICAgIFwiZXJyb3JcIixcbiAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgIGdyb3VwczogW1xuICAgICAgICAgICAgICAgICAgICAgICAgXCJidWlsdGluXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBcImV4dGVybmFsXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBcInBhcmVudFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgXCJzaWJsaW5nXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICBcImluZGV4XCIsXG4gICAgICAgICAgICAgICAgICAgIF0sXG4gICAgICAgICAgICAgICAgICAgIFwibmV3bGluZXMtYmV0d2VlblwiOiBcImFsd2F5c1wiLFxuICAgICAgICAgICAgICAgICAgICBwYXRoR3JvdXBzOiBbXG4gICAgICAgICAgICAgICAgICAgICAgICB7XG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcGF0dGVybjogXCJyZWFjdFwiLFxuICAgICAgICAgICAgICAgICAgICAgICAgICAgIGdyb3VwOiBcImV4dGVybmFsXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICAgICAgcG9zaXRpb246IFwiYmVmb3JlXCIsXG4gICAgICAgICAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgICAgICAgICBdLFxuICAgICAgICAgICAgICAgICAgICBwYXRoR3JvdXBzRXhjbHVkZWRJbXBvcnRUeXBlczogW1wicmVhY3RcIl0sXG4gICAgICAgICAgICAgICAgICAgIGFscGhhYmV0aXplOiB7XG4gICAgICAgICAgICAgICAgICAgICAgICBvcmRlcjogXCJhc2NcIixcbiAgICAgICAgICAgICAgICAgICAgICAgIGNhc2VJbnNlbnNpdGl2ZTogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgICAgICB9LFxuICAgICAgICAgICAgXSxcbiAgICAgICAgICAgIFwic29uYXJqcy9uby1yZWR1bmRhbnQtanVtcFwiOiBcIm9mZlwiLFxuICAgICAgICAgICAgXCJzb25hcmpzL25vLXNtYWxsLXN3aXRjaFwiOiBcIndhcm5cIixcbiAgICAgICAgICAgIFwiQHR5cGVzY3JpcHQtZXNsaW50L2V4cGxpY2l0LWZ1bmN0aW9uLXJldHVybi10eXBlXCI6IFtcbiAgICAgICAgICAgICAgICBcImVycm9yXCIsXG4gICAgICAgICAgICAgICAge1xuICAgICAgICAgICAgICAgICAgICBhbGxvd0V4cHJlc3Npb25zOiB0cnVlLFxuICAgICAgICAgICAgICAgICAgICBhbGxvd1R5cGVkRnVuY3Rpb25FeHByZXNzaW9uczogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYWxsb3dIaWdoZXJPcmRlckZ1bmN0aW9uczogdHJ1ZSxcbiAgICAgICAgICAgICAgICAgICAgYWxsb3dEaXJlY3RDb25zdEFzc2VydGlvbkluQXJyb3dGdW5jdGlvbnM6IHRydWUsXG4gICAgICAgICAgICAgICAgICAgIGFsbG93Q29uY2lzZUFycm93RnVuY3Rpb25FeHByZXNzaW9uc1N0YXJ0aW5nV2l0aFZvaWQ6IHRydWUsXG4gICAgICAgICAgICAgICAgfSxcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBcIkB0eXBlc2NyaXB0LWVzbGludC9yZXR1cm4tYXdhaXRcIjogW1wiZXJyb3JcIiwgXCJhbHdheXNcIl0sXG4gICAgICAgICAgICBcIkB0eXBlc2NyaXB0LWVzbGludC9uby11bnVzZWQtdmFyc1wiOiBbXG4gICAgICAgICAgICAgICAgXCJlcnJvclwiLFxuICAgICAgICAgICAgICAgIHtcbiAgICAgICAgICAgICAgICAgICAgaWdub3JlUmVzdFNpYmxpbmdzOiB0cnVlLFxuICAgICAgICAgICAgICAgIH0sXG4gICAgICAgICAgICBdLFxuICAgICAgICB9KTtcblxuICAgICAgICBwcm9qZWN0LmVzbGludD8uYWRkT3ZlcnJpZGUoe1xuICAgICAgICAgICAgZmlsZXM6IFtcIioudHNcIiwgXCIqLnRzeFwiXSxcbiAgICAgICAgICAgIGV4Y2x1ZGVkRmlsZXM6IFtcbiAgICAgICAgICAgICAgICAvLyBOZXh0LmpzIGZvcmNlZCBkZWZhdWx0IGV4cG9ydHNcbiAgICAgICAgICAgICAgICBcIioqL2FwcC8qKlwiLFxuICAgICAgICAgICAgICAgIFwiKiovYXBwLyoqXCIsXG4gICAgICAgICAgICAgICAgXCIqKi9wYWdlcy8qKlwiLFxuICAgICAgICAgICAgICAgIFwiKiovcGFnZXMvKipcIixcbiAgICAgICAgICAgICAgICAvLyBTdG9yeWJvb2sgU3RvcmllcyBoYXZlIGEgZm9yY2VkIGRlZmF1bHQgZXhwb3J0XG4gICAgICAgICAgICAgICAgXCIqKi8uc3Rvcnlib29rLyoqXCIsXG4gICAgICAgICAgICAgICAgXCIqLnN0b3JpZXMudHNcIixcbiAgICAgICAgICAgICAgICBcIiouc3Rvcmllcy50c3hcIixcbiAgICAgICAgICAgIF0sXG4gICAgICAgICAgICBydWxlczoge1xuICAgICAgICAgICAgICAgIFwiaW1wb3J0L25vLWRlZmF1bHQtZXhwb3J0XCI6IFwid2FyblwiLCAvLyBDYXVzZXMgaXNzdWVzIHdoZW4gdXNpbmcgYmFiZWwgYW5kIHRzYyBzZXBhcmF0ZWx5XG4gICAgICAgICAgICB9LFxuICAgICAgICB9KTtcblxuICAgICAgICBwcm9qZWN0LmVzbGludD8uYWRkT3ZlcnJpZGUoe1xuICAgICAgICAgICAgZmlsZXM6IFtcIiouanNcIiwgXCIqLmpzeFwiXSxcbiAgICAgICAgICAgIHJ1bGVzOiB7XG4gICAgICAgICAgICAgICAgXCJpbXBvcnQvbm8tdW5yZXNvbHZlZFwiOiBcImVycm9yXCIsXG4gICAgICAgICAgICAgICAgXCJAdHlwZXNjcmlwdC1lc2xpbnQvZXhwbGljaXQtZnVuY3Rpb24tcmV0dXJuLXR5cGVcIjogXCJvZmZcIixcbiAgICAgICAgICAgICAgICBcIkB0eXBlc2NyaXB0LWVzbGludC9leHBsaWNpdC1tb2R1bGUtYm91bmRhcnktdHlwZXNcIjogXCJvZmZcIixcbiAgICAgICAgICAgICAgICBcIkB0eXBlc2NyaXB0LWVzbGludC9uby12YXItcmVxdWlyZXNcIjogXCJvZmZcIixcbiAgICAgICAgICAgIH0sXG4gICAgICAgIH0pO1xuXG4gICAgICAgIGZvciAoY29uc3QgcGF0dGVybiBvZiBERVZfRklMRV9QQVRURVJOUykge1xuICAgICAgICAgICAgcHJvamVjdC5lc2xpbnQ/LmFsbG93RGV2RGVwcyhwYXR0ZXJuKTtcbiAgICAgICAgfVxuICAgIH1cbn1cblxuZXhwb3J0IGVudW0gREtUYXNrTmFtZSB7XG4gICAgQ0xFQU5fQ09NUElMRSA9IFwiY2xlYW4tY29tcGlsZVwiLFxuICAgIENJID0gXCJjaVwiLFxuICAgIERPQ0dFTl9SRU1PVkUgPSBcImRvY2dlbjpyZW1vdmVcIixcbiAgICBJID0gXCJpXCIsXG4gICAgTElOVCA9IFwibGludFwiLFxuICAgIFRFU1RfVU5JVCA9IFwidGVzdC11bml0XCIsXG4gICAgVFlQRV9DSEVDSyA9IFwidHlwZS1jaGVja1wiLFxuICAgIFVQR1JBREVfUEFDS0FHRSA9IFwidXBncmFkZTpwYWNrYWdlXCIsXG59XG5cbmV4cG9ydCBjbGFzcyBES1Rhc2tzIGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgICBwdWJsaWMgc3RhdGljIHJlYWRvbmx5IElTX05PVF9SRUxFQVNFX0NPTkRJVElPTiA9IGBpZiBbIFwiJFJFTEVBU0VcIiA9IFwidHJ1ZVwiIF0gOyB0aGVuIGV4aXQgMSA7IGZpYDtcblxuICAgIGRlY2xhcmUgcHJvamVjdDogVHlwZVNjcmlwdFByb2plY3Q7XG5cbiAgICBjb25zdHJ1Y3Rvcihwcm9qZWN0OiBUeXBlU2NyaXB0UHJvamVjdCkge1xuICAgICAgICBzdXBlcihwcm9qZWN0KTtcblxuICAgICAgICAvLyBJbnN0YWxsXG4gICAgICAgIHByb2plY3QuYWRkVGFzayhES1Rhc2tOYW1lLkNJKS5zcGF3bihwcm9qZWN0LnBhY2thZ2UuaW5zdGFsbENpVGFzayk7XG4gICAgICAgIHByb2plY3QuYWRkVGFzayhES1Rhc2tOYW1lLkkpLnNwYXduKHByb2plY3QucGFja2FnZS5pbnN0YWxsVGFzayk7XG5cbiAgICAgICAgY29uc3QgdHlwZUNoZWNrVGFzayA9IHByb2plY3QudGFza3MuYWRkVGFzayhES1Rhc2tOYW1lLlRZUEVfQ0hFQ0spO1xuICAgICAgICB0eXBlQ2hlY2tUYXNrLmV4ZWMoXCJ0c2MgLS1ub0VtaXRcIik7XG5cbiAgICAgICAgLy8gRXNsaW50XG4gICAgICAgIGNvbnN0IGxpbnRUYXNrID0gcHJvamVjdC5lc2xpbnQ/LmVzbGludFRhc2s7XG5cbiAgICAgICAgaWYgKGxpbnRUYXNrKSB7XG4gICAgICAgICAgICBsaW50VGFzay5hZGRDb25kaXRpb24oREtUYXNrcy5JU19OT1RfUkVMRUFTRV9DT05ESVRJT04pO1xuXG4gICAgICAgICAgICBwcm9qZWN0XG4gICAgICAgICAgICAgICAgLmFkZFRhc2soREtUYXNrTmFtZS5MSU5ULCB7XG4gICAgICAgICAgICAgICAgICAgIGNvbmRpdGlvbjogREtUYXNrcy5JU19OT1RfUkVMRUFTRV9DT05ESVRJT04sXG4gICAgICAgICAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIkFsdGVybmF0ZSBsaW50IGNvbW1hbmRcIixcbiAgICAgICAgICAgICAgICAgICAgcmVjZWl2ZUFyZ3M6IHRydWUsXG4gICAgICAgICAgICAgICAgfSlcbiAgICAgICAgICAgICAgICAuc3Bhd24obGludFRhc2spO1xuXG4gICAgICAgICAgICBjb25zdCBvcmlnaW5hbFRlc3RUYXNrU3RlcCA9IHByb2plY3QudGVzdFRhc2suc3RlcHNbMF07XG4gICAgICAgICAgICBjb25zdCB7IGV4ZWMsIC4uLnJlc3RPZlRlc3RUYXNrU3RlcCB9ID0gb3JpZ2luYWxUZXN0VGFza1N0ZXA7XG5cbiAgICAgICAgICAgIGNvbnN0IHVuaXRUZXN0VGFzayA9IHByb2plY3QuYWRkVGFzayhES1Rhc2tOYW1lLlRFU1RfVU5JVCwge1xuICAgICAgICAgICAgICAgIGNvbmRpdGlvbjogREtUYXNrcy5JU19OT1RfUkVMRUFTRV9DT05ESVRJT04sXG4gICAgICAgICAgICAgICAgcmVjZWl2ZUFyZ3M6IHRydWUsXG4gICAgICAgICAgICB9KTtcbiAgICAgICAgICAgIHVuaXRUZXN0VGFzay5leGVjKGV4ZWMgYXMgc3RyaW5nLCB7IC4uLnJlc3RPZlRlc3RUYXNrU3RlcCB9KTtcblxuICAgICAgICAgICAgcHJvamVjdC50ZXN0VGFzay5yZXNldCgpO1xuICAgICAgICAgICAgcHJvamVjdC50ZXN0VGFzay5zcGF3bihsaW50VGFzayk7XG4gICAgICAgICAgICBwcm9qZWN0LnRlc3RUYXNrLnNwYXduKHR5cGVDaGVja1Rhc2spO1xuICAgICAgICAgICAgcHJvamVjdC50ZXN0VGFzay5zcGF3bih1bml0VGVzdFRhc2spO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gQ29tcGlsZVxuICAgICAgICBjb25zdCBjbGVhbkNvbXBpbGVUYXNrID1cbiAgICAgICAgICAgIHByb2plY3QudGFza3MudHJ5RmluZChES1Rhc2tOYW1lLkNMRUFOX0NPTVBJTEUpID8/XG4gICAgICAgICAgICBwcm9qZWN0LnRhc2tzLmFkZFRhc2soREtUYXNrTmFtZS5DTEVBTl9DT01QSUxFLCB7XG4gICAgICAgICAgICAgICAgZGVzY3JpcHRpb246IFwiQ2xlYW4gdXAgdGhlIGNvbXBpbGVkIG91dHB1dFwiLFxuICAgICAgICAgICAgfSk7XG4gICAgICAgIGNsZWFuQ29tcGlsZVRhc2suZXhlYyhcbiAgICAgICAgICAgIGBybSAtcmYgJHtwcm9qZWN0LmxpYmRpcn0gJiYgcm0gLXJmICR7cHJvamVjdC5hcnRpZmFjdHNEaXJlY3Rvcnl9YCxcbiAgICAgICAgKTtcblxuICAgICAgICAvLyBEb2NnZW5cbiAgICAgICAgY29uc3QgZG9jZ2VuUmVtb3ZlVGFzayA9IHByb2plY3QuYWRkVGFzayhES1Rhc2tOYW1lLkRPQ0dFTl9SRU1PVkUsIHtcbiAgICAgICAgICAgIGRlc2NyaXB0aW9uOiBcIlJlbW92ZSB0aGUgZG9jZ2VuIGRpcmVjdG9yeVwiLFxuICAgICAgICB9KTtcbiAgICAgICAgZG9jZ2VuUmVtb3ZlVGFzay5leGVjKGBybSAtcmYgJHtwcm9qZWN0LmRvY3NEaXJlY3Rvcnl9YCk7XG5cbiAgICAgICAgY29uc3QgZG9jZ2VuVGFzayA9IHByb2plY3QudGFza3MudHJ5RmluZChcImRvY2dlblwiKTtcbiAgICAgICAgaWYgKGRvY2dlblRhc2spIHtcbiAgICAgICAgICAgIGRvY2dlblRhc2suYWRkQ29uZGl0aW9uKERLVGFza3MuSVNfTk9UX1JFTEVBU0VfQ09ORElUSU9OKTtcbiAgICAgICAgICAgIGRvY2dlblRhc2sucHJlcGVuZFNwYXduKGRvY2dlblJlbW92ZVRhc2spO1xuICAgICAgICB9XG5cbiAgICAgICAgLy8gVXBncmFkZSBQYWNrYWdlXG4gICAgICAgIHByb2plY3QuYWRkVGFzayhES1Rhc2tOYW1lLlVQR1JBREVfUEFDS0FHRSwge1xuICAgICAgICAgICAgZGVzY3JpcHRpb246XG4gICAgICAgICAgICAgICAgXCJVcGdyYWRlIGEgc2luZ2xlIHBhY2thZ2UgKG9yIG90aGVyd2lzZSB1c2UgTlBNIENoZWNrIFVwZGF0ZXMpLiBUaGlzIHNob3VsZCBiZSB1c2VkIGFzICducHggcHJvamVuIHVwZ3JhZGU6cGFja2FnZSAtLSA8cGFja2FnZS1uYW1lPidcIixcbiAgICAgICAgICAgIGV4ZWM6IFwicG5wbSBkbHggbnBtLWNoZWNrLXVwZGF0ZXNAMTYgLS11cGdyYWRlXCIsXG4gICAgICAgICAgICByZWNlaXZlQXJnczogdHJ1ZSxcbiAgICAgICAgfSk7XG4gICAgfVxuXG4gICAgb3ZlcnJpZGUgcHJlU3ludGhlc2l6ZSgpOiB2b2lkIHtcbiAgICAgICAgc3VwZXIucHJlU3ludGhlc2l6ZSgpO1xuICAgIH1cbn1cblxuZXhwb3J0IGludGVyZmFjZSBKZXN0VHJhbnNmb3JtZXJPcHRpb25zIHtcbiAgICAvKipcbiAgICAgKiBBZGRpdGlvbmFsIG1vZHVsZXMgZm9yIGplc3QgdG8gdHJhbnNmb3JtLCB0eXBpY2FsbHkgRVNNIG1vZHVsZXMuXG4gICAgICpcbiAgICAgKiBAZGVmYXVsdCAtIEEgbGlzdCBvZiBrbm93biBFU00gbW9kdWxlcyBjb21tb25seSB1c2VkIGluIHByb2plY3RzXG4gICAgICovXG4gICAgcmVhZG9ubHkgbW9kdWxlc1RvVHJhbnNmb3JtPzogc3RyaW5nW107XG59XG5cbmV4cG9ydCBpbnRlcmZhY2UgTm9kZTIwVHlwZVNjcmlwdFByb2plY3RKZXN0T3B0aW9uc1xuICAgIGV4dGVuZHMgSmVzdE9wdGlvbnMsXG4gICAgICAgIEplc3RUcmFuc2Zvcm1lck9wdGlvbnMge31cblxuZXhwb3J0IGNsYXNzIEplc3RUcmFuc2Zvcm1lciBleHRlbmRzIENvbXBvbmVudCB7XG4gICAgcHVibGljIHN0YXRpYyBFU01fTU9EVUxFU19UT19UUkFOU0ZPUk0gPSBbXG4gICAgICAgIFwiQGJhYmVsL3J1bnRpbWVcIixcbiAgICAgICAgXCJAbXVpLipcIixcbiAgICAgICAgXCJAcGFudmEvaGtkZlwiLFxuICAgICAgICBcIkBzaW5kcmVzb3JodXMvaXNcIixcbiAgICAgICAgXCJAc3ptYXJjemFrL2h0dHAtdGltZXJcIixcbiAgICAgICAgXCJiYWlsXCIsXG4gICAgICAgIFwiY2FjaGVhYmxlLWxvb2t1cFwiLFxuICAgICAgICBcImNhY2hlYWJsZS1yZXF1ZXN0XCIsXG4gICAgICAgIFwiY2NvdW50XCIsXG4gICAgICAgIFwiY2hhcmFjdGVyLWVudGl0aWVzLipcIixcbiAgICAgICAgXCJjb21tYS1zZXBhcmF0ZWQtdG9rZW5zXCIsXG4gICAgICAgIFwiZGVjb2RlLW5hbWVkLWNoYXJhY3Rlci1yZWZlcmVuY2VcIixcbiAgICAgICAgXCJkZXZsb3BcIixcbiAgICAgICAgXCJkaXJlY3Rpb25cIixcbiAgICAgICAgXCJkb203XCIsXG4gICAgICAgIFwiZXNjYXBlLXN0cmluZy1yZWdleHBcIixcbiAgICAgICAgXCJmaWxlLXR5cGVcIixcbiAgICAgICAgXCJmb3JtLWRhdGEtZW5jb2RlclwiLFxuICAgICAgICBcImdpdGh1Yi1zbHVnZ2VyXCIsXG4gICAgICAgIFwiZ290XCIsXG4gICAgICAgIFwiaGFzdC4qXCIsXG4gICAgICAgIFwiaHRtbC12b2lkLWVsZW1lbnRzXCIsXG4gICAgICAgIFwiaXMtcGxhaW4tb2JqXCIsXG4gICAgICAgIFwiam9zZVwiLFxuICAgICAgICBcImxvbmdlc3Qtc3RyZWFrXCIsXG4gICAgICAgIFwibG93ZXJjYXNlLWtleXNcIixcbiAgICAgICAgXCJtYXJrZG93bi4qXCIsXG4gICAgICAgIFwibWRhc3QuKlwiLFxuICAgICAgICBcIm1pY3JvbWFyay4qXCIsXG4gICAgICAgIFwibWltaWMtcmVzcG9uc2VcIixcbiAgICAgICAgXCJub3JtYWxpemUtdXJsXCIsXG4gICAgICAgIFwicC1jYW5jZWxhYmxlXCIsXG4gICAgICAgIFwicGVlay1yZWFkYWJsZVwiLFxuICAgICAgICBcInByb3BlcnR5LWluZm9ybWF0aW9uXCIsXG4gICAgICAgIFwicmVoeXBlLipcIixcbiAgICAgICAgXCJyZW1hcmsuKlwiLFxuICAgICAgICBcInJlc3BvbnNlbGlrZVwiLFxuICAgICAgICBcInNlcGFy