@decohere/create 0.0.1-dev.48 → 0.0.1-dev.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (127) hide show
  1. package/commonjs/src/cli.js +9 -3
  2. package/commonjs/src/scaffold.js +48 -0
  3. package/commonjs/src/templates.js +64 -0
  4. package/es6/src/cli.js +9 -3
  5. package/es6/src/scaffold.js +38 -0
  6. package/es6/src/templates.js +40 -0
  7. package/package.json +3 -8
  8. package/types/src/scaffold.d.ts +4 -0
  9. package/types/src/templates.d.ts +4 -0
  10. package/commonjs/src/domain/prompt.js +0 -64
  11. package/commonjs/src/models/compose.model.js +0 -138
  12. package/commonjs/src/models/config-yaml.model.js +0 -88
  13. package/commonjs/src/models/const.js +0 -31
  14. package/commonjs/src/models/dev-container.model.js +0 -100
  15. package/commonjs/src/models/docker-image.model.js +0 -221
  16. package/commonjs/src/models/env-file.model.js +0 -47
  17. package/commonjs/src/models/gitignore.model.js +0 -31
  18. package/commonjs/src/models/launch-json.model.js +0 -74
  19. package/commonjs/src/models/package-json.model.js +0 -133
  20. package/commonjs/src/models/project.model.js +0 -134
  21. package/commonjs/src/models/source-file.js +0 -6
  22. package/commonjs/src/models/tsconfig.model.js +0 -34
  23. package/commonjs/src/models/vscode-settings.model.js +0 -31
  24. package/commonjs/src/program.js +0 -135
  25. package/commonjs/src/resolve-target-dir.js +0 -19
  26. package/commonjs/src/runner.js +0 -144
  27. package/commonjs/src/services/scaffold.service.js +0 -62
  28. package/commonjs/src/version.js +0 -50
  29. package/commonjs/src/webapi/api-name.js +0 -95
  30. package/commonjs/src/webapi/const.js +0 -50
  31. package/commonjs/src/webapi/create-api.js +0 -285
  32. package/commonjs/src/webapi/features/auth.feature.js +0 -463
  33. package/commonjs/src/webapi/features/auth0-cli.js +0 -406
  34. package/commonjs/src/webapi/features/biome-format.js +0 -49
  35. package/commonjs/src/webapi/features/database.feature.js +0 -273
  36. package/commonjs/src/webapi/features/finalize.feature.js +0 -91
  37. package/commonjs/src/webapi/features/postman.feature.js +0 -319
  38. package/commonjs/src/webapi/models/api-package-json.model.js +0 -63
  39. package/commonjs/src/webapi/models/auth-config.model.js +0 -26
  40. package/commonjs/src/webapi/models/controller-source-file.model.js +0 -188
  41. package/commonjs/src/webapi/models/github-ci.model.js +0 -193
  42. package/commonjs/src/webapi/models/main-source-file.model.js +0 -165
  43. package/commonjs/src/webapi/models/production-dockerfile.model.js +0 -138
  44. package/commonjs/src/webapi/models/sample-files.model.js +0 -60
  45. package/commonjs/src/webapi/models/webapi-image.model.js +0 -22
  46. package/commonjs/src/webapi/postman/hello-openapi.js +0 -175
  47. package/commonjs/src/webapi/postman/local-view.js +0 -184
  48. package/commonjs/src/webapi/postman/openapi-to-postman.js +0 -202
  49. package/es6/src/domain/prompt.js +0 -43
  50. package/es6/src/models/compose.model.js +0 -132
  51. package/es6/src/models/config-yaml.model.js +0 -76
  52. package/es6/src/models/const.js +0 -21
  53. package/es6/src/models/dev-container.model.js +0 -90
  54. package/es6/src/models/docker-image.model.js +0 -185
  55. package/es6/src/models/env-file.model.js +0 -43
  56. package/es6/src/models/gitignore.model.js +0 -21
  57. package/es6/src/models/launch-json.model.js +0 -64
  58. package/es6/src/models/package-json.model.js +0 -129
  59. package/es6/src/models/project.model.js +0 -119
  60. package/es6/src/models/source-file.js +0 -3
  61. package/es6/src/models/tsconfig.model.js +0 -24
  62. package/es6/src/models/vscode-settings.model.js +0 -21
  63. package/es6/src/program.js +0 -76
  64. package/es6/src/resolve-target-dir.js +0 -9
  65. package/es6/src/runner.js +0 -146
  66. package/es6/src/services/scaffold.service.js +0 -52
  67. package/es6/src/version.js +0 -32
  68. package/es6/src/webapi/api-name.js +0 -59
  69. package/es6/src/webapi/const.js +0 -20
  70. package/es6/src/webapi/create-api.js +0 -265
  71. package/es6/src/webapi/features/auth.feature.js +0 -412
  72. package/es6/src/webapi/features/auth0-cli.js +0 -348
  73. package/es6/src/webapi/features/biome-format.js +0 -42
  74. package/es6/src/webapi/features/database.feature.js +0 -263
  75. package/es6/src/webapi/features/finalize.feature.js +0 -81
  76. package/es6/src/webapi/features/postman.feature.js +0 -253
  77. package/es6/src/webapi/models/api-package-json.model.js +0 -58
  78. package/es6/src/webapi/models/auth-config.model.js +0 -22
  79. package/es6/src/webapi/models/controller-source-file.model.js +0 -179
  80. package/es6/src/webapi/models/github-ci.model.js +0 -186
  81. package/es6/src/webapi/models/main-source-file.model.js +0 -161
  82. package/es6/src/webapi/models/production-dockerfile.model.js +0 -126
  83. package/es6/src/webapi/models/sample-files.model.js +0 -42
  84. package/es6/src/webapi/models/webapi-image.model.js +0 -12
  85. package/es6/src/webapi/postman/hello-openapi.js +0 -168
  86. package/es6/src/webapi/postman/local-view.js +0 -169
  87. package/es6/src/webapi/postman/openapi-to-postman.js +0 -179
  88. package/pack-builder-tgz.mjs +0 -177
  89. package/types/src/domain/prompt.d.ts +0 -4
  90. package/types/src/models/compose.model.d.ts +0 -59
  91. package/types/src/models/config-yaml.model.d.ts +0 -27
  92. package/types/src/models/const.d.ts +0 -19
  93. package/types/src/models/dev-container.model.d.ts +0 -33
  94. package/types/src/models/docker-image.model.d.ts +0 -56
  95. package/types/src/models/env-file.model.d.ts +0 -15
  96. package/types/src/models/gitignore.model.d.ts +0 -6
  97. package/types/src/models/launch-json.model.d.ts +0 -7
  98. package/types/src/models/package-json.model.d.ts +0 -32
  99. package/types/src/models/project.model.d.ts +0 -60
  100. package/types/src/models/source-file.d.ts +0 -11
  101. package/types/src/models/tsconfig.model.d.ts +0 -5
  102. package/types/src/models/vscode-settings.model.d.ts +0 -7
  103. package/types/src/program.d.ts +0 -3
  104. package/types/src/resolve-target-dir.d.ts +0 -5
  105. package/types/src/runner.d.ts +0 -15
  106. package/types/src/services/scaffold.service.d.ts +0 -22
  107. package/types/src/version.d.ts +0 -4
  108. package/types/src/webapi/api-name.d.ts +0 -14
  109. package/types/src/webapi/const.d.ts +0 -17
  110. package/types/src/webapi/create-api.d.ts +0 -15
  111. package/types/src/webapi/features/auth.feature.d.ts +0 -10
  112. package/types/src/webapi/features/auth0-cli.d.ts +0 -72
  113. package/types/src/webapi/features/biome-format.d.ts +0 -5
  114. package/types/src/webapi/features/database.feature.d.ts +0 -5
  115. package/types/src/webapi/features/finalize.feature.d.ts +0 -2
  116. package/types/src/webapi/features/postman.feature.d.ts +0 -16
  117. package/types/src/webapi/models/api-package-json.model.d.ts +0 -18
  118. package/types/src/webapi/models/auth-config.model.d.ts +0 -26
  119. package/types/src/webapi/models/controller-source-file.model.d.ts +0 -45
  120. package/types/src/webapi/models/github-ci.model.d.ts +0 -9
  121. package/types/src/webapi/models/main-source-file.model.d.ts +0 -54
  122. package/types/src/webapi/models/production-dockerfile.model.d.ts +0 -20
  123. package/types/src/webapi/models/sample-files.model.d.ts +0 -7
  124. package/types/src/webapi/models/webapi-image.model.d.ts +0 -5
  125. package/types/src/webapi/postman/hello-openapi.d.ts +0 -19
  126. package/types/src/webapi/postman/local-view.d.ts +0 -17
  127. package/types/src/webapi/postman/openapi-to-postman.d.ts +0 -62
@@ -1,285 +0,0 @@
1
- "use strict";
2
- Object.defineProperty(exports, "__esModule", {
3
- value: true
4
- });
5
- function _export(target, all) {
6
- for(var name in all)Object.defineProperty(target, name, {
7
- enumerable: true,
8
- get: Object.getOwnPropertyDescriptor(all, name).get
9
- });
10
- }
11
- _export(exports, {
12
- get WEBAPI_PROJECT_DIR () {
13
- return _const1.WEBAPI_PROJECT_DIR;
14
- },
15
- get WEBAPI_RELEASE_ENTRY () {
16
- return _const1.WEBAPI_RELEASE_ENTRY;
17
- },
18
- get scaffoldApi () {
19
- return scaffoldApi;
20
- }
21
- });
22
- const _nodefs = require("node:fs");
23
- const _nodepath = require("node:path");
24
- const _composemodel = require("../models/compose.model.js");
25
- const _configyamlmodel = require("../models/config-yaml.model.js");
26
- const _const = require("../models/const.js");
27
- const _devcontainermodel = require("../models/dev-container.model.js");
28
- const _envfilemodel = require("../models/env-file.model.js");
29
- const _gitignoremodel = require("../models/gitignore.model.js");
30
- const _launchjsonmodel = require("../models/launch-json.model.js");
31
- const _packagejsonmodel = require("../models/package-json.model.js");
32
- const _projectmodel = require("../models/project.model.js");
33
- const _tsconfigmodel = require("../models/tsconfig.model.js");
34
- const _vscodesettingsmodel = require("../models/vscode-settings.model.js");
35
- const _scaffoldservice = require("../services/scaffold.service.js");
36
- const _apiname = require("./api-name.js");
37
- const _const1 = require("./const.js");
38
- const _authfeature = require("./features/auth.feature.js");
39
- const _databasefeature = require("./features/database.feature.js");
40
- const _finalizefeature = require("./features/finalize.feature.js");
41
- const _postmanfeature = require("./features/postman.feature.js");
42
- const _apipackagejsonmodel = require("./models/api-package-json.model.js");
43
- const _controllersourcefilemodel = require("./models/controller-source-file.model.js");
44
- const _githubcimodel = require("./models/github-ci.model.js");
45
- const _mainsourcefilemodel = require("./models/main-source-file.model.js");
46
- const _productiondockerfilemodel = require("./models/production-dockerfile.model.js");
47
- const _samplefilesmodel = require("./models/sample-files.model.js");
48
- const _webapiimagemodel = require("./models/webapi-image.model.js");
49
- const features = [
50
- _databasefeature.DatabaseFeature,
51
- _authfeature.AuthFeature,
52
- _postmanfeature.PostmanFeature,
53
- _finalizefeature.FinalizeFeature
54
- ];
55
- async function scaffoldApi(cliOptions) {
56
- const targetDir = (0, _nodepath.resolve)(cliOptions.d ?? ".");
57
- const projectName = cliOptions.projectName?.trim() || process.env.DECOHERE_PROJECT_NAME?.trim() || (0, _nodepath.basename)(targetDir);
58
- const names = (0, _apiname.parseApiNames)(cliOptions.names);
59
- const workspace = cliOptions.add ? createAddWorkspace(targetDir, projectName, names) : createWorkspace(targetDir, projectName, names);
60
- await _scaffoldservice.ScaffoldService.scaffold(workspace, {
61
- ...cliOptions,
62
- names
63
- }, features);
64
- }
65
- function createWorkspace(targetDir, projectName, apiNames) {
66
- const monoRepo = new _projectmodel.MonoRepoScaffold();
67
- monoRepo.targetDir = targetDir;
68
- monoRepo.setName(projectName);
69
- const name = monoRepo.name;
70
- const compose = new _composemodel.DockerCompose().setProjectName(name).addNetwork(name, {
71
- name: `samples-${name}`
72
- }).addService("devcontainer", {
73
- build: ".",
74
- volumes: [
75
- // Workspace-local (created by initialize.sh as the host user).
76
- // Do NOT bind ${HOME}/.npm/... — Docker creates missing host paths as root.
77
- "./npm-auth:/home/node/.npm-config",
78
- "webapi-node-modules:/workspace/node_modules"
79
- ],
80
- environment: {
81
- NPM_CONFIG_USERCONFIG: "/home/node/.npm-config/.npmrc"
82
- },
83
- command: "sleep infinity",
84
- networks: [
85
- name
86
- ]
87
- }).addVolume("webapi-node-modules");
88
- const devContainer = new _devcontainermodel.DevContainer().addExtension("biomejs.biome", "vitest.explorer").setInitializeCommand("bash .devcontainer/initialize.sh").setPostStartCommand("bash .devcontainer/post-start.sh").useCompose();
89
- for (const [index, apiName] of apiNames.entries()){
90
- const port = (0, _const1.webapiPort)(index);
91
- devContainer.forwardPort(port);
92
- devContainer.setPortAttributes(port, {
93
- label: apiName === _const1.DEFAULT_WEBAPI_NAME ? "API" : apiName,
94
- requireLocalPort: true
95
- });
96
- }
97
- // Workspace-level models (repo root)
98
- monoRepo.addModel(compose);
99
- monoRepo.addModel(devContainer);
100
- monoRepo.addModel(new _webapiimagemodel.WebapiDevContainer());
101
- monoRepo.addModel(new _productiondockerfilemodel.WebapiProductionDockerfile(apiNames));
102
- monoRepo.addModel(new _githubcimodel.GithubCiWorkflows());
103
- monoRepo.addModel(new _vscodesettingsmodel.VSCodeSettings(name));
104
- monoRepo.addModel(new _launchjsonmodel.LaunchJson(apiNames));
105
- monoRepo.addModel(new _tsconfigmodel.TsConfig());
106
- monoRepo.addModel(new _packagejsonmodel.PackageJson(`${name}.api`, {
107
- apiNames,
108
- workspaceName: name
109
- }));
110
- monoRepo.addModel(new _configyamlmodel.ConfigYaml(_const.WELL_KNOWN_FILES.CONFIG_YAML, "config/config.yaml", ""));
111
- monoRepo.addModel(new _configyamlmodel.ConfigYaml(_const.WELL_KNOWN_FILES.CONFIG_DEV_YAML, "config/config.dev.yaml", ""));
112
- monoRepo.addModel(new _gitignoremodel.Gitignore());
113
- monoRepo.addModel(new _envfilemodel.EnvFile());
114
- // Biome formatter/linter config
115
- monoRepo.addFile({
116
- files: ()=>[
117
- {
118
- filePath: "biome.json",
119
- content: JSON.stringify({
120
- $schema: "https://biomejs.dev/schemas/2.0.0/schema.json",
121
- files: {
122
- includes: [
123
- "**/*.ts",
124
- "**/*.js",
125
- "**/*.json",
126
- "**/*.yml",
127
- "**/*.yaml"
128
- ]
129
- },
130
- assist: {
131
- actions: {
132
- source: {
133
- organizeImports: "on"
134
- }
135
- }
136
- },
137
- vcs: {
138
- enabled: true,
139
- clientKind: "git",
140
- useIgnoreFile: true
141
- },
142
- formatter: {
143
- enabled: true,
144
- formatWithErrors: true,
145
- indentStyle: "tab",
146
- lineWidth: 95
147
- },
148
- javascript: {
149
- parser: {
150
- unsafeParameterDecoratorsEnabled: true
151
- }
152
- },
153
- linter: {
154
- rules: {
155
- style: {
156
- useConsistentMemberAccessibility: {
157
- level: "error",
158
- options: {
159
- accessibility: "explicit"
160
- }
161
- }
162
- }
163
- }
164
- },
165
- overrides: [
166
- {
167
- includes: [
168
- "**/*.json"
169
- ],
170
- formatter: {
171
- indentStyle: "space",
172
- indentWidth: 2
173
- }
174
- }
175
- ]
176
- }, null, 2)
177
- }
178
- ]
179
- });
180
- monoRepo.addFile({
181
- files: ()=>[
182
- {
183
- filePath: ".devcontainer/initialize.sh",
184
- content: [
185
- "#!/usr/bin/env bash",
186
- "# Runs on the host before the container is created (devcontainer initializeCommand).",
187
- "# Creates npm-auth as the host user so the bind mount is not root-owned.",
188
- "# Do not scaffold npm-auth/ from the builder (that runs as root).",
189
- "set -euo pipefail",
190
- "",
191
- 'root="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"',
192
- 'npm_dir="$root/.devcontainer/npm-auth"',
193
- 'if ! mkdir -p "$npm_dir" 2>/dev/null; then',
194
- '\techo "Cannot create $npm_dir (permission denied)." >&2',
195
- '\techo "The scaffold container likely left .devcontainer root-owned. Fix with:" >&2',
196
- '\techo " sudo chown -R \\"$USER:$USER\\" \\"$root\\"" >&2',
197
- "\texit 1",
198
- "fi",
199
- "{",
200
- '\techo "*"',
201
- '\techo "!.gitignore"',
202
- '} >"$npm_dir/.gitignore"',
203
- "",
204
- 'if [[ ! -f "$npm_dir/.npmrc" ]]; then',
205
- '\tif [[ -f "${HOME}/.npmrc" ]]; then',
206
- '\t\tcp -a "${HOME}/.npmrc" "$npm_dir/.npmrc"',
207
- "\tfi",
208
- "fi",
209
- ""
210
- ].join("\n")
211
- },
212
- {
213
- filePath: ".devcontainer/post-start.sh",
214
- content: [
215
- "#!/usr/bin/env bash",
216
- "# Runs on every container start (devcontainer postStartCommand).",
217
- "set -euo pipefail",
218
- "",
219
- 'AUTH_REGISTRY="https://registry.npmjs.org"',
220
- "",
221
- 'if npm whoami --registry "$AUTH_REGISTRY" >/dev/null 2>&1; then',
222
- '\techo "npm: logged in as $(npm whoami --registry "$AUTH_REGISTRY")"',
223
- "\texit 0",
224
- "fi",
225
- "",
226
- "if [[ -t 0 && -t 1 ]]; then",
227
- '\techo "npm: not authenticated — starting login..."',
228
- '\tnpm login --registry "$AUTH_REGISTRY"',
229
- "\texit 0",
230
- "fi",
231
- "",
232
- 'echo "npm: not authenticated. Open a terminal and run: npm login" >&2',
233
- 'echo " (creds persist in .devcontainer/npm-auth/)" >&2',
234
- "exit 1",
235
- ""
236
- ].join("\n")
237
- }
238
- ]
239
- });
240
- for (const apiName of apiNames){
241
- addApiProject(monoRepo, name, apiName);
242
- }
243
- return monoRepo;
244
- }
245
- function createAddWorkspace(targetDir, projectName, apiNames) {
246
- if (!(0, _apiname.isDecohereWorkspace)(targetDir)) {
247
- throw new _apiname.CreateCliError(`Not a Decohere workspace: ${targetDir}. Scaffold one first with \`npx @decohere/create webapi\`.`);
248
- }
249
- const existing = (0, _apiname.listExistingApiNames)(targetDir);
250
- for (const apiName of apiNames){
251
- if (existing.includes(apiName)) {
252
- throw new _apiname.CreateCliError(`API "${apiName}" already exists at ${(0, _const1.webapiProjectDir)(apiName)}.`);
253
- }
254
- }
255
- const monoRepo = new _projectmodel.MonoRepoScaffold();
256
- monoRepo.targetDir = targetDir;
257
- monoRepo.setName(projectName);
258
- const name = monoRepo.name;
259
- const pkg = _packagejsonmodel.PackageJson.fromFile((0, _nodepath.join)(targetDir, "package.json"));
260
- monoRepo.addModel(pkg);
261
- monoRepo.addModel((0, _nodefs.existsSync)((0, _nodepath.join)(targetDir, ".env")) ? _envfilemodel.EnvFile.fromFile((0, _nodepath.join)(targetDir, ".env")) : new _envfilemodel.EnvFile());
262
- monoRepo.addModel((0, _nodefs.existsSync)((0, _nodepath.join)(targetDir, "config/config.yaml")) ? _configyamlmodel.ConfigYaml.fromFile(_const.WELL_KNOWN_FILES.CONFIG_YAML, "config/config.yaml", (0, _nodepath.join)(targetDir, "config/config.yaml")) : new _configyamlmodel.ConfigYaml(_const.WELL_KNOWN_FILES.CONFIG_YAML, "config/config.yaml", ""));
263
- monoRepo.addModel((0, _nodefs.existsSync)((0, _nodepath.join)(targetDir, "config/config.dev.yaml")) ? _configyamlmodel.ConfigYaml.fromFile(_const.WELL_KNOWN_FILES.CONFIG_DEV_YAML, "config/config.dev.yaml", (0, _nodepath.join)(targetDir, "config/config.dev.yaml")) : new _configyamlmodel.ConfigYaml(_const.WELL_KNOWN_FILES.CONFIG_DEV_YAML, "config/config.dev.yaml", ""));
264
- for (const [offset, apiName] of apiNames.entries()){
265
- const port = (0, _const1.webapiPort)(existing.length + offset);
266
- pkg.addScript(`start:${apiName}`, `node ${(0, _const1.webapiReleaseEntry)(apiName)}`);
267
- pkg.addScript(`dev:${apiName}`, `PORT=${port} flux serve --project ${(0, _const1.webapiPackageName)(name, apiName)}`);
268
- addApiProject(monoRepo, name, apiName);
269
- }
270
- monoRepo.addModel(new _productiondockerfilemodel.WebapiProductionDockerfile(apiNames, {
271
- namedOnly: true
272
- }));
273
- return monoRepo;
274
- }
275
- function addApiProject(monoRepo, workspaceName, apiName) {
276
- const apiProject = new _projectmodel.ProjectScaffold((0, _const1.webapiProjectDir)(apiName));
277
- apiProject.addModel(new _apipackagejsonmodel.ApiPackageJson(workspaceName, apiName));
278
- apiProject.addModel(new _mainsourcefilemodel.MainSourceFile(`${workspaceName}.${apiName}`));
279
- apiProject.addModel(new _controllersourcefilemodel.ControllerSourceFile());
280
- apiProject.addFile(new _samplefilesmodel.SampleConfigModel());
281
- apiProject.addFile(new _samplefilesmodel.SampleServiceModel());
282
- monoRepo.addProject(apiProject);
283
- }
284
-
285
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS9zcmMvd2ViYXBpL2NyZWF0ZS1hcGkudHMiXSwic291cmNlc0NvbnRlbnQiOlsiaW1wb3J0IHsgZXhpc3RzU3luYyB9IGZyb20gXCJub2RlOmZzXCI7XG5pbXBvcnQgeyBiYXNlbmFtZSwgam9pbiwgcmVzb2x2ZSB9IGZyb20gXCJub2RlOnBhdGhcIjtcbmltcG9ydCB7IERvY2tlckNvbXBvc2UgfSBmcm9tIFwiLi4vbW9kZWxzL2NvbXBvc2UubW9kZWwuanNcIjtcbmltcG9ydCB7IENvbmZpZ1lhbWwgfSBmcm9tIFwiLi4vbW9kZWxzL2NvbmZpZy15YW1sLm1vZGVsLmpzXCI7XG5pbXBvcnQgeyBXRUxMX0tOT1dOX0ZJTEVTIH0gZnJvbSBcIi4uL21vZGVscy9jb25zdC5qc1wiO1xuaW1wb3J0IHsgRGV2Q29udGFpbmVyIH0gZnJvbSBcIi4uL21vZGVscy9kZXYtY29udGFpbmVyLm1vZGVsLmpzXCI7XG5pbXBvcnQgeyBFbnZGaWxlIH0gZnJvbSBcIi4uL21vZGVscy9lbnYtZmlsZS5tb2RlbC5qc1wiO1xuaW1wb3J0IHsgR2l0aWdub3JlIH0gZnJvbSBcIi4uL21vZGVscy9naXRpZ25vcmUubW9kZWwuanNcIjtcbmltcG9ydCB7IExhdW5jaEpzb24gfSBmcm9tIFwiLi4vbW9kZWxzL2xhdW5jaC1qc29uLm1vZGVsLmpzXCI7XG5pbXBvcnQgeyBQYWNrYWdlSnNvbiB9IGZyb20gXCIuLi9tb2RlbHMvcGFja2FnZS1qc29uLm1vZGVsLmpzXCI7XG5pbXBvcnQgeyBNb25vUmVwb1NjYWZmb2xkLCBQcm9qZWN0U2NhZmZvbGQgfSBmcm9tIFwiLi4vbW9kZWxzL3Byb2plY3QubW9kZWwuanNcIjtcbmltcG9ydCB7IFRzQ29uZmlnIH0gZnJvbSBcIi4uL21vZGVscy90c2NvbmZpZy5tb2RlbC5qc1wiO1xuaW1wb3J0IHsgVlNDb2RlU2V0dGluZ3MgfSBmcm9tIFwiLi4vbW9kZWxzL3ZzY29kZS1zZXR0aW5ncy5tb2RlbC5qc1wiO1xuaW1wb3J0IHsgU2NhZmZvbGRTZXJ2aWNlIH0gZnJvbSBcIi4uL3NlcnZpY2VzL3NjYWZmb2xkLnNlcnZpY2UuanNcIjtcbmltcG9ydCB7XG5cdENyZWF0ZUNsaUVycm9yLFxuXHRpc0RlY29oZXJlV29ya3NwYWNlLFxuXHRsaXN0RXhpc3RpbmdBcGlOYW1lcyxcblx0cGFyc2VBcGlOYW1lcyxcbn0gZnJvbSBcIi4vYXBpLW5hbWUuanNcIjtcbmltcG9ydCB7XG5cdERFRkFVTFRfV0VCQVBJX05BTUUsXG5cdHdlYmFwaVBhY2thZ2VOYW1lLFxuXHR3ZWJhcGlQb3J0LFxuXHR3ZWJhcGlQcm9qZWN0RGlyLFxuXHR3ZWJhcGlSZWxlYXNlRW50cnksXG59IGZyb20gXCIuL2NvbnN0LmpzXCI7XG5pbXBvcnQgeyBBdXRoRmVhdHVyZSB9IGZyb20gXCIuL2ZlYXR1cmVzL2F1dGguZmVhdHVyZS5qc1wiO1xuaW1wb3J0IHsgRGF0YWJhc2VGZWF0dXJlIH0gZnJvbSBcIi4vZmVhdHVyZXMvZGF0YWJhc2UuZmVhdHVyZS5qc1wiO1xuaW1wb3J0IHsgRmluYWxpemVGZWF0dXJlIH0gZnJvbSBcIi4vZmVhdHVyZXMvZmluYWxpemUuZmVhdHVyZS5qc1wiO1xuaW1wb3J0IHsgUG9zdG1hbkZlYXR1cmUgfSBmcm9tIFwiLi9mZWF0dXJlcy9wb3N0bWFuLmZlYXR1cmUuanNcIjtcbmltcG9ydCB7IEFwaVBhY2thZ2VKc29uIH0gZnJvbSBcIi4vbW9kZWxzL2FwaS1wYWNrYWdlLWpzb24ubW9kZWwuanNcIjtcbmltcG9ydCB7IENvbnRyb2xsZXJTb3VyY2VGaWxlIH0gZnJvbSBcIi4vbW9kZWxzL2NvbnRyb2xsZXItc291cmNlLWZpbGUubW9kZWwuanNcIjtcbmltcG9ydCB7IEdpdGh1YkNpV29ya2Zsb3dzIH0gZnJvbSBcIi4vbW9kZWxzL2dpdGh1Yi1jaS5tb2RlbC5qc1wiO1xuaW1wb3J0IHsgTWFpblNvdXJjZUZpbGUgfSBmcm9tIFwiLi9tb2RlbHMvbWFpbi1zb3VyY2UtZmlsZS5tb2RlbC5qc1wiO1xuaW1wb3J0IHsgV2ViYXBpUHJvZHVjdGlvbkRvY2tlcmZpbGUgfSBmcm9tIFwiLi9tb2RlbHMvcHJvZHVjdGlvbi1kb2NrZXJmaWxlLm1vZGVsLmpzXCI7XG5pbXBvcnQgeyBTYW1wbGVDb25maWdNb2RlbCwgU2FtcGxlU2VydmljZU1vZGVsIH0gZnJvbSBcIi4vbW9kZWxzL3NhbXBsZS1maWxlcy5tb2RlbC5qc1wiO1xuaW1wb3J0IHsgV2ViYXBpRGV2Q29udGFpbmVyIH0gZnJvbSBcIi4vbW9kZWxzL3dlYmFwaS1pbWFnZS5tb2RlbC5qc1wiO1xuXG5leHBvcnQgeyBXRUJBUElfUFJPSkVDVF9ESVIsIFdFQkFQSV9SRUxFQVNFX0VOVFJZIH0gZnJvbSBcIi4vY29uc3QuanNcIjtcblxuZXhwb3J0IHR5cGUgQXBpT3B0aW9ucyA9IHtcblx0ZD86IHN0cmluZztcblx0LyoqIEhvc3QgcHJvamVjdCBuYW1lIChkaXJlY3RvcnkgYmFzZW5hbWUpLiBSZXF1aXJlZCB3aGVuIHNjYWZmb2xkaW5nIGludG8gYC93b3Jrc3BhY2VgLiAqL1xuXHRwcm9qZWN0TmFtZT86IHN0cmluZztcblx0LyoqIEFQSSBzbHVncyB1bmRlciBgcHJvamVjdHMvYC4gRGVmYXVsdCBgW1wiYXBpXCJdYC4gUmVwZWF0YWJsZSBgLS1uYW1lYC4gKi9cblx0bmFtZXM/OiBzdHJpbmdbXTtcblx0LyoqIEFkZCBBUElzIHRvIGFuIGV4aXN0aW5nIERlY29oZXJlIHdvcmtzcGFjZSBpbnN0ZWFkIG9mIGNyZWF0aW5nIGEgbmV3IG9uZS4gKi9cblx0YWRkPzogYm9vbGVhbjtcblx0YXV0aFByb3ZpZGVyPzogXCJhdXRoMFwiIHwgXCJub25lXCI7XG5cdGRhdGFiYXNlUHJvdmlkZXI/OiBcIm5vbmVcIiB8IFwicG9zdGdyZXMvdHlwZW9ybVwiO1xuXHRwb3N0bWFuUHJvdmlkZXI/OiBcImFwaVwiIHwgXCJsb2NhbFwiIHwgXCJub25lXCI7XG5cdGluc3RhbGxEZXBlbmRlbmNpZXM/OiBcInllc1wiIHwgXCJub1wiO1xufTtcblxuY29uc3QgZmVhdHVyZXMgPSBbRGF0YWJhc2VGZWF0dXJlLCBBdXRoRmVhdHVyZSwgUG9zdG1hbkZlYXR1cmUsIEZpbmFsaXplRmVhdHVyZV07XG5cbmV4cG9ydCBhc3luYyBmdW5jdGlvbiBzY2FmZm9sZEFwaShjbGlPcHRpb25zOiBBcGlPcHRpb25zKSB7XG5cdGNvbnN0IHRhcmdldERpciA9IHJlc29sdmUoY2xpT3B0aW9ucy5kID8/IFwiLlwiKTtcblx0Y29uc3QgcHJvamVjdE5hbWUgPVxuXHRcdGNsaU9wdGlvbnMucHJvamVjdE5hbWU/LnRyaW0oKSB8fFxuXHRcdHByb2Nlc3MuZW52LkRFQ09IRVJFX1BST0pFQ1RfTkFNRT8udHJpbSgpIHx8XG5cdFx0YmFzZW5hbWUodGFyZ2V0RGlyKTtcblx0Y29uc3QgbmFtZXMgPSBwYXJzZUFwaU5hbWVzKGNsaU9wdGlvbnMubmFtZXMpO1xuXHRjb25zdCB3b3Jrc3BhY2UgPSBjbGlPcHRpb25zLmFkZFxuXHRcdD8gY3JlYXRlQWRkV29ya3NwYWNlKHRhcmdldERpciwgcHJvamVjdE5hbWUsIG5hbWVzKVxuXHRcdDogY3JlYXRlV29ya3NwYWNlKHRhcmdldERpciwgcHJvamVjdE5hbWUsIG5hbWVzKTtcblx0YXdhaXQgU2NhZmZvbGRTZXJ2aWNlLnNjYWZmb2xkKHdvcmtzcGFjZSwgeyAuLi5jbGlPcHRpb25zLCBuYW1lcyB9LCBmZWF0dXJlcyk7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZVdvcmtzcGFjZShcblx0dGFyZ2V0RGlyOiBzdHJpbmcsXG5cdHByb2plY3ROYW1lOiBzdHJpbmcsXG5cdGFwaU5hbWVzOiByZWFkb25seSBzdHJpbmdbXSxcbik6IE1vbm9SZXBvU2NhZmZvbGQge1xuXHRjb25zdCBtb25vUmVwbyA9IG5ldyBNb25vUmVwb1NjYWZmb2xkKCk7XG5cdG1vbm9SZXBvLnRhcmdldERpciA9IHRhcmdldERpcjtcblx0bW9ub1JlcG8uc2V0TmFtZShwcm9qZWN0TmFtZSk7XG5cdGNvbnN0IG5hbWUgPSBtb25vUmVwby5uYW1lO1xuXG5cdGNvbnN0IGNvbXBvc2UgPSBuZXcgRG9ja2VyQ29tcG9zZSgpXG5cdFx0LnNldFByb2plY3ROYW1lKG5hbWUpXG5cdFx0LmFkZE5ldHdvcmsobmFtZSwgeyBuYW1lOiBgc2FtcGxlcy0ke25hbWV9YCB9KVxuXHRcdC5hZGRTZXJ2aWNlKFwiZGV2Y29udGFpbmVyXCIsIHtcblx0XHRcdGJ1aWxkOiBcIi5cIixcblx0XHRcdHZvbHVtZXM6IFtcblx0XHRcdFx0Ly8gV29ya3NwYWNlLWxvY2FsIChjcmVhdGVkIGJ5IGluaXRpYWxpemUuc2ggYXMgdGhlIGhvc3QgdXNlcikuXG5cdFx0XHRcdC8vIERvIE5PVCBiaW5kICR7SE9NRX0vLm5wbS8uLi4g4oCUIERvY2tlciBjcmVhdGVzIG1pc3NpbmcgaG9zdCBwYXRocyBhcyByb290LlxuXHRcdFx0XHRcIi4vbnBtLWF1dGg6L2hvbWUvbm9kZS8ubnBtLWNvbmZpZ1wiLFxuXHRcdFx0XHRcIndlYmFwaS1ub2RlLW1vZHVsZXM6L3dvcmtzcGFjZS9ub2RlX21vZHVsZXNcIixcblx0XHRcdF0sXG5cdFx0XHRlbnZpcm9ubWVudDogeyBOUE1fQ09ORklHX1VTRVJDT05GSUc6IFwiL2hvbWUvbm9kZS8ubnBtLWNvbmZpZy8ubnBtcmNcIiB9LFxuXHRcdFx0Y29tbWFuZDogXCJzbGVlcCBpbmZpbml0eVwiLFxuXHRcdFx0bmV0d29ya3M6IFtuYW1lXSxcblx0XHR9KVxuXHRcdC5hZGRWb2x1bWUoXCJ3ZWJhcGktbm9kZS1tb2R1bGVzXCIpO1xuXG5cdGNvbnN0IGRldkNvbnRhaW5lciA9IG5ldyBEZXZDb250YWluZXIoKVxuXHRcdC5hZGRFeHRlbnNpb24oXCJiaW9tZWpzLmJpb21lXCIsIFwidml0ZXN0LmV4cGxvcmVyXCIpXG5cdFx0LnNldEluaXRpYWxpemVDb21tYW5kKFwiYmFzaCAuZGV2Y29udGFpbmVyL2luaXRpYWxpemUuc2hcIilcblx0XHQuc2V0UG9zdFN0YXJ0Q29tbWFuZChcImJhc2ggLmRldmNvbnRhaW5lci9wb3N0LXN0YXJ0LnNoXCIpXG5cdFx0LnVzZUNvbXBvc2UoKTtcblxuXHRmb3IgKGNvbnN0IFtpbmRleCwgYXBpTmFtZV0gb2YgYXBpTmFtZXMuZW50cmllcygpKSB7XG5cdFx0Y29uc3QgcG9ydCA9IHdlYmFwaVBvcnQoaW5kZXgpO1xuXHRcdGRldkNvbnRhaW5lci5mb3J3YXJkUG9ydChwb3J0KTtcblx0XHRkZXZDb250YWluZXIuc2V0UG9ydEF0dHJpYnV0ZXMocG9ydCwge1xuXHRcdFx0bGFiZWw6IGFwaU5hbWUgPT09IERFRkFVTFRfV0VCQVBJX05BTUUgPyBcIkFQSVwiIDogYXBpTmFtZSxcblx0XHRcdHJlcXVpcmVMb2NhbFBvcnQ6IHRydWUsXG5cdFx0fSk7XG5cdH1cblxuXHQvLyBXb3Jrc3BhY2UtbGV2ZWwgbW9kZWxzIChyZXBvIHJvb3QpXG5cdG1vbm9SZXBvLmFkZE1vZGVsKGNvbXBvc2UpO1xuXHRtb25vUmVwby5hZGRNb2RlbChkZXZDb250YWluZXIpO1xuXHRtb25vUmVwby5hZGRNb2RlbChuZXcgV2ViYXBpRGV2Q29udGFpbmVyKCkpO1xuXHRtb25vUmVwby5hZGRNb2RlbChuZXcgV2ViYXBpUHJvZHVjdGlvbkRvY2tlcmZpbGUoYXBpTmFtZXMpKTtcblx0bW9ub1JlcG8uYWRkTW9kZWwobmV3IEdpdGh1YkNpV29ya2Zsb3dzKCkpO1xuXHRtb25vUmVwby5hZGRNb2RlbChuZXcgVlNDb2RlU2V0dGluZ3MobmFtZSkpO1xuXHRtb25vUmVwby5hZGRNb2RlbChuZXcgTGF1bmNoSnNvbihhcGlOYW1lcykpO1xuXHRtb25vUmVwby5hZGRNb2RlbChuZXcgVHNDb25maWcoKSk7XG5cdG1vbm9SZXBvLmFkZE1vZGVsKG5ldyBQYWNrYWdlSnNvbihgJHtuYW1lfS5hcGlgLCB7IGFwaU5hbWVzLCB3b3Jrc3BhY2VOYW1lOiBuYW1lIH0pKTtcblx0bW9ub1JlcG8uYWRkTW9kZWwobmV3IENvbmZpZ1lhbWwoV0VMTF9LTk9XTl9GSUxFUy5DT05GSUdfWUFNTCwgXCJjb25maWcvY29uZmlnLnlhbWxcIiwgXCJcIikpO1xuXHRtb25vUmVwby5hZGRNb2RlbChcblx0XHRuZXcgQ29uZmlnWWFtbChXRUxMX0tOT1dOX0ZJTEVTLkNPTkZJR19ERVZfWUFNTCwgXCJjb25maWcvY29uZmlnLmRldi55YW1sXCIsIFwiXCIpLFxuXHQpO1xuXHRtb25vUmVwby5hZGRNb2RlbChuZXcgR2l0aWdub3JlKCkpO1xuXHRtb25vUmVwby5hZGRNb2RlbChuZXcgRW52RmlsZSgpKTtcblxuXHQvLyBCaW9tZSBmb3JtYXR0ZXIvbGludGVyIGNvbmZpZ1xuXHRtb25vUmVwby5hZGRGaWxlKHtcblx0XHRmaWxlczogKCkgPT4gW1xuXHRcdFx0e1xuXHRcdFx0XHRmaWxlUGF0aDogXCJiaW9tZS5qc29uXCIsXG5cdFx0XHRcdGNvbnRlbnQ6IEpTT04uc3RyaW5naWZ5KFxuXHRcdFx0XHRcdHtcblx0XHRcdFx0XHRcdCRzY2hlbWE6IFwiaHR0cHM6Ly9iaW9tZWpzLmRldi9zY2hlbWFzLzIuMC4wL3NjaGVtYS5qc29uXCIsXG5cdFx0XHRcdFx0XHRmaWxlczoge1xuXHRcdFx0XHRcdFx0XHRpbmNsdWRlczogW1wiKiovKi50c1wiLCBcIioqLyouanNcIiwgXCIqKi8qLmpzb25cIiwgXCIqKi8qLnltbFwiLCBcIioqLyoueWFtbFwiXSxcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRhc3Npc3Q6IHsgYWN0aW9uczogeyBzb3VyY2U6IHsgb3JnYW5pemVJbXBvcnRzOiBcIm9uXCIgfSB9IH0sXG5cdFx0XHRcdFx0XHR2Y3M6IHsgZW5hYmxlZDogdHJ1ZSwgY2xpZW50S2luZDogXCJnaXRcIiwgdXNlSWdub3JlRmlsZTogdHJ1ZSB9LFxuXHRcdFx0XHRcdFx0Zm9ybWF0dGVyOiB7XG5cdFx0XHRcdFx0XHRcdGVuYWJsZWQ6IHRydWUsXG5cdFx0XHRcdFx0XHRcdGZvcm1hdFdpdGhFcnJvcnM6IHRydWUsXG5cdFx0XHRcdFx0XHRcdGluZGVudFN0eWxlOiBcInRhYlwiLFxuXHRcdFx0XHRcdFx0XHRsaW5lV2lkdGg6IDk1LFxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdGphdmFzY3JpcHQ6IHsgcGFyc2VyOiB7IHVuc2FmZVBhcmFtZXRlckRlY29yYXRvcnNFbmFibGVkOiB0cnVlIH0gfSxcblx0XHRcdFx0XHRcdGxpbnRlcjoge1xuXHRcdFx0XHRcdFx0XHRydWxlczoge1xuXHRcdFx0XHRcdFx0XHRcdHN0eWxlOiB7XG5cdFx0XHRcdFx0XHRcdFx0XHR1c2VDb25zaXN0ZW50TWVtYmVyQWNjZXNzaWJpbGl0eToge1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRsZXZlbDogXCJlcnJvclwiLFxuXHRcdFx0XHRcdFx0XHRcdFx0XHRvcHRpb25zOiB7IGFjY2Vzc2liaWxpdHk6IFwiZXhwbGljaXRcIiB9LFxuXHRcdFx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdG92ZXJyaWRlczogW1xuXHRcdFx0XHRcdFx0XHR7XG5cdFx0XHRcdFx0XHRcdFx0aW5jbHVkZXM6IFtcIioqLyouanNvblwiXSxcblx0XHRcdFx0XHRcdFx0XHRmb3JtYXR0ZXI6IHsgaW5kZW50U3R5bGU6IFwic3BhY2VcIiwgaW5kZW50V2lkdGg6IDIgfSxcblx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdF0sXG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRudWxsLFxuXHRcdFx0XHRcdDIsXG5cdFx0XHRcdCksXG5cdFx0XHR9LFxuXHRcdF0sXG5cdH0pO1xuXG5cdG1vbm9SZXBvLmFkZEZpbGUoe1xuXHRcdGZpbGVzOiAoKSA9PiBbXG5cdFx0XHR7XG5cdFx0XHRcdGZpbGVQYXRoOiBcIi5kZXZjb250YWluZXIvaW5pdGlhbGl6ZS5zaFwiLFxuXHRcdFx0XHRjb250ZW50OiBbXG5cdFx0XHRcdFx0XCIjIS91c3IvYmluL2VudiBiYXNoXCIsXG5cdFx0XHRcdFx0XCIjIFJ1bnMgb24gdGhlIGhvc3QgYmVmb3JlIHRoZSBjb250YWluZXIgaXMgY3JlYXRlZCAoZGV2Y29udGFpbmVyIGluaXRpYWxpemVDb21tYW5kKS5cIixcblx0XHRcdFx0XHRcIiMgQ3JlYXRlcyBucG0tYXV0aCBhcyB0aGUgaG9zdCB1c2VyIHNvIHRoZSBiaW5kIG1vdW50IGlzIG5vdCByb290LW93bmVkLlwiLFxuXHRcdFx0XHRcdFwiIyBEbyBub3Qgc2NhZmZvbGQgbnBtLWF1dGgvIGZyb20gdGhlIGJ1aWxkZXIgKHRoYXQgcnVucyBhcyByb290KS5cIixcblx0XHRcdFx0XHRcInNldCAtZXVvIHBpcGVmYWlsXCIsXG5cdFx0XHRcdFx0XCJcIixcblx0XHRcdFx0XHQncm9vdD1cIiQoY2QgXCIkKGRpcm5hbWUgXCIke0JBU0hfU09VUkNFWzBdfVwiKS8uLlwiICYmIHB3ZClcIicsXG5cdFx0XHRcdFx0J25wbV9kaXI9XCIkcm9vdC8uZGV2Y29udGFpbmVyL25wbS1hdXRoXCInLFxuXHRcdFx0XHRcdCdpZiAhIG1rZGlyIC1wIFwiJG5wbV9kaXJcIiAyPi9kZXYvbnVsbDsgdGhlbicsXG5cdFx0XHRcdFx0J1xcdGVjaG8gXCJDYW5ub3QgY3JlYXRlICRucG1fZGlyIChwZXJtaXNzaW9uIGRlbmllZCkuXCIgPiYyJyxcblx0XHRcdFx0XHQnXFx0ZWNobyBcIlRoZSBzY2FmZm9sZCBjb250YWluZXIgbGlrZWx5IGxlZnQgLmRldmNvbnRhaW5lciByb290LW93bmVkLiBGaXggd2l0aDpcIiA+JjInLFxuXHRcdFx0XHRcdCdcXHRlY2hvIFwiICBzdWRvIGNob3duIC1SIFxcXFxcIiRVU0VSOiRVU0VSXFxcXFwiIFxcXFxcIiRyb290XFxcXFwiXCIgPiYyJyxcblx0XHRcdFx0XHRcIlxcdGV4aXQgMVwiLFxuXHRcdFx0XHRcdFwiZmlcIixcblx0XHRcdFx0XHRcIntcIixcblx0XHRcdFx0XHQnXFx0ZWNobyBcIipcIicsXG5cdFx0XHRcdFx0J1xcdGVjaG8gXCIhLmdpdGlnbm9yZVwiJyxcblx0XHRcdFx0XHQnfSA+XCIkbnBtX2Rpci8uZ2l0aWdub3JlXCInLFxuXHRcdFx0XHRcdFwiXCIsXG5cdFx0XHRcdFx0J2lmIFtbICEgLWYgXCIkbnBtX2Rpci8ubnBtcmNcIiBdXTsgdGhlbicsXG5cdFx0XHRcdFx0J1xcdGlmIFtbIC1mIFwiJHtIT01FfS8ubnBtcmNcIiBdXTsgdGhlbicsXG5cdFx0XHRcdFx0J1xcdFxcdGNwIC1hIFwiJHtIT01FfS8ubnBtcmNcIiBcIiRucG1fZGlyLy5ucG1yY1wiJyxcblx0XHRcdFx0XHRcIlxcdGZpXCIsXG5cdFx0XHRcdFx0XCJmaVwiLFxuXHRcdFx0XHRcdFwiXCIsXG5cdFx0XHRcdF0uam9pbihcIlxcblwiKSxcblx0XHRcdH0sXG5cdFx0XHR7XG5cdFx0XHRcdGZpbGVQYXRoOiBcIi5kZXZjb250YWluZXIvcG9zdC1zdGFydC5zaFwiLFxuXHRcdFx0XHRjb250ZW50OiBbXG5cdFx0XHRcdFx0XCIjIS91c3IvYmluL2VudiBiYXNoXCIsXG5cdFx0XHRcdFx0XCIjIFJ1bnMgb24gZXZlcnkgY29udGFpbmVyIHN0YXJ0IChkZXZjb250YWluZXIgcG9zdFN0YXJ0Q29tbWFuZCkuXCIsXG5cdFx0XHRcdFx0XCJzZXQgLWV1byBwaXBlZmFpbFwiLFxuXHRcdFx0XHRcdFwiXCIsXG5cdFx0XHRcdFx0J0FVVEhfUkVHSVNUUlk9XCJodHRwczovL3JlZ2lzdHJ5Lm5wbWpzLm9yZ1wiJyxcblx0XHRcdFx0XHRcIlwiLFxuXHRcdFx0XHRcdCdpZiBucG0gd2hvYW1pIC0tcmVnaXN0cnkgXCIkQVVUSF9SRUdJU1RSWVwiID4vZGV2L251bGwgMj4mMTsgdGhlbicsXG5cdFx0XHRcdFx0J1xcdGVjaG8gXCJucG06IGxvZ2dlZCBpbiBhcyAkKG5wbSB3aG9hbWkgLS1yZWdpc3RyeSBcIiRBVVRIX1JFR0lTVFJZXCIpXCInLFxuXHRcdFx0XHRcdFwiXFx0ZXhpdCAwXCIsXG5cdFx0XHRcdFx0XCJmaVwiLFxuXHRcdFx0XHRcdFwiXCIsXG5cdFx0XHRcdFx0XCJpZiBbWyAtdCAwICYmIC10IDEgXV07IHRoZW5cIixcblx0XHRcdFx0XHQnXFx0ZWNobyBcIm5wbTogbm90IGF1dGhlbnRpY2F0ZWQg4oCUIHN0YXJ0aW5nIGxvZ2luLi4uXCInLFxuXHRcdFx0XHRcdCdcXHRucG0gbG9naW4gLS1yZWdpc3RyeSBcIiRBVVRIX1JFR0lTVFJZXCInLFxuXHRcdFx0XHRcdFwiXFx0ZXhpdCAwXCIsXG5cdFx0XHRcdFx0XCJmaVwiLFxuXHRcdFx0XHRcdFwiXCIsXG5cdFx0XHRcdFx0J2VjaG8gXCJucG06IG5vdCBhdXRoZW50aWNhdGVkLiBPcGVuIGEgdGVybWluYWwgYW5kIHJ1bjogbnBtIGxvZ2luXCIgPiYyJyxcblx0XHRcdFx0XHQnZWNobyBcIiAgICAoY3JlZHMgcGVyc2lzdCBpbiAuZGV2Y29udGFpbmVyL25wbS1hdXRoLylcIiA+JjInLFxuXHRcdFx0XHRcdFwiZXhpdCAxXCIsXG5cdFx0XHRcdFx0XCJcIixcblx0XHRcdFx0XS5qb2luKFwiXFxuXCIpLFxuXHRcdFx0fSxcblx0XHRdLFxuXHR9KTtcblxuXHRmb3IgKGNvbnN0IGFwaU5hbWUgb2YgYXBpTmFtZXMpIHtcblx0XHRhZGRBcGlQcm9qZWN0KG1vbm9SZXBvLCBuYW1lLCBhcGlOYW1lKTtcblx0fVxuXG5cdHJldHVybiBtb25vUmVwbztcbn1cblxuZnVuY3Rpb24gY3JlYXRlQWRkV29ya3NwYWNlKFxuXHR0YXJnZXREaXI6IHN0cmluZyxcblx0cHJvamVjdE5hbWU6IHN0cmluZyxcblx0YXBpTmFtZXM6IHJlYWRvbmx5IHN0cmluZ1tdLFxuKTogTW9ub1JlcG9TY2FmZm9sZCB7XG5cdGlmICghaXNEZWNvaGVyZVdvcmtzcGFjZSh0YXJnZXREaXIpKSB7XG5cdFx0dGhyb3cgbmV3IENyZWF0ZUNsaUVycm9yKFxuXHRcdFx0YE5vdCBhIERlY29oZXJlIHdvcmtzcGFjZTogJHt0YXJnZXREaXJ9LiBTY2FmZm9sZCBvbmUgZmlyc3Qgd2l0aCBcXGBucHggQGRlY29oZXJlL2NyZWF0ZSB3ZWJhcGlcXGAuYCxcblx0XHQpO1xuXHR9XG5cblx0Y29uc3QgZXhpc3RpbmcgPSBsaXN0RXhpc3RpbmdBcGlOYW1lcyh0YXJnZXREaXIpO1xuXHRmb3IgKGNvbnN0IGFwaU5hbWUgb2YgYXBpTmFtZXMpIHtcblx0XHRpZiAoZXhpc3RpbmcuaW5jbHVkZXMoYXBpTmFtZSkpIHtcblx0XHRcdHRocm93IG5ldyBDcmVhdGVDbGlFcnJvcihcblx0XHRcdFx0YEFQSSBcIiR7YXBpTmFtZX1cIiBhbHJlYWR5IGV4aXN0cyBhdCAke3dlYmFwaVByb2plY3REaXIoYXBpTmFtZSl9LmAsXG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXG5cdGNvbnN0IG1vbm9SZXBvID0gbmV3IE1vbm9SZXBvU2NhZmZvbGQoKTtcblx0bW9ub1JlcG8udGFyZ2V0RGlyID0gdGFyZ2V0RGlyO1xuXHRtb25vUmVwby5zZXROYW1lKHByb2plY3ROYW1lKTtcblx0Y29uc3QgbmFtZSA9IG1vbm9SZXBvLm5hbWU7XG5cblx0Y29uc3QgcGtnID0gUGFja2FnZUpzb24uZnJvbUZpbGUoam9pbih0YXJnZXREaXIsIFwicGFja2FnZS5qc29uXCIpKTtcblx0bW9ub1JlcG8uYWRkTW9kZWwocGtnKTtcblx0bW9ub1JlcG8uYWRkTW9kZWwoXG5cdFx0ZXhpc3RzU3luYyhqb2luKHRhcmdldERpciwgXCIuZW52XCIpKVxuXHRcdFx0PyBFbnZGaWxlLmZyb21GaWxlKGpvaW4odGFyZ2V0RGlyLCBcIi5lbnZcIikpXG5cdFx0XHQ6IG5ldyBFbnZGaWxlKCksXG5cdCk7XG5cdG1vbm9SZXBvLmFkZE1vZGVsKFxuXHRcdGV4aXN0c1N5bmMoam9pbih0YXJnZXREaXIsIFwiY29uZmlnL2NvbmZpZy55YW1sXCIpKVxuXHRcdFx0PyBDb25maWdZYW1sLmZyb21GaWxlKFxuXHRcdFx0XHRcdFdFTExfS05PV05fRklMRVMuQ09ORklHX1lBTUwsXG5cdFx0XHRcdFx0XCJjb25maWcvY29uZmlnLnlhbWxcIixcblx0XHRcdFx0XHRqb2luKHRhcmdldERpciwgXCJjb25maWcvY29uZmlnLnlhbWxcIiksXG5cdFx0XHRcdClcblx0XHRcdDogbmV3IENvbmZpZ1lhbWwoV0VMTF9LTk9XTl9GSUxFUy5DT05GSUdfWUFNTCwgXCJjb25maWcvY29uZmlnLnlhbWxcIiwgXCJcIiksXG5cdCk7XG5cdG1vbm9SZXBvLmFkZE1vZGVsKFxuXHRcdGV4aXN0c1N5bmMoam9pbih0YXJnZXREaXIsIFwiY29uZmlnL2NvbmZpZy5kZXYueWFtbFwiKSlcblx0XHRcdD8gQ29uZmlnWWFtbC5mcm9tRmlsZShcblx0XHRcdFx0XHRXRUxMX0tOT1dOX0ZJTEVTLkNPTkZJR19ERVZfWUFNTCxcblx0XHRcdFx0XHRcImNvbmZpZy9jb25maWcuZGV2LnlhbWxcIixcblx0XHRcdFx0XHRqb2luKHRhcmdldERpciwgXCJjb25maWcvY29uZmlnLmRldi55YW1sXCIpLFxuXHRcdFx0XHQpXG5cdFx0XHQ6IG5ldyBDb25maWdZYW1sKFdFTExfS05PV05fRklMRVMuQ09ORklHX0RFVl9ZQU1MLCBcImNvbmZpZy9jb25maWcuZGV2LnlhbWxcIiwgXCJcIiksXG5cdCk7XG5cblx0Zm9yIChjb25zdCBbb2Zmc2V0LCBhcGlOYW1lXSBvZiBhcGlOYW1lcy5lbnRyaWVzKCkpIHtcblx0XHRjb25zdCBwb3J0ID0gd2ViYXBpUG9ydChleGlzdGluZy5sZW5ndGggKyBvZmZzZXQpO1xuXHRcdHBrZy5hZGRTY3JpcHQoYHN0YXJ0OiR7YXBpTmFtZX1gLCBgbm9kZSAke3dlYmFwaVJlbGVhc2VFbnRyeShhcGlOYW1lKX1gKTtcblx0XHRwa2cuYWRkU2NyaXB0KFxuXHRcdFx0YGRldjoke2FwaU5hbWV9YCxcblx0XHRcdGBQT1JUPSR7cG9ydH0gZmx1eCBzZXJ2ZSAtLXByb2plY3QgJHt3ZWJhcGlQYWNrYWdlTmFtZShuYW1lLCBhcGlOYW1lKX1gLFxuXHRcdCk7XG5cdFx0YWRkQXBpUHJvamVjdChtb25vUmVwbywgbmFtZSwgYXBpTmFtZSk7XG5cdH1cblx0bW9ub1JlcG8uYWRkTW9kZWwobmV3IFdlYmFwaVByb2R1Y3Rpb25Eb2NrZXJmaWxlKGFwaU5hbWVzLCB7IG5hbWVkT25seTogdHJ1ZSB9KSk7XG5cblx0cmV0dXJuIG1vbm9SZXBvO1xufVxuXG5mdW5jdGlvbiBhZGRBcGlQcm9qZWN0KFxuXHRtb25vUmVwbzogTW9ub1JlcG9TY2FmZm9sZCxcblx0d29ya3NwYWNlTmFtZTogc3RyaW5nLFxuXHRhcGlOYW1lOiBzdHJpbmcsXG4pOiB2b2lkIHtcblx0Y29uc3QgYXBpUHJvamVjdCA9IG5ldyBQcm9qZWN0U2NhZmZvbGQod2ViYXBpUHJvamVjdERpcihhcGlOYW1lKSk7XG5cdGFwaVByb2plY3QuYWRkTW9kZWwobmV3IEFwaVBhY2thZ2VKc29uKHdvcmtzcGFjZU5hbWUsIGFwaU5hbWUpKTtcblx0YXBpUHJvamVjdC5hZGRNb2RlbChuZXcgTWFpblNvdXJjZUZpbGUoYCR7d29ya3NwYWNlTmFtZX0uJHthcGlOYW1lfWApKTtcblx0YXBpUHJvamVjdC5hZGRNb2RlbChuZXcgQ29udHJvbGxlclNvdXJjZUZpbGUoKSk7XG5cdGFwaVByb2plY3QuYWRkRmlsZShuZXcgU2FtcGxlQ29uZmlnTW9kZWwoKSk7XG5cdGFwaVByb2plY3QuYWRkRmlsZShuZXcgU2FtcGxlU2VydmljZU1vZGVsKCkpO1xuXHRtb25vUmVwby5hZGRQcm9qZWN0KGFwaVByb2plY3QpO1xufVxuIl0sIm5hbWVzIjpbIldFQkFQSV9QUk9KRUNUX0RJUiIsIldFQkFQSV9SRUxFQVNFX0VOVFJZIiwic2NhZmZvbGRBcGkiLCJmZWF0dXJlcyIsIkRhdGFiYXNlRmVhdHVyZSIsIkF1dGhGZWF0dXJlIiwiUG9zdG1hbkZlYXR1cmUiLCJGaW5hbGl6ZUZlYXR1cmUiLCJjbGlPcHRpb25zIiwidGFyZ2V0RGlyIiwicmVzb2x2ZSIsImQiLCJwcm9qZWN0TmFtZSIsInRyaW0iLCJwcm9jZXNzIiwiZW52IiwiREVDT0hFUkVfUFJPSkVDVF9OQU1FIiwiYmFzZW5hbWUiLCJuYW1lcyIsInBhcnNlQXBpTmFtZXMiLCJ3b3Jrc3BhY2UiLCJhZGQiLCJjcmVhdGVBZGRXb3Jrc3BhY2UiLCJjcmVhdGVXb3Jrc3BhY2UiLCJTY2FmZm9sZFNlcnZpY2UiLCJzY2FmZm9sZCIsImFwaU5hbWVzIiwibW9ub1JlcG8iLCJNb25vUmVwb1NjYWZmb2xkIiwic2V0TmFtZSIsIm5hbWUiLCJjb21wb3NlIiwiRG9ja2VyQ29tcG9zZSIsInNldFByb2plY3ROYW1lIiwiYWRkTmV0d29yayIsImFkZFNlcnZpY2UiLCJidWlsZCIsInZvbHVtZXMiLCJlbnZpcm9ubWVudCIsIk5QTV9DT05GSUdfVVNFUkNPTkZJRyIsImNvbW1hbmQiLCJuZXR3b3JrcyIsImFkZFZvbHVtZSIsImRldkNvbnRhaW5lciIsIkRldkNvbnRhaW5lciIsImFkZEV4dGVuc2lvbiIsInNldEluaXRpYWxpemVDb21tYW5kIiwic2V0UG9zdFN0YXJ0Q29tbWFuZCIsInVzZUNvbXBvc2UiLCJpbmRleCIsImFwaU5hbWUiLCJlbnRyaWVzIiwicG9ydCIsIndlYmFwaVBvcnQiLCJmb3J3YXJkUG9ydCIsInNldFBvcnRBdHRyaWJ1dGVzIiwibGFiZWwiLCJERUZBVUxUX1dFQkFQSV9OQU1FIiwicmVxdWlyZUxvY2FsUG9ydCIsImFkZE1vZGVsIiwiV2ViYXBpRGV2Q29udGFpbmVyIiwiV2ViYXBpUHJvZHVjdGlvbkRvY2tlcmZpbGUiLCJHaXRodWJDaVdvcmtmbG93cyIsIlZTQ29kZVNldHRpbmdzIiwiTGF1bmNoSnNvbiIsIlRzQ29uZmlnIiwiUGFja2FnZUpzb24iLCJ3b3Jrc3BhY2VOYW1lIiwiQ29uZmlnWWFtbCIsIldFTExfS05PV05fRklMRVMiLCJDT05GSUdfWUFNTCIsIkNPTkZJR19ERVZfWUFNTCIsIkdpdGlnbm9yZSIsIkVudkZpbGUiLCJhZGRGaWxlIiwiZmlsZXMiLCJmaWxlUGF0aCIsImNvbnRlbnQiLCJKU09OIiwic3RyaW5naWZ5IiwiJHNjaGVtYSIsImluY2x1ZGVzIiwiYXNzaXN0IiwiYWN0aW9ucyIsInNvdXJjZSIsIm9yZ2FuaXplSW1wb3J0cyIsInZjcyIsImVuYWJsZWQiLCJjbGllbnRLaW5kIiwidXNlSWdub3JlRmlsZSIsImZvcm1hdHRlciIsImZvcm1hdFdpdGhFcnJvcnMiLCJpbmRlbnRTdHlsZSIsImxpbmVXaWR0aCIsImphdmFzY3JpcHQiLCJwYXJzZXIiLCJ1bnNhZmVQYXJhbWV0ZXJEZWNvcmF0b3JzRW5hYmxlZCIsImxpbnRlciIsInJ1bGVzIiwic3R5bGUiLCJ1c2VDb25zaXN0ZW50TWVtYmVyQWNjZXNzaWJpbGl0eSIsImxldmVsIiwib3B0aW9ucyIsImFjY2Vzc2liaWxpdHkiLCJvdmVycmlkZXMiLCJpbmRlbnRXaWR0aCIsImpvaW4iLCJhZGRBcGlQcm9qZWN0IiwiaXNEZWNvaGVyZVdvcmtzcGFjZSIsIkNyZWF0ZUNsaUVycm9yIiwiZXhpc3RpbmciLCJsaXN0RXhpc3RpbmdBcGlOYW1lcyIsIndlYmFwaVByb2plY3REaXIiLCJwa2ciLCJmcm9tRmlsZSIsImV4aXN0c1N5bmMiLCJvZmZzZXQiLCJsZW5ndGgiLCJhZGRTY3JpcHQiLCJ3ZWJhcGlSZWxlYXNlRW50cnkiLCJ3ZWJhcGlQYWNrYWdlTmFtZSIsIm5hbWVkT25seSIsImFwaVByb2plY3QiLCJQcm9qZWN0U2NhZmZvbGQiLCJBcGlQYWNrYWdlSnNvbiIsIk1haW5Tb3VyY2VGaWxlIiwiQ29udHJvbGxlclNvdXJjZUZpbGUiLCJTYW1wbGVDb25maWdNb2RlbCIsIlNhbXBsZVNlcnZpY2VNb2RlbCIsImFkZFByb2plY3QiXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7O1FBdUNTQTtlQUFBQSwwQkFBa0I7O1FBQUVDO2VBQUFBLDRCQUFvQjs7UUFrQjNCQztlQUFBQTs7O3dCQXpESzswQkFDYTs4QkFDVjtpQ0FDSDt1QkFDTTttQ0FDSjs4QkFDTDtnQ0FDRTtpQ0FDQztrQ0FDQzs4QkFDc0I7K0JBQ3pCO3FDQUNNO2lDQUNDO3lCQU16Qjt3QkFPQTs2QkFDcUI7aUNBQ0k7aUNBQ0E7Z0NBQ0Q7cUNBQ0E7MkNBQ007K0JBQ0g7cUNBQ0g7MkNBQ1k7a0NBQ1c7a0NBQ25CO0FBa0JuQyxNQUFNQyxXQUFXO0lBQUNDLGdDQUFlO0lBQUVDLHdCQUFXO0lBQUVDLDhCQUFjO0lBQUVDLGdDQUFlO0NBQUM7QUFFekUsZUFBZUwsWUFBWU0sVUFBc0I7SUFDdkQs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