@decohere/create 0.0.1-dev.23 → 0.0.1-dev.25
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.
- package/commonjs/src/models/compose.model.js +56 -4
- package/commonjs/src/models/dev-container.model.js +29 -2
- package/commonjs/src/models/package-json.model.js +11 -6
- package/commonjs/src/runner.js +26 -2
- package/commonjs/src/webapi/create-api.js +66 -5
- package/commonjs/src/webapi/features/auth.feature.js +288 -7
- package/commonjs/src/webapi/features/auth0-cli.js +256 -9
- package/commonjs/src/webapi/features/database.feature.js +56 -24
- package/commonjs/src/webapi/features/postman.feature.js +337 -48
- package/commonjs/src/webapi/models/api-package-json.model.js +4 -1
- package/commonjs/src/webapi/models/auth-config.model.js +4 -1
- package/commonjs/src/webapi/models/controller-source-file.model.js +16 -8
- package/commonjs/src/webapi/models/main-source-file.model.js +28 -4
- package/es6/src/models/compose.model.js +57 -6
- package/es6/src/models/dev-container.model.js +30 -8
- package/es6/src/models/package-json.model.js +11 -6
- package/es6/src/runner.js +27 -3
- package/es6/src/webapi/create-api.js +66 -5
- package/es6/src/webapi/features/auth.feature.js +288 -7
- package/es6/src/webapi/features/auth0-cli.js +230 -9
- package/es6/src/webapi/features/database.feature.js +56 -24
- package/es6/src/webapi/features/postman.feature.js +324 -45
- package/es6/src/webapi/models/api-package-json.model.js +4 -1
- package/es6/src/webapi/models/auth-config.model.js +4 -1
- package/es6/src/webapi/models/controller-source-file.model.js +16 -8
- package/es6/src/webapi/models/main-source-file.model.js +28 -4
- package/package.json +2 -2
- package/types/src/models/compose.model.d.ts +27 -2
- package/types/src/models/dev-container.model.d.ts +12 -0
- package/types/src/models/package-json.model.d.ts +2 -0
- package/types/src/webapi/features/auth.feature.d.ts +3 -0
- package/types/src/webapi/features/auth0-cli.d.ts +50 -3
- package/types/src/webapi/features/postman.feature.d.ts +5 -0
- package/types/src/webapi/models/auth-config.model.d.ts +8 -0
- package/types/src/webapi/models/controller-source-file.model.d.ts +6 -3
- package/types/src/webapi/models/main-source-file.model.d.ts +12 -0
|
@@ -10,6 +10,7 @@ Object.defineProperty(exports, "AuthFeature", {
|
|
|
10
10
|
});
|
|
11
11
|
const _prompt = require("../../domain/prompt.js");
|
|
12
12
|
const _const = require("../../models/const.js");
|
|
13
|
+
const _createapi = require("../create-api.js");
|
|
13
14
|
const _authconfigmodel = require("../models/auth-config.model.js");
|
|
14
15
|
const _controllersourcefilemodel = require("../models/controller-source-file.model.js");
|
|
15
16
|
const _auth0cli = /*#__PURE__*/ _interop_require_wildcard(require("./auth0-cli.js"));
|
|
@@ -54,7 +55,151 @@ function _interop_require_wildcard(obj, nodeInterop) {
|
|
|
54
55
|
}
|
|
55
56
|
return newObj;
|
|
56
57
|
}
|
|
58
|
+
const ADMIN_ROLE = "admin";
|
|
59
|
+
const USER_ENTITY_TS = `import { Column, Entity, PrimaryGeneratedColumn } from "typeorm";
|
|
60
|
+
import type { Entity as IEntity } from "@decohere/codex";
|
|
61
|
+
|
|
62
|
+
@Entity()
|
|
63
|
+
export class UserEntity implements IEntity {
|
|
64
|
+
\t@PrimaryGeneratedColumn()
|
|
65
|
+
\tpublic id!: number;
|
|
66
|
+
|
|
67
|
+
\t@Column({ unique: true })
|
|
68
|
+
\tpublic sub!: string;
|
|
69
|
+
|
|
70
|
+
\t@Column({ type: "varchar", nullable: true })
|
|
71
|
+
\tpublic email!: string | null;
|
|
72
|
+
|
|
73
|
+
\t@Column()
|
|
74
|
+
\tpublic displayName!: string;
|
|
75
|
+
|
|
76
|
+
\t/** App-owned roles. The \`admin\` role grants CASL \`manage\`/\`all\` (wildcard). */
|
|
77
|
+
\t@Column({ type: "simple-json", default: "[]" })
|
|
78
|
+
\tpublic roles!: string[];
|
|
79
|
+
}
|
|
80
|
+
`;
|
|
81
|
+
const USER_REPOSITORY_TS = `import { injectable } from "@decohere/crucible/decorators";
|
|
82
|
+
import { injectUnitOfWork } from "@decohere/codex";
|
|
83
|
+
import { TypeOrmRepository, TypeOrmUnitOfWork } from "@decohere/codex-typeorm";
|
|
84
|
+
import { UserEntity } from "../entities/user.entity.js";
|
|
85
|
+
|
|
86
|
+
@injectable()
|
|
87
|
+
export class UserEntityRepository extends TypeOrmRepository<UserEntity> {
|
|
88
|
+
\tpublic constructor(@injectUnitOfWork() unitOfWork: TypeOrmUnitOfWork) {
|
|
89
|
+
\t\tsuper(unitOfWork, UserEntity);
|
|
90
|
+
\t}
|
|
91
|
+
|
|
92
|
+
\tpublic findBySub(sub: string): Promise<UserEntity | null> {
|
|
93
|
+
\t\treturn this.firstOrDefault({ where: { sub } });
|
|
94
|
+
\t}
|
|
95
|
+
}
|
|
96
|
+
`;
|
|
97
|
+
const USER_SERVICE_TS = `import { injectable } from "@decohere/crucible/decorators";
|
|
98
|
+
import type { Principal } from "@decohere/cortex";
|
|
99
|
+
import { UserEntity } from "../entities/user.entity.js";
|
|
100
|
+
import { UserEntityRepository } from "../repositories/user.repository.js";
|
|
101
|
+
|
|
102
|
+
function claimString(principal: Principal | undefined, key: string): string | undefined {
|
|
103
|
+
\tconst value = principal?.[key];
|
|
104
|
+
\treturn typeof value === "string" && value.length > 0 ? value : undefined;
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
@injectable()
|
|
108
|
+
export class UserService {
|
|
109
|
+
\tpublic constructor(private readonly users: UserEntityRepository) {}
|
|
110
|
+
|
|
111
|
+
\t/**
|
|
112
|
+
\t * Upsert a local profile keyed by JWT \`sub\`.
|
|
113
|
+
\t * Profile fields from the token fill gaps; seeded rows keep displayName/email/roles.
|
|
114
|
+
\t */
|
|
115
|
+
\tpublic async ensureFromPrincipal(principal: Principal | undefined): Promise<UserEntity> {
|
|
116
|
+
\t\tconst sub = principal?.sub;
|
|
117
|
+
\t\tif (!sub) {
|
|
118
|
+
\t\t\tthrow new Error("Authenticated request is missing principal.sub");
|
|
119
|
+
\t\t}
|
|
120
|
+
|
|
121
|
+
\t\tconst email =
|
|
122
|
+
\t\t\tclaimString(principal, "email") ?? claimString(principal, "preferred_username");
|
|
123
|
+
\t\tconst displayFromToken =
|
|
124
|
+
\t\t\tclaimString(principal, "name") ??
|
|
125
|
+
\t\t\tclaimString(principal, "nickname") ??
|
|
126
|
+
\t\t\temail;
|
|
127
|
+
|
|
128
|
+
\t\tconst existing = await this.users.findBySub(sub);
|
|
129
|
+
\t\tif (existing) {
|
|
130
|
+
\t\t\tlet dirty = false;
|
|
131
|
+
\t\t\tif (!existing.email && email) {
|
|
132
|
+
\t\t\t\texisting.email = email;
|
|
133
|
+
\t\t\t\tdirty = true;
|
|
134
|
+
\t\t\t}
|
|
135
|
+
\t\t\tif (existing.displayName === existing.sub && displayFromToken) {
|
|
136
|
+
\t\t\t\texisting.displayName = displayFromToken;
|
|
137
|
+
\t\t\t\tdirty = true;
|
|
138
|
+
\t\t\t}
|
|
139
|
+
\t\t\treturn dirty ? this.users.save(existing) : existing;
|
|
140
|
+
\t\t}
|
|
141
|
+
|
|
142
|
+
\t\tconst created = new UserEntity();
|
|
143
|
+
\t\tcreated.sub = sub;
|
|
144
|
+
\t\tcreated.email = email ?? null;
|
|
145
|
+
\t\tcreated.displayName = displayFromToken ?? sub;
|
|
146
|
+
\t\tcreated.roles = Array.isArray(principal.roles)
|
|
147
|
+
\t\t\t? principal.roles.filter((r): r is string => typeof r === "string")
|
|
148
|
+
\t\t\t: [];
|
|
149
|
+
\t\treturn this.users.save(created);
|
|
150
|
+
\t}
|
|
151
|
+
}
|
|
152
|
+
`;
|
|
153
|
+
const ABILITY_FACTORY_TS = `import { AbilityBuilder, createMongoAbility } from "@casl/ability";
|
|
154
|
+
import type { Principal } from "@decohere/cortex";
|
|
155
|
+
|
|
156
|
+
/** Root role — expands to CASL \`manage\`/\`all\` (covers every future ability). */
|
|
157
|
+
export const ADMIN_ROLE = "admin";
|
|
158
|
+
|
|
159
|
+
/**
|
|
160
|
+
* Roles are collections of abilities. Admin is a wildcard, not an enumerated list.
|
|
161
|
+
* Non-admin principals keep the default Auth0 scope → ability mapping.
|
|
162
|
+
*/
|
|
163
|
+
export function createAbilityFactory(principal: Principal) {
|
|
164
|
+
\tconst { can, build } = new AbilityBuilder(createMongoAbility);
|
|
165
|
+
\tif (principal.roles?.includes(ADMIN_ROLE)) {
|
|
166
|
+
\t\tcan("manage", "all");
|
|
167
|
+
\t\treturn build();
|
|
168
|
+
\t}
|
|
169
|
+
\tfor (const scope of principal.scopes ?? []) {
|
|
170
|
+
\t\tconst [action, subject] = scope.split(":");
|
|
171
|
+
\t\tif (action && subject) can(action, subject);
|
|
172
|
+
\t}
|
|
173
|
+
\treturn build();
|
|
174
|
+
}
|
|
175
|
+
|
|
176
|
+
/**
|
|
177
|
+
* Map JWT payload → Principal. Bootstraps the seeded Auth0 admin \`sub\` with
|
|
178
|
+
* the admin role so authorization works before/without roles in the access token.
|
|
179
|
+
*/
|
|
180
|
+
export function mapPrincipal(payload: Record<string, unknown>): Principal {
|
|
181
|
+
\tconst sub = typeof payload.sub === "string" ? payload.sub : "";
|
|
182
|
+
\tconst scopes = Array.isArray(payload.scopes)
|
|
183
|
+
\t\t? (payload.scopes as string[])
|
|
184
|
+
\t\t: typeof payload.scope === "string"
|
|
185
|
+
\t\t\t? payload.scope.split(" ")
|
|
186
|
+
\t\t\t: undefined;
|
|
187
|
+
\tconst fromToken = Array.isArray(payload.roles)
|
|
188
|
+
\t\t? (payload.roles as unknown[]).filter((r): r is string => typeof r === "string")
|
|
189
|
+
\t\t: [];
|
|
190
|
+
\tconst roles =
|
|
191
|
+
\t\tsub && sub === process.env.AUTH0_ADMIN_USER_SUB
|
|
192
|
+
\t\t\t? [...new Set([ADMIN_ROLE, ...fromToken])]
|
|
193
|
+
\t\t\t: fromToken.length > 0
|
|
194
|
+
\t\t\t\t? fromToken
|
|
195
|
+
\t\t\t\t: undefined;
|
|
196
|
+
\treturn { ...payload, sub, roles, scopes };
|
|
197
|
+
}
|
|
198
|
+
`;
|
|
57
199
|
async function getOptions(workspace, cliOptions) {
|
|
200
|
+
if (cliOptions.authProvider === "auth0" && !cliOptions.issuerBaseUrl) {
|
|
201
|
+
return getAuth0Options(workspace, cliOptions);
|
|
202
|
+
}
|
|
58
203
|
if (cliOptions.authProvider != null) return {};
|
|
59
204
|
const choices = [
|
|
60
205
|
{
|
|
@@ -69,9 +214,9 @@ async function getOptions(workspace, cliOptions) {
|
|
|
69
214
|
if (provider !== "auth0") return {
|
|
70
215
|
authProvider: "none"
|
|
71
216
|
};
|
|
72
|
-
return getAuth0Options(workspace);
|
|
217
|
+
return getAuth0Options(workspace, cliOptions);
|
|
73
218
|
}
|
|
74
|
-
async function getAuth0Options(workspace) {
|
|
219
|
+
async function getAuth0Options(workspace, cliOptions) {
|
|
75
220
|
if (!_auth0cli.isInstalled()) {
|
|
76
221
|
console.error("\n The Auth0 CLI is required for automated setup.\n" + " Install: brew install auth0/auth0-cli/auth0\n" + " Or visit: https://github.com/auth0/auth0-cli\n");
|
|
77
222
|
process.exit(1);
|
|
@@ -128,24 +273,156 @@ async function getAuth0Options(workspace) {
|
|
|
128
273
|
} else {
|
|
129
274
|
audience = apiSelected.existing;
|
|
130
275
|
console.log(` \u2713 Selected: ${audience}`);
|
|
276
|
+
try {
|
|
277
|
+
_auth0cli.updateApiScopes(audience);
|
|
278
|
+
console.log(` \u2713 API scopes ensured (${_auth0cli.HELLO_API_SCOPES.join(", ")})`);
|
|
279
|
+
} catch {
|
|
280
|
+
console.error(" ✗ Failed to update API scopes — add Hello scopes in the Auth0 dashboard.");
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
const withLocalUsers = cliOptions.databaseProvider === "postgres/typeorm";
|
|
284
|
+
let adminUsername;
|
|
285
|
+
let adminPassword;
|
|
286
|
+
if (withLocalUsers) {
|
|
287
|
+
adminUsername = cliOptions.adminUsername ?? await (0, _prompt.ask)("\n Admin username [admin]: ", "admin");
|
|
288
|
+
adminPassword = cliOptions.adminPassword;
|
|
289
|
+
if (adminPassword == null) {
|
|
290
|
+
adminPassword = await (0, _prompt.ask)(" Admin password (leave blank to generate): ");
|
|
291
|
+
if (!adminPassword) {
|
|
292
|
+
adminPassword = _auth0cli.generateAdminPassword();
|
|
293
|
+
console.log(` ✓ Generated admin password (written to .env): ${adminPassword}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
131
296
|
}
|
|
132
297
|
return {
|
|
133
298
|
authProvider: "auth0",
|
|
134
299
|
issuerBaseUrl,
|
|
135
|
-
audience
|
|
300
|
+
audience,
|
|
301
|
+
...withLocalUsers ? {
|
|
302
|
+
adminUsername,
|
|
303
|
+
adminPassword
|
|
304
|
+
} : {}
|
|
136
305
|
};
|
|
137
306
|
}
|
|
307
|
+
function adminEmail(workspaceName, username) {
|
|
308
|
+
if (username.includes("@")) return username;
|
|
309
|
+
const slug = workspaceName.toLowerCase().replace(/[^a-z0-9-]/g, "-");
|
|
310
|
+
return `${username}@${slug}.example.com`;
|
|
311
|
+
}
|
|
312
|
+
function createAuth0AdminUser(workspace, options, authConfig) {
|
|
313
|
+
const username = options.adminUsername ?? "admin";
|
|
314
|
+
const password = options.adminPassword;
|
|
315
|
+
if (!password) return;
|
|
316
|
+
const email = adminEmail(workspace.name, username);
|
|
317
|
+
try {
|
|
318
|
+
const admin = _auth0cli.createAdminDatabaseUser({
|
|
319
|
+
email,
|
|
320
|
+
password,
|
|
321
|
+
username
|
|
322
|
+
});
|
|
323
|
+
authConfig.setAdminUser({
|
|
324
|
+
sub: admin.user_id,
|
|
325
|
+
email: admin.email,
|
|
326
|
+
password: admin.password,
|
|
327
|
+
username: admin.username
|
|
328
|
+
});
|
|
329
|
+
workspace.getModel(_const.WELL_KNOWN_FILES.ENV_FILE)?.addEntry("AUTH0_ADMIN_USER_SUB", admin.user_id).addEntry("AUTH0_ADMIN_USER_EMAIL", admin.email).addEntry("AUTH0_ADMIN_USER_PASSWORD", admin.password).addEntry("AUTH0_ADMIN_USERNAME", admin.username);
|
|
330
|
+
console.log(` ✓ Auth0 admin user ready: ${admin.email} (role: ${ADMIN_ROLE})`);
|
|
331
|
+
console.log(` Login with EMAIL (not username): ${admin.email}`);
|
|
332
|
+
console.log(` Password: see AUTH0_ADMIN_USER_PASSWORD in .env`);
|
|
333
|
+
} catch (err) {
|
|
334
|
+
console.error(` ✗ Failed to ensure Auth0 admin user (${email}): ${err instanceof Error ? err.message : err}`);
|
|
335
|
+
}
|
|
336
|
+
}
|
|
337
|
+
function scaffoldLocalUserProfile(workspace) {
|
|
338
|
+
workspace.getModel(_const.WELL_KNOWN_FILES.PACKAGE_JSON)?.addDependency("@casl/ability", "^6.8.1");
|
|
339
|
+
workspace.getModel(_const.WELL_KNOWN_FILES.API_PACKAGE_JSON)?.addDependency("@casl/ability", "^6.8.1");
|
|
340
|
+
const main = workspace.getModel(_const.WELL_KNOWN_FILES.MAIN_TS);
|
|
341
|
+
main?.addEntity({
|
|
342
|
+
className: "UserEntity",
|
|
343
|
+
importPath: "./entities/user.entity.js"
|
|
344
|
+
}).addRepository({
|
|
345
|
+
className: "UserEntityRepository",
|
|
346
|
+
importPath: "./repositories/user.repository.js"
|
|
347
|
+
}).addService({
|
|
348
|
+
className: "UserService",
|
|
349
|
+
importPath: "./services/user.service.js",
|
|
350
|
+
scope: "request"
|
|
351
|
+
}).addImport("createAbilityFactory", "./auth/ability.factory.js").addImport("mapPrincipal", "./auth/ability.factory.js").setTypeOrmSeed([
|
|
352
|
+
"const sub = process.env.AUTH0_ADMIN_USER_SUB;",
|
|
353
|
+
"if (!sub) return;",
|
|
354
|
+
"const repo = dataSource.getRepository(UserEntity);",
|
|
355
|
+
"const existing = await repo.findOne({ where: { sub } });",
|
|
356
|
+
"if (existing) return;",
|
|
357
|
+
"await repo.save(repo.create({",
|
|
358
|
+
" sub,",
|
|
359
|
+
" email: process.env.AUTH0_ADMIN_USER_EMAIL ?? null,",
|
|
360
|
+
' displayName: process.env.AUTH0_ADMIN_USERNAME ?? "admin",',
|
|
361
|
+
' roles: ["admin"],',
|
|
362
|
+
"}));"
|
|
363
|
+
].join(" "));
|
|
364
|
+
workspace.getProject(_createapi.WEBAPI_PROJECT_DIR)?.addFile({
|
|
365
|
+
files: ()=>[
|
|
366
|
+
{
|
|
367
|
+
filePath: "src/entities/user.entity.ts",
|
|
368
|
+
content: USER_ENTITY_TS
|
|
369
|
+
},
|
|
370
|
+
{
|
|
371
|
+
filePath: "src/repositories/user.repository.ts",
|
|
372
|
+
content: USER_REPOSITORY_TS
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
filePath: "src/services/user.service.ts",
|
|
376
|
+
content: USER_SERVICE_TS
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
filePath: "src/auth/ability.factory.ts",
|
|
380
|
+
content: ABILITY_FACTORY_TS
|
|
381
|
+
}
|
|
382
|
+
]
|
|
383
|
+
});
|
|
384
|
+
for (const controller of workspace.getModels(_controllersourcefilemodel.ControllerSourceFile)){
|
|
385
|
+
controller.addImport("UserService", "../services/user.service.js").addConstructorParam("private readonly users: UserService");
|
|
386
|
+
controller.getMethod("getOne").setAsync(true).setBody([
|
|
387
|
+
"const user = await this.users.ensureFromPrincipal(this.principalProvider.currentPrincipal);",
|
|
388
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: template literal in generated code
|
|
389
|
+
"return { id, message: `Hello ${user.displayName}!`, username: user.displayName };"
|
|
390
|
+
]);
|
|
391
|
+
}
|
|
392
|
+
}
|
|
138
393
|
function scaffold(workspace, options) {
|
|
139
394
|
if (options.authProvider !== "auth0") return;
|
|
140
395
|
const resource = "Hello";
|
|
396
|
+
const withLocalUsers = options.databaseProvider === "postgres/typeorm";
|
|
141
397
|
for (const controller of workspace.getModels(_controllersourcefilemodel.ControllerSourceFile)){
|
|
142
398
|
controller.addDecorator(`@Authorize("read", "${resource}")`).addCortexImport("AllowAnonymous").addCortexImport("Authorize").addCortexImport("IPrincipalProviderToken").addCortexImport("IPrincipalProvider", true).addImport("inject", "@decohere/crucible/decorators").addConstructorParam(`@inject(IPrincipalProviderToken) private readonly principalProvider: IPrincipalProvider`);
|
|
143
399
|
controller.getMethod("getAll").addDecorator("@AllowAnonymous()");
|
|
400
|
+
if (!withLocalUsers) {
|
|
401
|
+
controller.getMethod("getOne").setBody([
|
|
402
|
+
"const principal = this.principalProvider.currentPrincipal;",
|
|
403
|
+
"const username =",
|
|
404
|
+
'\t(typeof principal?.name === "string" && principal.name) ||',
|
|
405
|
+
'\t(typeof principal?.nickname === "string" && principal.nickname) ||',
|
|
406
|
+
'\t(typeof principal?.email === "string" && principal.email) ||',
|
|
407
|
+
'\t(typeof principal?.preferred_username === "string" && principal.preferred_username) ||',
|
|
408
|
+
"\tprincipal?.sub ||",
|
|
409
|
+
'\t"unknown";',
|
|
410
|
+
// biome-ignore lint/suspicious/noTemplateCurlyInString: template literal in generated code
|
|
411
|
+
"return { id, message: `Hello ${username}!`, username };"
|
|
412
|
+
]);
|
|
413
|
+
}
|
|
144
414
|
controller.getMethod("create").addDecorator(`@Authorize("create", "${resource}")`);
|
|
145
415
|
controller.getMethod("update").addDecorator(`@Authorize("update", "${resource}")`);
|
|
146
416
|
controller.getMethod("remove").addDecorator(`@Authorize("delete", "${resource}")`);
|
|
147
417
|
}
|
|
148
|
-
workspace.getModel(_const.WELL_KNOWN_FILES.MAIN_TS)
|
|
418
|
+
const main = workspace.getModel(_const.WELL_KNOWN_FILES.MAIN_TS);
|
|
419
|
+
main?.addSideEffectImport("@decohere/cortex/auth");
|
|
420
|
+
if (withLocalUsers) {
|
|
421
|
+
scaffoldLocalUserProfile(workspace);
|
|
422
|
+
main?.addBuilderCall(".withAuth(createAbilityFactory, { principalMapper: mapPrincipal })");
|
|
423
|
+
} else {
|
|
424
|
+
main?.addBuilderCall(".withAuth()");
|
|
425
|
+
}
|
|
149
426
|
// biome-ignore lint/suspicious/noTemplateCurlyInString: intentional YAML env-var placeholders
|
|
150
427
|
const issuerPlaceholder = "${AUTH0_ISSUER_BASE_URL}";
|
|
151
428
|
// biome-ignore lint/suspicious/noTemplateCurlyInString: intentional YAML env-var placeholders
|
|
@@ -153,14 +430,18 @@ function scaffold(workspace, options) {
|
|
|
153
430
|
const configSection = `auth:\n discoveryUrl: ${issuerPlaceholder}\n audience: ${audPlaceholder}\n`;
|
|
154
431
|
workspace.getModel(_const.WELL_KNOWN_FILES.CONFIG_YAML)?.addSection(configSection);
|
|
155
432
|
workspace.getModel(_const.WELL_KNOWN_FILES.ENV_FILE)?.addEntry("AUTH0_ISSUER_BASE_URL", options.issuerBaseUrl ?? "").addEntry("AUTH0_AUDIENCE", options.audience ?? "");
|
|
156
|
-
|
|
433
|
+
const authConfig = new _authconfigmodel.AuthConfigModel({
|
|
157
434
|
issuerBaseUrl: options.issuerBaseUrl ?? "",
|
|
158
435
|
audience: options.audience ?? ""
|
|
159
|
-
})
|
|
436
|
+
});
|
|
437
|
+
workspace.addModel(authConfig);
|
|
438
|
+
if (withLocalUsers && options.adminPassword) {
|
|
439
|
+
createAuth0AdminUser(workspace, options, authConfig);
|
|
440
|
+
}
|
|
160
441
|
}
|
|
161
442
|
const AuthFeature = {
|
|
162
443
|
getOptions,
|
|
163
444
|
scaffold
|
|
164
445
|
};
|
|
165
446
|
|
|
166
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS9zcmMvd2ViYXBpL2ZlYXR1cmVzL2F1dGguZmVhdHVyZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhc2ssIHBpY2sgfSBmcm9tIFwiLi4vLi4vZG9tYWluL3Byb21wdC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBDb25maWdZYW1sIH0gZnJvbSBcIi4uLy4uL21vZGVscy9jb25maWcteWFtbC5tb2RlbC5qc1wiO1xuaW1wb3J0IHsgV0VMTF9LTk9XTl9GSUxFUyB9IGZyb20gXCIuLi8uLi9tb2RlbHMvY29uc3QuanNcIjtcbmltcG9ydCB0eXBlIHsgRW52RmlsZSB9IGZyb20gXCIuLi8uLi9tb2RlbHMvZW52LWZpbGUubW9kZWwuanNcIjtcbmltcG9ydCB0eXBlIHsgV29ya3NwYWNlU2NhZmZvbGQgfSBmcm9tIFwiLi4vLi4vbW9kZWxzL3Byb2plY3QubW9kZWwuanNcIjtcbmltcG9ydCB0eXBlIHsgRmVhdHVyZSB9IGZyb20gXCIuLi8uLi9zZXJ2aWNlcy9zY2FmZm9sZC5zZXJ2aWNlLmpzXCI7XG5pbXBvcnQgeyBBdXRoQ29uZmlnTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWxzL2F1dGgtY29uZmlnLm1vZGVsLmpzXCI7XG5pbXBvcnQgeyBDb250cm9sbGVyU291cmNlRmlsZSB9IGZyb20gXCIuLi9tb2RlbHMvY29udHJvbGxlci1zb3VyY2UtZmlsZS5tb2RlbC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBNYWluU291cmNlRmlsZSB9IGZyb20gXCIuLi9tb2RlbHMvbWFpbi1zb3VyY2UtZmlsZS5tb2RlbC5qc1wiO1xuaW1wb3J0ICogYXMgYXV0aDBDbGkgZnJvbSBcIi4vYXV0aDAtY2xpLmpzXCI7XG5cbmV4cG9ydCB0eXBlIEF1dGhPcHRpb25zID0ge1xuXHRhdXRoUHJvdmlkZXI/OiBcImF1dGgwXCIgfCBcIm5vbmVcIjtcblx0aXNzdWVyQmFzZVVybD86IHN0cmluZztcblx0YXVkaWVuY2U/OiBzdHJpbmc7XG59O1xuXG5hc3luYyBmdW5jdGlvbiBnZXRPcHRpb25zKFxuXHR3b3Jrc3BhY2U6IFdvcmtzcGFjZVNjYWZmb2xkLFxuXHRjbGlPcHRpb25zOiBQYXJ0aWFsPEF1dGhPcHRpb25zPixcbik6IFByb21pc2U8UGFydGlhbDxBdXRoT3B0aW9ucz4+IHtcblx0aWYgKGNsaU9wdGlvbnMuYXV0aFByb3ZpZGVyICE9IG51bGwpIHJldHVybiB7fTtcblxuXHRjb25zdCBjaG9pY2VzID0gW3sgbGFiZWw6IFwibm9uZVwiIGFzIGNvbnN0IH0sIHsgbGFiZWw6IFwiYXV0aDBcIiBhcyBjb25zdCB9XTtcblx0Y29uc3Qgc2VsZWN0ZWQgPSBhd2FpdCBwaWNrKFwiXFxuICBBdXRoIHByb3ZpZGVyOiBcIiwgY2hvaWNlcywgKGMpID0+IGMubGFiZWwpO1xuXHRjb25zdCBwcm92aWRlciA9IHNlbGVjdGVkPy5sYWJlbCA/PyBcIm5vbmVcIjtcblxuXHRpZiAocHJvdmlkZXIgIT09IFwiYXV0aDBcIikgcmV0dXJuIHsgYXV0aFByb3ZpZGVyOiBcIm5vbmVcIiB9O1xuXG5cdHJldHVybiBnZXRBdXRoME9wdGlvbnMod29ya3NwYWNlKTtcbn1cblxuYXN5bmMgZnVuY3Rpb24gZ2V0QXV0aDBPcHRpb25zKHdvcmtzcGFjZTogV29ya3NwYWNlU2NhZmZvbGQpOiBQcm9taXNlPFBhcnRpYWw8QXV0aE9wdGlvbnM+PiB7XG5cdGlmICghYXV0aDBDbGkuaXNJbnN0YWxsZWQoKSkge1xuXHRcdGNvbnNvbGUuZXJyb3IoXG5cdFx0XHRcIlxcbiAgVGhlIEF1dGgwIENMSSBpcyByZXF1aXJlZCBmb3IgYXV0b21hdGVkIHNldHVwLlxcblwiICtcblx0XHRcdFx0XCIgIEluc3RhbGw6IGJyZXcgaW5zdGFsbCBhdXRoMC9hdXRoMC1jbGkvYXV0aDBcXG5cIiArXG5cdFx0XHRcdFwiICBPciB2aXNpdDogaHR0cHM6Ly9naXRodWIuY29tL2F1dGgwL2F1dGgwLWNsaVxcblwiLFxuXHRcdCk7XG5cdFx0cHJvY2Vzcy5leGl0KDEpO1xuXHR9XG5cblx0cHJvY2Vzcy5zdGRvdXQud3JpdGUoXCJcXG4gIENoZWNraW5nIEF1dGgwIGNyZWRlbnRpYWxzLi4uXCIpO1xuXHRsZXQgdGVuYW50cyA9IGF1dGgwQ2xpLmxpc3RUZW5hbnRzKCk7XG5cdGlmICh0ZW5hbnRzLmxlbmd0aCA9PT0gMCkge1xuXHRcdHByb2Nlc3Muc3Rkb3V0LndyaXRlKFwiIG5vdCBsb2dnZWQgaW4uXFxuXCIpO1xuXHRcdGNvbnNvbGUubG9nKFwiICBMb2dnaW5nIGluIHRvIEF1dGgwICh5b3VyIGJyb3dzZXIgd2lsbCBvcGVuKS4uLlwiKTtcblx0XHRpZiAoIWF1dGgwQ2xpLmxvZ2luKCkpIHtcblx0XHRcdGNvbnNvbGUuZXJyb3IoXCJcXG4gIEF1dGgwIGxvZ2luIGZhaWxlZC5cIik7XG5cdFx0XHRwcm9jZXNzLmV4aXQoMSk7XG5cdFx0fVxuXHRcdHRlbmFudHMgPSBhdXRoMENsaS5saXN0VGVuYW50cygpO1xuXHR9XG5cblx0dHJ5IHtcblx0XHRhdXRoMENsaS5saXN0QXBpcygpO1xuXHRcdHByb2Nlc3Muc3Rkb3V0LndyaXRlKFwiIG9rLlxcblwiKTtcblx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0aWYgKGVyciBpbnN0YW5jZW9mIGF1dGgwQ2xpLkF1dGgwQXV0aEVycm9yKSB7XG5cdFx0XHRwcm9jZXNzLnN0ZG91dC53cml0ZShcIiB0b2tlbiBleHBpcmVkLlxcblwiKTtcblx0XHRcdGNvbnNvbGUubG9nKFwiICBSZS1hdXRoZW50aWNhdGluZyAoeW91ciBicm93c2VyIHdpbGwgb3BlbikuLi5cIik7XG5cdFx0XHRpZiAoIWF1dGgwQ2xpLmxvZ2luKCkpIHtcblx0XHRcdFx0Y29uc29sZS5lcnJvcihcIlxcbiAgQXV0aDAgbG9naW4gZmFpbGVkLlwiKTtcblx0XHRcdFx0cHJvY2Vzcy5leGl0KDEpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGNvbnN0IGFjdGl2ZSA9IHRlbmFudHMuZmluZCgodCkgPT4gdC5hY3RpdmUpID8/IHRlbmFudHNbMF07XG5cdGNvbnN0IGlzc3VlckJhc2VVcmwgPSBgaHR0cHM6Ly8ke2FjdGl2ZS5uYW1lfWA7XG5cdGNvbnNvbGUubG9nKGBcXG4gIOKckyBBdXRoMCB0ZW5hbnQ6ICR7aXNzdWVyQmFzZVVybH1gKTtcblxuXHRwcm9jZXNzLnN0ZG91dC53cml0ZShcIlxcbiAgRmV0Y2hpbmcgQXV0aDAgQVBJcy4uLlwiKTtcblx0Y29uc3QgdXNlckFwaXMgPSBhdXRoMENsaS5saXN0QXBpcygpLmZpbHRlcigoYSkgPT4gIWEubmFtZS5pbmNsdWRlcyhcIk1hbmFnZW1lbnQgQVBJXCIpKTtcblx0cHJvY2Vzcy5zdGRvdXQud3JpdGUoYCBmb3VuZCAke3VzZXJBcGlzLmxlbmd0aH0uXFxuYCk7XG5cblx0dHlwZSBBcGlDaG9pY2UgPSB7IGxhYmVsOiBzdHJpbmc7IGV4aXN0aW5nOiBzdHJpbmcgfCBudWxsIH07XG5cdGNvbnN0IHByb2plY3ROYW1lID0gd29ya3NwYWNlLm5hbWU7XG5cdGNvbnN0IGFwaUNob2ljZXM6IEFwaUNob2ljZVtdID0gW1xuXHRcdHsgbGFiZWw6IGA8bmV3PiBodHRwczovL2FwaS4ke3Byb2plY3ROYW1lfWAsIGV4aXN0aW5nOiBudWxsIH0sXG5cdFx0Li4udXNlckFwaXMubWFwKChhKSA9PiAoeyBsYWJlbDogYCR7YS5uYW1lfSDigJQgJHthLmlkZW50aWZpZXJ9YCwgZXhpc3Rpbmc6IGEuaWRlbnRpZmllciB9KSksXG5cdF07XG5cblx0Y29uc3QgYXBpU2VsZWN0ZWQgPSBhd2FpdCBwaWNrKFwiXFxuICBTZWxlY3QgQXV0aDAgQVBJOiBcIiwgYXBpQ2hvaWNlcywgKGMpID0+IGMubGFiZWwpO1xuXG5cdGxldCBhdWRpZW5jZTogc3RyaW5nO1xuXHRpZiAoIWFwaVNlbGVjdGVkIHx8IGFwaVNlbGVjdGVkLmV4aXN0aW5nID09PSBudWxsKSB7XG5cdFx0Y29uc3QgZGVmYXVsdElkID0gYGh0dHBzOi8vYXBpLiR7cHJvamVjdE5hbWV9YDtcblx0XHRhdWRpZW5jZSA9IGF3YWl0IGFzayhgICBBUEkgSWRlbnRpZmllciBbJHtkZWZhdWx0SWR9XTogYCwgZGVmYXVsdElkKTtcblx0XHRjb25zb2xlLmxvZyhcIlxcbiAgQ3JlYXRpbmcgQXV0aDAgQVBJLi4uXCIpO1xuXHRcdGF1ZGllbmNlID0gYXV0aDBDbGkuY3JlYXRlQXBpKGAke3Byb2plY3ROYW1lfSBBUElgLCBhdWRpZW5jZSkuaWRlbnRpZmllcjtcblx0XHRjb25zb2xlLmxvZyhgICBcXHUyNzEzIEFQSSBjcmVhdGVkOiAke2F1ZGllbmNlfWApO1xuXHR9IGVsc2Uge1xuXHRcdGF1ZGllbmNlID0gYXBpU2VsZWN0ZWQuZXhpc3Rpbmc7XG5cdFx0Y29uc29sZS5sb2coYCAgXFx1MjcxMyBTZWxlY3RlZDogJHthdWRpZW5jZX1gKTtcblx0fVxuXG5cdHJldHVybiB7IGF1dGhQcm92aWRlcjogXCJhdXRoMFwiLCBpc3N1ZXJCYXNlVXJsLCBhdWRpZW5jZSB9O1xufVxuXG5mdW5jdGlvbiBzY2FmZm9sZCh3b3Jrc3BhY2U6IFdvcmtzcGFjZVNjYWZmb2xkLCBvcHRpb25zOiBBdXRoT3B0aW9ucyk6IHZvaWQge1xuXHRpZiAob3B0aW9ucy5hdXRoUHJvdmlkZXIgIT09IFwiYXV0aDBcIikgcmV0dXJuO1xuXG5cdGNvbnN0IHJlc291cmNlID0gXCJIZWxsb1wiO1xuXG5cdGZvciAoY29uc3QgY29udHJvbGxlciBvZiB3b3Jrc3BhY2UuZ2V0TW9kZWxzKENvbnRyb2xsZXJTb3VyY2VGaWxlKSkge1xuXHRcdGNvbnRyb2xsZXJcblx0XHRcdC5hZGREZWNvcmF0b3IoYEBBdXRob3JpemUoXCJyZWFkXCIsIFwiJHtyZXNvdXJjZX1cIilgKVxuXHRcdFx0LmFkZENvcnRleEltcG9ydChcIkFsbG93QW5vbnltb3VzXCIpXG5cdFx0XHQuYWRkQ29ydGV4SW1wb3J0KFwiQXV0aG9yaXplXCIpXG5cdFx0XHQuYWRkQ29ydGV4SW1wb3J0KFwiSVByaW5jaXBhbFByb3ZpZGVyVG9rZW5cIilcblx0XHRcdC5hZGRDb3J0ZXhJbXBvcnQoXCJJUHJpbmNpcGFsUHJvdmlkZXJcIiwgdHJ1ZSlcblx0XHRcdC5hZGRJbXBvcnQoXCJpbmplY3RcIiwgXCJAZGVjb2hlcmUvY3J1Y2libGUvZGVjb3JhdG9yc1wiKVxuXHRcdFx0LmFkZENvbnN0cnVjdG9yUGFyYW0oXG5cdFx0XHRcdGBAaW5qZWN0KElQcmluY2lwYWxQcm92aWRlclRva2VuKSBwcml2YXRlIHJlYWRvbmx5IHByaW5jaXBhbFByb3ZpZGVyOiBJUHJpbmNpcGFsUHJvdmlkZXJgLFxuXHRcdFx0KTtcblx0XHRjb250cm9sbGVyLmdldE1ldGhvZChcImdldEFsbFwiKS5hZGREZWNvcmF0b3IoXCJAQWxsb3dBbm9ueW1vdXMoKVwiKTtcblx0XHRjb250cm9sbGVyLmdldE1ldGhvZChcImNyZWF0ZVwiKS5hZGREZWNvcmF0b3IoYEBBdXRob3JpemUoXCJjcmVhdGVcIiwgXCIke3Jlc291cmNlfVwiKWApO1xuXHRcdGNvbnRyb2xsZXIuZ2V0TWV0aG9kKFwidXBkYXRlXCIpLmFkZERlY29yYXRvcihgQEF1dGhvcml6ZShcInVwZGF0ZVwiLCBcIiR7cmVzb3VyY2V9XCIpYCk7XG5cdFx0Y29udHJvbGxlci5nZXRNZXRob2QoXCJyZW1vdmVcIikuYWRkRGVjb3JhdG9yKGBAQXV0aG9yaXplKFwiZGVsZXRlXCIsIFwiJHtyZXNvdXJjZX1cIilgKTtcblx0fVxuXG5cdHdvcmtzcGFjZVxuXHRcdC5nZXRNb2RlbDxNYWluU291cmNlRmlsZT4oV0VMTF9LTk9XTl9GSUxFUy5NQUlOX1RTKVxuXHRcdD8uYWRkU2lkZUVmZmVjdEltcG9ydChcIkBkZWNvaGVyZS9jb3J0ZXgvYXV0aFwiKVxuXHRcdC5hZGRCdWlsZGVyQ2FsbChcIi53aXRoQXV0aCgpXCIpO1xuXG5cdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9UZW1wbGF0ZUN1cmx5SW5TdHJpbmc6IGludGVudGlvbmFsIFlBTUwgZW52LXZhciBwbGFjZWhvbGRlcnNcblx0Y29uc3QgaXNzdWVyUGxhY2Vob2xkZXIgPSBcIiR7QVVUSDBfSVNTVUVSX0JBU0VfVVJMfVwiO1xuXHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vVGVtcGxhdGVDdXJseUluU3RyaW5nOiBpbnRlbnRpb25hbCBZQU1MIGVudi12YXIgcGxhY2Vob2xkZXJzXG5cdGNvbnN0IGF1ZFBsYWNlaG9sZGVyID0gXCIke0FVVEgwX0FVRElFTkNFfVwiO1xuXG5cdGNvbnN0IGNvbmZpZ1NlY3Rpb24gPSBgYXV0aDpcXG4gIGRpc2NvdmVyeVVybDogJHtpc3N1ZXJQbGFjZWhvbGRlcn1cXG4gIGF1ZGllbmNlOiAke2F1ZFBsYWNlaG9sZGVyfVxcbmA7XG5cblx0d29ya3NwYWNlLmdldE1vZGVsPENvbmZpZ1lhbWw+KFdFTExfS05PV05fRklMRVMuQ09ORklHX1lBTUwpPy5hZGRTZWN0aW9uKGNvbmZpZ1NlY3Rpb24pO1xuXG5cdHdvcmtzcGFjZVxuXHRcdC5nZXRNb2RlbDxFbnZGaWxlPihXRUxMX0tOT1dOX0ZJTEVTLkVOVl9GSUxFKVxuXHRcdD8uYWRkRW50cnkoXCJBVVRIMF9JU1NVRVJfQkFTRV9VUkxcIiwgb3B0aW9ucy5pc3N1ZXJCYXNlVXJsID8/IFwiXCIpXG5cdFx0LmFkZEVudHJ5KFwiQVVUSDBfQVVESUVOQ0VcIiwgb3B0aW9ucy5hdWRpZW5jZSA/PyBcIlwiKTtcblxuXHR3b3Jrc3BhY2UuYWRkTW9kZWwoXG5cdFx0bmV3IEF1dGhDb25maWdNb2RlbCh7XG5cdFx0XHRpc3N1ZXJCYXNlVXJsOiBvcHRpb25zLmlzc3VlckJhc2VVcmwgPz8gXCJcIixcblx0XHRcdGF1ZGllbmNlOiBvcHRpb25zLmF1ZGllbmNlID8/IFwiXCIsXG5cdFx0fSksXG5cdCk7XG59XG5cbmV4cG9ydCBjb25zdCBBdXRoRmVhdHVyZTogRmVhdHVyZTxBdXRoT3B0aW9ucz4gPSB7IGdldE9wdGlvbnMsIHNjYWZmb2xkIH07XG4iXSwibmFtZXMiOlsiQXV0aEZlYXR1cmUiLCJnZXRPcHRpb25zIiwid29ya3NwYWNlIiwiY2xpT3B0aW9ucyIsImF1dGhQcm92aWRlciIsImNob2ljZXMiLCJsYWJlbCIsInNlbGVjdGVkIiwicGljayIsImMiLCJwcm92aWRlciIsImdldEF1dGgwT3B0aW9ucyIsImF1dGgwQ2xpIiwiaXNJbnN0YWxsZWQiLCJjb25zb2xlIiwiZXJyb3IiLCJwcm9jZXNzIiwiZXhpdCIsInN0ZG91dCIsIndyaXRlIiwidGVuYW50cyIsImxpc3RUZW5hbnRzIiwibGVuZ3RoIiwibG9nIiwibG9naW4iLCJsaXN0QXBpcyIsImVyciIsIkF1dGgwQXV0aEVycm9yIiwiYWN0aXZlIiwiZmluZCIsInQiLCJpc3N1ZXJCYXNlVXJsIiwibmFtZSIsInVzZXJBcGlzIiwiZmlsdGVyIiwiYSIsImluY2x1ZGVzIiwicHJvamVjdE5hbWUiLCJhcGlDaG9pY2VzIiwiZXhpc3RpbmciLCJtYXAiLCJpZGVudGlmaWVyIiwiYXBpU2VsZWN0ZWQiLCJhdWRpZW5jZSIsImRlZmF1bHRJZCIsImFzayIsImNyZWF0ZUFwaSIsInNjYWZmb2xkIiwib3B0aW9ucyIsInJlc291cmNlIiwiY29udHJvbGxlciIsImdldE1vZGVscyIsIkNvbnRyb2xsZXJTb3VyY2VGaWxlIiwiYWRkRGVjb3JhdG9yIiwiYWRkQ29ydGV4SW1wb3J0IiwiYWRkSW1wb3J0IiwiYWRkQ29uc3RydWN0b3JQYXJhbSIsImdldE1ldGhvZCIsImdldE1vZGVsIiwiV0VMTF9LTk9XTl9GSUxFUyIsIk1BSU5fVFMiLCJhZGRTaWRlRWZmZWN0SW1wb3J0IiwiYWRkQnVpbGRlckNhbGwiLCJpc3N1ZXJQbGFjZWhvbGRlciIsImF1ZFBsYWNlaG9sZGVyIiwiY29uZmlnU2VjdGlvbiIsIkNPTkZJR19ZQU1MIiwiYWRkU2VjdGlvbiIsIkVOVl9GSUxFIiwiYWRkRW50cnkiLCJhZGRNb2RlbCIsIkF1dGhDb25maWdNb2RlbCJdLCJtYXBwaW5ncyI6Ijs7OzsrQkFxSmFBOzs7ZUFBQUE7Ozt3QkFySmE7dUJBRU87aUNBSUQ7MkNBQ0s7a0VBRVg7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7OztBQVEx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
|
|
447
|
+
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2VzIjpbIi9ob21lL3J1bm5lci93b3JrL2RlY29oZXJlL2RlY29oZXJlL3Byb2plY3RzL2NyZWF0ZS9zcmMvd2ViYXBpL2ZlYXR1cmVzL2F1dGguZmVhdHVyZS50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBhc2ssIHBpY2sgfSBmcm9tIFwiLi4vLi4vZG9tYWluL3Byb21wdC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBDb25maWdZYW1sIH0gZnJvbSBcIi4uLy4uL21vZGVscy9jb25maWcteWFtbC5tb2RlbC5qc1wiO1xuaW1wb3J0IHsgV0VMTF9LTk9XTl9GSUxFUyB9IGZyb20gXCIuLi8uLi9tb2RlbHMvY29uc3QuanNcIjtcbmltcG9ydCB0eXBlIHsgRW52RmlsZSB9IGZyb20gXCIuLi8uLi9tb2RlbHMvZW52LWZpbGUubW9kZWwuanNcIjtcbmltcG9ydCB0eXBlIHsgUGFja2FnZUpzb24gfSBmcm9tIFwiLi4vLi4vbW9kZWxzL3BhY2thZ2UtanNvbi5tb2RlbC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBXb3Jrc3BhY2VTY2FmZm9sZCB9IGZyb20gXCIuLi8uLi9tb2RlbHMvcHJvamVjdC5tb2RlbC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBGZWF0dXJlIH0gZnJvbSBcIi4uLy4uL3NlcnZpY2VzL3NjYWZmb2xkLnNlcnZpY2UuanNcIjtcbmltcG9ydCB7IFdFQkFQSV9QUk9KRUNUX0RJUiB9IGZyb20gXCIuLi9jcmVhdGUtYXBpLmpzXCI7XG5pbXBvcnQgdHlwZSB7IEFwaVBhY2thZ2VKc29uIH0gZnJvbSBcIi4uL21vZGVscy9hcGktcGFja2FnZS1qc29uLm1vZGVsLmpzXCI7XG5pbXBvcnQgeyBBdXRoQ29uZmlnTW9kZWwgfSBmcm9tIFwiLi4vbW9kZWxzL2F1dGgtY29uZmlnLm1vZGVsLmpzXCI7XG5pbXBvcnQgeyBDb250cm9sbGVyU291cmNlRmlsZSB9IGZyb20gXCIuLi9tb2RlbHMvY29udHJvbGxlci1zb3VyY2UtZmlsZS5tb2RlbC5qc1wiO1xuaW1wb3J0IHR5cGUgeyBNYWluU291cmNlRmlsZSB9IGZyb20gXCIuLi9tb2RlbHMvbWFpbi1zb3VyY2UtZmlsZS5tb2RlbC5qc1wiO1xuaW1wb3J0ICogYXMgYXV0aDBDbGkgZnJvbSBcIi4vYXV0aDAtY2xpLmpzXCI7XG5cbmV4cG9ydCB0eXBlIEF1dGhPcHRpb25zID0ge1xuXHRhdXRoUHJvdmlkZXI/OiBcImF1dGgwXCIgfCBcIm5vbmVcIjtcblx0aXNzdWVyQmFzZVVybD86IHN0cmluZztcblx0YXVkaWVuY2U/OiBzdHJpbmc7XG5cdGRhdGFiYXNlUHJvdmlkZXI/OiBcIm5vbmVcIiB8IFwicG9zdGdyZXMvdHlwZW9ybVwiO1xuXHRhZG1pblVzZXJuYW1lPzogc3RyaW5nO1xuXHRhZG1pblBhc3N3b3JkPzogc3RyaW5nO1xufTtcblxuY29uc3QgQURNSU5fUk9MRSA9IFwiYWRtaW5cIjtcblxuY29uc3QgVVNFUl9FTlRJVFlfVFMgPSBgaW1wb3J0IHsgQ29sdW1uLCBFbnRpdHksIFByaW1hcnlHZW5lcmF0ZWRDb2x1bW4gfSBmcm9tIFwidHlwZW9ybVwiO1xuaW1wb3J0IHR5cGUgeyBFbnRpdHkgYXMgSUVudGl0eSB9IGZyb20gXCJAZGVjb2hlcmUvY29kZXhcIjtcblxuQEVudGl0eSgpXG5leHBvcnQgY2xhc3MgVXNlckVudGl0eSBpbXBsZW1lbnRzIElFbnRpdHkge1xuXFx0QFByaW1hcnlHZW5lcmF0ZWRDb2x1bW4oKVxuXFx0cHVibGljIGlkITogbnVtYmVyO1xuXG5cXHRAQ29sdW1uKHsgdW5pcXVlOiB0cnVlIH0pXG5cXHRwdWJsaWMgc3ViITogc3RyaW5nO1xuXG5cXHRAQ29sdW1uKHsgdHlwZTogXCJ2YXJjaGFyXCIsIG51bGxhYmxlOiB0cnVlIH0pXG5cXHRwdWJsaWMgZW1haWwhOiBzdHJpbmcgfCBudWxsO1xuXG5cXHRAQ29sdW1uKClcblxcdHB1YmxpYyBkaXNwbGF5TmFtZSE6IHN0cmluZztcblxuXFx0LyoqIEFwcC1vd25lZCByb2xlcy4gVGhlIFxcYGFkbWluXFxgIHJvbGUgZ3JhbnRzIENBU0wgXFxgbWFuYWdlXFxgL1xcYGFsbFxcYCAod2lsZGNhcmQpLiAqL1xuXFx0QENvbHVtbih7IHR5cGU6IFwic2ltcGxlLWpzb25cIiwgZGVmYXVsdDogXCJbXVwiIH0pXG5cXHRwdWJsaWMgcm9sZXMhOiBzdHJpbmdbXTtcbn1cbmA7XG5cbmNvbnN0IFVTRVJfUkVQT1NJVE9SWV9UUyA9IGBpbXBvcnQgeyBpbmplY3RhYmxlIH0gZnJvbSBcIkBkZWNvaGVyZS9jcnVjaWJsZS9kZWNvcmF0b3JzXCI7XG5pbXBvcnQgeyBpbmplY3RVbml0T2ZXb3JrIH0gZnJvbSBcIkBkZWNvaGVyZS9jb2RleFwiO1xuaW1wb3J0IHsgVHlwZU9ybVJlcG9zaXRvcnksIFR5cGVPcm1Vbml0T2ZXb3JrIH0gZnJvbSBcIkBkZWNvaGVyZS9jb2RleC10eXBlb3JtXCI7XG5pbXBvcnQgeyBVc2VyRW50aXR5IH0gZnJvbSBcIi4uL2VudGl0aWVzL3VzZXIuZW50aXR5LmpzXCI7XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBVc2VyRW50aXR5UmVwb3NpdG9yeSBleHRlbmRzIFR5cGVPcm1SZXBvc2l0b3J5PFVzZXJFbnRpdHk+IHtcblxcdHB1YmxpYyBjb25zdHJ1Y3RvcihAaW5qZWN0VW5pdE9mV29yaygpIHVuaXRPZldvcms6IFR5cGVPcm1Vbml0T2ZXb3JrKSB7XG5cXHRcXHRzdXBlcih1bml0T2ZXb3JrLCBVc2VyRW50aXR5KTtcblxcdH1cblxuXFx0cHVibGljIGZpbmRCeVN1YihzdWI6IHN0cmluZyk6IFByb21pc2U8VXNlckVudGl0eSB8IG51bGw+IHtcblxcdFxcdHJldHVybiB0aGlzLmZpcnN0T3JEZWZhdWx0KHsgd2hlcmU6IHsgc3ViIH0gfSk7XG5cXHR9XG59XG5gO1xuXG5jb25zdCBVU0VSX1NFUlZJQ0VfVFMgPSBgaW1wb3J0IHsgaW5qZWN0YWJsZSB9IGZyb20gXCJAZGVjb2hlcmUvY3J1Y2libGUvZGVjb3JhdG9yc1wiO1xuaW1wb3J0IHR5cGUgeyBQcmluY2lwYWwgfSBmcm9tIFwiQGRlY29oZXJlL2NvcnRleFwiO1xuaW1wb3J0IHsgVXNlckVudGl0eSB9IGZyb20gXCIuLi9lbnRpdGllcy91c2VyLmVudGl0eS5qc1wiO1xuaW1wb3J0IHsgVXNlckVudGl0eVJlcG9zaXRvcnkgfSBmcm9tIFwiLi4vcmVwb3NpdG9yaWVzL3VzZXIucmVwb3NpdG9yeS5qc1wiO1xuXG5mdW5jdGlvbiBjbGFpbVN0cmluZyhwcmluY2lwYWw6IFByaW5jaXBhbCB8IHVuZGVmaW5lZCwga2V5OiBzdHJpbmcpOiBzdHJpbmcgfCB1bmRlZmluZWQge1xuXFx0Y29uc3QgdmFsdWUgPSBwcmluY2lwYWw/LltrZXldO1xuXFx0cmV0dXJuIHR5cGVvZiB2YWx1ZSA9PT0gXCJzdHJpbmdcIiAmJiB2YWx1ZS5sZW5ndGggPiAwID8gdmFsdWUgOiB1bmRlZmluZWQ7XG59XG5cbkBpbmplY3RhYmxlKClcbmV4cG9ydCBjbGFzcyBVc2VyU2VydmljZSB7XG5cXHRwdWJsaWMgY29uc3RydWN0b3IocHJpdmF0ZSByZWFkb25seSB1c2VyczogVXNlckVudGl0eVJlcG9zaXRvcnkpIHt9XG5cblxcdC8qKlxuXFx0ICogVXBzZXJ0IGEgbG9jYWwgcHJvZmlsZSBrZXllZCBieSBKV1QgXFxgc3ViXFxgLlxuXFx0ICogUHJvZmlsZSBmaWVsZHMgZnJvbSB0aGUgdG9rZW4gZmlsbCBnYXBzOyBzZWVkZWQgcm93cyBrZWVwIGRpc3BsYXlOYW1lL2VtYWlsL3JvbGVzLlxuXFx0ICovXG5cXHRwdWJsaWMgYXN5bmMgZW5zdXJlRnJvbVByaW5jaXBhbChwcmluY2lwYWw6IFByaW5jaXBhbCB8IHVuZGVmaW5lZCk6IFByb21pc2U8VXNlckVudGl0eT4ge1xuXFx0XFx0Y29uc3Qgc3ViID0gcHJpbmNpcGFsPy5zdWI7XG5cXHRcXHRpZiAoIXN1Yikge1xuXFx0XFx0XFx0dGhyb3cgbmV3IEVycm9yKFwiQXV0aGVudGljYXRlZCByZXF1ZXN0IGlzIG1pc3NpbmcgcHJpbmNpcGFsLnN1YlwiKTtcblxcdFxcdH1cblxuXFx0XFx0Y29uc3QgZW1haWwgPVxuXFx0XFx0XFx0Y2xhaW1TdHJpbmcocHJpbmNpcGFsLCBcImVtYWlsXCIpID8/IGNsYWltU3RyaW5nKHByaW5jaXBhbCwgXCJwcmVmZXJyZWRfdXNlcm5hbWVcIik7XG5cXHRcXHRjb25zdCBkaXNwbGF5RnJvbVRva2VuID1cblxcdFxcdFxcdGNsYWltU3RyaW5nKHByaW5jaXBhbCwgXCJuYW1lXCIpID8/XG5cXHRcXHRcXHRjbGFpbVN0cmluZyhwcmluY2lwYWwsIFwibmlja25hbWVcIikgPz9cblxcdFxcdFxcdGVtYWlsO1xuXG5cXHRcXHRjb25zdCBleGlzdGluZyA9IGF3YWl0IHRoaXMudXNlcnMuZmluZEJ5U3ViKHN1Yik7XG5cXHRcXHRpZiAoZXhpc3RpbmcpIHtcblxcdFxcdFxcdGxldCBkaXJ0eSA9IGZhbHNlO1xuXFx0XFx0XFx0aWYgKCFleGlzdGluZy5lbWFpbCAmJiBlbWFpbCkge1xuXFx0XFx0XFx0XFx0ZXhpc3RpbmcuZW1haWwgPSBlbWFpbDtcblxcdFxcdFxcdFxcdGRpcnR5ID0gdHJ1ZTtcblxcdFxcdFxcdH1cblxcdFxcdFxcdGlmIChleGlzdGluZy5kaXNwbGF5TmFtZSA9PT0gZXhpc3Rpbmcuc3ViICYmIGRpc3BsYXlGcm9tVG9rZW4pIHtcblxcdFxcdFxcdFxcdGV4aXN0aW5nLmRpc3BsYXlOYW1lID0gZGlzcGxheUZyb21Ub2tlbjtcblxcdFxcdFxcdFxcdGRpcnR5ID0gdHJ1ZTtcblxcdFxcdFxcdH1cblxcdFxcdFxcdHJldHVybiBkaXJ0eSA/IHRoaXMudXNlcnMuc2F2ZShleGlzdGluZykgOiBleGlzdGluZztcblxcdFxcdH1cblxuXFx0XFx0Y29uc3QgY3JlYXRlZCA9IG5ldyBVc2VyRW50aXR5KCk7XG5cXHRcXHRjcmVhdGVkLnN1YiA9IHN1YjtcblxcdFxcdGNyZWF0ZWQuZW1haWwgPSBlbWFpbCA/PyBudWxsO1xuXFx0XFx0Y3JlYXRlZC5kaXNwbGF5TmFtZSA9IGRpc3BsYXlGcm9tVG9rZW4gPz8gc3ViO1xuXFx0XFx0Y3JlYXRlZC5yb2xlcyA9IEFycmF5LmlzQXJyYXkocHJpbmNpcGFsLnJvbGVzKVxuXFx0XFx0XFx0PyBwcmluY2lwYWwucm9sZXMuZmlsdGVyKChyKTogciBpcyBzdHJpbmcgPT4gdHlwZW9mIHIgPT09IFwic3RyaW5nXCIpXG5cXHRcXHRcXHQ6IFtdO1xuXFx0XFx0cmV0dXJuIHRoaXMudXNlcnMuc2F2ZShjcmVhdGVkKTtcblxcdH1cbn1cbmA7XG5cbmNvbnN0IEFCSUxJVFlfRkFDVE9SWV9UUyA9IGBpbXBvcnQgeyBBYmlsaXR5QnVpbGRlciwgY3JlYXRlTW9uZ29BYmlsaXR5IH0gZnJvbSBcIkBjYXNsL2FiaWxpdHlcIjtcbmltcG9ydCB0eXBlIHsgUHJpbmNpcGFsIH0gZnJvbSBcIkBkZWNvaGVyZS9jb3J0ZXhcIjtcblxuLyoqIFJvb3Qgcm9sZSDigJQgZXhwYW5kcyB0byBDQVNMIFxcYG1hbmFnZVxcYC9cXGBhbGxcXGAgKGNvdmVycyBldmVyeSBmdXR1cmUgYWJpbGl0eSkuICovXG5leHBvcnQgY29uc3QgQURNSU5fUk9MRSA9IFwiYWRtaW5cIjtcblxuLyoqXG4gKiBSb2xlcyBhcmUgY29sbGVjdGlvbnMgb2YgYWJpbGl0aWVzLiBBZG1pbiBpcyBhIHdpbGRjYXJkLCBub3QgYW4gZW51bWVyYXRlZCBsaXN0LlxuICogTm9uLWFkbWluIHByaW5jaXBhbHMga2VlcCB0aGUgZGVmYXVsdCBBdXRoMCBzY29wZSDihpIgYWJpbGl0eSBtYXBwaW5nLlxuICovXG5leHBvcnQgZnVuY3Rpb24gY3JlYXRlQWJpbGl0eUZhY3RvcnkocHJpbmNpcGFsOiBQcmluY2lwYWwpIHtcblxcdGNvbnN0IHsgY2FuLCBidWlsZCB9ID0gbmV3IEFiaWxpdHlCdWlsZGVyKGNyZWF0ZU1vbmdvQWJpbGl0eSk7XG5cXHRpZiAocHJpbmNpcGFsLnJvbGVzPy5pbmNsdWRlcyhBRE1JTl9ST0xFKSkge1xuXFx0XFx0Y2FuKFwibWFuYWdlXCIsIFwiYWxsXCIpO1xuXFx0XFx0cmV0dXJuIGJ1aWxkKCk7XG5cXHR9XG5cXHRmb3IgKGNvbnN0IHNjb3BlIG9mIHByaW5jaXBhbC5zY29wZXMgPz8gW10pIHtcblxcdFxcdGNvbnN0IFthY3Rpb24sIHN1YmplY3RdID0gc2NvcGUuc3BsaXQoXCI6XCIpO1xuXFx0XFx0aWYgKGFjdGlvbiAmJiBzdWJqZWN0KSBjYW4oYWN0aW9uLCBzdWJqZWN0KTtcblxcdH1cblxcdHJldHVybiBidWlsZCgpO1xufVxuXG4vKipcbiAqIE1hcCBKV1QgcGF5bG9hZCDihpIgUHJpbmNpcGFsLiBCb290c3RyYXBzIHRoZSBzZWVkZWQgQXV0aDAgYWRtaW4gXFxgc3ViXFxgIHdpdGhcbiAqIHRoZSBhZG1pbiByb2xlIHNvIGF1dGhvcml6YXRpb24gd29ya3MgYmVmb3JlL3dpdGhvdXQgcm9sZXMgaW4gdGhlIGFjY2VzcyB0b2tlbi5cbiAqL1xuZXhwb3J0IGZ1bmN0aW9uIG1hcFByaW5jaXBhbChwYXlsb2FkOiBSZWNvcmQ8c3RyaW5nLCB1bmtub3duPik6IFByaW5jaXBhbCB7XG5cXHRjb25zdCBzdWIgPSB0eXBlb2YgcGF5bG9hZC5zdWIgPT09IFwic3RyaW5nXCIgPyBwYXlsb2FkLnN1YiA6IFwiXCI7XG5cXHRjb25zdCBzY29wZXMgPSBBcnJheS5pc0FycmF5KHBheWxvYWQuc2NvcGVzKVxuXFx0XFx0PyAocGF5bG9hZC5zY29wZXMgYXMgc3RyaW5nW10pXG5cXHRcXHQ6IHR5cGVvZiBwYXlsb2FkLnNjb3BlID09PSBcInN0cmluZ1wiXG5cXHRcXHRcXHQ/IHBheWxvYWQuc2NvcGUuc3BsaXQoXCIgXCIpXG5cXHRcXHRcXHQ6IHVuZGVmaW5lZDtcblxcdGNvbnN0IGZyb21Ub2tlbiA9IEFycmF5LmlzQXJyYXkocGF5bG9hZC5yb2xlcylcblxcdFxcdD8gKHBheWxvYWQucm9sZXMgYXMgdW5rbm93bltdKS5maWx0ZXIoKHIpOiByIGlzIHN0cmluZyA9PiB0eXBlb2YgciA9PT0gXCJzdHJpbmdcIilcblxcdFxcdDogW107XG5cXHRjb25zdCByb2xlcyA9XG5cXHRcXHRzdWIgJiYgc3ViID09PSBwcm9jZXNzLmVudi5BVVRIMF9BRE1JTl9VU0VSX1NVQlxuXFx0XFx0XFx0PyBbLi4ubmV3IFNldChbQURNSU5fUk9MRSwgLi4uZnJvbVRva2VuXSldXG5cXHRcXHRcXHQ6IGZyb21Ub2tlbi5sZW5ndGggPiAwXG5cXHRcXHRcXHRcXHQ/IGZyb21Ub2tlblxuXFx0XFx0XFx0XFx0OiB1bmRlZmluZWQ7XG5cXHRyZXR1cm4geyAuLi5wYXlsb2FkLCBzdWIsIHJvbGVzLCBzY29wZXMgfTtcbn1cbmA7XG5cbmFzeW5jIGZ1bmN0aW9uIGdldE9wdGlvbnMoXG5cdHdvcmtzcGFjZTogV29ya3NwYWNlU2NhZmZvbGQsXG5cdGNsaU9wdGlvbnM6IFBhcnRpYWw8QXV0aE9wdGlvbnM+LFxuKTogUHJvbWlzZTxQYXJ0aWFsPEF1dGhPcHRpb25zPj4ge1xuXHRpZiAoY2xpT3B0aW9ucy5hdXRoUHJvdmlkZXIgPT09IFwiYXV0aDBcIiAmJiAhY2xpT3B0aW9ucy5pc3N1ZXJCYXNlVXJsKSB7XG5cdFx0cmV0dXJuIGdldEF1dGgwT3B0aW9ucyh3b3Jrc3BhY2UsIGNsaU9wdGlvbnMpO1xuXHR9XG5cdGlmIChjbGlPcHRpb25zLmF1dGhQcm92aWRlciAhPSBudWxsKSByZXR1cm4ge307XG5cblx0Y29uc3QgY2hvaWNlcyA9IFt7IGxhYmVsOiBcIm5vbmVcIiBhcyBjb25zdCB9LCB7IGxhYmVsOiBcImF1dGgwXCIgYXMgY29uc3QgfV07XG5cdGNvbnN0IHNlbGVjdGVkID0gYXdhaXQgcGljayhcIlxcbiAgQXV0aCBwcm92aWRlcjogXCIsIGNob2ljZXMsIChjKSA9PiBjLmxhYmVsKTtcblx0Y29uc3QgcHJvdmlkZXIgPSBzZWxlY3RlZD8ubGFiZWwgPz8gXCJub25lXCI7XG5cblx0aWYgKHByb3ZpZGVyICE9PSBcImF1dGgwXCIpIHJldHVybiB7IGF1dGhQcm92aWRlcjogXCJub25lXCIgfTtcblxuXHRyZXR1cm4gZ2V0QXV0aDBPcHRpb25zKHdvcmtzcGFjZSwgY2xpT3B0aW9ucyk7XG59XG5cbmFzeW5jIGZ1bmN0aW9uIGdldEF1dGgwT3B0aW9ucyhcblx0d29ya3NwYWNlOiBXb3Jrc3BhY2VTY2FmZm9sZCxcblx0Y2xpT3B0aW9uczogUGFydGlhbDxBdXRoT3B0aW9ucz4sXG4pOiBQcm9taXNlPFBhcnRpYWw8QXV0aE9wdGlvbnM+PiB7XG5cdGlmICghYXV0aDBDbGkuaXNJbnN0YWxsZWQoKSkge1xuXHRcdGNvbnNvbGUuZXJyb3IoXG5cdFx0XHRcIlxcbiAgVGhlIEF1dGgwIENMSSBpcyByZXF1aXJlZCBmb3IgYXV0b21hdGVkIHNldHVwLlxcblwiICtcblx0XHRcdFx0XCIgIEluc3RhbGw6IGJyZXcgaW5zdGFsbCBhdXRoMC9hdXRoMC1jbGkvYXV0aDBcXG5cIiArXG5cdFx0XHRcdFwiICBPciB2aXNpdDogaHR0cHM6Ly9naXRodWIuY29tL2F1dGgwL2F1dGgwLWNsaVxcblwiLFxuXHRcdCk7XG5cdFx0cHJvY2Vzcy5leGl0KDEpO1xuXHR9XG5cblx0cHJvY2Vzcy5zdGRvdXQud3JpdGUoXCJcXG4gIENoZWNraW5nIEF1dGgwIGNyZWRlbnRpYWxzLi4uXCIpO1xuXHRsZXQgdGVuYW50cyA9IGF1dGgwQ2xpLmxpc3RUZW5hbnRzKCk7XG5cdGlmICh0ZW5hbnRzLmxlbmd0aCA9PT0gMCkge1xuXHRcdHByb2Nlc3Muc3Rkb3V0LndyaXRlKFwiIG5vdCBsb2dnZWQgaW4uXFxuXCIpO1xuXHRcdGNvbnNvbGUubG9nKFwiICBMb2dnaW5nIGluIHRvIEF1dGgwICh5b3VyIGJyb3dzZXIgd2lsbCBvcGVuKS4uLlwiKTtcblx0XHRpZiAoIWF1dGgwQ2xpLmxvZ2luKCkpIHtcblx0XHRcdGNvbnNvbGUuZXJyb3IoXCJcXG4gIEF1dGgwIGxvZ2luIGZhaWxlZC5cIik7XG5cdFx0XHRwcm9jZXNzLmV4aXQoMSk7XG5cdFx0fVxuXHRcdHRlbmFudHMgPSBhdXRoMENsaS5saXN0VGVuYW50cygpO1xuXHR9XG5cblx0dHJ5IHtcblx0XHRhdXRoMENsaS5saXN0QXBpcygpO1xuXHRcdHByb2Nlc3Muc3Rkb3V0LndyaXRlKFwiIG9rLlxcblwiKTtcblx0fSBjYXRjaCAoZXJyKSB7XG5cdFx0aWYgKGVyciBpbnN0YW5jZW9mIGF1dGgwQ2xpLkF1dGgwQXV0aEVycm9yKSB7XG5cdFx0XHRwcm9jZXNzLnN0ZG91dC53cml0ZShcIiB0b2tlbiBleHBpcmVkLlxcblwiKTtcblx0XHRcdGNvbnNvbGUubG9nKFwiICBSZS1hdXRoZW50aWNhdGluZyAoeW91ciBicm93c2VyIHdpbGwgb3BlbikuLi5cIik7XG5cdFx0XHRpZiAoIWF1dGgwQ2xpLmxvZ2luKCkpIHtcblx0XHRcdFx0Y29uc29sZS5lcnJvcihcIlxcbiAgQXV0aDAgbG9naW4gZmFpbGVkLlwiKTtcblx0XHRcdFx0cHJvY2Vzcy5leGl0KDEpO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdGNvbnN0IGFjdGl2ZSA9IHRlbmFudHMuZmluZCgodCkgPT4gdC5hY3RpdmUpID8/IHRlbmFudHNbMF07XG5cdGNvbnN0IGlzc3VlckJhc2VVcmwgPSBgaHR0cHM6Ly8ke2FjdGl2ZS5uYW1lfWA7XG5cdGNvbnNvbGUubG9nKGBcXG4gIOKckyBBdXRoMCB0ZW5hbnQ6ICR7aXNzdWVyQmFzZVVybH1gKTtcblxuXHRwcm9jZXNzLnN0ZG91dC53cml0ZShcIlxcbiAgRmV0Y2hpbmcgQXV0aDAgQVBJcy4uLlwiKTtcblx0Y29uc3QgdXNlckFwaXMgPSBhdXRoMENsaS5saXN0QXBpcygpLmZpbHRlcigoYSkgPT4gIWEubmFtZS5pbmNsdWRlcyhcIk1hbmFnZW1lbnQgQVBJXCIpKTtcblx0cHJvY2Vzcy5zdGRvdXQud3JpdGUoYCBmb3VuZCAke3VzZXJBcGlzLmxlbmd0aH0uXFxuYCk7XG5cblx0dHlwZSBBcGlDaG9pY2UgPSB7IGxhYmVsOiBzdHJpbmc7IGV4aXN0aW5nOiBzdHJpbmcgfCBudWxsIH07XG5cdGNvbnN0IHByb2plY3ROYW1lID0gd29ya3NwYWNlLm5hbWU7XG5cdGNvbnN0IGFwaUNob2ljZXM6IEFwaUNob2ljZVtdID0gW1xuXHRcdHsgbGFiZWw6IGA8bmV3PiBodHRwczovL2FwaS4ke3Byb2plY3ROYW1lfWAsIGV4aXN0aW5nOiBudWxsIH0sXG5cdFx0Li4udXNlckFwaXMubWFwKChhKSA9PiAoeyBsYWJlbDogYCR7YS5uYW1lfSDigJQgJHthLmlkZW50aWZpZXJ9YCwgZXhpc3Rpbmc6IGEuaWRlbnRpZmllciB9KSksXG5cdF07XG5cblx0Y29uc3QgYXBpU2VsZWN0ZWQgPSBhd2FpdCBwaWNrKFwiXFxuICBTZWxlY3QgQXV0aDAgQVBJOiBcIiwgYXBpQ2hvaWNlcywgKGMpID0+IGMubGFiZWwpO1xuXG5cdGxldCBhdWRpZW5jZTogc3RyaW5nO1xuXHRpZiAoIWFwaVNlbGVjdGVkIHx8IGFwaVNlbGVjdGVkLmV4aXN0aW5nID09PSBudWxsKSB7XG5cdFx0Y29uc3QgZGVmYXVsdElkID0gYGh0dHBzOi8vYXBpLiR7cHJvamVjdE5hbWV9YDtcblx0XHRhdWRpZW5jZSA9IGF3YWl0IGFzayhgICBBUEkgSWRlbnRpZmllciBbJHtkZWZhdWx0SWR9XTogYCwgZGVmYXVsdElkKTtcblx0XHRjb25zb2xlLmxvZyhcIlxcbiAgQ3JlYXRpbmcgQXV0aDAgQVBJLi4uXCIpO1xuXHRcdGF1ZGllbmNlID0gYXV0aDBDbGkuY3JlYXRlQXBpKGAke3Byb2plY3ROYW1lfSBBUElgLCBhdWRpZW5jZSkuaWRlbnRpZmllcjtcblx0XHRjb25zb2xlLmxvZyhgICBcXHUyNzEzIEFQSSBjcmVhdGVkOiAke2F1ZGllbmNlfWApO1xuXHR9IGVsc2Uge1xuXHRcdGF1ZGllbmNlID0gYXBpU2VsZWN0ZWQuZXhpc3Rpbmc7XG5cdFx0Y29uc29sZS5sb2coYCAgXFx1MjcxMyBTZWxlY3RlZDogJHthdWRpZW5jZX1gKTtcblx0XHR0cnkge1xuXHRcdFx0YXV0aDBDbGkudXBkYXRlQXBpU2NvcGVzKGF1ZGllbmNlKTtcblx0XHRcdGNvbnNvbGUubG9nKGAgIFxcdTI3MTMgQVBJIHNjb3BlcyBlbnN1cmVkICgke2F1dGgwQ2xpLkhFTExPX0FQSV9TQ09QRVMuam9pbihcIiwgXCIpfSlgKTtcblx0XHR9IGNhdGNoIHtcblx0XHRcdGNvbnNvbGUuZXJyb3IoXG5cdFx0XHRcdFwiICDinJcgRmFpbGVkIHRvIHVwZGF0ZSBBUEkgc2NvcGVzIOKAlCBhZGQgSGVsbG8gc2NvcGVzIGluIHRoZSBBdXRoMCBkYXNoYm9hcmQuXCIsXG5cdFx0XHQpO1xuXHRcdH1cblx0fVxuXG5cdGNvbnN0IHdpdGhMb2NhbFVzZXJzID0gY2xpT3B0aW9ucy5kYXRhYmFzZVByb3ZpZGVyID09PSBcInBvc3RncmVzL3R5cGVvcm1cIjtcblx0bGV0IGFkbWluVXNlcm5hbWU6IHN0cmluZyB8IHVuZGVmaW5lZDtcblx0bGV0IGFkbWluUGFzc3dvcmQ6IHN0cmluZyB8IHVuZGVmaW5lZDtcblx0aWYgKHdpdGhMb2NhbFVzZXJzKSB7XG5cdFx0YWRtaW5Vc2VybmFtZSA9XG5cdFx0XHRjbGlPcHRpb25zLmFkbWluVXNlcm5hbWUgPz8gKGF3YWl0IGFzayhcIlxcbiAgQWRtaW4gdXNlcm5hbWUgW2FkbWluXTogXCIsIFwiYWRtaW5cIikpO1xuXHRcdGFkbWluUGFzc3dvcmQgPSBjbGlPcHRpb25zLmFkbWluUGFzc3dvcmQ7XG5cdFx0aWYgKGFkbWluUGFzc3dvcmQgPT0gbnVsbCkge1xuXHRcdFx0YWRtaW5QYXNzd29yZCA9IGF3YWl0IGFzayhcIiAgQWRtaW4gcGFzc3dvcmQgKGxlYXZlIGJsYW5rIHRvIGdlbmVyYXRlKTogXCIpO1xuXHRcdFx0aWYgKCFhZG1pblBhc3N3b3JkKSB7XG5cdFx0XHRcdGFkbWluUGFzc3dvcmQgPSBhdXRoMENsaS5nZW5lcmF0ZUFkbWluUGFzc3dvcmQoKTtcblx0XHRcdFx0Y29uc29sZS5sb2coYCAg4pyTIEdlbmVyYXRlZCBhZG1pbiBwYXNzd29yZCAod3JpdHRlbiB0byAuZW52KTogJHthZG1pblBhc3N3b3JkfWApO1xuXHRcdFx0fVxuXHRcdH1cblx0fVxuXG5cdHJldHVybiB7XG5cdFx0YXV0aFByb3ZpZGVyOiBcImF1dGgwXCIsXG5cdFx0aXNzdWVyQmFzZVVybCxcblx0XHRhdWRpZW5jZSxcblx0XHQuLi4od2l0aExvY2FsVXNlcnMgPyB7IGFkbWluVXNlcm5hbWUsIGFkbWluUGFzc3dvcmQgfSA6IHt9KSxcblx0fTtcbn1cblxuZnVuY3Rpb24gYWRtaW5FbWFpbCh3b3Jrc3BhY2VOYW1lOiBzdHJpbmcsIHVzZXJuYW1lOiBzdHJpbmcpOiBzdHJpbmcge1xuXHRpZiAodXNlcm5hbWUuaW5jbHVkZXMoXCJAXCIpKSByZXR1cm4gdXNlcm5hbWU7XG5cdGNvbnN0IHNsdWcgPSB3b3Jrc3BhY2VOYW1lLnRvTG93ZXJDYXNlKCkucmVwbGFjZSgvW15hLXowLTktXS9nLCBcIi1cIik7XG5cdHJldHVybiBgJHt1c2VybmFtZX1AJHtzbHVnfS5leGFtcGxlLmNvbWA7XG59XG5cbmZ1bmN0aW9uIGNyZWF0ZUF1dGgwQWRtaW5Vc2VyKFxuXHR3b3Jrc3BhY2U6IFdvcmtzcGFjZVNjYWZmb2xkLFxuXHRvcHRpb25zOiBBdXRoT3B0aW9ucyxcblx0YXV0aENvbmZpZzogQXV0aENvbmZpZ01vZGVsLFxuKTogdm9pZCB7XG5cdGNvbnN0IHVzZXJuYW1lID0gb3B0aW9ucy5hZG1pblVzZXJuYW1lID8/IFwiYWRtaW5cIjtcblx0Y29uc3QgcGFzc3dvcmQgPSBvcHRpb25zLmFkbWluUGFzc3dvcmQ7XG5cdGlmICghcGFzc3dvcmQpIHJldHVybjtcblxuXHRjb25zdCBlbWFpbCA9IGFkbWluRW1haWwod29ya3NwYWNlLm5hbWUsIHVzZXJuYW1lKTtcblx0dHJ5IHtcblx0XHRjb25zdCBhZG1pbiA9IGF1dGgwQ2xpLmNyZWF0ZUFkbWluRGF0YWJhc2VVc2VyKHsgZW1haWwsIHBhc3N3b3JkLCB1c2VybmFtZSB9KTtcblx0XHRhdXRoQ29uZmlnLnNldEFkbWluVXNlcih7XG5cdFx0XHRzdWI6IGFkbWluLnVzZXJfaWQsXG5cdFx0XHRlbWFpbDogYWRtaW4uZW1haWwsXG5cdFx0XHRwYXNzd29yZDogYWRtaW4ucGFzc3dvcmQsXG5cdFx0XHR1c2VybmFtZTogYWRtaW4udXNlcm5hbWUsXG5cdFx0fSk7XG5cdFx0d29ya3NwYWNlXG5cdFx0XHQuZ2V0TW9kZWw8RW52RmlsZT4oV0VMTF9LTk9XTl9GSUxFUy5FTlZfRklMRSlcblx0XHRcdD8uYWRkRW50cnkoXCJBVVRIMF9BRE1JTl9VU0VSX1NVQlwiLCBhZG1pbi51c2VyX2lkKVxuXHRcdFx0LmFkZEVudHJ5KFwiQVVUSDBfQURNSU5fVVNFUl9FTUFJTFwiLCBhZG1pbi5lbWFpbClcblx0XHRcdC5hZGRFbnRyeShcIkFVVEgwX0FETUlOX1VTRVJfUEFTU1dPUkRcIiwgYWRtaW4ucGFzc3dvcmQpXG5cdFx0XHQuYWRkRW50cnkoXCJBVVRIMF9BRE1JTl9VU0VSTkFNRVwiLCBhZG1pbi51c2VybmFtZSk7XG5cdFx0Y29uc29sZS5sb2coYCAg4pyTIEF1dGgwIGFkbWluIHVzZXIgcmVhZHk6ICR7YWRtaW4uZW1haWx9IChyb2xlOiAke0FETUlOX1JPTEV9KWApO1xuXHRcdGNvbnNvbGUubG9nKGAgICAgTG9naW4gd2l0aCBFTUFJTCAobm90IHVzZXJuYW1lKTogJHthZG1pbi5lbWFpbH1gKTtcblx0XHRjb25zb2xlLmxvZyhgICAgIFBhc3N3b3JkOiBzZWUgQVVUSDBfQURNSU5fVVNFUl9QQVNTV09SRCBpbiAuZW52YCk7XG5cdH0gY2F0Y2ggKGVycikge1xuXHRcdGNvbnNvbGUuZXJyb3IoXG5cdFx0XHRgICDinJcgRmFpbGVkIHRvIGVuc3VyZSBBdXRoMCBhZG1pbiB1c2VyICgke2VtYWlsfSk6ICR7ZXJyIGluc3RhbmNlb2YgRXJyb3IgPyBlcnIubWVzc2FnZSA6IGVycn1gLFxuXHRcdCk7XG5cdH1cbn1cblxuZnVuY3Rpb24gc2NhZmZvbGRMb2NhbFVzZXJQcm9maWxlKHdvcmtzcGFjZTogV29ya3NwYWNlU2NhZmZvbGQpOiB2b2lkIHtcblx0d29ya3NwYWNlXG5cdFx0LmdldE1vZGVsPFBhY2thZ2VKc29uPihXRUxMX0tOT1dOX0ZJTEVTLlBBQ0tBR0VfSlNPTilcblx0XHQ/LmFkZERlcGVuZGVuY3koXCJAY2FzbC9hYmlsaXR5XCIsIFwiXjYuOC4xXCIpO1xuXHR3b3Jrc3BhY2Vcblx0XHQuZ2V0TW9kZWw8QXBpUGFja2FnZUpzb24+KFdFTExfS05PV05fRklMRVMuQVBJX1BBQ0tBR0VfSlNPTilcblx0XHQ/LmFkZERlcGVuZGVuY3koXCJAY2FzbC9hYmlsaXR5XCIsIFwiXjYuOC4xXCIpO1xuXG5cdGNvbnN0IG1haW4gPSB3b3Jrc3BhY2UuZ2V0TW9kZWw8TWFpblNvdXJjZUZpbGU+KFdFTExfS05PV05fRklMRVMuTUFJTl9UUyk7XG5cdG1haW5cblx0XHQ/LmFkZEVudGl0eSh7IGNsYXNzTmFtZTogXCJVc2VyRW50aXR5XCIsIGltcG9ydFBhdGg6IFwiLi9lbnRpdGllcy91c2VyLmVudGl0eS5qc1wiIH0pXG5cdFx0LmFkZFJlcG9zaXRvcnkoe1xuXHRcdFx0Y2xhc3NOYW1lOiBcIlVzZXJFbnRpdHlSZXBvc2l0b3J5XCIsXG5cdFx0XHRpbXBvcnRQYXRoOiBcIi4vcmVwb3NpdG9yaWVzL3VzZXIucmVwb3NpdG9yeS5qc1wiLFxuXHRcdH0pXG5cdFx0LmFkZFNlcnZpY2Uoe1xuXHRcdFx0Y2xhc3NOYW1lOiBcIlVzZXJTZXJ2aWNlXCIsXG5cdFx0XHRpbXBvcnRQYXRoOiBcIi4vc2VydmljZXMvdXNlci5zZXJ2aWNlLmpzXCIsXG5cdFx0XHRzY29wZTogXCJyZXF1ZXN0XCIsXG5cdFx0fSlcblx0XHQuYWRkSW1wb3J0KFwiY3JlYXRlQWJpbGl0eUZhY3RvcnlcIiwgXCIuL2F1dGgvYWJpbGl0eS5mYWN0b3J5LmpzXCIpXG5cdFx0LmFkZEltcG9ydChcIm1hcFByaW5jaXBhbFwiLCBcIi4vYXV0aC9hYmlsaXR5LmZhY3RvcnkuanNcIilcblx0XHQuc2V0VHlwZU9ybVNlZWQoXG5cdFx0XHRbXG5cdFx0XHRcdFwiY29uc3Qgc3ViID0gcHJvY2Vzcy5lbnYuQVVUSDBfQURNSU5fVVNFUl9TVUI7XCIsXG5cdFx0XHRcdFwiaWYgKCFzdWIpIHJldHVybjtcIixcblx0XHRcdFx0XCJjb25zdCByZXBvID0gZGF0YVNvdXJjZS5nZXRSZXBvc2l0b3J5KFVzZXJFbnRpdHkpO1wiLFxuXHRcdFx0XHRcImNvbnN0IGV4aXN0aW5nID0gYXdhaXQgcmVwby5maW5kT25lKHsgd2hlcmU6IHsgc3ViIH0gfSk7XCIsXG5cdFx0XHRcdFwiaWYgKGV4aXN0aW5nKSByZXR1cm47XCIsXG5cdFx0XHRcdFwiYXdhaXQgcmVwby5zYXZlKHJlcG8uY3JlYXRlKHtcIixcblx0XHRcdFx0XCIgIHN1YixcIixcblx0XHRcdFx0XCIgIGVtYWlsOiBwcm9jZXNzLmVudi5BVVRIMF9BRE1JTl9VU0VSX0VNQUlMID8/IG51bGwsXCIsXG5cdFx0XHRcdCcgIGRpc3BsYXlOYW1lOiBwcm9jZXNzLmVudi5BVVRIMF9BRE1JTl9VU0VSTkFNRSA/PyBcImFkbWluXCIsJyxcblx0XHRcdFx0JyAgcm9sZXM6IFtcImFkbWluXCJdLCcsXG5cdFx0XHRcdFwifSkpO1wiLFxuXHRcdFx0XS5qb2luKFwiIFwiKSxcblx0XHQpO1xuXG5cdHdvcmtzcGFjZS5nZXRQcm9qZWN0KFdFQkFQSV9QUk9KRUNUX0RJUik/LmFkZEZpbGUoe1xuXHRcdGZpbGVzOiAoKSA9PiBbXG5cdFx0XHR7IGZpbGVQYXRoOiBcInNyYy9lbnRpdGllcy91c2VyLmVudGl0eS50c1wiLCBjb250ZW50OiBVU0VSX0VOVElUWV9UUyB9LFxuXHRcdFx0eyBmaWxlUGF0aDogXCJzcmMvcmVwb3NpdG9yaWVzL3VzZXIucmVwb3NpdG9yeS50c1wiLCBjb250ZW50OiBVU0VSX1JFUE9TSVRPUllfVFMgfSxcblx0XHRcdHsgZmlsZVBhdGg6IFwic3JjL3NlcnZpY2VzL3VzZXIuc2VydmljZS50c1wiLCBjb250ZW50OiBVU0VSX1NFUlZJQ0VfVFMgfSxcblx0XHRcdHsgZmlsZVBhdGg6IFwic3JjL2F1dGgvYWJpbGl0eS5mYWN0b3J5LnRzXCIsIGNvbnRlbnQ6IEFCSUxJVFlfRkFDVE9SWV9UUyB9LFxuXHRcdF0sXG5cdH0pO1xuXG5cdGZvciAoY29uc3QgY29udHJvbGxlciBvZiB3b3Jrc3BhY2UuZ2V0TW9kZWxzKENvbnRyb2xsZXJTb3VyY2VGaWxlKSkge1xuXHRcdGNvbnRyb2xsZXJcblx0XHRcdC5hZGRJbXBvcnQoXCJVc2VyU2VydmljZVwiLCBcIi4uL3NlcnZpY2VzL3VzZXIuc2VydmljZS5qc1wiKVxuXHRcdFx0LmFkZENvbnN0cnVjdG9yUGFyYW0oXCJwcml2YXRlIHJlYWRvbmx5IHVzZXJzOiBVc2VyU2VydmljZVwiKTtcblx0XHRjb250cm9sbGVyLmdldE1ldGhvZChcImdldE9uZVwiKS5zZXRBc3luYyh0cnVlKS5zZXRCb2R5KFtcblx0XHRcdFwiY29uc3QgdXNlciA9IGF3YWl0IHRoaXMudXNlcnMuZW5zdXJlRnJvbVByaW5jaXBhbCh0aGlzLnByaW5jaXBhbFByb3ZpZGVyLmN1cnJlbnRQcmluY2lwYWwpO1wiLFxuXHRcdFx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub1RlbXBsYXRlQ3VybHlJblN0cmluZzogdGVtcGxhdGUgbGl0ZXJhbCBpbiBnZW5lcmF0ZWQgY29kZVxuXHRcdFx0XCJyZXR1cm4geyBpZCwgbWVzc2FnZTogYEhlbGxvICR7dXNlci5kaXNwbGF5TmFtZX0hYCwgdXNlcm5hbWU6IHVzZXIuZGlzcGxheU5hbWUgfTtcIixcblx0XHRdKTtcblx0fVxufVxuXG5mdW5jdGlvbiBzY2FmZm9sZCh3b3Jrc3BhY2U6IFdvcmtzcGFjZVNjYWZmb2xkLCBvcHRpb25zOiBBdXRoT3B0aW9ucyk6IHZvaWQge1xuXHRpZiAob3B0aW9ucy5hdXRoUHJvdmlkZXIgIT09IFwiYXV0aDBcIikgcmV0dXJuO1xuXG5cdGNvbnN0IHJlc291cmNlID0gXCJIZWxsb1wiO1xuXHRjb25zdCB3aXRoTG9jYWxVc2VycyA9IG9wdGlvbnMuZGF0YWJhc2VQcm92aWRlciA9PT0gXCJwb3N0Z3Jlcy90eXBlb3JtXCI7XG5cblx0Zm9yIChjb25zdCBjb250cm9sbGVyIG9mIHdvcmtzcGFjZS5nZXRNb2RlbHMoQ29udHJvbGxlclNvdXJjZUZpbGUpKSB7XG5cdFx0Y29udHJvbGxlclxuXHRcdFx0LmFkZERlY29yYXRvcihgQEF1dGhvcml6ZShcInJlYWRcIiwgXCIke3Jlc291cmNlfVwiKWApXG5cdFx0XHQuYWRkQ29ydGV4SW1wb3J0KFwiQWxsb3dBbm9ueW1vdXNcIilcblx0XHRcdC5hZGRDb3J0ZXhJbXBvcnQoXCJBdXRob3JpemVcIilcblx0XHRcdC5hZGRDb3J0ZXhJbXBvcnQoXCJJUHJpbmNpcGFsUHJvdmlkZXJUb2tlblwiKVxuXHRcdFx0LmFkZENvcnRleEltcG9ydChcIklQcmluY2lwYWxQcm92aWRlclwiLCB0cnVlKVxuXHRcdFx0LmFkZEltcG9ydChcImluamVjdFwiLCBcIkBkZWNvaGVyZS9jcnVjaWJsZS9kZWNvcmF0b3JzXCIpXG5cdFx0XHQuYWRkQ29uc3RydWN0b3JQYXJhbShcblx0XHRcdFx0YEBpbmplY3QoSVByaW5jaXBhbFByb3ZpZGVyVG9rZW4pIHByaXZhdGUgcmVhZG9ubHkgcHJpbmNpcGFsUHJvdmlkZXI6IElQcmluY2lwYWxQcm92aWRlcmAsXG5cdFx0XHQpO1xuXHRcdGNvbnRyb2xsZXIuZ2V0TWV0aG9kKFwiZ2V0QWxsXCIpLmFkZERlY29yYXRvcihcIkBBbGxvd0Fub255bW91cygpXCIpO1xuXHRcdGlmICghd2l0aExvY2FsVXNlcnMpIHtcblx0XHRcdGNvbnRyb2xsZXIuZ2V0TWV0aG9kKFwiZ2V0T25lXCIpLnNldEJvZHkoW1xuXHRcdFx0XHRcImNvbnN0IHByaW5jaXBhbCA9IHRoaXMucHJpbmNpcGFsUHJvdmlkZXIuY3VycmVudFByaW5jaXBhbDtcIixcblx0XHRcdFx0XCJjb25zdCB1c2VybmFtZSA9XCIsXG5cdFx0XHRcdCdcXHQodHlwZW9mIHByaW5jaXBhbD8ubmFtZSA9PT0gXCJzdHJpbmdcIiAmJiBwcmluY2lwYWwubmFtZSkgfHwnLFxuXHRcdFx0XHQnXFx0KHR5cGVvZiBwcmluY2lwYWw/Lm5pY2tuYW1lID09PSBcInN0cmluZ1wiICYmIHByaW5jaXBhbC5uaWNrbmFtZSkgfHwnLFxuXHRcdFx0XHQnXFx0KHR5cGVvZiBwcmluY2lwYWw/LmVtYWlsID09PSBcInN0cmluZ1wiICYmIHByaW5jaXBhbC5lbWFpbCkgfHwnLFxuXHRcdFx0XHQnXFx0KHR5cGVvZiBwcmluY2lwYWw/LnByZWZlcnJlZF91c2VybmFtZSA9PT0gXCJzdHJpbmdcIiAmJiBwcmluY2lwYWwucHJlZmVycmVkX3VzZXJuYW1lKSB8fCcsXG5cdFx0XHRcdFwiXFx0cHJpbmNpcGFsPy5zdWIgfHxcIixcblx0XHRcdFx0J1xcdFwidW5rbm93blwiOycsXG5cdFx0XHRcdC8vIGJpb21lLWlnbm9yZSBsaW50L3N1c3BpY2lvdXMvbm9UZW1wbGF0ZUN1cmx5SW5TdHJpbmc6IHRlbXBsYXRlIGxpdGVyYWwgaW4gZ2VuZXJhdGVkIGNvZGVcblx0XHRcdFx0XCJyZXR1cm4geyBpZCwgbWVzc2FnZTogYEhlbGxvICR7dXNlcm5hbWV9IWAsIHVzZXJuYW1lIH07XCIsXG5cdFx0XHRdKTtcblx0XHR9XG5cdFx0Y29udHJvbGxlci5nZXRNZXRob2QoXCJjcmVhdGVcIikuYWRkRGVjb3JhdG9yKGBAQXV0aG9yaXplKFwiY3JlYXRlXCIsIFwiJHtyZXNvdXJjZX1cIilgKTtcblx0XHRjb250cm9sbGVyLmdldE1ldGhvZChcInVwZGF0ZVwiKS5hZGREZWNvcmF0b3IoYEBBdXRob3JpemUoXCJ1cGRhdGVcIiwgXCIke3Jlc291cmNlfVwiKWApO1xuXHRcdGNvbnRyb2xsZXIuZ2V0TWV0aG9kKFwicmVtb3ZlXCIpLmFkZERlY29yYXRvcihgQEF1dGhvcml6ZShcImRlbGV0ZVwiLCBcIiR7cmVzb3VyY2V9XCIpYCk7XG5cdH1cblxuXHRjb25zdCBtYWluID0gd29ya3NwYWNlLmdldE1vZGVsPE1haW5Tb3VyY2VGaWxlPihXRUxMX0tOT1dOX0ZJTEVTLk1BSU5fVFMpO1xuXHRtYWluPy5hZGRTaWRlRWZmZWN0SW1wb3J0KFwiQGRlY29oZXJlL2NvcnRleC9hdXRoXCIpO1xuXG5cdGlmICh3aXRoTG9jYWxVc2Vycykge1xuXHRcdHNjYWZmb2xkTG9jYWxVc2VyUHJvZmlsZSh3b3Jrc3BhY2UpO1xuXHRcdG1haW4/LmFkZEJ1aWxkZXJDYWxsKFwiLndpdGhBdXRoKGNyZWF0ZUFiaWxpdHlGYWN0b3J5LCB7IHByaW5jaXBhbE1hcHBlcjogbWFwUHJpbmNpcGFsIH0pXCIpO1xuXHR9IGVsc2Uge1xuXHRcdG1haW4/LmFkZEJ1aWxkZXJDYWxsKFwiLndpdGhBdXRoKClcIik7XG5cdH1cblxuXHQvLyBiaW9tZS1pZ25vcmUgbGludC9zdXNwaWNpb3VzL25vVGVtcGxhdGVDdXJseUluU3RyaW5nOiBpbnRlbnRpb25hbCBZQU1MIGVudi12YXIgcGxhY2Vob2xkZXJzXG5cdGNvbnN0IGlzc3VlclBsYWNlaG9sZGVyID0gXCIke0FVVEgwX0lTU1VFUl9CQVNFX1VSTH1cIjtcblx0Ly8gYmlvbWUtaWdub3JlIGxpbnQvc3VzcGljaW91cy9ub1RlbXBsYXRlQ3VybHlJblN0cmluZzogaW50ZW50aW9uYWwgWUFNTCBlbnYtdmFyIHBsYWNlaG9sZGVyc1xuXHRjb25zdCBhdWRQbGFjZWhvbGRlciA9IFwiJHtBVVRIMF9BVURJRU5DRX1cIjtcblxuXHRjb25zdCBjb25maWdTZWN0aW9uID0gYGF1dGg6XFxuICBkaXNjb3ZlcnlVcmw6ICR7aXNzdWVyUGxhY2Vob2xkZXJ9XFxuICBhdWRpZW5jZTogJHthdWRQbGFjZWhvbGRlcn1cXG5gO1xuXG5cdHdvcmtzcGFjZS5nZXRNb2RlbDxDb25maWdZYW1sPihXRUxMX0tOT1dOX0ZJTEVTLkNPTkZJR19ZQU1MKT8uYWRkU2VjdGlvbihjb25maWdTZWN0aW9uKTtcblxuXHR3b3Jrc3BhY2Vcblx0XHQuZ2V0TW9kZWw8RW52RmlsZT4oV0VMTF9LTk9XTl9GSUxFUy5FTlZfRklMRSlcblx0XHQ/LmFkZEVudHJ5KFwiQVVUSDBfSVNTVUVSX0JBU0VfVVJMXCIsIG9wdGlvbnMuaXNzdWVyQmFzZVVybCA/PyBcIlwiKVxuXHRcdC5hZGRFbnRyeShcIkFVVEgwX0FVRElFTkNFXCIsIG9wdGlvbnMuYXVkaWVuY2UgPz8gXCJcIik7XG5cblx0Y29uc3QgYXV0aENvbmZpZyA9IG5ldyBBdXRoQ29uZmlnTW9kZWwoe1xuXHRcdGlzc3VlckJhc2VVcmw6IG9wdGlvbnMuaXNzdWVyQmFzZVVybCA/PyBcIlwiLFxuXHRcdGF1ZGllbmNlOiBvcHRpb25zLmF1ZGllbmNlID8/IFwiXCIsXG5cdH0pO1xuXHR3b3Jrc3BhY2UuYWRkTW9kZWwoYXV0aENvbmZpZyk7XG5cblx0aWYgKHdpdGhMb2NhbFVzZXJzICYmIG9wdGlvbnMuYWRtaW5QYXNzd29yZCkge1xuXHRcdGNyZWF0ZUF1dGgwQWRtaW5Vc2VyKHdvcmtzcGFjZSwgb3B0aW9ucywgYXV0aENvbmZpZyk7XG5cdH1cbn1cblxuZXhwb3J0IGNvbnN0IEF1dGhGZWF0dXJlOiBGZWF0dXJlPEF1dGhPcHRpb25zPiA9IHsgZ2V0T3B0aW9ucywgc2NhZmZvbGQgfTtcbiJdLCJuYW1lcyI6WyJBdXRoRmVhdHVyZSIsIkFETUlOX1JPTEUiLCJVU0VSX0VOVElUWV9UUyIsIlVTRVJfUkVQT1NJVE9SWV9UUyIsIlVTRVJfU0VSVklDRV9UUyIsIkFCSUxJVFlfRkFDVE9SWV9UUyIsImdldE9wdGlvbnMiLCJ3b3Jrc3BhY2UiLCJjbGlPcHRpb25zIiwiYXV0aFByb3ZpZGVyIiwiaXNzdWVyQmFzZVVybCIsImdldEF1dGgwT3B0aW9ucyIsImNob2ljZXMiLCJsYWJlbCIsInNlbGVjdGVkIiwicGljayIsImMiLCJwcm92aWRlciIsImF1dGgwQ2xpIiwiaXNJbnN0YWxsZWQiLCJjb25zb2xlIiwiZXJyb3IiLCJwcm9jZXNzIiwiZXhpdCIsInN0ZG91dCIsIndyaXRlIiwidGVuYW50cyIsImxpc3RUZW5hbnRzIiwibGVuZ3RoIiwibG9nIiwibG9naW4iLCJsaXN0QXBpcyIsImVyciIsIkF1dGgwQXV0aEVycm9yIiwiYWN0aXZlIiwiZmluZCIsInQiLCJuYW1lIiwidXNlckFwaXMiLCJmaWx0ZXIiLCJhIiwiaW5jbHVkZXMiLCJwcm9qZWN0TmFtZSIsImFwaUNob2ljZXMiLCJleGlzdGluZyIsIm1hcCIsImlkZW50aWZpZXIiLCJhcGlTZWxlY3RlZCIsImF1ZGllbmNlIiwiZGVmYXVsdElkIiwiYXNrIiwiY3JlYXRlQXBpIiwidXBkYXRlQXBpU2NvcGVzIiwiSEVMTE9fQVBJX1NDT1BFUyIsImpvaW4iLCJ3aXRoTG9jYWxVc2VycyIsImRhdGFiYXNlUHJvdmlkZXIiLCJhZG1pblVzZXJuYW1lIiwiYWRtaW5QYXNzd29yZCIsImdlbmVyYXRlQWRtaW5QYXNzd29yZCIsImFkbWluRW1haWwiLCJ3b3Jrc3BhY2VOYW1lIiwidXNlcm5hbWUiLCJzbHVnIiwidG9Mb3dlckNhc2UiLCJyZXBsYWNlIiwiY3JlYXRlQXV0aDBBZG1pblVzZXIiLCJvcHRpb25zIiwiYXV0aENvbmZpZyIsInBhc3N3b3JkIiwiZW1haWwiLCJhZG1pbiIsImNyZWF0ZUFkbWluRGF0YWJhc2VVc2VyIiwic2V0QWRtaW5Vc2VyIiwic3ViIiwidXNlcl9pZCIsImdldE1vZGVsIiwiV0VMTF9LTk9XTl9GSUxFUyIsIkVOVl9GSUxFIiwiYWRkRW50cnkiLCJFcnJvciIsIm1lc3NhZ2UiLCJzY2FmZm9sZExvY2FsVXNlclByb2ZpbGUiLCJQQUNLQUdFX0pTT04iLCJhZGREZXBlbmRlbmN5IiwiQVBJX1BBQ0tBR0VfSlNPTiIsIm1haW4iLCJNQUlOX1RTIiwiYWRkRW50aXR5IiwiY2xhc3NOYW1lIiwiaW1wb3J0UGF0aCIsImFkZFJlcG9zaXRvcnkiLCJhZGRTZXJ2aWNlIiwic2NvcGUiLCJhZGRJbXBvcnQiLCJzZXRUeXBlT3JtU2VlZCIsImdldFByb2plY3QiLCJXRUJBUElfUFJPSkVDVF9ESVIiLCJhZGRGaWxlIiwiZmlsZXMiLCJmaWxlUGF0aCIsImNvbnRlbnQiLCJjb250cm9sbGVyIiwiZ2V0TW9kZWxzIiwiQ29udHJvbGxlclNvdXJjZUZpbGUiLCJhZGRDb25zdHJ1Y3RvclBhcmFtIiwiZ2V0TWV0aG9kIiwic2V0QXN5bmMiLCJzZXRCb2R5Iiwic2NhZmZvbGQiLCJyZXNvdXJjZSIsImFkZERlY29yYXRvciIsImFkZENvcnRleEltcG9ydCIsImFkZFNpZGVFZmZlY3RJbXBvcnQiLCJhZGRCdWlsZGVyQ2FsbCIsImlzc3VlclBsYWNlaG9sZGVyIiwiYXVkUGxhY2Vob2xkZXIiLCJjb25maWdTZWN0aW9uIiwiQ09ORklHX1lBTUwiLCJhZGRTZWN0aW9uIiwiQXV0aENvbmZpZ01vZGVsIiwiYWRkTW9kZWwiXSwibWFwcGluZ3MiOiI7Ozs7K0JBMGNhQTs7O2VBQUFBOzs7d0JBMWNhO3VCQUVPOzJCQUtFO2lDQUVIOzJDQUNLO2tFQUVYOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUFXMUIsTUFBTUMsYUFBYTtBQUVuQixNQUFNQyxpQkFBaUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBcUJ4QixDQUFDO0FBRUQsTUFBTUMscUJBQXFCLENBQUM7Ozs7Ozs7Ozs7Ozs7OztBQWU1QixDQUFDO0FBRUQsTUFBTUMsa0JBQWtCLENBQUM7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7QUF1RHpCLENBQUM7QUFFRCxNQUFNQyxxQkFBcUIsQ0FBQzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0FBNkM1QixDQUFDO0FBRUQsZUFBZUMsV0FDZEMsU0FBNEIsRUFDNUJDLFVBQWdDO0lBRWhDLElBQUlBLFdBQVdDLFlBQVksS0FBSyxXQUFXLENBQUNELFdBQVdFLGFBQWEsRUFBRTtRQUNyRSxPQUFPQyxnQkFBZ0JKLFdBQVdDO0lBQ25DO0lBQ0EsSUFBSUEsV0FBV0MsWUFBWSxJQUFJLE1BQU0sT0FBTyxDQUFDO0lBRTdDLE1BQU1HLFVBQVU7UUFBQztZQUFFQyxPQUFPO1FBQWdCO1FBQUc7WUFBRUEsT0FBTztRQUFpQjtLQUFFO0lBQ3pFLE1BQU1DLFdBQVcsTUFBTUMsSUFBQUEsWUFBSSxFQUFDLHVCQUF1QkgsU0FBUyxDQUFDSSxJQUFNQSxFQUFFSCxLQUFLO0lBQzFFLE1BQU1JLFdBQVdILFVBQVVELFNBQVM7SUFFcEMsSUFBSUksYUFBYSxTQUFTLE9BQU87UUFBRVIsY0FBYztJQUFPO0lBRXhELE9BQU9FLGdCQUFnQkosV0FBV0M7QUFDbkM7QUFFQSxlQUFlRyxnQkFDZEosU0FBNEIsRUFDNUJDLFVBQWdD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
|