projen
Version:
CDK for software projects
387 lines • 51.3 kB
JavaScript
"use strict";
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 () {
var ownKeys = function(o) {
ownKeys = Object.getOwnPropertyNames || function (o) {
var ar = [];
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
return ar;
};
return ownKeys(o);
};
return function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
__setModuleDefault(result, mod);
return result;
};
})();
Object.defineProperty(exports, "__esModule", { value: true });
exports.ReactComponent = exports.ReactTypeScriptProject = exports.ReactProject = void 0;
const JSII_RTTI_SYMBOL_1 = Symbol.for("jsii.rtti");
const path = __importStar(require("path"));
const component_1 = require("../component");
const javascript_1 = require("../javascript");
const sample_file_1 = require("../sample-file");
const source_code_1 = require("../source-code");
const typescript_1 = require("../typescript");
const util_1 = require("../util");
/**
* React project using JavaScript.
*
* @pjid react
*/
class ReactProject extends javascript_1.NodeProject {
static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.web.ReactProject", version: "0.103.12" };
/**
* The directory in which source files reside.
* @default "src"
*/
srcdir;
constructor(options) {
super({
jest: false,
...options,
});
this.srcdir = options.srcdir ?? "src";
new ReactComponent(this, { typescript: false, rewire: options.rewire });
// generate sample code in `src` and `public` if these directories are empty or non-existent.
if (options.sampleCode ?? true) {
new ReactSampleCode(this, {
fileExt: "jsx",
srcdir: this.srcdir,
});
new sample_file_1.SampleDir(this, "public", {
sourceDir: path.join(__dirname, "..", "..", "assets", "web", "react"),
});
}
}
}
exports.ReactProject = ReactProject;
/**
* React project using TypeScript.
*
* @pjid react-ts
*/
class ReactTypeScriptProject extends typescript_1.TypeScriptAppProject {
static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.web.ReactTypeScriptProject", version: "0.103.12" };
/**
* The directory in which source files reside.
*/
srcdir;
constructor(options) {
const defaultOptions = {
srcdir: "src",
eslint: true,
jest: false,
tsconfig: {
include: ["src"],
compilerOptions: {
target: "es5",
lib: ["dom", "dom.iterable", "esnext"],
allowJs: true,
skipLibCheck: true,
esModuleInterop: true,
allowSyntheticDefaultImports: true,
strict: true,
forceConsistentCasingInFileNames: true,
noFallthroughCasesInSwitch: true,
module: "commonjs",
moduleResolution: javascript_1.TypeScriptModuleResolution.NODE,
resolveJsonModule: true,
isolatedModules: true,
noEmit: true,
jsx: javascript_1.TypeScriptJsxMode.REACT_JSX,
},
},
typescriptVersion: options.typescriptVersion ?? "^4.0.3",
};
// never generate default TypeScript sample code, since this class provides its own
super((0, util_1.deepMerge)([
defaultOptions,
options,
{ sampleCode: false },
]));
this.srcdir = options.srcdir ?? "src";
this.eslint?.addRules({
"import/no-extraneous-dependencies": [
"error",
{
devDependencies: ["**/src/**/*.test.tsx", "**/src/setupTests.ts"],
optionalDependencies: false,
peerDependencies: true,
},
],
});
new ReactComponent(this, { typescript: true, rewire: options.rewire });
// generate sample code in `src` and `public` if these directories are empty or non-existent.
if (options.sampleCode ?? true) {
new ReactSampleCode(this, {
fileExt: "tsx",
srcdir: this.srcdir,
});
new sample_file_1.SampleDir(this, "public", {
sourceDir: path.join(__dirname, "..", "..", "assets", "web", "react"),
});
}
this.package.addPackageResolutions(
// https://github.com/DefinitelyTyped/DefinitelyTyped/issues/62300
"@types/express@4.17.13", "@types/express-serve-static-core@4.17.30");
}
}
exports.ReactTypeScriptProject = ReactTypeScriptProject;
class ReactComponent extends component_1.Component {
static [JSII_RTTI_SYMBOL_1] = { fqn: "projen.web.ReactComponent", version: "0.103.12" };
typescript;
constructor(project, options) {
super(project);
this.typescript = options.typescript ?? false;
// No compile for react app
project.compileTask.reset();
project.addDeps("react", "react-dom", "web-vitals");
project.addDevDeps("react-scripts@^5", "@testing-library/dom", "@testing-library/jest-dom", "@testing-library/react", "@testing-library/user-event");
if (this.typescript) {
project.addDevDeps("@types/jest", "@types/react", "@types/react-dom");
}
const rewire = options.rewire ?? false;
if (rewire) {
const overridesPath = ".projen/react-config-overrides.js";
project.addDevDeps("react-app-rewired");
project.addFields({ "config-overrides-path": overridesPath });
const configOverrides = new source_code_1.SourceCode(this.project, overridesPath);
if (!configOverrides.marker) {
configOverrides.line(`// ${configOverrides.marker}`);
}
configOverrides.line("/**");
configOverrides.line(" * Override CRA configuration without needing to eject.");
configOverrides.line(" *");
configOverrides.line(" * @see https://www.npmjs.com/package/react-app-rewired");
configOverrides.line(" */");
configOverrides.open("module.exports = function override(config, env) {");
for (const [key, value] of Object.entries(rewire)) {
configOverrides.line(`config.${key} = ${JSON.stringify(value)};`);
}
configOverrides.line("return config;");
configOverrides.close("};");
}
const reactScripts = rewire ? "react-app-rewired" : "react-scripts";
// Create React App CLI commands, see: https://create-react-app.dev/docs/available-scripts/
project.addTask("dev", {
description: "Starts the react application",
execArgs: [reactScripts, "start"],
});
project.compileTask.execArgs([reactScripts, "build"]);
project.testTask.execArgs([reactScripts, "test", "--watchAll=false"]);
const testWatch = project.tasks.tryFind("test:watch");
testWatch?.reset(`${reactScripts} test`);
project.npmignore?.exclude("# Build", "/build/");
project.gitignore.exclude("# Build", "/build/");
project.package.addField("eslintConfig", {
extends: ["react-app", "react-app/jest"],
});
project.package.addField("browserslist", {
production: [">0.2%", "not dead", "not op_mini all"],
development: [
"last 1 chrome version",
"last 1 firefox version",
"last 1 safari version",
],
});
}
}
exports.ReactComponent = ReactComponent;
class ReactSampleCode extends component_1.Component {
fileExt;
srcdir;
constructor(project, options) {
super(project);
this.fileExt = options.fileExt ?? "jsx";
this.srcdir = options.srcdir;
const logoSvg = [
'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 841.9 595.3">',
' <g fill="#61DAFB">',
' <path d="M666.3 296.5c0-32.5-40.7-63.3-103.1-82.4 14.4-63.6 8-114.2-20.2-130.4-6.5-3.8-14.1-5.6-22.4-5.6v22.3c4.6 0 8.3.9 11.4 2.6 13.6 7.8 19.5 37.5 14.9 75.7-1.1 9.4-2.9 19.3-5.1 29.4-19.6-4.8-41-8.5-63.5-10.9-13.5-18.5-27.5-35.3-41.6-50 32.6-30.3 63.2-46.9 84-46.9V78c-27.5 0-63.5 19.6-99.9 53.6-36.4-33.8-72.4-53.2-99.9-53.2v22.3c20.7 0 51.4 16.5 84 46.6-14 14.7-28 31.4-41.3 49.9-22.6 2.4-44 6.1-63.6 11-2.3-10-4-19.7-5.2-29-4.7-38.2 1.1-67.9 14.6-75.8 3-1.8 6.9-2.6 11.5-2.6V78.5c-8.4 0-16 1.8-22.6 5.6-28.1 16.2-34.4 66.7-19.9 130.1-62.2 19.2-102.7 49.9-102.7 82.3 0 32.5 40.7 63.3 103.1 82.4-14.4 63.6-8 114.2 20.2 130.4 6.5 3.8 14.1 5.6 22.5 5.6 27.5 0 63.5-19.6 99.9-53.6 36.4 33.8 72.4 53.2 99.9 53.2 8.4 0 16-1.8 22.6-5.6 28.1-16.2 34.4-66.7 19.9-130.1 62-19.1 102.5-49.9 102.5-82.3zm-130.2-66.7c-3.7 12.9-8.3 26.2-13.5 39.5-4.1-8-8.4-16-13.1-24-4.6-8-9.5-15.8-14.4-23.4 14.2 2.1 27.9 4.7 41 7.9zm-45.8 106.5c-7.8 13.5-15.8 26.3-24.1 38.2-14.9 1.3-30 2-45.2 2-15.1 0-30.2-.7-45-1.9-8.3-11.9-16.4-24.6-24.2-38-7.6-13.1-14.5-26.4-20.8-39.8 6.2-13.4 13.2-26.8 20.7-39.9 7.8-13.5 15.8-26.3 24.1-38.2 14.9-1.3 30-2 45.2-2 15.1 0 30.2.7 45 1.9 8.3 11.9 16.4 24.6 24.2 38 7.6 13.1 14.5 26.4 20.8 39.8-6.3 13.4-13.2 26.8-20.7 39.9zm32.3-13c5.4 13.4 10 26.8 13.8 39.8-13.1 3.2-26.9 5.9-41.2 8 4.9-7.7 9.8-15.6 14.4-23.7 4.6-8 8.9-16.1 13-24.1zM421.2 430c-9.3-9.6-18.6-20.3-27.8-32 9 .4 18.2.7 27.5.7 9.4 0 18.7-.2 27.8-.7-9 11.7-18.3 22.4-27.5 32zm-74.4-58.9c-14.2-2.1-27.9-4.7-41-7.9 3.7-12.9 8.3-26.2 13.5-39.5 4.1 8 8.4 16 13.1 24 4.7 8 9.5 15.8 14.4 23.4zM420.7 163c9.3 9.6 18.6 20.3 27.8 32-9-.4-18.2-.7-27.5-.7-9.4 0-18.7.2-27.8.7 9-11.7 18.3-22.4 27.5-32zm-74 58.9c-4.9 7.7-9.8 15.6-14.4 23.7-4.6 8-8.9 16-13 24-5.4-13.4-10-26.8-13.8-39.8 13.1-3.1 26.9-5.8 41.2-7.9zm-90.5 125.2c-35.4-15.1-58.3-34.9-58.3-50.6 0-15.7 22.9-35.6 58.3-50.6 8.6-3.7 18-7 27.7-10.1 5.7 19.6 13.2 40 22.5 60.9-9.2 20.8-16.6 41.1-22.2 60.6-9.9-3.1-19.3-6.5-28-10.2zM310 490c-13.6-7.8-19.5-37.5-14.9-75.7 1.1-9.4 2.9-19.3 5.1-29.4 19.6 4.8 41 8.5 63.5 10.9 13.5 18.5 27.5 35.3 41.6 50-32.6 30.3-63.2 46.9-84 46.9-4.5-.1-8.3-1-11.3-2.7zm237.2-76.2c4.7 38.2-1.1 67.9-14.6 75.8-3 1.8-6.9 2.6-11.5 2.6-20.7 0-51.4-16.5-84-46.6 14-14.7 28-31.4 41.3-49.9 22.6-2.4 44-6.1 63.6-11 2.3 10.1 4.1 19.8 5.2 29.1zm38.5-66.7c-8.6 3.7-18 7-27.7 10.1-5.7-19.6-13.2-40-22.5-60.9 9.2-20.8 16.6-41.1 22.2-60.6 9.9 3.1 19.3 6.5 28.1 10.2 35.4 15.1 58.3 34.9 58.3 50.6-.1 15.7-23 35.6-58.4 50.6zM320.8 78.4z"/>',
' <circle cx="420.9" cy="296.5" r="45.7"/>',
' <path d="M520.5 78.1z"/>',
" </g>",
"</svg>",
"",
];
const appJsx = [
"import logo from './logo.svg';",
"import './App.css'",
"",
"function App() {",
" return (",
' <div className="App">',
' <header className="App-header">',
' <img src={logo} className="App-logo" alt="logo" />',
" <p>",
` Edit <code>src/App.${this.fileExt}</code> and save to reload.`,
" </p>",
' <a className="App-link"',
' href="https://reactjs.org"',
' target="_blank"',
' rel="noopener noreferrer"',
" >",
" Learn React",
" </a>",
" </header>",
" </div>",
" );",
"}",
"",
"export default App;",
"",
];
const appCss = [
".App {",
" text-align: center;",
"}",
"",
".App-logo {",
" height: 40vmin;",
" pointer-events: none;",
"}",
"",
"@media (prefers-reduced-motion: no-preference) {",
" .App-logo {",
" animation: App-logo-spin infinite 20s linear;",
" }",
"}",
"",
".App-header {",
" background-color: #282c34;",
" min-height: 100vh;",
" display: flex;",
" flex-direction: column;",
" align-items: center;",
" justify-content: center;",
" font-size: calc(10px + 2vmin);",
" color: white;",
"}",
"",
".App-link {",
" color: #61dafb;",
"}",
"",
"@keyframes App-logo-spin {",
" from {",
" transform: rotate(0deg);",
" }",
" to {",
" transform: rotate(360deg);",
" }",
"}",
"",
];
const appTestJsx = [
"import { render, screen } from '@testing-library/react';",
"import App from './App';",
"",
"test('renders learn react link', () => {",
" render(<App />);",
" const linkElement = screen.getByText(/learn react/i);",
" expect(linkElement).toBeInTheDocument();",
"});",
"",
];
const indexJsx = [
"import React from 'react';",
"import ReactDOM from 'react-dom';",
"import './index.css';",
"import App from './App';",
"import reportWebVitals from './reportWebVitals';",
"",
"ReactDOM.render(",
" <React.StrictMode>",
" <App />",
" </React.StrictMode>,",
" document.getElementById('root')",
");",
"",
"// If you want to start measuring performance in your app, pass a function",
"// to log results (for example: reportWebVitals(console.log))",
"// or send to an analytics endpoint. Learn more: https://bit.ly/CRA-vitals",
"reportWebVitals();",
"",
];
const indexCss = [
"body {",
" margin: 0;",
" font-family: -apple-system, BlinkMacSystemFont, 'Segoe UI', 'Roboto', 'Oxygen',",
" 'Ubuntu', 'Cantarell', 'Fira Sans', 'Droid Sans', 'Helvetica Neue',",
" sans-serif;",
" -webkit-font-smoothing: antialiased;",
" -moz-osx-font-smoothing: grayscale;",
"}",
"",
"code {",
" font-family: source-code-pro, Menlo, Monaco, Consolas, 'Courier New',",
" monospace;",
"}",
"",
];
const reportWebVitalsJs = [
"import { ReportHandler } from 'web-vitals';",
"",
"const reportWebVitals = (onPerfEntry?: ReportHandler) => {",
" if (onPerfEntry && onPerfEntry instanceof Function) {",
" import('web-vitals').then(",
" ({ getCLS, getFID, getFCP, getLCP, getTTFB }) => {",
" getCLS(onPerfEntry);",
" getFID(onPerfEntry);",
" getFCP(onPerfEntry);",
" getLCP(onPerfEntry);",
" getTTFB(onPerfEntry);",
" },",
" () => {}",
" );",
" }",
"};",
"",
"export default reportWebVitals;",
];
const setupTestsJs = [
"// jest-dom adds custom jest matchers for asserting on DOM nodes.",
"// allows you to do things like:",
"// expect(element).toHaveTextContent(/react/i)",
"// learn more: https://github.com/testing-library/jest-dom",
"import '@testing-library/jest-dom';",
"",
];
const reactTypeDef = ['/// <reference types="react-scripts" />'];
// js/ts not jsx/tsx
const fileExtWithoutX = this.fileExt.replace("x", "");
new sample_file_1.SampleDir(project, this.srcdir, {
files: {
"react-app-env.d.ts": reactTypeDef.join("\n"),
"logo.svg": logoSvg.join("\n"),
["App." + this.fileExt]: appJsx.join("\n"),
["App.test." + this.fileExt]: appTestJsx.join("\n"),
"App.css": appCss.join("\n"),
["index." + this.fileExt]: indexJsx.join("\n"),
"index.css": indexCss.join("\n"),
["reportWebVitals." + fileExtWithoutX]: reportWebVitalsJs.join("\n"),
["setupTests." + fileExtWithoutX]: setupTestsJs.join("\n"),
},
});
}
}
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVhY3QuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi9zcmMvd2ViL3JlYWN0LnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFBQSwyQ0FBNkI7QUFDN0IsNENBQXlDO0FBRXpDLDhDQUl1QjtBQUN2QixnREFBMkM7QUFDM0MsZ0RBQTRDO0FBRTVDLDhDQUFxRDtBQUNyRCxrQ0FBb0M7QUF3RHBDOzs7O0dBSUc7QUFDSCxNQUFhLFlBQWEsU0FBUSx3QkFBVzs7SUFDM0M7OztPQUdHO0lBQ2EsTUFBTSxDQUFTO0lBRS9CLFlBQVksT0FBNEI7UUFDdEMsS0FBSyxDQUFDO1lBQ0osSUFBSSxFQUFFLEtBQUs7WUFDWCxHQUFHLE9BQU87U0FDWCxDQUFDLENBQUM7UUFFSCxJQUFJLENBQUMsTUFBTSxHQUFHLE9BQU8sQ0FBQyxNQUFNLElBQUksS0FBSyxDQUFDO1FBRXRDLElBQUksY0FBYyxDQUFDLElBQUksRUFBRSxFQUFFLFVBQVUsRUFBRSxLQUFLLEVBQUUsTUFBTSxFQUFFLE9BQU8sQ0FBQyxNQUFNLEVBQUUsQ0FBQyxDQUFDO1FBRXhFLDZGQUE2RjtRQUM3RixJQUFJLE9BQU8sQ0FBQyxVQUFVLElBQUksSUFBSSxFQUFFLENBQUM7WUFDL0IsSUFBSSxlQUFlLENBQUMsSUFBSSxFQUFFO2dCQUN4QixPQUFPLEVBQUUsS0FBSztnQkFDZCxNQUFNLEVBQUUsSUFBSSxDQUFDLE1BQU07YUFDcEIsQ0FBQyxDQUFDO1lBQ0gsSUFBSSx1QkFBUyxDQUFDLElBQUksRUFBRSxRQUFRLEVBQUU7Z0JBQzVCLFNBQVMsRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLFNBQVMsRUFBRSxJQUFJLEVBQUUsSUFBSSxFQUFFLFFBQVEsRUFBRSxLQUFLLEVBQUUsT0FBTyxDQUFDO2FBQ3RFLENBQUMsQ0FBQztRQUNMLENBQUM7SUFDSCxDQUFDOztBQTNCSCxvQ0E0QkM7QUFFRDs7OztHQUlHO0FB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QyxFQUFFLE1BQU0sQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUMxQyxDQUFDLFdBQVcsR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLEVBQUUsVUFBVSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ25ELFNBQVMsRUFBRSxNQUFNLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDNUIsQ0FBQyxRQUFRLEdBQUcsSUFBSSxDQUFDLE9BQU8sQ0FBQyxFQUFFLFFBQVEsQ0FBQyxJQUFJLENBQUMsSUFBSSxDQUFDO2dCQUM5QyxXQUFXLEVBQUUsUUFBUSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7Z0JBQ2hDLENBQUMsa0JBQWtCLEdBQUcsZUFBZSxDQUFDLEVBQUUsaUJBQWlCLENBQUMsSUFBSSxDQUFDLElBQUksQ0FBQztnQkFDcEUsQ0FBQyxhQUFhLEdBQUcsZUFBZSxDQUFDLEVBQUUsWUFBWSxDQUFDLElBQUksQ0FBQyxJQUFJLENBQUM7YUFDM0Q7U0FDRixDQUFDLENBQUM7SUFDTCxDQUFDO0NBQ0YiLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgKiBhcyBwYXRoIGZyb20gXCJwYXRoXCI7XG5pbXBvcnQgeyBDb21wb25lbnQgfSBmcm9tIFwiLi4vY29tcG9uZW50XCI7XG5pbXBvcnQgdHlwZSB7IE5vZGVQcm9qZWN0T3B0aW9ucyB9IGZyb20gXCIuLi9qYXZhc2NyaXB0XCI7XG5pbXBvcnQge1xuICBOb2RlUHJvamVjdCxcbiAgVHlwZVNjcmlwdEpzeE1vZGUsXG4gIFR5cGVTY3JpcHRNb2R1bGVSZXNvbHV0aW9uLFxufSBmcm9tIFwiLi4vamF2YXNjcmlwdFwiO1xuaW1wb3J0IHsgU2FtcGxlRGlyIH0gZnJvbSBcIi4uL3NhbXBsZS1maWxlXCI7XG5pbXBvcnQgeyBTb3VyY2VDb2RlIH0gZnJvbSBcIi4uL3NvdXJjZS1jb2RlXCI7XG5pbXBvcnQgdHlwZSB7IFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9ucyB9IGZyb20gXCIuLi90eXBlc2NyaXB0XCI7XG5pbXBvcnQgeyBUeXBlU2NyaXB0QXBwUHJvamVjdCB9IGZyb20gXCIuLi90eXBlc2NyaXB0XCI7XG5pbXBvcnQgeyBkZWVwTWVyZ2UgfSBmcm9tIFwiLi4vdXRpbFwiO1xuXG5leHBvcnQgaW50ZXJmYWNlIFJlYWN0UmV3aXJlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBSZXdpcmUgd2VicGFjayBjb25maWd1cmF0aW9uLlxuICAgKlxuICAgKiBVc2UgdGhpcyBwcm9wZXJ0eSB0byBvdmVycmlkZSB3ZWJwYWNrIGNvbmZpZ3VyYXRpb24gcHJvcGVydGllcyBwcm92aWRlZFxuICAgKiBieSBjcmVhdGUtcmVhY3QtYXBwLCB3aXRob3V0IG5lZWRpbmcgdG8gZWplY3QuXG4gICAqXG4gICAqIFRoaXMgcHJvcGVydHkgd2lsbCBjcmVhdGUgYSBgY29uZmlnLW92ZXJyaWRlcy5qc2AgZmlsZSBpbiB5b3VyIHJvb3QgZGlyZWN0b3J5LFxuICAgKiB3aGljaCB3aWxsIGNvbnRhaW4gdGhlIGRlc2lyZWQgcmV3aXJpbmcgY29kZS5cbiAgICpcbiAgICogVG8gKipvdmVycmlkZSoqIHRoZSBjb25maWd1cmF0aW9uLCB5b3UgY2FuIHByb3ZpZGUgc2ltcGxlIGtleSB2YWx1ZSBwYWlycy5cbiAgICogS2V5cyB0YWtlIHRoZSBmb3JtIG9mIGpzIGNvZGUgZGlyZWN0aXZlcyB0aGF0IHRyYXZlcnNlIHRvIHRoZSBkZXNpcmVkIHByb3BlcnR5LlxuICAgKiBWYWx1ZXMgc2hvdWxkIGJlIEpTT04gc2VyaWFsaXphYmxlIG9iamVjdHMuXG4gICAqXG4gICAqIEZvciBleGFtcGxlLCB0aGUgZm9sbG93aW5nIGNvbmZpZzpcbiAgICpcbiAgICogYGBganNvblxuICAgKiByZXdpcmU6IHsgXCJtb2R1bGUudW5rbm93bkNvbnRleHRDcml0aWNhbFwiOiBmYWxzZSB9XG4gICAqIGBgYFxuICAgKlxuICAgKiBXaWxsIHRyYW5zbGF0ZSB0byB0aGUgZm9sbG93aW5nIGBjb25maWctb3ZlcnJpZGVzLmpzYCBmaWxlOlxuICAgKlxuICAgKiBgYGBqc1xuICAgKiBtb2R1bGUuZXhwb3J0cyA9IGZ1bmN0aW9uIG92ZXJyaWRlKGNvbmZpZywgZW52KSB7XG4gICAqICAgY29uZmlnLm1vZHVsZS51bmtub3duQ29udGV4dENyaXRpY2FsID0gZmFsc2U7XG4gICAqIH1cbiAgICogYGBgXG4gICAqXG4gICAqIEBkZWZhdWx0IC0gTm8gcmV3aXJlZCBjb25maWcuXG4gICAqXG4gICAqIEBzZWUgaHR0cHM6Ly93ZWJwYWNrLmpzLm9yZy9jb25maWd1cmF0aW9uL1xuICAgKiBAc2VlIGh0dHBzOi8vZ2l0aHViLmNvbS90aW1hcm5leS9yZWFjdC1hcHAtcmV3aXJlZFxuICAgKi9cbiAgcmVhZG9ubHkgcmV3aXJlPzogeyBba2V5OiBzdHJpbmddOiBhbnkgfTtcbn1cblxuZXhwb3J0IGludGVyZmFjZSBSZWFjdFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9uc1xuICBleHRlbmRzIFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9ucywgUmVhY3RSZXdpcmVPcHRpb25zIHt9XG5cbmV4cG9ydCBpbnRlcmZhY2UgUmVhY3RQcm9qZWN0T3B0aW9uc1xuICBleHRlbmRzIE5vZGVQcm9qZWN0T3B0aW9ucywgUmVhY3RSZXdpcmVPcHRpb25zIHtcbiAgLyoqXG4gICAqIFNvdXJjZSBkaXJlY3RvcnkuXG4gICAqXG4gICAqIEBkZWZhdWx0IFwic3JjXCJcbiAgICovXG4gIHJlYWRvbmx5IHNyY2Rpcj86IHN0cmluZztcbiAgLyoqXG4gICAqIEdlbmVyYXRlIG9uZS10aW1lIHNhbXBsZSBpbiBgc3JjL2AgYW5kIGBwdWJsaWMvYCBpZiB0aGVyZSBhcmUgbm8gZmlsZXMgdGhlcmUuXG4gICAqIEBkZWZhdWx0IHRydWVcbiAgICovXG4gIHJlYWRvbmx5IHNhbXBsZUNvZGU/OiBib29sZWFuO1xufVxuXG4vKipcbiAqIFJlYWN0IHByb2plY3QgdXNpbmcgSmF2YVNjcmlwdC5cbiAqXG4gKiBAcGppZCByZWFjdFxuICovXG5leHBvcnQgY2xhc3MgUmVhY3RQcm9qZWN0IGV4dGVuZHMgTm9kZVByb2plY3Qge1xuICAvKipcbiAgICogVGhlIGRpcmVjdG9yeSBpbiB3aGljaCBzb3VyY2UgZmlsZXMgcmVzaWRlLlxuICAgKiBAZGVmYXVsdCBcInNyY1wiXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc3JjZGlyOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogUmVhY3RQcm9qZWN0T3B0aW9ucykge1xuICAgIHN1cGVyKHtcbiAgICAgIGplc3Q6IGZhbHNlLFxuICAgICAgLi4ub3B0aW9ucyxcbiAgICB9KTtcblxuICAgIHRoaXMuc3JjZGlyID0gb3B0aW9ucy5zcmNkaXIgPz8gXCJzcmNcIjtcblxuICAgIG5ldyBSZWFjdENvbXBvbmVudCh0aGlzLCB7IHR5cGVzY3JpcHQ6IGZhbHNlLCByZXdpcmU6IG9wdGlvbnMucmV3aXJlIH0pO1xuXG4gICAgLy8gZ2VuZXJhdGUgc2FtcGxlIGNvZGUgaW4gYHNyY2AgYW5kIGBwdWJsaWNgIGlmIHRoZXNlIGRpcmVjdG9yaWVzIGFyZSBlbXB0eSBvciBub24tZXhpc3RlbnQuXG4gICAgaWYgKG9wdGlvbnMuc2FtcGxlQ29kZSA/PyB0cnVlKSB7XG4gICAgICBuZXcgUmVhY3RTYW1wbGVDb2RlKHRoaXMsIHtcbiAgICAgICAgZmlsZUV4dDogXCJqc3hcIixcbiAgICAgICAgc3JjZGlyOiB0aGlzLnNyY2RpcixcbiAgICAgIH0pO1xuICAgICAgbmV3IFNhbXBsZURpcih0aGlzLCBcInB1YmxpY1wiLCB7XG4gICAgICAgIHNvdXJjZURpcjogcGF0aC5qb2luKF9fZGlybmFtZSwgXCIuLlwiLCBcIi4uXCIsIFwiYXNzZXRzXCIsIFwid2ViXCIsIFwicmVhY3RcIiksXG4gICAgICB9KTtcbiAgICB9XG4gIH1cbn1cblxuLyoqXG4gKiBSZWFjdCBwcm9qZWN0IHVzaW5nIFR5cGVTY3JpcHQuXG4gKlxuICogQHBqaWQgcmVhY3QtdHNcbiAqL1xuZXhwb3J0IGNsYXNzIFJlYWN0VHlwZVNjcmlwdFByb2plY3QgZXh0ZW5kcyBUeXBlU2NyaXB0QXBwUHJvamVjdCB7XG4gIC8qKlxuICAgKiBUaGUgZGlyZWN0b3J5IGluIHdoaWNoIHNvdXJjZSBmaWxlcyByZXNpZGUuXG4gICAqL1xuICBwdWJsaWMgcmVhZG9ubHkgc3JjZGlyOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3Iob3B0aW9uczogUmVhY3RUeXBlU2NyaXB0UHJvamVjdE9wdGlvbnMpIHtcbiAgICBjb25zdCBkZWZhdWx0T3B0aW9ucyA9IHtcbiAgICAgIHNyY2RpcjogXCJzcmNcIixcbiAgICAgIGVzbGludDogdHJ1ZSxcbiAgICAgIGplc3Q6IGZhbHNlLFxuICAgICAgdHNjb25maWc6IHtcbiAgICAgICAgaW5jbHVkZTogW1wic3JjXCJdLFxuICAgICAgICBjb21waWxlck9wdGlvbnM6IHtcbiAgICAgICAgICB0YXJnZXQ6IFwiZXM1XCIsXG4gICAgICAgICAgbGliOiBbXCJkb21cIiwgXCJkb20uaXRlcmFibGVcIiwgXCJlc25leHRcIl0sXG4gICAgICAgICAgYWxsb3dKczogdHJ1ZSxcbiAgICAgICAgICBza2lwTGliQ2hlY2s6IHRydWUsXG4gICAgICAgICAgZXNNb2R1bGVJbnRlcm9wOiB0cnVlLFxuICAgICAgICAgIGFsbG93U3ludGhldGljRGVmYXVsdEltcG9ydHM6IHRydWUsXG4gICAgICAgICAgc3RyaWN0OiB0cnVlLFxuICAgICAgICAgIGZvcmNlQ29uc2lzdGVudENhc2luZ0luRmlsZU5hbWVzOiB0cnVlLFxuICAgICAgICAgIG5vRmFsbHRocm91Z2hDYXNlc0luU3dpdGNoOiB0cnVlLFxuICAgICAgICAgIG1vZHVsZTogXCJjb21tb25qc1wiLFxuICAgICAgICAgIG1vZHVsZVJlc29sdXRpb246IFR5cGVTY3JpcHRNb2R1bGVSZXNvbHV0aW9uLk5PREUsXG4gICAgICAgICAgcmVzb2x2ZUpzb25Nb2R1bGU6IHRydWUsXG4gICAgICAgICAgaXNvbGF0ZWRNb2R1bGVzOiB0cnVlLFxuICAgICAgICAgIG5vRW1pdDogdHJ1ZSxcbiAgICAgICAgICBqc3g6IFR5cGVTY3JpcHRKc3hNb2RlLlJFQUNUX0pTWCxcbiAgICAgICAgfSxcbiAgICAgIH0sXG4gICAgICB0eXBlc2NyaXB0VmVyc2lvbjogb3B0aW9ucy50eXBlc2NyaXB0VmVyc2lvbiA/PyBcIl40LjAuM1wiLFxuICAgIH07XG5cbiAgICAvLyBuZXZlciBnZW5lcmF0ZSBkZWZhdWx0IFR5cGVTY3JpcHQgc2FtcGxlIGNvZGUsIHNpbmNlIHRoaXMgY2xhc3MgcHJvdmlkZXMgaXRzIG93blxuICAgIHN1cGVyKFxuICAgICAgZGVlcE1lcmdlKFtcbiAgICAgICAgZGVmYXVsdE9wdGlvbnMsXG4gICAgICAgIG9wdGlvbnMsXG4gICAgICAgIHsgc2FtcGxlQ29kZTogZmFsc2UgfSxcbiAgICAgIF0pIGFzIFR5cGVTY3JpcHRQcm9qZWN0T3B0aW9ucyxcbiAgICApO1xuXG4gICAgdGhpcy5zcmNkaXIgPSBvcHRpb25zLnNyY2RpciA/PyBcInNyY1wiO1xuXG4gICAgdGhpcy5lc2xpbnQ/LmFkZFJ1bGVzKHtcbiAgICAgIFwiaW1wb3J0L25vLWV4dHJhbmVvdXMtZGVwZW5kZW5jaWVzXCI6IFtcbiAgICAgICAgXCJlcnJvclwiLFxuICAgICAgICB7XG4gICAgICAgICAgZGV2RGVwZW5kZW5jaWVzOiBbXCIqKi9zcmMvKiovKi50ZXN0LnRzeFwiLCBcIioqL3NyYy9zZXR1cFRlc3RzLnRzXCJdLFxuICAgICAgICAgIG9wdGlvbmFsRGVwZW5kZW5jaWVzOiBmYWxzZSxcbiAgICAgICAgICBwZWVyRGVwZW5kZW5jaWVzOiB0cnVlLFxuICAgICAgICB9LFxuICAgICAgXSxcbiAgICB9KTtcblxuICAgIG5ldyBSZWFjdENvbXBvbmVudCh0aGlzLCB7IHR5cGVzY3JpcHQ6IHRydWUsIHJld2lyZTogb3B0aW9ucy5yZXdpcmUgfSk7XG5cbiAgICAvLyBnZW5lcmF0ZSBzYW1wbGUgY29kZSBpbiBgc3JjYCBhbmQgYHB1YmxpY2AgaWYgdGhlc2UgZGlyZWN0b3JpZXMgYXJlIGVtcHR5IG9yIG5vbi1leGlzdGVudC5cbiAgICBpZiAob3B0aW9ucy5zYW1wbGVDb2RlID8/IHRydWUpIHtcbiAgICAgIG5ldyBSZWFjdFNhbXBsZUNvZGUodGhpcywge1xuICAgICAgICBmaWxlRXh0OiBcInRzeFwiLFxuICAgICAgICBzcmNkaXI6IHRoaXMuc3JjZGlyLFxuICAgICAgfSk7XG4gICAgICBuZXcgU2FtcGxlRGlyKHRoaXMsIFwicHVibGljXCIsIHtcbiAgICAgICAgc291cmNlRGlyOiBwYXRoLmpvaW4oX19kaXJuYW1lLCBcIi4uXCIsIFwiLi5cIiwgXCJhc3NldHNcIiwgXCJ3ZWJcIiwgXCJyZWFjdFwiKSxcbiAgICAgIH0pO1xuICAgIH1cblxuICAgIHRoaXMucGFja2FnZS5hZGRQYWNrYWdlUmVzb2x1dGlvbnMoXG4gICAgICAvLyBodHRwczovL2dpdGh1Yi5jb20vRGVmaW5pdGVseVR5cGVkL0RlZmluaXRlbHlUeXBlZC9pc3N1ZXMvNjIzMDBcbiAgICAgIFwiQHR5cGVzL2V4cHJlc3NANC4xNy4xM1wiLFxuICAgICAgXCJAdHlwZXMvZXhwcmVzcy1zZXJ2ZS1zdGF0aWMtY29yZUA0LjE3LjMwXCIsXG4gICAgKTtcbiAgfVxufVxuXG5leHBvcnQgaW50ZXJmYWNlIFJlYWN0Q29tcG9uZW50T3B0aW9ucyBleHRlbmRzIFJlYWN0UmV3aXJlT3B0aW9ucyB7XG4gIC8qKlxuICAgKiBXaGV0aGVyIHRvIGFwcGx5IG9wdGlvbnMgc3BlY2lmaWMgZm9yIFR5cGVTY3JpcHQgUmVhY3QgcHJvamVjdHMuXG4gICAqXG4gICAqIEBkZWZhdWx0IGZhbHNlXG4gICAqL1xuICByZWFkb25seSB0eXBlc2NyaXB0PzogYm9vbGVhbjtcbn1cblxuZXhwb3J0IGNsYXNzIFJlYWN0Q29tcG9uZW50IGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgcHJpdmF0ZSByZWFkb25seSB0eXBlc2NyaXB0OiBib29sZWFuO1xuXG4gIGNvbnN0cnVjdG9yKHByb2plY3Q6IE5vZGVQcm9qZWN0LCBvcHRpb25zOiBSZWFjdENvbXBvbmVudE9wdGlvbnMpIHtcbiAgICBzdXBlcihwcm9qZWN0KTtcblxuICAgIHRoaXMudHlwZXNjcmlwdCA9IG9wdGlvbnMudHlwZXNjcmlwdCA/PyBmYWxzZTtcblxuICAgIC8vIE5vIGNvbXBpbGUgZm9yIHJlYWN0IGFwcFxuICAgIHByb2plY3QuY29tcGlsZVRhc2sucmVzZXQoKTtcblxuICAgIHByb2plY3QuYWRkRGVwcyhcInJlYWN0XCIsIFwicmVhY3QtZG9tXCIsIFwid2ViLXZpdGFsc1wiKTtcbiAgICBwcm9qZWN0LmFkZERldkRlcHMoXG4gICAgICBcInJlYWN0LXNjcmlwdHNAXjVcIixcbiAgICAgIFwiQHRlc3RpbmctbGlicmFyeS9kb21cIixcbiAgICAgIFwiQHRlc3RpbmctbGlicmFyeS9qZXN0LWRvbVwiLFxuICAgICAgXCJAdGVzdGluZy1saWJyYXJ5L3JlYWN0XCIsXG4gICAgICBcIkB0ZXN0aW5nLWxpYnJhcnkvdXNlci1ldmVudFwiLFxuICAgICk7XG4gICAgaWYgKHRoaXMudHlwZXNjcmlwdCkge1xuICAgICAgcHJvamVjdC5hZGREZXZEZXBzKFwiQHR5cGVzL2plc3RcIiwgXCJAdHlwZXMvcmVhY3RcIiwgXCJAdHlwZXMvcmVhY3QtZG9tXCIpO1xuICAgIH1cblxuICAgIGNvbnN0IHJld2lyZSA9IG9wdGlvbnMucmV3aXJlID8/IGZhbHNlO1xuXG4gICAgaWYgKHJld2lyZSkge1xuICAgICAgY29uc3Qgb3ZlcnJpZGVzUGF0aCA9IFwiLnByb2plbi9yZWFjdC1jb25maWctb3ZlcnJpZGVzLmpzXCI7XG4gICAgICBwcm9qZWN0LmFkZERldkRlcHMoXCJyZWFjdC1hcHAtcmV3aXJlZFwiKTtcbiAgICAgIHByb2plY3QuYWRkRmllbGRzKHsgXCJjb25maWctb3ZlcnJpZGVzLXBhdGhcIjogb3ZlcnJpZGVzUGF0aCB9KTtcblxuICAgICAgY29uc3QgY29uZmlnT3ZlcnJpZGVzID0gbmV3IFNvdXJjZUNvZGUodGhpcy5wcm9qZWN0LCBvdmVycmlkZXNQYXRoKTtcbiAgICAgIGlmICghY29uZmlnT3ZlcnJpZGVzLm1hcmtlcikge1xuICAgICAgICBjb25maWdPdmVycmlkZXMubGluZShgLy8gJHtjb25maWdPdmVycmlkZXMubWFya2VyfWApO1xuICAgICAgfVxuICAgICAgY29uZmlnT3ZlcnJpZGVzLmxpbmUoXCIvKipcIik7XG4gICAgICBjb25maWdPdmVycmlkZXMubGluZShcbiAgICAgICAgXCIgKiBPdmVycmlkZSBDUkEgY29uZmlndXJhdGlvbiB3aXRob3V0IG5lZWRpbmcgdG8gZWplY3QuXCIsXG4gICAgICApO1xuICAgICAgY29uZmlnT3ZlcnJpZGVzLmxpbmUoXCIgKlwiKTtcbiAgICAgIGNvbmZpZ092ZXJyaWRlcy5saW5lKFxuICAgICAgICBcIiAqIEBzZWUgaHR0cHM6Ly93d3cubnBtanMuY29tL3BhY2thZ2UvcmVhY3QtYXBwLXJld2lyZWRcIixcbiAgICAgICk7XG4gICAgICBjb25maWdPdmVycmlkZXMubGluZShcIiAqL1wiKTtcbiAgICAgIGNvbmZpZ092ZXJyaWRlcy5vcGVuKFwibW9kdWxlLmV4cG9ydHMgPSBmdW5jdGlvbiBvdmVycmlkZShjb25maWcsIGVudikge1wiKTtcbiAgICAgIGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHJld2lyZSkpIHtcbiAgICAgICAgY29uZmlnT3ZlcnJpZGVzLmxpbmUoYGNvbmZpZy4ke2tleX0gPSAke0pTT04uc3RyaW5naWZ5KHZhbHVlKX07YCk7XG4gICAgICB9XG4gICAgICBjb25maWdPdmVycmlkZXMubGluZShcInJldHVybiBjb25maWc7XCIpO1xuICAgICAgY29uZmlnT3ZlcnJpZGVzLmNsb3NlKFwifTtcIik7XG4gICAgfVxuXG4gICAgY29uc3QgcmVhY3RTY3JpcHRzID0gcmV3aXJlID8gXCJyZWFjdC1hcHAtcmV3aXJlZFwiIDogXCJyZWFjdC1zY3JpcHRzXCI7XG5cbiAgICAvLyBDcmVhdGUgUmVhY3QgQXBwIENMSSBjb21tYW5kcywgc2VlOiBodHRwczovL2NyZWF0ZS1yZWFjdC1hcHAuZGV2L2RvY3MvYXZhaWxhYmxlLXNjcmlwdHMvXG4gICAgcHJvamVjdC5hZGRUYXNrKFwiZGV2XCIsIHtcbiAgICAgIGRlc2NyaXB0aW9uOiBcIlN0YXJ0cyB0aGUgcmVhY3QgYXBwbGljYXRpb25cIixcbiAgICAgIGV4ZWNBcmdzOiBbcmVhY3RTY3JpcHRzLCBcInN0YXJ0XCJdLFxuICAgIH0pO1xuXG4gICAgcHJvamVjdC5jb21waWxlVGFzay5leGVjQXJncyhbcmVhY3RTY3JpcHRzLCBcImJ1aWxkXCJdKTtcblxuICAgIHByb2plY3QudGVzdFRhc2suZXhlY0FyZ3MoW3JlYWN0U2NyaXB0cywgXCJ0ZXN0XCIsIFwiLS13YXRjaEFsbD1mYWxzZVwiXSk7XG5cbiAgICBjb25zdCB0ZXN0V2F0Y2ggPSBwcm9qZWN0LnRhc2tzLnRyeUZpbmQoXCJ0ZXN0OndhdGNoXCIpO1xuICAgIHRlc3RXYXRjaD8ucmVzZXQoYCR7cmVhY3RTY3JpcHRzfSB0ZXN0YCk7XG5cbiAgICBwcm9qZWN0Lm5wbWlnbm9yZT8uZXhjbHVkZShcIiMgQnVpbGRcIiwgXCIvYnVpbGQvXCIpO1xuICAgIHByb2plY3QuZ2l0aWdub3JlLmV4Y2x1ZGUoXCIjIEJ1aWxkXCIsIFwiL2J1aWxkL1wiKTtcblxuICAgIHByb2plY3QucGFja2FnZS5hZGRGaWVsZChcImVzbGludENvbmZpZ1wiLCB7XG4gICAgICBleHRlbmRzOiBbXCJyZWFjdC1hcHBcIiwgXCJyZWFjdC1hcHAvamVzdFwiXSxcbiAgICB9KTtcblxuICAgIHByb2plY3QucGFja2FnZS5hZGRGaWVsZChcImJyb3dzZXJzbGlzdFwiLCB7XG4gICAgICBwcm9kdWN0aW9uOiBbXCI+MC4yJVwiLCBcIm5vdCBkZWFkXCIsIFwibm90IG9wX21pbmkgYWxsXCJdLFxuICAgICAgZGV2ZWxvcG1lbnQ6IFtcbiAgICAgICAgXCJsYXN0IDEgY2hyb21lIHZlcnNpb25cIixcbiAgICAgICAgXCJsYXN0IDEgZmlyZWZveCB2ZXJzaW9uXCIsXG4gICAgICAgIFwibGFzdCAxIHNhZmFyaSB2ZXJzaW9uXCIsXG4gICAgICBdLFxuICAgIH0pO1xuICB9XG59XG5cbmludGVyZmFjZSBSZWFjdFNhbXBsZUNvZGVPcHRpb25zIHtcbiAgLyoqXG4gICAqIEZpbGUgZXh0ZW5zaW9uIGZvciBzYW1wbGUgamF2YXNjcmlwdCBjb2RlIHRvIGJlIHNhdmVkIGFzLlxuICAgKlxuICAgKiBAZGVmYXVsdCBcImpzeFwiXG4gICAqL1xuICByZWFkb25seSBmaWxlRXh0Pzogc3RyaW5nO1xuXG4gIC8qKlxuICAgKiBUaGUgZGlyZWN0b3J5IGluIHdoaWNoIFJlYWN0IGpzeCBmaWxlcyBhcmUgZGVjbGFyZWQuXG4gICAqL1xuICByZWFkb25seSBzcmNkaXI6IHN0cmluZztcbn1cblxuY2xhc3MgUmVhY3RTYW1wbGVDb2RlIGV4dGVuZHMgQ29tcG9uZW50IHtcbiAgcHJpdmF0ZSByZWFkb25seSBmaWxlRXh0OiBzdHJpbmc7XG4gIHByaXZhdGUgcmVhZG9ubHkgc3JjZGlyOiBzdHJpbmc7XG5cbiAgY29uc3RydWN0b3IocHJvamVjdDogTm9kZVByb2plY3QsIG9wdGlvbnM6IFJlYWN0U2FtcGxlQ29kZU9wdGlvbnMpIHtcbiAgICBzdXBlcihwcm9qZWN0KTtcblxuICAgIHRoaXMuZmlsZUV4dCA9IG9wdGlvbnMuZmlsZUV4dCA/PyBcImpzeFwiO1xuICAgIHRoaXMuc3JjZGlyID0gb3B0aW9ucy5zcmNkaXI7XG5cbiAgICBjb25zdCBsb2dvU3ZnID0gW1xuICAgICAgJzxzdmcgeG1sbnM9XCJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2Z1wiIHZpZXdCb3g9XCIwIDAgODQxLjkgNTk1LjNcIj4nLFxuICAgICAgJyAgICA8ZyBmaWxsPVwiIzYxREFGQlwiPicsXG4gICAgICAnICAgICAgICA8cGF0aCBkPVwiTTY2Ni4zIDI5Ni41YzAtMzIuNS00MC43LTYzLjMtMTAzLjEtODIuNCAxNC40LTYzLjYgOC0xMTQuMi0yMC4yLTEzMC40LTYuNS0zLjgtMTQuMS01LjYtMjIuNC01LjZ2MjIuM2M0LjYgMCA4LjMuOSAxMS40IDIuNiAxMy42IDcuOCAxOS41IDM3LjUgMTQuOSA3NS43LTEuMSA5LjQtMi45IDE5LjMtNS4xIDI5LjQtMTkuNi00LjgtNDEtOC41LTYzLjUtMTAuOS0xMy41LTE4LjUtMjcuNS0zNS4zLTQxLjYtNTAgMzIuNi0zMC4zIDYzLjItNDYuOSA4NC00Ni45Vjc4Yy0yNy41IDAtNjMuNSAxOS42LTk5LjkgNTMuNi0zNi40LTMzLjgtNzIuNC01My4yLTk5LjktNTMuMnYyMi4zYzIwLjcgMCA1MS40IDE2LjUgODQgNDYuNi0xNCAxNC43LTI4IDMxLjQtNDEuMyA0OS45LTIyLjYgMi40LTQ0IDYuMS02My42IDExLTIuMy0xMC00LTE5LjctNS4yLTI5LTQuNy0zOC4yIDEuMS02Ny45IDE0LjYtNzUuOCAzLTEuOCA2LjktMi42IDExLjUtMi42Vjc4LjVjLTguNCAwLTE2IDEuOC0yMi42IDUuNi0yOC4xIDE2LjItMzQuNCA2Ni43LTE5LjkgMTMwLjEtNjIuMiAxOS4yLTEwMi43IDQ5LjktMTAyLjcgODIuMyAwIDMyLjUgNDAuNyA2My4zIDEwMy4xIDgyLjQtMTQuNCA2My42LTggMTE0LjIgMjAuMiAxMzAuNCA2LjUgMy44IDE0LjEgNS42IDIyLjUgNS42IDI3LjUgMCA2My41LTE5LjYgOTkuOS01My42IDM2LjQgMzMuOCA3Mi40IDUzLjIgOTkuOSA1My4yIDguNCAwIDE2LTEuOCAyMi42LTUuNiAyOC4xLTE2LjIgMzQuNC02Ni43IDE5LjktMTMwLjEgNjItMTkuMSAxMDIuNS00OS45IDEwMi41LTgyLjN6bS0xMzAuMi02Ni43Yy0zLjcgMTIuOS04LjMgMjYuMi0xMy41IDM5LjUtNC4xLTgtOC40LTE2LTEzLjEtMjQtNC42LTgtOS41LTE1LjgtMTQuNC0yMy40IDE0LjIgMi4xIDI3LjkgNC43IDQxIDcuOXptLTQ1LjggMTA2LjVjLTcuOCAxMy41LTE1LjggMjYuMy0yNC4xIDM4LjItMTQuOSAxLjMtMzAgMi00NS4yIDItMTUuMSAwLTMwLjItLjctNDUtMS45LTguMy0xMS45LTE2LjQtMjQuNi0yNC4yLTM4LTcuNi0xMy4xLTE0LjUtMjYuNC0yMC44LTM5LjggNi4yLTEzLjQgMTMuMi0yNi44IDIwLjctMzkuOSA3LjgtMTMuNSAxNS44LTI2LjMgMjQuMS0zOC4yIDE0LjktMS4zIDMwLTIgNDUuMi0yIDE1LjEgMCAzMC4yLjcgNDUgMS45IDguMyAxMS45IDE2LjQgMjQuNiAyNC4yIDM4IDcuNiAxMy4xIDE0LjUgMjYuNCAyMC44IDM5LjgtNi4zIDEzLjQtMTMuMiAyNi44LTIwLjcgMzkuOXptMzIuMy0xM2M1LjQgMTMuNCAxMCAyNi44IDEzLjggMzkuOC0xMy4xIDMuMi0yNi45IDUuOS00MS4yIDggNC45LTcuNyA5LjgtMTUuNiAxNC40LTIzLjcgNC42LTggOC45LTE2LjEgMTMtMjQuMXpNNDIxLjIgNDMwYy05LjMtOS42LTE4LjYtMjAuMy0yNy44LTMyIDkgLjQgMTguMi43IDI3LjUuNyA5LjQgMCAxOC43LS4yIDI3LjgtLjctOSAxMS43LTE4LjMgMjIuNC0yNy41IDMyem0tNzQuNC01OC45Yy0xNC4yLTIuMS0yNy45LTQuNy00MS03LjkgMy43LTEyLjkgOC4zLTI2LjIgMTMuNS0zOS41IDQuMSA4IDguNCAxNiAxMy4xIDI0IDQuNyA4IDkuNSAxNS44IDE0LjQgMjMuNHpNNDIwLjcgMTYzYzkuMyA5LjYgMTguNiAyMC4zIDI3LjggMzItOS0uNC0xOC4yLS43LTI3LjUtLjctOS40IDAtMTguNy4yLTI3LjguNyA5LTExLjcgMTguMy0yMi40IDI3LjUtMzJ6bS03NCA1OC45Yy00LjkgNy43LTkuOCAxNS42LTE0LjQgMjMuNy00LjYgOC04LjkgMTYtMTMgMjQtNS40LTEzLjQtMTAtMjYuOC0xMy44LTM5LjggMTMuMS0zLjEgMjYuOS01LjggNDEuMi03Ljl6bS05MC41IDEyNS4yYy0zNS40LTE1LjEtNTguMy0zNC45LTU4LjMtNTAuNiAwLTE1LjcgMjIuOS0zNS42IDU4LjMtNTAuNiA4LjYtMy43IDE4LTcgMjcuNy0xMC4xIDUuNyAxOS42IDEzLjIgNDAgMjIuNSA2MC45LTkuMiAyMC44LTE2LjYgNDEuMS0yMi4yIDYwLjYtOS45LTMuMS0xOS4zLTYuNS0yOC0xMC4yek0zMTAgNDkwYy0xMy42LTcuOC0xOS41LTM3LjUtMTQuOS03NS43IDEuMS05LjQgMi45LTE5LjMgNS4xLTI5LjQgMTkuNiA0LjggNDEgOC41IDYzLjUgMTAuOSAxMy41IDE4LjUgMjcuNSAzNS4zIDQxLjYgNTAtMzIuNiAzMC4zLTYzLjIgNDYuOS04NCA0Ni45LTQuNS0uMS04LjMtMS0xMS4zLTIuN3ptMjM3LjItNzYuMmM0LjcgMzguMi0xLjEgNjcuOS0xNC42IDc1LjgtMyAxLjgtNi45IDIuNi0xMS41IDIuNi0yMC43IDAtNTEuNC0xNi41LTg0LTQ2LjYgMTQtMTQuNyAyOC0zMS40IDQxLjMtNDkuOSAyMi42LTIuNCA0NC02LjEgNjMuNi0xMSAyLjMgMTAuMSA0LjEgMTkuOCA1LjIgMjkuMXptMzguNS02Ni43Yy04LjYgMy43LTE4IDctMjcuNyAxMC4xLTUuNy0xOS42LTEzLjItNDAtMjIuNS02MC45IDkuMi0yMC44IDE2LjYtNDEuMSAyMi4yLTYwLjYgOS45IDMuMSAxOS4zIDYuNSAyOC4xIDEwLjIgMzUuNCAxNS4xIDU4LjMgMzQuOSA1OC4zIDUwLjYtLjEgMTUuNy0yMyAzNS42LTU4LjQgNTAuNnpNMzIwLjggNzguNHpcIi8+JyxcbiAgICAgICcgICAgICAgIDxjaXJjbGUgY3g9XCI0MjAuOVwiIGN5PVwiMjk2LjVcIiByPVwiNDUuN1wiLz4nLFxuICAgICAgJyAgICAgICAgPHBhdGggZD1cIk01MjAuNSA3OC4xelwiLz4nLFxuICAgICAgXCIgICAgPC9nPlwiLFxuICAgICAgXCI8L3N2Zz5cIixcbiAgICAgIFwiXCIsXG4gICAgXTtcblxuICAgIGNvbnN0IGFwcEpzeCA9IFtcbiAgICAgIFwiaW1wb3J0IGxvZ28gZnJvbSAnLi9sb2dvLnN2Zyc7XCIsXG4gICAgICBcImltcG9ydCAnLi9BcHAuY3NzJ1wiLFxuICAgICAgXCJcIixcbiAgICAgIFwiZnVuY3Rpb24gQXBwKCkge1wiLFxuICAgICAgXCIgIHJldHVybiAoXCIsXG4gICAgICAnICAgPGRpdiBjbGFzc05hbWU9XCJBcHBcIj4nLFxuICAgICAgJyAgICAgIDxoZWFkZXIgY2xhc3NOYW1lPVwiQXBwLWhlYWRlclwiPicsXG4gICAgICAnICAgICAgICA8aW1nIHNyYz17bG9nb30gY2xhc3NOYW1lPVwiQXBwLWxvZ29cIiBhbHQ9XCJsb2dvXCIgLz4nLFxuICAgICAgXCIgICAgICAgIDxwPlwiLFxuICAgICAgYCAgICAgICAgICBFZGl0IDxjb2RlPnNyYy9BcHAuJHt0aGlzLmZpbGVFeHR9PC9jb2RlPiBhbmQgc2F2ZSB0byByZWxvYWQuYCxcbiAgICAgIFwiICAgICAgICA8L3A+XCIsXG4gICAgICAnICAgICAgICA8YSBjbGFzc05hbWU9XCJBcHAtbGlua1wiJyxcbiAgICAgICcgICAgICAgICAgaHJlZj1cImh0dHBzOi8vcmVhY3Rqcy5vcmdcIicsXG4gICAgICAnICAgICAgICAgIHRhcmdldD1cIl9ibGFua1wiJyxcbiAgICAgICcgICAgICAgICAgcmVsPVwibm9vcGVuZXIgbm9yZWZlcnJlclwiJyxcbiAgICAgIFwiICAgICAgICA+XCIsXG4gICAgICBcIiAgICAgICAgICBMZWFybiBSZWFjdFwiLFxuICAgICAgXCIgICAgICAgIDwvYT5cIixcbiAgICAgIFwiICAgICAgPC9oZWFkZXI+XCIsXG4gICAgICBcIiAgICA8L2Rpdj5cIixcbiAgICAgIFwiICApO1wiLFxuICAgICAgXCJ9XCIsXG4gICAgICBcIlwiLFxuICAgICAgXCJleHBvcnQgZGVmYXVsdCBBcHA7XCIsXG4gICAgICBcIlwiLFxuICAgIF07XG5cbiAgICBjb25zdCBhcHBDc3MgPSBbXG4gICAgICBcIi5BcHAge1wiLFxuICAgICAgXCIgIHRleHQtYWxpZ246IGNlbnRlcjtcIixcbiAgICAgIFwifVwiLFxuICAgICAgXCJcIixcbiAgICAgIFwiLkFwcC1sb2dvIHtcIixcbiAgICAgIFwiICBoZWlnaHQ6IDQwdm1pbjtcIixcbiAgICAgIFwiICBwb2ludGVyLWV2ZW50czogbm9uZTtcIixcbiAgICAgIFwifVwiLFxuICAgICAgXCJcIixcbiAgICAgIFwiQG1lZGlhIChwcmVmZXJzLXJlZHVjZWQtbW90aW9uOiBuby1wcmVmZXJlbmNlKSB7XCIsXG4gICAgICBcIiAgLkFwcC1sb2dvIHtcIixcbiAgICAgIFwiICAgIGFuaW1hdGlvbjogQXBwLWxvZ28tc3BpbiBpbmZpbml0ZSAyMHMgbGluZWFyO1wiLFxuICAgICAgXCIgIH1cIixcbiAgICAgIFwifVwiLFxuICAgICAgXCJcIixcbiAgICAgIFwiLkFwcC1oZWFkZXIge1wiLFxuICAgICAgXCIgIGJhY2tncm91bmQtY29sb3I6ICMyODJjMzQ7XCIsXG4gICAgICBcIiAgbWluLWhlaWdodDogMTAwdmg7XCIsXG4gICAgICBcIiAgZGlzcGxheTogZmxleDtcIixcbiAgICAgIFwiICBmbGV4LWRpcmVjdGlvbjogY29sdW1uO1wiLFxuICAgICAgXCIgIGFsaWduLWl0ZW1zOiBjZW50ZXI7XCIsXG4gICAgICBcIiAganVzdGlmeS1jb250ZW50OiBjZW50ZXI7XCIsXG4gICAgICBcIiAgZm9udC1zaXplOiBjYWxjKDEwcHggKyAydm1pbik7XCIsXG4gICAgICBcIiAgY29sb3I6IHdoaXRlO1wiLFxuICAgICAgXCJ9XCIsXG4gICAgICBcIlwiLFxuICAgICAgXCIuQXBwLWxpbmsge1wiLFxuICAgICAgXCIgIGNvbG9yOiAjNjFkYWZiO1wiLFxuICAgICAgXCJ9XCIsXG4gICAgICBcIlwiLFxuICAgICAgXCJAa2V5ZnJhbWVzIEFwcC1sb2dvLXNwaW4ge1wiLFxuICAgICAgXCIgIGZyb20ge1wiLFxuICAgICAgXCIgICAgdHJhbnNmb3JtOiByb3RhdGUoMGRlZyk7XCIsXG4gICAgICBcIiAgfVwiLFxuICAgICAgXCIgIHRvIHtcIixcbiAgICAgIFwiICAgIHRyYW5zZm9ybTogcm90YXRlKDM2MGRlZyk7XCIsXG4gICAgICBcIiAgfVwiLFxuICAgICAgXCJ9XCIsXG4gICAgICBcIlwiLFxuICAgIF07XG5cbiAgICBjb25zdCBhcHBUZXN0SnN4ID0gW1xuICAgICAgXCJpbXBvcnQgeyByZW5kZXIsIHNjcmVlbiB9IGZyb20gJ0B0ZXN0aW5nLWxpYnJhcnkvcmVhY3QnO1wiLFxuICAgICAgXCJpbXBvcnQgQXBwIGZyb20gJy4vQXBwJztcIixcbiAgICAgIFwiXCIsXG4gICAgICBcInRlc3QoJ3JlbmRlcnMgbGVhcm4gcmVhY3QgbGluaycsICgpID0+IHtcIixcbiAgICAgIFwiICByZW5kZXIoPEFwcCAvPik7XCIsXG4gICAgICBcIiAgY29uc3QgbGlua0VsZW1lbnQgPSBzY3JlZW4uZ2V0QnlUZXh0KC9sZWFybiByZWFjdC9pKTtcIixcbiAgICAgIFwiICBleHBlY3QobGlua0VsZW1lbnQpLnRvQmVJblRoZURvY3VtZW50KCk7XCIsXG4gICAgICBcIn0pO1wiLFxuICAgICAgXCJcIixcbiAgICBdO1xuXG4gICAgY29uc3QgaW5kZXhKc3ggPSBbXG4gICAgICBcImltcG9ydCBSZWFjdCBmcm9tICdyZWFjdCc7XCIsXG4gICAgICBcImltcG9ydCBSZWFjdERPTSBmcm9tICdyZWFjdC1kb20nO1wiLFxuICAgICAgXCJpbXBvcnQgJy4vaW5kZXguY3NzJztcIixcbiAgICAgIFwiaW1wb3J0IEFwcCBmcm9tICcuL0FwcCc7XCIsXG4gICAgICBcImltcG9ydCByZXBvcnRXZWJWaXRhbHMgZnJvbSAnLi9yZXBvcnRXZWJWaXRhbHMnO1wiLFxuICAgICAgXCJcIixcbiAgICAgIFwiUmVhY3RET00ucmVuZGVyKFwiLFxuICAgICAgXCIgIDxSZWFjdC5TdHJpY3RNb2RlPlwiLFxuICAgICAgXCIgICAgPEFwcCAvPlwiLFxuICAgICAgXCIgIDwvUmVhY3QuU3RyaWN0TW9kZT4sXCIsXG4gICAgICBcIiAgZG9jdW1lbnQuZ2V0RWxlbWVudEJ5SWQoJ3Jvb3QnKVwiLFxuICAgICAgXCIpO1wiLFxuICAgICAgXCJcIixcbiAgICAgIFwiLy8gSWYgeW91IHdhbnQgdG8gc3RhcnQgbWVhc3VyaW5nIHBlcmZvcm1hbmNlIGluIHlvdXIgYXBwLCBwYXNzIGEgZnVuY3Rpb25cIixcbiAgICAgIFwiLy8gdG8gbG9nIHJlc3VsdHMgKGZvciBleGFtcGxlOiByZXBvcnRXZWJWaXRhbHMoY29uc29sZS5sb2cpKVwiLFxuICAgICAgXCIvLyBvciBzZW5kIHRvIGFuIGFuYWx5dGljcyBlbmRwb2ludC4gTGVhcm4gbW9yZTogaHR0cHM6Ly9iaXQubHkvQ1JBLXZpdGFsc1wiLFxuICAgICAgXCJyZXBvcnRXZWJWaXRhbHMoKTtcIixcbiAgICAgIFwiXCIsXG4gICAgXTtcblxuICAgIGNvbnN0IGluZGV4Q3NzID0gW1xuICAgICAgXCJib2R5IHtcIixcbiAgICAgIFwiICBtYXJnaW46IDA7XCIsXG4gICAgICBcIiAgZm9udC1mYW1pbHk6IC1hcHBsZS1zeXN0ZW0sIEJsaW5rTWFjU3lzdGVtRm9udCwgJ1NlZ29lIFVJJywgJ1JvYm90bycsICdPeHlnZW4nLFwiLFxuICAgICAgXCIgICAgJ1VidW50dScsICdDYW50YXJlbGwnLCAnRmlyYSBTYW5zJywgJ0Ryb2lkIFNhbnMnLCAnSGVsdmV0aWNhIE5ldWUnLFwiLFxuICAgICAgXCIgICAgc2Fucy1zZXJpZjtcIixcbiAgICAgIFwiICAtd2Via2l0LWZvbnQtc21vb3RoaW5nOiBhbnRpYWxpYXNlZDtcIixcbiAgICAgIFwiICAtbW96LW9zeC1mb250LXNtb290aGluZzogZ3JheXNjYWxlO1wiLFxuICAgICAgXCJ9XCIsXG4gICAgICBcIlwiLFxuICAgICAgXCJjb2RlIHtcIixcbiAgICAgIFwiICBmb250LWZhbWlseTogc291cmNlLWNvZGUtcHJvLCBNZW5sbywgTW9uYWNvLCBDb25zb2xhcywgJ0NvdXJpZXIgTmV3JyxcIixcbiAgICAgIFwiICAgIG1vbm9zcGFjZTtcIixcbiAgICAgIFwifVwiLFxuICAgICAgXCJcIixcbiAgICBdO1xuXG4gICAgY29uc3QgcmVwb3J0V2ViVml0YWxzSnMgPSBbXG4gICAgICBcImltcG9ydCB7IFJlcG9ydEhhbmRsZXIgfSBmcm9tICd3ZWItdml0YWxzJztcIixcbiAgICAgIFwiXCIsXG4gICAgICBcImNvbnN0IHJlcG9ydFdlYlZpdGFscyA9IChvblBlcmZFbnRyeT86IFJlcG9ydEhhbmRsZXIpID0+IHtcIixcbiAgICAgIFwiICBpZiAob25QZXJmRW50cnkgJiYgb25QZXJmRW50cnkgaW5zdGFuY2VvZiBGdW5jdGlvbikge1wiLFxuICAgICAgXCIgICAgaW1wb3J0KCd3ZWItdml0YWxzJykudGhlbihcIixcbiAgICAgIFwiICAgICAgKHsgZ2V0Q0xTLCBnZXRGSUQsIGdldEZDUCwgZ2V0TENQLCBnZXRUVEZCIH0pID0+IHtcIixcbiAgICAgIFwiICAgICAgICBnZXRDTFMob25QZXJmRW50cnkpO1wiLFxuICAgICAgXCIgICAgICAgIGdldEZJRChvblBlcmZFbnRyeSk7XCIsXG4gICAgICBcIiAgICAgICAgZ2V0RkNQKG9uUGVyZkVudHJ5KTtcIixcbiAgICAgIFwiICAgICAgICBnZXRMQ1Aob25QZXJmRW50cnkpO1wiLFxuICAgICAgXCIgICAgICAgIGdldFRURkIob25QZXJmRW50cnkpO1wiLFxuICAgICAgXCIgICAgICB9LFwiLFxuICAgICAgXCIgICAgICAoKSA9PiB7fVwiLFxuICAgICAgXCIgICAgKTtcIixcbiAgICAgIFwiICB9XCIsXG4gICAgICBcIn07XCIsXG4gICAgICBcIlwiLFxuICAgICAgXCJleHBvcnQgZGVmYXVsdCByZXBvcnRXZWJWaXRhbHM7XCIsXG4gICAgXTtcblxuICAgIGNvbnN0IHNldHVwVGVzdHNKcyA9IFtcbiAgICAgIFwiLy8gamVzdC1kb20gYWRkcyBjdXN0b20gamVzdCBtYXRjaGVycyBmb3IgYXNzZXJ0aW5nIG9uIERPTSBub2Rlcy5cIixcbiAgICAgIFwiLy8gYWxsb3dzIHlvdSB0byBkbyB0aGluZ3MgbGlrZTpcIixcbiAgICAgIFwiLy8gZXhwZWN0KGVsZW1lbnQpLnRvSGF2ZVRleHRDb250ZW50KC9yZWFjdC9pKVwiLFxuICAgICAgXCIvLyBsZWFybiBtb3JlOiBodHRwczovL2dpdGh1Yi5jb20vdGVzdGluZy1saWJyYXJ5L2plc3QtZG9tXCIsXG4gICAgICBcImltcG9ydCAnQHRlc3RpbmctbGlicmFyeS9qZXN0LWRvbSc7XCIsXG4gICAgICBcIlwiLFxuICAgIF07XG5cbiAgICBjb25zdCByZWFjdFR5cGVEZWYgPSBbJy8vLyA8cmVmZXJlbmNlIHR5cGVzPVwicmVhY3Qtc2NyaXB0c1wiIC8+J107XG5cbiAgICAvLyBqcy90cyBub3QganN4L3RzeFxuICAgIGNvbnN0IGZpbGVFeHRXaXRob3V0WCA9IHRoaXMuZmlsZUV4dC5yZXBsYWNlKFwieFwiLCBcIlwiKTtcblxuICAgIG5ldyBTYW1wbGVEaXIocHJvamVjdCwgdGhpcy5zcmNkaXIsIHtcbiAgICAgIGZpbGVzOiB7XG4gICAgICAgIFwicmVhY3QtYXBwLWVudi5kLnRzXCI6IHJlYWN0VHlwZURlZi5qb2luKFwiXFxuXCIpLFxuICAgICAgICBcImxvZ28uc3ZnXCI6IGxvZ29Tdmcuam9pbihcIlxcblwiKSxcbiAgICAgICAgW1wiQXBwLlwiICsgdGhpcy5maWxlRXh0XTogYXBwSnN4LmpvaW4oXCJcXG5cIiksXG4gICAgICAgIFtcIkFwcC50ZXN0LlwiICsgdGhpcy5maWxlRXh0XTogYXBwVGVzdEpzeC5qb2luKFwiXFxuXCIpLFxuICAgICAgICBcIkFwcC5jc3NcIjogYXBwQ3NzLmpvaW4oXCJcXG5cIiksXG4gICAgICAgIFtcImluZGV4LlwiICsgdGhpcy5maWxlRXh0XTogaW5kZXhKc3guam9pbihcIlxcblwiKSxcbiAgICAgICAgXCJpbmRleC5jc3NcIjogaW5kZXhDc3Muam9pbihcIlxcblwiKSxcbiAgICAgICAgW1wicmVwb3J0V2ViVml0YWxzLlwiICsgZmlsZUV4dFdpdGhvdXRYXTogcmVwb3J0V2ViVml0YWxzSnMuam9pbihcIlxcblwiKSxcbiAgICAgICAgW1wic2V0dXBUZXN0cy5cIiArIGZpbGVFeHRXaXRob3V0WF06IHNldHVwVGVzdHNKcy5qb2luKFwiXFxuXCIpLFxuICAgICAgfSxcbiAgICB9KTtcbiAgfVxufVxuIl19