every-plugin 0.4.13 → 0.4.14

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.
@@ -0,0 +1,524 @@
1
+ const require_chunk = require('./chunk-zltIcp7o.cjs');
2
+ const require_normalize = require('./normalize-D4Qh0wVk.cjs');
3
+ const require_package$1 = require('./package-CgNIVjVe.cjs');
4
+ let effect = require("effect");
5
+ let zod = require("zod");
6
+ let __orpc_server = require("@orpc/server");
7
+ let __orpc_contract = require("@orpc/contract");
8
+ let __better_fetch_fetch = require("@better-fetch/fetch");
9
+ let __module_federation_enhanced_runtime = require("@module-federation/enhanced/runtime");
10
+ let __module_federation_runtime_core = require("@module-federation/runtime-core");
11
+
12
+ //#region src/runtime/errors.ts
13
+ var PluginRuntimeError = class extends effect.Data.TaggedError("PluginRuntimeError") {};
14
+ var ModuleFederationError = class extends effect.Data.TaggedError("ModuleFederationError") {};
15
+ var ValidationError = class extends effect.Data.TaggedError("ValidationError") {};
16
+ const isRetryableORPCCode = (code) => {
17
+ switch (code) {
18
+ case "TOO_MANY_REQUESTS":
19
+ case "SERVICE_UNAVAILABLE":
20
+ case "BAD_GATEWAY":
21
+ case "GATEWAY_TIMEOUT":
22
+ case "TIMEOUT": return true;
23
+ default: return false;
24
+ }
25
+ };
26
+ const wrapORPCError = (orpcError, pluginId, procedureName, operation) => {
27
+ return new PluginRuntimeError({
28
+ pluginId,
29
+ operation,
30
+ procedureName,
31
+ retryable: isRetryableORPCCode(orpcError.code),
32
+ cause: orpcError
33
+ });
34
+ };
35
+ const toPluginRuntimeError = (error, pluginId, procedureName, operation, defaultRetryable = false) => {
36
+ if (error instanceof __orpc_contract.ORPCError) return wrapORPCError(error, pluginId, procedureName, operation);
37
+ if (error instanceof PluginRuntimeError) return error;
38
+ return new PluginRuntimeError({
39
+ pluginId,
40
+ operation,
41
+ procedureName,
42
+ retryable: defaultRetryable,
43
+ cause: error instanceof Error ? error : new Error(String(error))
44
+ });
45
+ };
46
+
47
+ //#endregion
48
+ //#region src/runtime/services/module-federation.service.ts
49
+ var import_package = /* @__PURE__ */ require_chunk.__toESM(require_package$1.require_package(), 1);
50
+ const createModuleFederationInstance = effect.Effect.cached(effect.Effect.sync(() => {
51
+ try {
52
+ let instance = (0, __module_federation_enhanced_runtime.getInstance)();
53
+ if (!instance) {
54
+ instance = (0, __module_federation_enhanced_runtime.createInstance)({
55
+ name: "host",
56
+ remotes: [],
57
+ shared: {
58
+ "every-plugin": {
59
+ version: import_package.default.version,
60
+ shareConfig: {
61
+ singleton: true,
62
+ requiredVersion: `^${import_package.default.version}`,
63
+ eager: true,
64
+ strictVersion: false
65
+ }
66
+ },
67
+ effect: {
68
+ version: import_package.default.dependencies.effect,
69
+ shareConfig: {
70
+ singleton: true,
71
+ requiredVersion: "^3.18.0",
72
+ eager: true,
73
+ strictVersion: false
74
+ }
75
+ },
76
+ zod: {
77
+ version: import_package.default.dependencies.zod,
78
+ shareConfig: {
79
+ singleton: true,
80
+ requiredVersion: "^4.1.0",
81
+ eager: true,
82
+ strictVersion: false
83
+ }
84
+ },
85
+ "@orpc/contract": {
86
+ version: import_package.default.dependencies["@orpc/contract"],
87
+ shareConfig: {
88
+ singleton: true,
89
+ requiredVersion: "^1.8.0",
90
+ eager: true,
91
+ strictVersion: false
92
+ }
93
+ },
94
+ "@orpc/server": {
95
+ version: import_package.default.dependencies["@orpc/server"],
96
+ shareConfig: {
97
+ singleton: true,
98
+ requiredVersion: "^1.8.0",
99
+ eager: true,
100
+ strictVersion: false
101
+ }
102
+ }
103
+ }
104
+ });
105
+ (0, __module_federation_runtime_core.setGlobalFederationInstance)(instance);
106
+ }
107
+ return instance;
108
+ } catch (error) {
109
+ throw new Error(`Failed to initialize Module Federation: ${error}`);
110
+ }
111
+ }));
112
+ var ModuleFederationService = class extends effect.Effect.Service()("ModuleFederationService", { effect: effect.Effect.gen(function* () {
113
+ const mf = yield* effect.Effect.flatten(createModuleFederationInstance);
114
+ return {
115
+ registerRemote: (pluginId, url) => effect.Effect.gen(function* () {
116
+ console.log(`[MF] Registering ${pluginId}`);
117
+ const manifestUrl = url.endsWith("/") ? `${url}mf-manifest.json` : `${url}/mf-manifest.json`;
118
+ const { error: manifestError } = yield* effect.Effect.tryPromise({
119
+ try: () => (0, __better_fetch_fetch.betterFetch)(manifestUrl, { method: "HEAD" }),
120
+ catch: (error) => error
121
+ });
122
+ let entryUrl;
123
+ let isManifestMode = false;
124
+ if (!manifestError) {
125
+ entryUrl = manifestUrl;
126
+ isManifestMode = true;
127
+ console.log(`[MF] Using MF 2.0 manifest mode for ${pluginId}`);
128
+ } else {
129
+ console.log(`[MF] ⚠️ Manifest not found, falling back to MF 1.5 mode for ${pluginId}`);
130
+ entryUrl = url;
131
+ isManifestMode = false;
132
+ }
133
+ const remoteName = isManifestMode ? pluginId : require_normalize.getNormalizedRemoteName(pluginId);
134
+ yield* effect.Effect.try({
135
+ try: () => mf.registerRemotes([{
136
+ name: remoteName,
137
+ entry: entryUrl,
138
+ ...isManifestMode && { alias: pluginId }
139
+ }]),
140
+ catch: (error) => new ModuleFederationError({
141
+ pluginId,
142
+ remoteUrl: url,
143
+ cause: error instanceof Error ? error : new Error(String(error))
144
+ })
145
+ });
146
+ console.log(`[MF] ✅ Registered ${pluginId} (${isManifestMode ? "MF 2.0" : "MF 1.5"})`);
147
+ }),
148
+ loadRemoteConstructor: (pluginId, url) => effect.Effect.gen(function* () {
149
+ const remoteName = require_normalize.getNormalizedRemoteName(pluginId);
150
+ console.log(`[MF] Loading remote ${remoteName}`);
151
+ const modulePath = `${remoteName}/plugin`;
152
+ return yield* effect.Effect.tryPromise({
153
+ try: async () => {
154
+ const container = await mf.loadRemote(modulePath);
155
+ if (!container) throw new Error(`No container returned for ${modulePath}`);
156
+ const Constructor = typeof container === "function" ? container : container.default ? container.default : Object.values(container).find((exp) => typeof exp === "function" && exp.prototype?.constructor === exp);
157
+ if (!Constructor || typeof Constructor !== "function") {
158
+ const containerInfo = typeof container === "object" ? `Available exports: ${Object.keys(container).join(", ")}` : `Container type: ${typeof container}`;
159
+ throw new Error(`No valid plugin constructor found for '${pluginId}'.\nSupported patterns:\n - export const YourPlugin = createPlugin({...})\n - export default createPlugin({...})\n${containerInfo}`);
160
+ }
161
+ if (!Constructor.binding) {
162
+ const containerInfo = typeof container === "object" ? `Found exports: ${Object.keys(container).join(", ")}` : `Container type: ${typeof container}`;
163
+ throw new Error(`Invalid plugin constructor for '${pluginId}'. The exported value must be created with createPlugin(). Found a function but it's missing the required 'binding' property.\n${containerInfo}`);
164
+ }
165
+ console.log(`[MF] ✅ Loaded constructor for ${pluginId}`);
166
+ return Constructor;
167
+ },
168
+ catch: (error) => new ModuleFederationError({
169
+ pluginId,
170
+ remoteUrl: url,
171
+ cause: error instanceof Error ? error : new Error(String(error))
172
+ })
173
+ });
174
+ })
175
+ };
176
+ }) }) {};
177
+
178
+ //#endregion
179
+ //#region src/runtime/services/plugin-lifecycle.service.ts
180
+ var PluginLifecycleService = class extends effect.Effect.Service()("PluginLifecycleService", { effect: effect.Effect.gen(function* () {
181
+ const activePlugins = yield* effect.Ref.make(/* @__PURE__ */ new Set());
182
+ return {
183
+ register: (plugin) => effect.Ref.update(activePlugins, (plugins) => new Set(plugins).add(plugin)),
184
+ unregister: (plugin) => effect.Ref.update(activePlugins, (plugins) => {
185
+ const newSet = new Set(plugins);
186
+ newSet.delete(plugin);
187
+ return newSet;
188
+ }),
189
+ shutdown: (plugin) => effect.Effect.gen(function* () {
190
+ yield* effect.Ref.update(activePlugins, (plugins) => {
191
+ const newSet = new Set(plugins);
192
+ newSet.delete(plugin);
193
+ return newSet;
194
+ });
195
+ yield* plugin.plugin.shutdown().pipe(effect.Effect.mapError((error) => toPluginRuntimeError(error, plugin.plugin.id, void 0, "shutdown-plugin", false)));
196
+ }),
197
+ cleanup: () => effect.Effect.gen(function* () {
198
+ const plugins = yield* effect.Ref.get(activePlugins);
199
+ yield* effect.Effect.forEach(plugins, (plugin) => plugin.plugin.shutdown().pipe(effect.Effect.mapError((error) => toPluginRuntimeError(error, plugin.plugin.id, void 0, "cleanup-shutdown", false)), effect.Effect.catchAll((error) => effect.Effect.logError(`Failed to shutdown plugin ${plugin.plugin.id} during cleanup`, error, { pluginId: plugin.plugin.id }))), { concurrency: "unbounded" });
200
+ yield* effect.Ref.set(activePlugins, /* @__PURE__ */ new Set());
201
+ }).pipe(effect.Effect.catchAll(() => effect.Effect.void))
202
+ };
203
+ }) }) {};
204
+
205
+ //#endregion
206
+ //#region src/runtime/validation.ts
207
+ const validate = (schema, data, pluginId, stage) => effect.Effect.gen(function* () {
208
+ const result = schema.safeParse(data);
209
+ if (result.success) return result.data;
210
+ return yield* effect.Effect.fail(new ValidationError({
211
+ pluginId,
212
+ stage,
213
+ zodError: result.error
214
+ }));
215
+ });
216
+
217
+ //#endregion
218
+ //#region src/runtime/services/secrets.service.ts
219
+ const configSchema = zod.z.object({ secrets: zod.z.record(zod.z.string(), zod.z.unknown()) }).loose();
220
+ var SecretsConfigTag = class extends effect.Context.Tag("SecretsConfig")() {};
221
+ var SecretsService = class extends effect.Effect.Service()("SecretsService", { effect: effect.Effect.gen(function* () {
222
+ const secrets = yield* SecretsConfigTag;
223
+ return { hydrateSecrets: (config) => effect.Effect.gen(function* () {
224
+ const parseResult = configSchema.parse(config);
225
+ try {
226
+ let hydratedString = JSON.stringify(parseResult);
227
+ for (const [key, value] of Object.entries(secrets)) {
228
+ const pattern = new RegExp(`{{${key}}}`, "g");
229
+ hydratedString = hydratedString.replace(pattern, String(value));
230
+ }
231
+ return JSON.parse(hydratedString);
232
+ } catch (error) {
233
+ return yield* effect.Effect.fail(new PluginRuntimeError({
234
+ operation: "hydrate-secrets",
235
+ cause: error instanceof Error ? error : new Error(String(error)),
236
+ retryable: false
237
+ }));
238
+ }
239
+ }) };
240
+ }) }) {};
241
+
242
+ //#endregion
243
+ //#region src/runtime/services/plugin-loader.service.ts
244
+ var PluginRegistryTag = class extends effect.Context.Tag("PluginRegistry")() {};
245
+ var RegistryService = class extends effect.Effect.Service()("RegistryService", { effect: effect.Effect.gen(function* () {
246
+ const registry = yield* PluginRegistryTag;
247
+ return { get: (pluginId) => effect.Effect.fromNullable(registry[pluginId]).pipe(effect.Effect.mapError(() => new PluginRuntimeError({
248
+ pluginId,
249
+ operation: "validate-plugin-id",
250
+ cause: /* @__PURE__ */ new Error(`Plugin ${pluginId} not found in registry`),
251
+ retryable: false
252
+ }))) };
253
+ }) }) {};
254
+ var PluginLoaderService = class extends effect.Effect.Service()("PluginLoaderService", { effect: effect.Effect.gen(function* () {
255
+ const moduleFederationService = yield* ModuleFederationService;
256
+ const secretsService = yield* SecretsService;
257
+ const registryService = yield* RegistryService;
258
+ const resolveUrl = (baseUrl, version) => version && version !== "latest" ? baseUrl.replace("@latest", `@${version}`) : baseUrl;
259
+ const getMetadata = (pluginId) => registryService.get(pluginId);
260
+ return {
261
+ loadPlugin: (pluginId) => effect.Effect.gen(function* () {
262
+ const metadata = yield* getMetadata(pluginId);
263
+ const url = resolveUrl(metadata.remoteUrl);
264
+ yield* moduleFederationService.registerRemote(pluginId, url).pipe(effect.Effect.mapError((error) => toPluginRuntimeError(error, pluginId, void 0, "register-remote", true)));
265
+ yield* effect.Effect.logDebug("Loading plugin", {
266
+ pluginId,
267
+ url
268
+ });
269
+ return {
270
+ ctor: yield* moduleFederationService.loadRemoteConstructor(pluginId, url).pipe(effect.Effect.mapError((error) => toPluginRuntimeError(error, pluginId, void 0, "load-remote", false))),
271
+ metadata
272
+ };
273
+ }),
274
+ instantiatePlugin: (pluginId, loadedPlugin) => effect.Effect.gen(function* () {
275
+ const instance = yield* effect.Effect.try(() => new loadedPlugin.ctor()).pipe(effect.Effect.mapError((error) => toPluginRuntimeError(error, pluginId, void 0, "instantiate-plugin", false)));
276
+ instance.id = pluginId;
277
+ return {
278
+ plugin: instance,
279
+ metadata: loadedPlugin.metadata
280
+ };
281
+ }),
282
+ initializePlugin: (pluginInstance, config) => effect.Effect.gen(function* () {
283
+ const { plugin } = pluginInstance;
284
+ const validatedVariables = yield* validate(plugin.configSchema.variables, config.variables, plugin.id, "config").pipe(effect.Effect.mapError((validationError) => new PluginRuntimeError({
285
+ pluginId: plugin.id,
286
+ operation: "validate-config",
287
+ cause: validationError.zodError,
288
+ retryable: false
289
+ })));
290
+ const validatedSecrets = yield* validate(plugin.configSchema.secrets, config.secrets, plugin.id, "config").pipe(effect.Effect.mapError((validationError) => new PluginRuntimeError({
291
+ pluginId: plugin.id,
292
+ operation: "validate-secrets",
293
+ cause: validationError.zodError,
294
+ retryable: false
295
+ })));
296
+ const hydratedConfig = yield* secretsService.hydrateSecrets({
297
+ variables: validatedVariables,
298
+ secrets: validatedSecrets
299
+ });
300
+ const _variables = yield* validate(plugin.configSchema.variables, hydratedConfig.variables, plugin.id, "config").pipe(effect.Effect.mapError((validationError) => new PluginRuntimeError({
301
+ pluginId: plugin.id,
302
+ operation: "validate-hydrated-config",
303
+ cause: validationError.zodError,
304
+ retryable: false
305
+ })));
306
+ const scope = yield* effect.Scope.make();
307
+ const context = yield* plugin.initialize({
308
+ variables: _variables,
309
+ secrets: hydratedConfig.secrets
310
+ }).pipe(effect.Effect.provideService(effect.Scope.Scope, scope), effect.Effect.mapError((error) => toPluginRuntimeError(error, plugin.id, void 0, "initialize-plugin", false)));
311
+ return {
312
+ plugin,
313
+ metadata: pluginInstance.metadata,
314
+ config: {
315
+ variables: _variables,
316
+ secrets: hydratedConfig.secrets
317
+ },
318
+ context,
319
+ scope
320
+ };
321
+ })
322
+ };
323
+ }) }) {};
324
+
325
+ //#endregion
326
+ //#region src/runtime/services/plugin.service.ts
327
+ var PluginService = class PluginService extends effect.Effect.Service()("PluginService", { scoped: effect.Effect.gen(function* () {
328
+ const loader = yield* PluginLoaderService;
329
+ const lifecycle = yield* PluginLifecycleService;
330
+ return {
331
+ loadPlugin: loader.loadPlugin,
332
+ instantiatePlugin: loader.instantiatePlugin,
333
+ initializePlugin: loader.initializePlugin,
334
+ shutdownPlugin: (plugin) => effect.Effect.gen(function* () {
335
+ yield* plugin.plugin.shutdown().pipe(effect.Effect.catchAll(() => effect.Effect.void));
336
+ yield* effect.Scope.close(plugin.scope, effect.Exit.succeed(void 0));
337
+ yield* lifecycle.unregister(plugin);
338
+ }),
339
+ cleanup: lifecycle.cleanup
340
+ };
341
+ }) }) {
342
+ static Live = (registry, secrets) => {
343
+ const contextLayer = effect.Layer.mergeAll(effect.Layer.succeed(PluginRegistryTag, registry), effect.Layer.succeed(SecretsConfigTag, secrets));
344
+ const servicesLayer = effect.Layer.mergeAll(ModuleFederationService.Default, SecretsService.Default, RegistryService.Default, PluginLifecycleService.Default).pipe(effect.Layer.provide(contextLayer));
345
+ return PluginService.Default.pipe(effect.Layer.provide(PluginLoaderService.Default), effect.Layer.provide(servicesLayer));
346
+ };
347
+ };
348
+
349
+ //#endregion
350
+ //#region src/runtime/index.ts
351
+ var PluginRuntime = class {
352
+ pluginCache = /* @__PURE__ */ new Map();
353
+ constructor(runtime, registry) {
354
+ this.runtime = runtime;
355
+ this.registry = registry;
356
+ }
357
+ generateCacheKey(pluginId, config) {
358
+ return `${pluginId}:${effect.Hash.structure(config).toString()}`;
359
+ }
360
+ validatePluginId(pluginId) {
361
+ if (!(pluginId in this.registry)) return effect.Effect.fail(new PluginRuntimeError({
362
+ pluginId: String(pluginId),
363
+ operation: "validate-plugin-id",
364
+ cause: /* @__PURE__ */ new Error(`Plugin ID '${String(pluginId)}' not found in registry.`),
365
+ retryable: false
366
+ }));
367
+ return effect.Effect.succeed(String(pluginId));
368
+ }
369
+ async runPromise(effect$1) {
370
+ const exit = await this.runtime.runPromiseExit(effect$1);
371
+ if (effect.Exit.isFailure(exit)) {
372
+ const error = effect.Cause.failureOption(exit.cause);
373
+ if (effect.Option.isSome(error)) throw error.value;
374
+ throw effect.Cause.squash(exit.cause);
375
+ }
376
+ return exit.value;
377
+ }
378
+ async usePlugin(pluginId, config) {
379
+ const cacheKey = this.generateCacheKey(pluginId, config);
380
+ let cachedPlugin = this.pluginCache.get(cacheKey);
381
+ if (!cachedPlugin) {
382
+ const operation = effect.Effect.gen(this, function* () {
383
+ const pluginService = yield* PluginService;
384
+ const validatedId = yield* this.validatePluginId(pluginId);
385
+ const ctor = yield* pluginService.loadPlugin(validatedId);
386
+ const instance = yield* pluginService.instantiatePlugin(pluginId, ctor);
387
+ return yield* pluginService.initializePlugin(instance, config);
388
+ }).pipe(effect.Effect.provide(this.runtime));
389
+ cachedPlugin = effect.Effect.cached(operation).pipe(effect.Effect.flatten);
390
+ this.pluginCache.set(cacheKey, cachedPlugin);
391
+ }
392
+ const initialized = await this.runPromise(cachedPlugin);
393
+ const router = initialized.plugin.createRouter(initialized.context);
394
+ return {
395
+ router,
396
+ client: (0, __orpc_server.createRouterClient)(router),
397
+ metadata: initialized.metadata,
398
+ initialized
399
+ };
400
+ }
401
+ async loadPlugin(pluginId) {
402
+ const effect$1 = effect.Effect.gen(function* () {
403
+ return yield* (yield* PluginService).loadPlugin(pluginId);
404
+ });
405
+ return this.runPromise(effect$1);
406
+ }
407
+ async instantiatePlugin(pluginId, loadedPlugin) {
408
+ const effect$1 = effect.Effect.gen(function* () {
409
+ return yield* (yield* PluginService).instantiatePlugin(pluginId, loadedPlugin);
410
+ });
411
+ return this.runPromise(effect$1);
412
+ }
413
+ async initializePlugin(instance, config) {
414
+ const effect$1 = effect.Effect.gen(function* () {
415
+ return yield* (yield* PluginService).initializePlugin(instance, config);
416
+ });
417
+ return this.runPromise(effect$1);
418
+ }
419
+ async shutdown() {
420
+ const effect$1 = effect.Effect.gen(function* () {
421
+ yield* (yield* PluginService).cleanup();
422
+ });
423
+ return this.runPromise(effect$1);
424
+ }
425
+ async evictPlugin(pluginId, config) {
426
+ const cacheKey = this.generateCacheKey(pluginId, config);
427
+ const effect$1 = effect.Effect.gen(this, function* () {
428
+ const pluginService = yield* PluginService;
429
+ const cachedPlugin = this.pluginCache.get(cacheKey);
430
+ if (cachedPlugin) {
431
+ this.pluginCache.delete(cacheKey);
432
+ const pluginResult = yield* cachedPlugin.pipe(effect.Effect.catchAll(() => effect.Effect.succeed(null)));
433
+ if (pluginResult) yield* pluginService.shutdownPlugin(pluginResult).pipe(effect.Effect.catchAll(() => effect.Effect.void));
434
+ }
435
+ }).pipe(effect.Effect.catchAll(() => effect.Effect.void));
436
+ return this.runPromise(effect$1);
437
+ }
438
+ };
439
+ /**
440
+ * Normalizes a remote URL to ensure it points to remoteEntry.js
441
+ * If the URL doesn't end with a file extension, appends /remoteEntry.js
442
+ */
443
+ function normalizeRemoteUrl(url) {
444
+ if (url.endsWith(".js")) return url;
445
+ return `${url.endsWith("/") ? url.slice(0, -1) : url}/remoteEntry.js`;
446
+ }
447
+ function createPluginRuntime(config) {
448
+ const secrets = config.secrets || {};
449
+ const normalizedRegistry = Object.fromEntries(Object.entries(config.registry).map(([pluginId, entry]) => [pluginId, {
450
+ ...entry,
451
+ remoteUrl: normalizeRemoteUrl(entry.remoteUrl)
452
+ }]));
453
+ const layer = PluginService.Live(normalizedRegistry, secrets);
454
+ return new PluginRuntime(effect.ManagedRuntime.make(layer), normalizedRegistry);
455
+ }
456
+
457
+ //#endregion
458
+ Object.defineProperty(exports, 'ModuleFederationError', {
459
+ enumerable: true,
460
+ get: function () {
461
+ return ModuleFederationError;
462
+ }
463
+ });
464
+ Object.defineProperty(exports, 'ModuleFederationService', {
465
+ enumerable: true,
466
+ get: function () {
467
+ return ModuleFederationService;
468
+ }
469
+ });
470
+ Object.defineProperty(exports, 'PluginLifecycleService', {
471
+ enumerable: true,
472
+ get: function () {
473
+ return PluginLifecycleService;
474
+ }
475
+ });
476
+ Object.defineProperty(exports, 'PluginLoaderService', {
477
+ enumerable: true,
478
+ get: function () {
479
+ return PluginLoaderService;
480
+ }
481
+ });
482
+ Object.defineProperty(exports, 'PluginRegistryTag', {
483
+ enumerable: true,
484
+ get: function () {
485
+ return PluginRegistryTag;
486
+ }
487
+ });
488
+ Object.defineProperty(exports, 'PluginRuntime', {
489
+ enumerable: true,
490
+ get: function () {
491
+ return PluginRuntime;
492
+ }
493
+ });
494
+ Object.defineProperty(exports, 'PluginService', {
495
+ enumerable: true,
496
+ get: function () {
497
+ return PluginService;
498
+ }
499
+ });
500
+ Object.defineProperty(exports, 'RegistryService', {
501
+ enumerable: true,
502
+ get: function () {
503
+ return RegistryService;
504
+ }
505
+ });
506
+ Object.defineProperty(exports, 'SecretsConfigTag', {
507
+ enumerable: true,
508
+ get: function () {
509
+ return SecretsConfigTag;
510
+ }
511
+ });
512
+ Object.defineProperty(exports, 'SecretsService', {
513
+ enumerable: true,
514
+ get: function () {
515
+ return SecretsService;
516
+ }
517
+ });
518
+ Object.defineProperty(exports, 'createPluginRuntime', {
519
+ enumerable: true,
520
+ get: function () {
521
+ return createPluginRuntime;
522
+ }
523
+ });
524
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS1CWXJkTkFmZi5janMiLCJuYW1lcyI6WyJEYXRhIiwiT1JQQ0Vycm9yIiwiRWZmZWN0IiwicGtnIiwiZW50cnlVcmw6IHN0cmluZyIsImdldE5vcm1hbGl6ZWRSZW1vdGVOYW1lIiwiRWZmZWN0IiwiUmVmIiwiRWZmZWN0IiwieiIsIkNvbnRleHQiLCJFZmZlY3QiLCJDb250ZXh0IiwiRWZmZWN0IiwiU2NvcGUiLCJFZmZlY3QiLCJTY29wZSIsIkV4aXQiLCJMYXllciIsInJ1bnRpbWU6IE1hbmFnZWRSdW50aW1lLk1hbmFnZWRSdW50aW1lPFBsdWdpblNlcnZpY2UsIG5ldmVyPiIsInJlZ2lzdHJ5OiBQbHVnaW5SZWdpc3RyeSIsIkhhc2giLCJFZmZlY3QiLCJlZmZlY3QiLCJFeGl0IiwiQ2F1c2UiLCJPcHRpb24iLCJNYW5hZ2VkUnVudGltZSJdLCJzb3VyY2VzIjpbIi4uL3NyYy9ydW50aW1lL2Vycm9ycy50cyIsIi4uL3NyYy9ydW50aW1lL3NlcnZpY2VzL21vZHVsZS1mZWRlcmF0aW9uLnNlcnZpY2UudHMiLCIuLi9zcmMvcnVudGltZS9zZXJ2aWNlcy9wbHVnaW4tbGlmZWN5Y2xlLnNlcnZpY2UudHMiLCIuLi9zcmMvcnVudGltZS92YWxpZGF0aW9uLnRzIiwiLi4vc3JjL3J1bnRpbWUvc2VydmljZXMvc2VjcmV0cy5zZXJ2aWNlLnRzIiwiLi4vc3JjL3J1bnRpbWUvc2VydmljZXMvcGx1Z2luLWxvYWRlci5zZXJ2aWNlLnRzIiwiLi4vc3JjL3J1bnRpbWUvc2VydmljZXMvcGx1Z2luLnNlcnZpY2UudHMiLCIuLi9zcmMvcnVudGltZS9pbmRleC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyJpbXBvcnQgeyBPUlBDRXJyb3IgfSBmcm9tIFwiQG9ycGMvY29udHJhY3RcIjtcbmltcG9ydCB7IERhdGEgfSBmcm9tIFwiZWZmZWN0XCI7XG5pbXBvcnQgdHlwZSB7IHogfSBmcm9tIFwiem9kXCI7XG5cbmV4cG9ydCBjbGFzcyBQbHVnaW5SdW50aW1lRXJyb3IgZXh0ZW5kcyBEYXRhLlRhZ2dlZEVycm9yKFwiUGx1Z2luUnVudGltZUVycm9yXCIpPHtcblx0cmVhZG9ubHkgcGx1Z2luSWQ/OiBzdHJpbmc7XG5cdHJlYWRvbmx5IG9wZXJhdGlvbj86IHN0cmluZztcblx0cmVhZG9ubHkgcHJvY2VkdXJlTmFtZT86IHN0cmluZztcblx0cmVhZG9ubHkgY2F1c2U/OiBFcnJvcjtcblx0cmVhZG9ubHkgcmV0cnlhYmxlOiBib29sZWFuO1xufT4geyB9XG5cbmV4cG9ydCBjbGFzcyBNb2R1bGVGZWRlcmF0aW9uRXJyb3IgZXh0ZW5kcyBEYXRhLlRhZ2dlZEVycm9yKFxuXHRcIk1vZHVsZUZlZGVyYXRpb25FcnJvclwiLFxuKTx7XG5cdHJlYWRvbmx5IHBsdWdpbklkOiBzdHJpbmc7XG5cdHJlYWRvbmx5IHJlbW90ZVVybDogc3RyaW5nO1xuXHRyZWFkb25seSBjYXVzZT86IEVycm9yO1xufT4geyB9XG5cbmV4cG9ydCBjbGFzcyBWYWxpZGF0aW9uRXJyb3IgZXh0ZW5kcyBEYXRhLlRhZ2dlZEVycm9yKFwiVmFsaWRhdGlvbkVycm9yXCIpPHtcblx0cmVhZG9ubHkgcGx1Z2luSWQ6IHN0cmluZztcblx0cmVhZG9ubHkgc3RhZ2U6IFwiY29uZmlnXCIgfCBcImlucHV0XCIgfCBcIm91dHB1dFwiIHwgXCJzdGF0ZVwiO1xuXHRyZWFkb25seSB6b2RFcnJvcjogei5ab2RFcnJvcjtcbn0+IHsgfVxuXG4vLyBIZWxwZXIgdG8gZGV0ZXJtaW5lIGlmIGFuIG9SUEMgZXJyb3IgY29kZSBpcyByZXRyeWFibGVcbmV4cG9ydCBjb25zdCBpc1JldHJ5YWJsZU9SUENDb2RlID0gKGNvZGU6IHN0cmluZyk6IGJvb2xlYW4gPT4ge1xuXHRzd2l0Y2ggKGNvZGUpIHtcblx0XHRjYXNlICdUT09fTUFOWV9SRVFVRVNUUyc6XG5cdFx0Y2FzZSAnU0VSVklDRV9VTkFWQUlMQUJMRSc6XG5cdFx0Y2FzZSAnQkFEX0dBVEVXQVknOlxuXHRcdGNhc2UgJ0dBVEVXQVlfVElNRU9VVCc6XG5cdFx0Y2FzZSAnVElNRU9VVCc6XG5cdFx0XHRyZXR1cm4gdHJ1ZTtcblx0XHRkZWZhdWx0OlxuXHRcdFx0cmV0dXJuIGZhbHNlO1xuXHR9XG59O1xuXG4vLyBDb252ZXJ0IE9SUEMgZXJyb3JzIGZyb20gcGx1Z2luIHByb2NlZHVyZXMgdG8gUGx1Z2luUnVudGltZUVycm9yXG5leHBvcnQgY29uc3Qgd3JhcE9SUENFcnJvciA9IChcblx0b3JwY0Vycm9yOiBPUlBDRXJyb3I8c3RyaW5nLCB1bmtub3duPixcblx0cGx1Z2luSWQ/OiBzdHJpbmcsXG5cdHByb2NlZHVyZU5hbWU/OiBzdHJpbmcsXG5cdG9wZXJhdGlvbj86IHN0cmluZ1xuKTogUGx1Z2luUnVudGltZUVycm9yID0+IHtcblx0cmV0dXJuIG5ldyBQbHVnaW5SdW50aW1lRXJyb3Ioe1xuXHRcdHBsdWdpbklkLFxuXHRcdG9wZXJhdGlvbixcblx0XHRwcm9jZWR1cmVOYW1lLFxuXHRcdHJldHJ5YWJsZTogaXNSZXRyeWFibGVPUlBDQ29kZShvcnBjRXJyb3IuY29kZSksXG5cdFx0Y2F1c2U6IG9ycGNFcnJvciBhcyBFcnJvclxuXHR9KTtcbn07XG5cbi8vIFVuaXZlcnNhbCBlcnJvciBjb252ZXJ0ZXIgZm9yIHRoZSBydW50aW1lXG5leHBvcnQgY29uc3QgdG9QbHVnaW5SdW50aW1lRXJyb3IgPSAoXG5cdGVycm9yOiB1bmtub3duLFxuXHRwbHVnaW5JZD86IHN0cmluZyxcblx0cHJvY2VkdXJlTmFtZT86IHN0cmluZyxcblx0b3BlcmF0aW9uPzogc3RyaW5nLFxuXHRkZWZhdWx0UmV0cnlhYmxlID0gZmFsc2Vcbik6IFBsdWdpblJ1bnRpbWVFcnJvciA9PiB7XG5cdGlmIChlcnJvciBpbnN0YW5jZW9mIE9SUENFcnJvcikge1xuXHRcdHJldHVybiB3cmFwT1JQQ0Vycm9yKGVycm9yLCBwbHVnaW5JZCwgcHJvY2VkdXJlTmFtZSwgb3BlcmF0aW9uKTtcblx0fVxuXG5cdGlmIChlcnJvciBpbnN0YW5jZW9mIFBsdWdpblJ1bnRpbWVFcnJvcikge1xuXHRcdHJldHVybiBlcnJvcjsgLy8gQWxyZWFkeSBjb252ZXJ0ZWRcblx0fVxuXG5cdHJldHVybiBuZXcgUGx1Z2luUnVudGltZUVycm9yKHtcblx0XHRwbHVnaW5JZCxcblx0XHRvcGVyYXRpb24sXG5cdFx0cHJvY2VkdXJlTmFtZSxcblx0XHRyZXRyeWFibGU6IGRlZmF1bHRSZXRyeWFibGUsXG5cdFx0Y2F1c2U6IGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKVxuXHR9KTtcbn07XG4iLCJpbXBvcnQgeyBiZXR0ZXJGZXRjaCB9IGZyb20gXCJAYmV0dGVyLWZldGNoL2ZldGNoXCI7XG5pbXBvcnQge1xuXHRjcmVhdGVJbnN0YW5jZSxcblx0Z2V0SW5zdGFuY2UsXG59IGZyb20gXCJAbW9kdWxlLWZlZGVyYXRpb24vZW5oYW5jZWQvcnVudGltZVwiO1xuaW1wb3J0IHsgc2V0R2xvYmFsRmVkZXJhdGlvbkluc3RhbmNlIH0gZnJvbSBcIkBtb2R1bGUtZmVkZXJhdGlvbi9ydW50aW1lLWNvcmVcIjtcbmltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCJlZmZlY3RcIjtcbmltcG9ydCB0eXBlIHsgQW55UGx1Z2luIH0gZnJvbSBcIi4uLy4uL3R5cGVzXCI7XG5pbXBvcnQgeyBNb2R1bGVGZWRlcmF0aW9uRXJyb3IgfSBmcm9tIFwiLi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBnZXROb3JtYWxpemVkUmVtb3RlTmFtZSB9IGZyb20gXCIuL25vcm1hbGl6ZVwiO1xuXG50eXBlIFJlbW90ZU1vZHVsZSA9IFxuICB8IChuZXcgKCkgPT4gQW55UGx1Z2luKVxuICB8IHsgZGVmYXVsdDogbmV3ICgpID0+IEFueVBsdWdpbiB9O1xuXG5pbXBvcnQgcGtnIGZyb20gXCIuLi8uLi8uLi9wYWNrYWdlLmpzb25cIjtcblxuY29uc3QgY3JlYXRlTW9kdWxlRmVkZXJhdGlvbkluc3RhbmNlID0gRWZmZWN0LmNhY2hlZChcblx0RWZmZWN0LnN5bmMoKCkgPT4ge1xuXHRcdHRyeSB7XG5cdFx0XHRsZXQgaW5zdGFuY2UgPSBnZXRJbnN0YW5jZSgpO1xuXG5cdFx0XHRpZiAoIWluc3RhbmNlKSB7XG5cdFx0XHRcdGluc3RhbmNlID0gY3JlYXRlSW5zdGFuY2Uoe1xuXHRcdFx0XHRcdG5hbWU6IFwiaG9zdFwiLFxuXHRcdFx0XHRcdHJlbW90ZXM6IFtdLFxuXHRcdFx0XHRcdHNoYXJlZDoge1xuXHRcdFx0XHRcdFx0XCJldmVyeS1wbHVnaW5cIjoge1xuXHRcdFx0XHRcdFx0XHR2ZXJzaW9uOiBwa2cudmVyc2lvbixcblx0XHRcdFx0XHRcdFx0c2hhcmVDb25maWc6IHtcblx0XHRcdFx0XHRcdFx0XHRzaW5nbGV0b246IHRydWUsXG5cdFx0XHRcdFx0XHRcdFx0cmVxdWlyZWRWZXJzaW9uOiBgXiR7cGtnLnZlcnNpb259YCxcblx0XHRcdFx0XHRcdFx0XHRlYWdlcjogdHJ1ZSxcblx0XHRcdFx0XHRcdFx0XHRzdHJpY3RWZXJzaW9uOiBmYWxzZSwgLy8gQWxsb3cgYmlkaXJlY3Rpb25hbCB2ZXJzaW9uIGNvbXBhdGliaWxpdHlcblx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRlZmZlY3Q6IHtcblx0XHRcdFx0XHRcdFx0dmVyc2lvbjogcGtnLmRlcGVuZGVuY2llcy5lZmZlY3QsXG5cdFx0XHRcdFx0XHRcdHNoYXJlQ29uZmlnOiB7XG5cdFx0XHRcdFx0XHRcdFx0c2luZ2xldG9uOiB0cnVlLFxuXHRcdFx0XHRcdFx0XHRcdHJlcXVpcmVkVmVyc2lvbjogXCJeMy4xOC4wXCIsIC8vIEFsbG93IGFueSAzLjE4LnggcGF0Y2ggdmVyc2lvblxuXHRcdFx0XHRcdFx0XHRcdGVhZ2VyOiB0cnVlLFxuXHRcdFx0XHRcdFx0XHRcdHN0cmljdFZlcnNpb246IGZhbHNlLCAvLyBBbGxvdyB2ZXJzaW9uIGZsZXhpYmlsaXR5IGZvciBjb21wYXRpYmlsaXR5XG5cdFx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0em9kOiB7XG5cdFx0XHRcdFx0XHRcdHZlcnNpb246IHBrZy5kZXBlbmRlbmNpZXMuem9kLFxuXHRcdFx0XHRcdFx0XHRzaGFyZUNvbmZpZzoge1xuXHRcdFx0XHRcdFx0XHRcdHNpbmdsZXRvbjogdHJ1ZSxcblx0XHRcdFx0XHRcdFx0XHRyZXF1aXJlZFZlcnNpb246IFwiXjQuMS4wXCIsIC8vIEFsbG93IGFueSA0LjEueCBwYXRjaCB2ZXJzaW9uXG5cdFx0XHRcdFx0XHRcdFx0ZWFnZXI6IHRydWUsXG5cdFx0XHRcdFx0XHRcdFx0c3RyaWN0VmVyc2lvbjogZmFsc2UsIC8vIEFsbG93IHZlcnNpb24gZmxleGliaWxpdHkgZm9yIGNvbXBhdGliaWxpdHlcblx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcIkBvcnBjL2NvbnRyYWN0XCI6IHtcblx0XHRcdFx0XHRcdFx0dmVyc2lvbjogcGtnLmRlcGVuZGVuY2llc1tcIkBvcnBjL2NvbnRyYWN0XCJdLFxuXHRcdFx0XHRcdFx0XHRzaGFyZUNvbmZpZzoge1xuXHRcdFx0XHRcdFx0XHRcdHNpbmdsZXRvbjogdHJ1ZSxcblx0XHRcdFx0XHRcdFx0XHRyZXF1aXJlZFZlcnNpb246IFwiXjEuOC4wXCIsIC8vIEFsbG93IGFueSAxLjgueCBwYXRjaCB2ZXJzaW9uXG5cdFx0XHRcdFx0XHRcdFx0ZWFnZXI6IHRydWUsXG5cdFx0XHRcdFx0XHRcdFx0c3RyaWN0VmVyc2lvbjogZmFsc2UsIC8vIEFsbG93IHZlcnNpb24gZmxleGliaWxpdHkgZm9yIGNvbXBhdGliaWxpdHlcblx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHRcIkBvcnBjL3NlcnZlclwiOiB7XG5cdFx0XHRcdFx0XHRcdHZlcnNpb246IHBrZy5kZXBlbmRlbmNpZXNbXCJAb3JwYy9zZXJ2ZXJcIl0sXG5cdFx0XHRcdFx0XHRcdHNoYXJlQ29uZmlnOiB7XG5cdFx0XHRcdFx0XHRcdFx0c2luZ2xldG9uOiB0cnVlLFxuXHRcdFx0XHRcdFx0XHRcdHJlcXVpcmVkVmVyc2lvbjogXCJeMS44LjBcIiwgLy8gQWxsb3cgYW55IDEuOC54IHBhdGNoIHZlcnNpb25cblx0XHRcdFx0XHRcdFx0XHRlYWdlcjogdHJ1ZSxcblx0XHRcdFx0XHRcdFx0XHRzdHJpY3RWZXJzaW9uOiBmYWxzZSwgLy8gQWxsb3cgdmVyc2lvbiBmbGV4aWJpbGl0eSBmb3IgY29tcGF0aWJpbGl0eVxuXHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0fVxuXHRcdFx0XHRcdH0sXG5cdFx0XHRcdH0pO1xuXG5cdFx0XHRcdHNldEdsb2JhbEZlZGVyYXRpb25JbnN0YW5jZShpbnN0YW5jZSk7XG5cdFx0XHR9XG5cblx0XHRcdHJldHVybiBpbnN0YW5jZTtcblx0XHR9IGNhdGNoIChlcnJvcikge1xuXHRcdFx0dGhyb3cgbmV3IEVycm9yKGBGYWlsZWQgdG8gaW5pdGlhbGl6ZSBNb2R1bGUgRmVkZXJhdGlvbjogJHtlcnJvcn1gKTtcblx0XHR9XG5cdH0pLFxuKTtcblxuZXhwb3J0IGNsYXNzIE1vZHVsZUZlZGVyYXRpb25TZXJ2aWNlIGV4dGVuZHMgRWZmZWN0LlNlcnZpY2U8TW9kdWxlRmVkZXJhdGlvblNlcnZpY2U+KCkoXCJNb2R1bGVGZWRlcmF0aW9uU2VydmljZVwiLCB7XG5cdGVmZmVjdDogRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuXHRcdGNvbnN0IG1mID0geWllbGQqIEVmZmVjdC5mbGF0dGVuKGNyZWF0ZU1vZHVsZUZlZGVyYXRpb25JbnN0YW5jZSk7XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0cmVnaXN0ZXJSZW1vdGU6IChwbHVnaW5JZDogc3RyaW5nLCB1cmw6IHN0cmluZykgPT5cblx0XHRcdFx0RWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuXHRcdFx0XHRcdGNvbnNvbGUubG9nKGBbTUZdIFJlZ2lzdGVyaW5nICR7cGx1Z2luSWR9YCk7XG5cblx0XHRcdFx0XHRjb25zdCBtYW5pZmVzdFVybCA9IHVybC5lbmRzV2l0aCgnLycpXG5cdFx0XHRcdFx0XHQ/IGAke3VybH1tZi1tYW5pZmVzdC5qc29uYFxuXHRcdFx0XHRcdFx0OiBgJHt1cmx9L21mLW1hbmlmZXN0Lmpzb25gO1xuXG5cdFx0XHRcdFx0Ly8gQ2hlY2sgaWYgbWFuaWZlc3QgaXMgYXZhaWxhYmxlIChNRiAyLjAgd2l0aCBtYW5pZmVzdHMpXG5cdFx0XHRcdFx0Y29uc3QgeyBlcnJvcjogbWFuaWZlc3RFcnJvciB9ID0geWllbGQqIEVmZmVjdC50cnlQcm9taXNlKHtcblx0XHRcdFx0XHRcdHRyeTogKCkgPT4gYmV0dGVyRmV0Y2gobWFuaWZlc3RVcmwsIHsgbWV0aG9kOiBcIkhFQURcIiB9KSxcblx0XHRcdFx0XHRcdGNhdGNoOiAoZXJyb3IpID0+IGVycm9yLCAvLyBEb24ndCBmYWlsIHlldCwgdHJ5IGZhbGxiYWNrXG5cdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0XHRsZXQgZW50cnlVcmw6IHN0cmluZztcblx0XHRcdFx0XHRsZXQgaXNNYW5pZmVzdE1vZGUgPSBmYWxzZTtcblxuXHRcdFx0XHRcdGlmICghbWFuaWZlc3RFcnJvcikge1xuXHRcdFx0XHRcdFx0Ly8gTUYgMi4wIG1hbmlmZXN0IG1vZGUgLSB1c2UgbWFuaWZlc3QgVVJMXG5cdFx0XHRcdFx0XHRlbnRyeVVybCA9IG1hbmlmZXN0VXJsO1xuXHRcdFx0XHRcdFx0aXNNYW5pZmVzdE1vZGUgPSB0cnVlO1xuXHRcdFx0XHRcdFx0Y29uc29sZS5sb2coYFtNRl0gVXNpbmcgTUYgMi4wIG1hbmlmZXN0IG1vZGUgZm9yICR7cGx1Z2luSWR9YCk7XG5cdFx0XHRcdFx0fSBlbHNlIHtcblx0XHRcdFx0XHRcdC8vIEZhbGxiYWNrIHRvIE1GIDEuNSBkaXJlY3QgbW9kZSAtIGFzc3VtZSBVUkwgcG9pbnRzIHRvIHJlbW90ZUVudHJ5LmpzXG5cdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhgW01GXSDimqDvuI8gTWFuaWZlc3Qgbm90IGZvdW5kLCBmYWxsaW5nIGJhY2sgdG8gTUYgMS41IG1vZGUgZm9yICR7cGx1Z2luSWR9YCk7XG5cdFx0XHRcdFx0XHRlbnRyeVVybCA9IHVybDtcblx0XHRcdFx0XHRcdGlzTWFuaWZlc3RNb2RlID0gZmFsc2U7XG5cdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0Ly8gRm9yIE1GIDIuMCwgdGhlIG5hbWUgY2FuIGJlIHRoZSBwbHVnaW5JZCAoYWxpYXMpXG5cdFx0XHRcdFx0Ly8gVGhlIG1hbmlmZXN0IHdpbGwgY29udGFpbiB0aGUgYWN0dWFsIGNvbnRhaW5lciBuYW1lXG5cdFx0XHRcdFx0Y29uc3QgcmVtb3RlTmFtZSA9IGlzTWFuaWZlc3RNb2RlID8gcGx1Z2luSWQgOiBnZXROb3JtYWxpemVkUmVtb3RlTmFtZShwbHVnaW5JZCk7XG5cblx0XHRcdFx0XHR5aWVsZCogRWZmZWN0LnRyeSh7XG5cdFx0XHRcdFx0XHR0cnk6ICgpID0+IG1mLnJlZ2lzdGVyUmVtb3Rlcyhbe1xuXHRcdFx0XHRcdFx0XHRuYW1lOiByZW1vdGVOYW1lLFxuXHRcdFx0XHRcdFx0XHRlbnRyeTogZW50cnlVcmwsXG5cdFx0XHRcdFx0XHRcdC4uLihpc01hbmlmZXN0TW9kZSAmJiB7IGFsaWFzOiBwbHVnaW5JZCB9KSAvLyBFeHBsaWNpdCBhbGlhcyBmb3IgY2xhcml0eVxuXHRcdFx0XHRcdFx0fV0pLFxuXHRcdFx0XHRcdFx0Y2F0Y2g6IChlcnJvcik6IE1vZHVsZUZlZGVyYXRpb25FcnJvciA9PlxuXHRcdFx0XHRcdFx0XHRuZXcgTW9kdWxlRmVkZXJhdGlvbkVycm9yKHtcblx0XHRcdFx0XHRcdFx0XHRwbHVnaW5JZCxcblx0XHRcdFx0XHRcdFx0XHRyZW1vdGVVcmw6IHVybCxcblx0XHRcdFx0XHRcdFx0XHRjYXVzZTpcblx0XHRcdFx0XHRcdFx0XHRcdGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKSxcblx0XHRcdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0XHRjb25zb2xlLmxvZyhgW01GXSDinIUgUmVnaXN0ZXJlZCAke3BsdWdpbklkfSAoJHtpc01hbmlmZXN0TW9kZSA/ICdNRiAyLjAnIDogJ01GIDEuNSd9KWApO1xuXHRcdFx0XHR9KSxcblxuXHRcdFx0bG9hZFJlbW90ZUNvbnN0cnVjdG9yOiAocGx1Z2luSWQ6IHN0cmluZywgdXJsOiBzdHJpbmcpID0+XG5cdFx0XHRcdEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRcdFx0XHRjb25zdCByZW1vdGVOYW1lID0gZ2V0Tm9ybWFsaXplZFJlbW90ZU5hbWUocGx1Z2luSWQpO1xuXHRcdFx0XHRcdGNvbnNvbGUubG9nKGBbTUZdIExvYWRpbmcgcmVtb3RlICR7cmVtb3RlTmFtZX1gKTtcblx0XHRcdFx0XHRjb25zdCBtb2R1bGVQYXRoID0gYCR7cmVtb3RlTmFtZX0vcGx1Z2luYDtcblxuXHRcdFx0XHRcdHJldHVybiB5aWVsZCogRWZmZWN0LnRyeVByb21pc2Uoe1xuXHRcdFx0XHRcdFx0dHJ5OiBhc3luYyAoKSA9PiB7XG5cblx0XHRcdFx0XHRcdFx0Y29uc3QgY29udGFpbmVyID0gYXdhaXQgbWYubG9hZFJlbW90ZTxSZW1vdGVNb2R1bGU+KG1vZHVsZVBhdGgpO1xuXHRcdFx0XHRcdFx0XHRpZiAoIWNvbnRhaW5lcikge1xuXHRcdFx0XHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcihgTm8gY29udGFpbmVyIHJldHVybmVkIGZvciAke21vZHVsZVBhdGh9YCk7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHQvLyBTdXBwb3J0IG11bHRpcGxlIGV4cG9ydCBwYXR0ZXJuczogZGlyZWN0IGZ1bmN0aW9uLCBkZWZhdWx0IGV4cG9ydCwgbmFtZWQgZXhwb3J0c1xuXHRcdFx0XHRcdFx0XHRjb25zdCBDb25zdHJ1Y3RvciA9XG5cdFx0XHRcdFx0XHRcdFx0dHlwZW9mIGNvbnRhaW5lciA9PT0gXCJmdW5jdGlvblwiXG5cdFx0XHRcdFx0XHRcdFx0XHQ/IGNvbnRhaW5lciAgLy8gRGlyZWN0IGZ1bmN0aW9uIGV4cG9ydFxuXHRcdFx0XHRcdFx0XHRcdFx0OiBjb250YWluZXIuZGVmYXVsdFxuXHRcdFx0XHRcdFx0XHRcdFx0PyBjb250YWluZXIuZGVmYXVsdCAgLy8gRGVmYXVsdCBleHBvcnRcblx0XHRcdFx0XHRcdFx0XHRcdDogT2JqZWN0LnZhbHVlcyhjb250YWluZXIpLmZpbmQoICAvLyBOYW1lZCBleHBvcnQgZmFsbGJhY2tcblx0XHRcdFx0XHRcdFx0XHRcdFx0XHQoZXhwKSA9PiB0eXBlb2YgZXhwID09PSBcImZ1bmN0aW9uXCIgJiYgZXhwLnByb3RvdHlwZT8uY29uc3RydWN0b3IgPT09IGV4cFxuXHRcdFx0XHRcdFx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0XHRcdGlmICghQ29uc3RydWN0b3IgfHwgdHlwZW9mIENvbnN0cnVjdG9yICE9PSBcImZ1bmN0aW9uXCIpIHtcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBjb250YWluZXJJbmZvID0gdHlwZW9mIGNvbnRhaW5lciA9PT0gXCJvYmplY3RcIlxuXHRcdFx0XHRcdFx0XHRcdFx0PyBgQXZhaWxhYmxlIGV4cG9ydHM6ICR7T2JqZWN0LmtleXMoY29udGFpbmVyKS5qb2luKCcsICcpfWBcblx0XHRcdFx0XHRcdFx0XHRcdDogYENvbnRhaW5lciB0eXBlOiAke3R5cGVvZiBjb250YWluZXJ9YDtcblxuXHRcdFx0XHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcihcblx0XHRcdFx0XHRcdFx0XHRcdGBObyB2YWxpZCBwbHVnaW4gY29uc3RydWN0b3IgZm91bmQgZm9yICcke3BsdWdpbklkfScuXFxuYCArXG5cdFx0XHRcdFx0XHRcdFx0XHRgU3VwcG9ydGVkIHBhdHRlcm5zOlxcbmAgK1xuXHRcdFx0XHRcdFx0XHRcdFx0YCAgLSBleHBvcnQgY29uc3QgWW91clBsdWdpbiA9IGNyZWF0ZVBsdWdpbih7Li4ufSlcXG5gICtcblx0XHRcdFx0XHRcdFx0XHRcdGAgIC0gZXhwb3J0IGRlZmF1bHQgY3JlYXRlUGx1Z2luKHsuLi59KVxcbmAgK1xuXHRcdFx0XHRcdFx0XHRcdFx0YCR7Y29udGFpbmVySW5mb31gLFxuXHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHQvLyBWYWxpZGF0ZSBpdCBsb29rcyBsaWtlIGEgcGx1Z2luIGNvbnN0cnVjdG9yIChoYXMgYmluZGluZyBwcm9wZXJ0eSlcblx0XHRcdFx0XHRcdFx0aWYgKCEoQ29uc3RydWN0b3IgYXMgYW55KS5iaW5kaW5nKSB7XG5cdFx0XHRcdFx0XHRcdFx0Y29uc3QgY29udGFpbmVySW5mbyA9IHR5cGVvZiBjb250YWluZXIgPT09IFwib2JqZWN0XCJcblx0XHRcdFx0XHRcdFx0XHRcdD8gYEZvdW5kIGV4cG9ydHM6ICR7T2JqZWN0LmtleXMoY29udGFpbmVyKS5qb2luKCcsICcpfWBcblx0XHRcdFx0XHRcdFx0XHRcdDogYENvbnRhaW5lciB0eXBlOiAke3R5cGVvZiBjb250YWluZXJ9YDtcblxuXHRcdFx0XHRcdFx0XHRcdHRocm93IG5ldyBFcnJvcihcblx0XHRcdFx0XHRcdFx0XHRcdGBJbnZhbGlkIHBsdWdpbiBjb25zdHJ1Y3RvciBmb3IgJyR7cGx1Z2luSWR9Jy4gYCArXG5cdFx0XHRcdFx0XHRcdFx0XHRgVGhlIGV4cG9ydGVkIHZhbHVlIG11c3QgYmUgY3JlYXRlZCB3aXRoIGNyZWF0ZVBsdWdpbigpLiBgICtcblx0XHRcdFx0XHRcdFx0XHRcdGBGb3VuZCBhIGZ1bmN0aW9uIGJ1dCBpdCdzIG1pc3NpbmcgdGhlIHJlcXVpcmVkICdiaW5kaW5nJyBwcm9wZXJ0eS5cXG5gICtcblx0XHRcdFx0XHRcdFx0XHRcdGAke2NvbnRhaW5lckluZm99YCxcblx0XHRcdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdFx0Y29uc29sZS5sb2coYFtNRl0g4pyFIExvYWRlZCBjb25zdHJ1Y3RvciBmb3IgJHtwbHVnaW5JZH1gKTtcblx0XHRcdFx0XHRcdFx0cmV0dXJuIENvbnN0cnVjdG9yO1xuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdGNhdGNoOiAoZXJyb3IpOiBNb2R1bGVGZWRlcmF0aW9uRXJyb3IgPT5cblx0XHRcdFx0XHRcdFx0bmV3IE1vZHVsZUZlZGVyYXRpb25FcnJvcih7XG5cdFx0XHRcdFx0XHRcdFx0cGx1Z2luSWQsXG5cdFx0XHRcdFx0XHRcdFx0cmVtb3RlVXJsOiB1cmwsXG5cdFx0XHRcdFx0XHRcdFx0Y2F1c2U6XG5cdFx0XHRcdFx0XHRcdFx0XHRlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSksXG5cdFx0XHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdH0pO1xuXHRcdFx0XHR9KSxcblx0XHR9O1xuXHR9KSxcbn0pIHt9XG4iLCJpbXBvcnQgeyBFZmZlY3QsIFJlZiB9IGZyb20gXCJlZmZlY3RcIjtcbmltcG9ydCB0eXBlIHsgQW55UGx1Z2luLCBJbml0aWFsaXplZFBsdWdpbiB9IGZyb20gXCIuLi8uLi90eXBlc1wiO1xuaW1wb3J0IHsgdG9QbHVnaW5SdW50aW1lRXJyb3IgfSBmcm9tIFwiLi4vZXJyb3JzXCI7XG5cbmV4cG9ydCBjbGFzcyBQbHVnaW5MaWZlY3ljbGVTZXJ2aWNlIGV4dGVuZHMgRWZmZWN0LlNlcnZpY2U8UGx1Z2luTGlmZWN5Y2xlU2VydmljZT4oKShcIlBsdWdpbkxpZmVjeWNsZVNlcnZpY2VcIiwge1xuICBlZmZlY3Q6IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICBjb25zdCBhY3RpdmVQbHVnaW5zID0geWllbGQqIFJlZi5tYWtlKG5ldyBTZXQ8SW5pdGlhbGl6ZWRQbHVnaW48QW55UGx1Z2luPj4oKSk7XG5cbiAgICByZXR1cm4ge1xuICAgICAgcmVnaXN0ZXI6IDxUIGV4dGVuZHMgQW55UGx1Z2luPihwbHVnaW46IEluaXRpYWxpemVkUGx1Z2luPFQ+KSA9PlxuICAgICAgICBSZWYudXBkYXRlKGFjdGl2ZVBsdWdpbnMsIHBsdWdpbnMgPT5cbiAgICAgICAgICBuZXcgU2V0KHBsdWdpbnMpLmFkZChwbHVnaW4gYXMgSW5pdGlhbGl6ZWRQbHVnaW48QW55UGx1Z2luPilcbiAgICAgICAgKSxcblxuICAgICAgdW5yZWdpc3RlcjogKHBsdWdpbjogSW5pdGlhbGl6ZWRQbHVnaW48QW55UGx1Z2luPikgPT5cbiAgICAgICAgUmVmLnVwZGF0ZShhY3RpdmVQbHVnaW5zLCBwbHVnaW5zID0+IHtcbiAgICAgICAgICBjb25zdCBuZXdTZXQgPSBuZXcgU2V0KHBsdWdpbnMpO1xuICAgICAgICAgIG5ld1NldC5kZWxldGUocGx1Z2luKTtcbiAgICAgICAgICByZXR1cm4gbmV3U2V0O1xuICAgICAgICB9KSxcblxuICAgICAgc2h1dGRvd246IChwbHVnaW46IEluaXRpYWxpemVkUGx1Z2luPEFueVBsdWdpbj4pID0+XG4gICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICAvLyBSZW1vdmUgZnJvbSBhY3RpdmUgcGx1Z2luc1xuICAgICAgICAgIHlpZWxkKiBSZWYudXBkYXRlKGFjdGl2ZVBsdWdpbnMsIHBsdWdpbnMgPT4ge1xuICAgICAgICAgICAgY29uc3QgbmV3U2V0ID0gbmV3IFNldChwbHVnaW5zKTtcbiAgICAgICAgICAgIG5ld1NldC5kZWxldGUocGx1Z2luKTtcbiAgICAgICAgICAgIHJldHVybiBuZXdTZXQ7XG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICAvLyBTaHV0ZG93biB0aGUgcGx1Z2luXG4gICAgICAgICAgeWllbGQqIHBsdWdpbi5wbHVnaW4uc2h1dGRvd24oKS5waXBlKFxuICAgICAgICAgICAgRWZmZWN0Lm1hcEVycm9yKGVycm9yID0+XG4gICAgICAgICAgICAgIHRvUGx1Z2luUnVudGltZUVycm9yKGVycm9yLCBwbHVnaW4ucGx1Z2luLmlkLCB1bmRlZmluZWQsIFwic2h1dGRvd24tcGx1Z2luXCIsIGZhbHNlKVxuICAgICAgICAgICAgKVxuICAgICAgICAgICk7XG4gICAgICAgIH0pLFxuXG4gICAgICBjbGVhbnVwOiAoKSA9PlxuICAgICAgICBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG4gICAgICAgICAgY29uc3QgcGx1Z2lucyA9IHlpZWxkKiBSZWYuZ2V0KGFjdGl2ZVBsdWdpbnMpO1xuXG4gICAgICAgICAgLy8gU2h1dGRvd24gYWxsIGFjdGl2ZSBwbHVnaW5zIGNvbmN1cnJlbnRseVxuICAgICAgICAgIHlpZWxkKiBFZmZlY3QuZm9yRWFjaChcbiAgICAgICAgICAgIHBsdWdpbnMsXG4gICAgICAgICAgICBwbHVnaW4gPT5cbiAgICAgICAgICAgICAgcGx1Z2luLnBsdWdpbi5zaHV0ZG93bigpLnBpcGUoXG4gICAgICAgICAgICAgICAgRWZmZWN0Lm1hcEVycm9yKGVycm9yID0+XG4gICAgICAgICAgICAgICAgICB0b1BsdWdpblJ1bnRpbWVFcnJvcihlcnJvciwgcGx1Z2luLnBsdWdpbi5pZCwgdW5kZWZpbmVkLCBcImNsZWFudXAtc2h1dGRvd25cIiwgZmFsc2UpXG4gICAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgICAgICBFZmZlY3QuY2F0Y2hBbGwoZXJyb3IgPT5cbiAgICAgICAgICAgICAgICAgIEVmZmVjdC5sb2dFcnJvcihcbiAgICAgICAgICAgICAgICAgICAgYEZhaWxlZCB0byBzaHV0ZG93biBwbHVnaW4gJHtwbHVnaW4ucGx1Z2luLmlkfSBkdXJpbmcgY2xlYW51cGAsXG4gICAgICAgICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICAgICAgICB7IHBsdWdpbklkOiBwbHVnaW4ucGx1Z2luLmlkIH1cbiAgICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgICApXG4gICAgICAgICAgICAgICksXG4gICAgICAgICAgICB7IGNvbmN1cnJlbmN5OiBcInVuYm91bmRlZFwiIH1cbiAgICAgICAgICApO1xuXG4gICAgICAgICAgLy8gQ2xlYXIgdGhlIGFjdGl2ZSBwbHVnaW5zIHNldFxuICAgICAgICAgIHlpZWxkKiBSZWYuc2V0KGFjdGl2ZVBsdWdpbnMsIG5ldyBTZXQoKSk7XG4gICAgICAgIH0pLnBpcGUoXG4gICAgICAgICAgRWZmZWN0LmNhdGNoQWxsKCgpID0+IEVmZmVjdC52b2lkKSAvLyBDb252ZXJ0IGVycm9ycyB0byB2b2lkIGZvciBjbGVhbnVwXG4gICAgICAgICksXG4gICAgfTtcbiAgfSksXG59KSB7IH1cbiIsImltcG9ydCB7IEVmZmVjdCB9IGZyb20gXCJlZmZlY3RcIjtcbmltcG9ydCB0eXBlIHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB7IFZhbGlkYXRpb25FcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuXG5leHBvcnQgY29uc3QgdmFsaWRhdGUgPSA8VD4oXG5cdHNjaGVtYTogei5ab2RTY2hlbWE8VD4sXG5cdGRhdGE6IHVua25vd24sXG5cdHBsdWdpbklkOiBzdHJpbmcsXG5cdHN0YWdlOiBcImNvbmZpZ1wiIHwgXCJpbnB1dFwiIHwgXCJvdXRwdXRcIiB8IFwic3RhdGVcIixcbik6IEVmZmVjdC5FZmZlY3Q8VCwgVmFsaWRhdGlvbkVycm9yPiA9PlxuXHRFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG5cdFx0Y29uc3QgcmVzdWx0ID0gc2NoZW1hLnNhZmVQYXJzZShkYXRhKTtcblx0XHRpZiAocmVzdWx0LnN1Y2Nlc3MpIHtcblx0XHRcdHJldHVybiByZXN1bHQuZGF0YTtcblx0XHR9XG5cdFx0cmV0dXJuIHlpZWxkKiBFZmZlY3QuZmFpbChcblx0XHRcdG5ldyBWYWxpZGF0aW9uRXJyb3Ioe1xuXHRcdFx0XHRwbHVnaW5JZCxcblx0XHRcdFx0c3RhZ2UsXG5cdFx0XHRcdHpvZEVycm9yOiByZXN1bHQuZXJyb3IsXG5cdFx0XHR9KSxcblx0XHQpO1xuXHR9KTtcbiIsImltcG9ydCB7IENvbnRleHQsIEVmZmVjdCB9IGZyb20gXCJlZmZlY3RcIjtcbmltcG9ydCB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgdHlwZSB7IFNlY3JldHNDb25maWcgfSBmcm9tIFwiLi4vLi4vdHlwZXNcIjtcbmltcG9ydCB7IFBsdWdpblJ1bnRpbWVFcnJvciB9IGZyb20gXCIuLi9lcnJvcnNcIjtcblxuY29uc3QgY29uZmlnU2NoZW1hID0gei5vYmplY3Qoe1xuXHRzZWNyZXRzOiB6LnJlY29yZCh6LnN0cmluZygpLCB6LnVua25vd24oKSlcbn0pLmxvb3NlKCk7XG5cbmV4cG9ydCBjbGFzcyBTZWNyZXRzQ29uZmlnVGFnIGV4dGVuZHMgQ29udGV4dC5UYWcoXCJTZWNyZXRzQ29uZmlnXCIpPFxuXHRTZWNyZXRzQ29uZmlnVGFnLFxuXHRTZWNyZXRzQ29uZmlnXG4+KCkgeyB9XG5cbmV4cG9ydCBjbGFzcyBTZWNyZXRzU2VydmljZSBleHRlbmRzIEVmZmVjdC5TZXJ2aWNlPFNlY3JldHNTZXJ2aWNlPigpKFwiU2VjcmV0c1NlcnZpY2VcIiwge1xuXHRlZmZlY3Q6IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRjb25zdCBzZWNyZXRzID0geWllbGQqIFNlY3JldHNDb25maWdUYWc7XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0aHlkcmF0ZVNlY3JldHM6IDxUPihjb25maWc6IFQpID0+XG5cdFx0XHRcdEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRcdFx0XHRjb25zdCBwYXJzZVJlc3VsdCA9IGNvbmZpZ1NjaGVtYS5wYXJzZShjb25maWcpO1xuXHRcdFx0XHRcdHRyeSB7XG5cdFx0XHRcdFx0XHRjb25zdCBjb25maWdTdHJpbmcgPSBKU09OLnN0cmluZ2lmeShwYXJzZVJlc3VsdCk7XG5cdFx0XHRcdFx0XHRsZXQgaHlkcmF0ZWRTdHJpbmcgPSBjb25maWdTdHJpbmc7XG5cblx0XHRcdFx0XHRcdGZvciAoY29uc3QgW2tleSwgdmFsdWVdIG9mIE9iamVjdC5lbnRyaWVzKHNlY3JldHMpKSB7XG5cdFx0XHRcdFx0XHRcdGNvbnN0IHBhdHRlcm4gPSBuZXcgUmVnRXhwKGB7eyR7a2V5fX19YCwgXCJnXCIpO1xuXHRcdFx0XHRcdFx0XHRoeWRyYXRlZFN0cmluZyA9IGh5ZHJhdGVkU3RyaW5nLnJlcGxhY2UocGF0dGVybiwgU3RyaW5nKHZhbHVlKSk7XG5cdFx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHRcdHJldHVybiBKU09OLnBhcnNlKGh5ZHJhdGVkU3RyaW5nKSBhcyBUO1xuXHRcdFx0XHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHRcdFx0XHRyZXR1cm4geWllbGQqIEVmZmVjdC5mYWlsKFxuXHRcdFx0XHRcdFx0XHRuZXcgUGx1Z2luUnVudGltZUVycm9yKHtcblx0XHRcdFx0XHRcdFx0XHRvcGVyYXRpb246IFwiaHlkcmF0ZS1zZWNyZXRzXCIsXG5cdFx0XHRcdFx0XHRcdFx0Y2F1c2U6XG5cdFx0XHRcdFx0XHRcdFx0XHRlcnJvciBpbnN0YW5jZW9mIEVycm9yID8gZXJyb3IgOiBuZXcgRXJyb3IoU3RyaW5nKGVycm9yKSksXG5cdFx0XHRcdFx0XHRcdFx0cmV0cnlhYmxlOiBmYWxzZSxcblx0XHRcdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0XHQpO1xuXHRcdFx0XHRcdH1cblx0XHRcdFx0fSksXG5cdFx0fTtcblx0fSksXG59KSB7IH1cbiIsImltcG9ydCB0eXBlIHsgSW5mZXJTY2hlbWFJbnB1dCwgSW5mZXJTY2hlbWFPdXRwdXQgfSBmcm9tIFwiQG9ycGMvY29udHJhY3RcIjtcbmltcG9ydCB7IENvbnRleHQsIEVmZmVjdCwgU2NvcGUgfSBmcm9tIFwiZWZmZWN0XCI7XG5pbXBvcnQgdHlwZSB7IHogfSBmcm9tIFwiem9kXCI7XG5pbXBvcnQgdHlwZSB7XG5cdEFueVBsdWdpbixcblx0SW5pdGlhbGl6ZWRQbHVnaW4sXG5cdExvYWRlZFBsdWdpbixcblx0UGx1Z2luSW5zdGFuY2UsXG5cdFBsdWdpblJlZ2lzdHJ5XG59IGZyb20gXCIuLi8uLi90eXBlc1wiO1xuaW1wb3J0IHsgUGx1Z2luUnVudGltZUVycm9yLCB0b1BsdWdpblJ1bnRpbWVFcnJvciB9IGZyb20gXCIuLi9lcnJvcnNcIjtcbmltcG9ydCB7IHZhbGlkYXRlIH0gZnJvbSBcIi4uL3ZhbGlkYXRpb25cIjtcbmltcG9ydCB7IE1vZHVsZUZlZGVyYXRpb25TZXJ2aWNlIH0gZnJvbSBcIi4vbW9kdWxlLWZlZGVyYXRpb24uc2VydmljZVwiO1xuaW1wb3J0IHsgU2VjcmV0c1NlcnZpY2UgfSBmcm9tIFwiLi9zZWNyZXRzLnNlcnZpY2VcIjtcblxuZXhwb3J0IGNsYXNzIFBsdWdpblJlZ2lzdHJ5VGFnIGV4dGVuZHMgQ29udGV4dC5UYWcoXCJQbHVnaW5SZWdpc3RyeVwiKTxcblx0UGx1Z2luUmVnaXN0cnlUYWcsXG5cdFBsdWdpblJlZ2lzdHJ5XG4+KCkgeyB9XG5cbmV4cG9ydCBjbGFzcyBSZWdpc3RyeVNlcnZpY2UgZXh0ZW5kcyBFZmZlY3QuU2VydmljZTxSZWdpc3RyeVNlcnZpY2U+KCkoXCJSZWdpc3RyeVNlcnZpY2VcIiwge1xuXHRlZmZlY3Q6IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRjb25zdCByZWdpc3RyeSA9IHlpZWxkKiBQbHVnaW5SZWdpc3RyeVRhZztcblxuXHRcdHJldHVybiB7XG5cdFx0XHRnZXQ6IChwbHVnaW5JZDogc3RyaW5nKSA9PlxuXHRcdFx0XHRFZmZlY3QuZnJvbU51bGxhYmxlKHJlZ2lzdHJ5W3BsdWdpbklkXSkucGlwZShcblx0XHRcdFx0XHRFZmZlY3QubWFwRXJyb3IoKCkgPT5cblx0XHRcdFx0XHRcdG5ldyBQbHVnaW5SdW50aW1lRXJyb3Ioe1xuXHRcdFx0XHRcdFx0XHRwbHVnaW5JZCxcblx0XHRcdFx0XHRcdFx0b3BlcmF0aW9uOiBcInZhbGlkYXRlLXBsdWdpbi1pZFwiLFxuXHRcdFx0XHRcdFx0XHRjYXVzZTogbmV3IEVycm9yKGBQbHVnaW4gJHtwbHVnaW5JZH0gbm90IGZvdW5kIGluIHJlZ2lzdHJ5YCksXG5cdFx0XHRcdFx0XHRcdHJldHJ5YWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHQpLFxuXHRcdFx0XHQpLFxuXHRcdH07XG5cdH0pLFxufSkgeyB9XG5cbmV4cG9ydCBjbGFzcyBQbHVnaW5Mb2FkZXJTZXJ2aWNlIGV4dGVuZHMgRWZmZWN0LlNlcnZpY2U8UGx1Z2luTG9hZGVyU2VydmljZT4oKShcIlBsdWdpbkxvYWRlclNlcnZpY2VcIiwge1xuXHRlZmZlY3Q6IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRjb25zdCBtb2R1bGVGZWRlcmF0aW9uU2VydmljZSA9IHlpZWxkKiBNb2R1bGVGZWRlcmF0aW9uU2VydmljZTtcblx0XHRjb25zdCBzZWNyZXRzU2VydmljZSA9IHlpZWxkKiBTZWNyZXRzU2VydmljZTtcblx0XHRjb25zdCByZWdpc3RyeVNlcnZpY2UgPSB5aWVsZCogUmVnaXN0cnlTZXJ2aWNlO1xuXG5cdFx0Y29uc3QgcmVzb2x2ZVVybCA9IChiYXNlVXJsOiBzdHJpbmcsIHZlcnNpb24/OiBzdHJpbmcpOiBzdHJpbmcgPT5cblx0XHRcdHZlcnNpb24gJiYgdmVyc2lvbiAhPT0gXCJsYXRlc3RcIlxuXHRcdFx0XHQ/IGJhc2VVcmwucmVwbGFjZShcIkBsYXRlc3RcIiwgYEAke3ZlcnNpb259YClcblx0XHRcdFx0OiBiYXNlVXJsO1xuXG5cdFx0Y29uc3QgZ2V0TWV0YWRhdGEgPSAocGx1Z2luSWQ6IHN0cmluZykgPT4gcmVnaXN0cnlTZXJ2aWNlLmdldChwbHVnaW5JZCk7XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0bG9hZFBsdWdpbjogKHBsdWdpbklkOiBzdHJpbmcpID0+XG5cdFx0XHRcdEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRcdFx0XHRjb25zdCBtZXRhZGF0YSA9IHlpZWxkKiBnZXRNZXRhZGF0YShwbHVnaW5JZCk7XG5cdFx0XHRcdFx0Y29uc3QgdXJsID0gcmVzb2x2ZVVybChtZXRhZGF0YS5yZW1vdGVVcmwpO1xuXG5cdFx0XHRcdFx0eWllbGQqIG1vZHVsZUZlZGVyYXRpb25TZXJ2aWNlLnJlZ2lzdGVyUmVtb3RlKHBsdWdpbklkLCB1cmwpLnBpcGUoXG5cdFx0XHRcdFx0XHRFZmZlY3QubWFwRXJyb3IoKGVycm9yKSA9PlxuXHRcdFx0XHRcdFx0XHR0b1BsdWdpblJ1bnRpbWVFcnJvcihlcnJvciwgcGx1Z2luSWQsIHVuZGVmaW5lZCwgXCJyZWdpc3Rlci1yZW1vdGVcIiwgdHJ1ZSksXG5cdFx0XHRcdFx0XHQpLFxuXHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHR5aWVsZCogRWZmZWN0LmxvZ0RlYnVnKFwiTG9hZGluZyBwbHVnaW5cIiwgeyBwbHVnaW5JZCwgdXJsIH0pO1xuXG5cdFx0XHRcdFx0Y29uc3QgY3RvciA9IHlpZWxkKiBtb2R1bGVGZWRlcmF0aW9uU2VydmljZS5sb2FkUmVtb3RlQ29uc3RydWN0b3IocGx1Z2luSWQsIHVybCkucGlwZShcblx0XHRcdFx0XHRcdEVmZmVjdC5tYXBFcnJvcigoZXJyb3IpID0+XG5cdFx0XHRcdFx0XHRcdHRvUGx1Z2luUnVudGltZUVycm9yKGVycm9yLCBwbHVnaW5JZCwgdW5kZWZpbmVkLCBcImxvYWQtcmVtb3RlXCIsIGZhbHNlKSxcblx0XHRcdFx0XHRcdCksXG5cdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRjdG9yLFxuXHRcdFx0XHRcdFx0bWV0YWRhdGE6IG1ldGFkYXRhLFxuXHRcdFx0XHRcdH0gc2F0aXNmaWVzIExvYWRlZFBsdWdpbjtcblx0XHRcdFx0fSksXG5cblx0XHRcdGluc3RhbnRpYXRlUGx1Z2luOiA8VCBleHRlbmRzIEFueVBsdWdpbj4oXG5cdFx0XHRcdHBsdWdpbklkOiBzdHJpbmcsXG5cdFx0XHRcdGxvYWRlZFBsdWdpbjogTG9hZGVkUGx1Z2luPFQ+LFxuXHRcdFx0KSA9PlxuXHRcdFx0XHRFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG5cdFx0XHRcdFx0Y29uc3QgaW5zdGFuY2UgPSB5aWVsZCogRWZmZWN0LnRyeSgoKSA9PiBuZXcgbG9hZGVkUGx1Z2luLmN0b3IoKSkucGlwZShcblx0XHRcdFx0XHRcdEVmZmVjdC5tYXBFcnJvcigoZXJyb3IpID0+XG5cdFx0XHRcdFx0XHRcdHRvUGx1Z2luUnVudGltZUVycm9yKFxuXHRcdFx0XHRcdFx0XHRcdGVycm9yLFxuXHRcdFx0XHRcdFx0XHRcdHBsdWdpbklkLFxuXHRcdFx0XHRcdFx0XHRcdHVuZGVmaW5lZCxcblx0XHRcdFx0XHRcdFx0XHRcImluc3RhbnRpYXRlLXBsdWdpblwiLFxuXHRcdFx0XHRcdFx0XHRcdGZhbHNlLFxuXHRcdFx0XHRcdFx0XHQpLFxuXHRcdFx0XHRcdFx0KSxcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0KGluc3RhbmNlLmlkIGFzIHN0cmluZykgPSBwbHVnaW5JZDtcblxuXHRcdFx0XHRcdHJldHVybiB7XG5cdFx0XHRcdFx0XHRwbHVnaW46IGluc3RhbmNlLFxuXHRcdFx0XHRcdFx0bWV0YWRhdGE6IGxvYWRlZFBsdWdpbi5tZXRhZGF0YSxcblx0XHRcdFx0XHR9IHNhdGlzZmllcyBQbHVnaW5JbnN0YW5jZTxUPjtcblx0XHRcdFx0fSksXG5cblx0XHRcdGluaXRpYWxpemVQbHVnaW46IDxUIGV4dGVuZHMgQW55UGx1Z2luPihcblx0XHRcdFx0cGx1Z2luSW5zdGFuY2U6IFBsdWdpbkluc3RhbmNlPFQ+LFxuXHRcdFx0XHRjb25maWc6IHsgdmFyaWFibGVzOiBJbmZlclNjaGVtYUlucHV0PFRbXCJjb25maWdTY2hlbWFcIl1bXCJ2YXJpYWJsZXNcIl0+OyBzZWNyZXRzOiBJbmZlclNjaGVtYUlucHV0PFRbXCJjb25maWdTY2hlbWFcIl1bXCJzZWNyZXRzXCJdPiB9LFxuXHRcdFx0KSA9PlxuXHRcdFx0XHRFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG5cdFx0XHRcdFx0Y29uc3QgeyBwbHVnaW4gfSA9IHBsdWdpbkluc3RhbmNlO1xuXG5cdFx0XHRcdFx0Ly8gVmFsaWRhdGUgYW5kIGh5ZHJhdGUgY29uZmlnXG5cdFx0XHRcdFx0Y29uc3QgdmFsaWRhdGVkVmFyaWFibGVzID0geWllbGQqIHZhbGlkYXRlKFxuXHRcdFx0XHRcdFx0cGx1Z2luLmNvbmZpZ1NjaGVtYS52YXJpYWJsZXMgYXMgei5ab2RTY2hlbWE8SW5mZXJTY2hlbWFPdXRwdXQ8VFtcImNvbmZpZ1NjaGVtYVwiXVtcInZhcmlhYmxlc1wiXT4+LFxuXHRcdFx0XHRcdFx0Y29uZmlnLnZhcmlhYmxlcyxcblx0XHRcdFx0XHRcdHBsdWdpbi5pZCxcblx0XHRcdFx0XHRcdFwiY29uZmlnXCIsXG5cdFx0XHRcdFx0KS5waXBlKFxuXHRcdFx0XHRcdFx0RWZmZWN0Lm1hcEVycm9yKCh2YWxpZGF0aW9uRXJyb3IpID0+XG5cdFx0XHRcdFx0XHRcdG5ldyBQbHVnaW5SdW50aW1lRXJyb3Ioe1xuXHRcdFx0XHRcdFx0XHRcdHBsdWdpbklkOiBwbHVnaW4uaWQsXG5cdFx0XHRcdFx0XHRcdFx0b3BlcmF0aW9uOiBcInZhbGlkYXRlLWNvbmZpZ1wiLFxuXHRcdFx0XHRcdFx0XHRcdGNhdXNlOiB2YWxpZGF0aW9uRXJyb3Iuem9kRXJyb3IsXG5cdFx0XHRcdFx0XHRcdFx0cmV0cnlhYmxlOiBmYWxzZSxcblx0XHRcdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0XHQpLFxuXHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHQvLyBWYWxpZGF0ZSBzZWNyZXRzXG5cdFx0XHRcdFx0Y29uc3QgdmFsaWRhdGVkU2VjcmV0cyA9IHlpZWxkKiB2YWxpZGF0ZShcblx0XHRcdFx0XHRcdHBsdWdpbi5jb25maWdTY2hlbWEuc2VjcmV0cyBhcyB6LlpvZFNjaGVtYTxJbmZlclNjaGVtYU91dHB1dDxUW1wiY29uZmlnU2NoZW1hXCJdW1wic2VjcmV0c1wiXT4+LFxuXHRcdFx0XHRcdFx0Y29uZmlnLnNlY3JldHMsXG5cdFx0XHRcdFx0XHRwbHVnaW4uaWQsXG5cdFx0XHRcdFx0XHRcImNvbmZpZ1wiLFxuXHRcdFx0XHRcdCkucGlwZShcblx0XHRcdFx0XHRcdEVmZmVjdC5tYXBFcnJvcigodmFsaWRhdGlvbkVycm9yKSA9PlxuXHRcdFx0XHRcdFx0XHRuZXcgUGx1Z2luUnVudGltZUVycm9yKHtcblx0XHRcdFx0XHRcdFx0XHRwbHVnaW5JZDogcGx1Z2luLmlkLFxuXHRcdFx0XHRcdFx0XHRcdG9wZXJhdGlvbjogXCJ2YWxpZGF0ZS1zZWNyZXRzXCIsXG5cdFx0XHRcdFx0XHRcdFx0Y2F1c2U6IHZhbGlkYXRpb25FcnJvci56b2RFcnJvcixcblx0XHRcdFx0XHRcdFx0XHRyZXRyeWFibGU6IGZhbHNlLFxuXHRcdFx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHRcdCksXG5cdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdC8vIEh5ZHJhdGUgc2VjcmV0cyBpbiB2YXJpYWJsZXNcblx0XHRcdFx0XHRjb25zdCBoeWRyYXRlZENvbmZpZyA9IHlpZWxkKiBzZWNyZXRzU2VydmljZS5oeWRyYXRlU2VjcmV0cyh7XG5cdFx0XHRcdFx0XHR2YXJpYWJsZXM6IHZhbGlkYXRlZFZhcmlhYmxlcyxcblx0XHRcdFx0XHRcdHNlY3JldHM6IHZhbGlkYXRlZFNlY3JldHMsXG5cdFx0XHRcdFx0fSk7XG5cblx0XHRcdFx0XHRjb25zdCBfdmFyaWFibGVzID0geWllbGQqIHZhbGlkYXRlKFxuXHRcdFx0XHRcdFx0cGx1Z2luLmNvbmZpZ1NjaGVtYS52YXJpYWJsZXMgYXMgei5ab2RTY2hlbWE8SW5mZXJTY2hlbWFPdXRwdXQ8VFtcImNvbmZpZ1NjaGVtYVwiXVtcInZhcmlhYmxlc1wiXT4+LFxuXHRcdFx0XHRcdFx0aHlkcmF0ZWRDb25maWcudmFyaWFibGVzLFxuXHRcdFx0XHRcdFx0cGx1Z2luLmlkLFxuXHRcdFx0XHRcdFx0XCJjb25maWdcIixcblx0XHRcdFx0XHQpLnBpcGUoXG5cdFx0XHRcdFx0XHRFZmZlY3QubWFwRXJyb3IoKHZhbGlkYXRpb25FcnJvcikgPT5cblx0XHRcdFx0XHRcdFx0bmV3IFBsdWdpblJ1bnRpbWVFcnJvcih7XG5cdFx0XHRcdFx0XHRcdFx0cGx1Z2luSWQ6IHBsdWdpbi5pZCxcblx0XHRcdFx0XHRcdFx0XHRvcGVyYXRpb246IFwidmFsaWRhdGUtaHlkcmF0ZWQtY29uZmlnXCIsXG5cdFx0XHRcdFx0XHRcdFx0Y2F1c2U6IHZhbGlkYXRpb25FcnJvci56b2RFcnJvcixcblx0XHRcdFx0XHRcdFx0XHRyZXRyeWFibGU6IGZhbHNlLFxuXHRcdFx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHRcdCksXG5cdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdC8vIENyZWF0ZSBhIGxvbmctbGl2ZWQgc2NvcGUgZm9yIHRoaXMgcGx1Z2luIGluc3RhbmNlXG5cdFx0XHRcdFx0Y29uc3Qgc2NvcGUgPSB5aWVsZCogU2NvcGUubWFrZSgpO1xuXG5cdFx0XHRcdFx0Ly8gSW5pdGlhbGl6ZSBwbHVnaW4gd2l0aGluIHRoZSBzY29wZVxuXHRcdFx0XHRcdGNvbnN0IGNvbnRleHQgPSB5aWVsZCogcGx1Z2luLmluaXRpYWxpemUoeyB2YXJpYWJsZXM6IF92YXJpYWJsZXMsIHNlY3JldHM6IGh5ZHJhdGVkQ29uZmlnLnNlY3JldHMgfSkucGlwZShcblx0XHRcdFx0XHRcdEVmZmVjdC5wcm92aWRlU2VydmljZShTY29wZS5TY29wZSwgc2NvcGUpLFxuXHRcdFx0XHRcdFx0RWZmZWN0Lm1hcEVycm9yKChlcnJvcikgPT5cblx0XHRcdFx0XHRcdFx0dG9QbHVnaW5SdW50aW1lRXJyb3IoZXJyb3IsIHBsdWdpbi5pZCwgdW5kZWZpbmVkLCBcImluaXRpYWxpemUtcGx1Z2luXCIsIGZhbHNlKSxcblx0XHRcdFx0XHRcdClcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdHBsdWdpbixcblx0XHRcdFx0XHRcdG1ldGFkYXRhOiBwbHVnaW5JbnN0YW5jZS5tZXRhZGF0YSxcblx0XHRcdFx0XHRcdGNvbmZpZzogeyB2YXJpYWJsZXM6IF92YXJpYWJsZXMsIHNlY3JldHM6IGh5ZHJhdGVkQ29uZmlnLnNlY3JldHMgfSxcblx0XHRcdFx0XHRcdGNvbnRleHQsXG5cdFx0XHRcdFx0XHRzY29wZSxcblx0XHRcdFx0XHR9IHNhdGlzZmllcyBJbml0aWFsaXplZFBsdWdpbjxUPjtcblx0XHRcdFx0fSksXG5cdFx0fTtcblx0fSksXG59KSB7XG59XG4iLCJpbXBvcnQgeyBFZmZlY3QsIEV4aXQsIExheWVyLCBTY29wZSB9IGZyb20gXCJlZmZlY3RcIjtcbmltcG9ydCB0eXBlIHtcblx0QW55UGx1Z2luLFxuXHRJbml0aWFsaXplZFBsdWdpbixcblx0UGx1Z2luUmVnaXN0cnksXG5cdFNlY3JldHNDb25maWdcbn0gZnJvbSBcIi4uLy4uL3R5cGVzXCI7XG5pbXBvcnQgeyBNb2R1bGVGZWRlcmF0aW9uU2VydmljZSB9IGZyb20gXCIuL21vZHVsZS1mZWRlcmF0aW9uLnNlcnZpY2VcIjtcbmltcG9ydCB7IFBsdWdpbkxpZmVjeWNsZVNlcnZpY2UgfSBmcm9tIFwiLi9wbHVnaW4tbGlmZWN5Y2xlLnNlcnZpY2VcIjtcbmltcG9ydCB7IFBsdWdpbkxvYWRlclNlcnZpY2UsIFBsdWdpblJlZ2lzdHJ5VGFnLCBSZWdpc3RyeVNlcnZpY2UgfSBmcm9tIFwiLi9wbHVnaW4tbG9hZGVyLnNlcnZpY2VcIjtcbmltcG9ydCB7IFNlY3JldHNDb25maWdUYWcsIFNlY3JldHNTZXJ2aWNlIH0gZnJvbSBcIi4vc2VjcmV0cy5zZXJ2aWNlXCI7XG5cbmV4cG9ydCBjbGFzcyBQbHVnaW5TZXJ2aWNlIGV4dGVuZHMgRWZmZWN0LlNlcnZpY2U8UGx1Z2luU2VydmljZT4oKShcIlBsdWdpblNlcnZpY2VcIiwge1xuXHRzY29wZWQ6IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRjb25zdCBsb2FkZXIgPSB5aWVsZCogUGx1Z2luTG9hZGVyU2VydmljZTtcblx0XHRjb25zdCBsaWZlY3ljbGUgPSB5aWVsZCogUGx1Z2luTGlmZWN5Y2xlU2VydmljZTtcblxuXHRcdHJldHVybiB7XG5cdFx0XHRsb2FkUGx1Z2luOiBsb2FkZXIubG9hZFBsdWdpbixcblx0XHRcdGluc3RhbnRpYXRlUGx1Z2luOiBsb2FkZXIuaW5zdGFudGlhdGVQbHVnaW4sXG5cdFx0XHRpbml0aWFsaXplUGx1Z2luOiBsb2FkZXIuaW5pdGlhbGl6ZVBsdWdpbixcblx0XHRcdHNodXRkb3duUGx1Z2luOiAocGx1Z2luOiBJbml0aWFsaXplZFBsdWdpbjxBbnlQbHVnaW4+KSA9PlxuXHRcdFx0XHRFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG5cdFx0XHRcdFx0Ly8gU2h1dGRvd24gdGhlIHBsdWdpbiBmaXJzdCAoZ3JhY2VmdWwgY2xlYW51cClcblx0XHRcdFx0XHR5aWVsZCogcGx1Z2luLnBsdWdpbi5zaHV0ZG93bigpLnBpcGUoXG5cdFx0XHRcdFx0XHRFZmZlY3QuY2F0Y2hBbGwoKCkgPT4gRWZmZWN0LnZvaWQpXG5cdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdC8vIENsb3NlIHRoZSBwbHVnaW4gc2NvcGUgdG8gaW50ZXJydXB0IGZpYmVycyBhbmQgcmVsZWFzZSByZXNvdXJjZXNcblx0XHRcdFx0XHR5aWVsZCogU2NvcGUuY2xvc2UocGx1Z2luLnNjb3BlLCBFeGl0LnN1Y2NlZWQodW5kZWZpbmVkKSk7XG5cblx0XHRcdFx0XHQvLyBVbnJlZ2lzdGVyIGZyb20gbGlmZWN5Y2xlIHRyYWNraW5nXG5cdFx0XHRcdFx0eWllbGQqIGxpZmVjeWNsZS51bnJlZ2lzdGVyKHBsdWdpbik7XG5cdFx0XHRcdH0pLFxuXHRcdFx0Y2xlYW51cDogbGlmZWN5Y2xlLmNsZWFudXAsXG5cdFx0fTtcblx0fSksXG59KSB7XG5cdHN0YXRpYyBMaXZlID0gKHJlZ2lzdHJ5OiBQbHVnaW5SZWdpc3RyeSwgc2VjcmV0czogU2VjcmV0c0NvbmZpZykgPT4ge1xuXHRcdGNvbnN0IGNvbnRleHRMYXllciA9IExheWVyLm1lcmdlQWxsKFxuXHRcdFx0TGF5ZXIuc3VjY2VlZChQbHVnaW5SZWdpc3RyeVRhZywgcmVnaXN0cnkpLFxuXHRcdFx0TGF5ZXIuc3VjY2VlZChTZWNyZXRzQ29uZmlnVGFnLCBzZWNyZXRzKSxcblx0XHQpO1xuXG5cdFx0Y29uc3Qgc2VydmljZXNMYXllciA9IExheWVyLm1lcmdlQWxsKFxuXHRcdFx0TW9kdWxlRmVkZXJhdGlvblNlcnZpY2UuRGVmYXVsdCxcblx0XHRcdFNlY3JldHNTZXJ2aWNlLkRlZmF1bHQsXG5cdFx0XHRSZWdpc3RyeVNlcnZpY2UuRGVmYXVsdCxcblx0XHRcdFBsdWdpbkxpZmVjeWNsZVNlcnZpY2UuRGVmYXVsdCxcblx0XHQpLnBpcGUoXG5cdFx0XHRMYXllci5wcm92aWRlKGNvbnRleHRMYXllcilcblx0XHQpO1xuXG5cdFx0cmV0dXJuIFBsdWdpblNlcnZpY2UuRGVmYXVsdC5waXBlKFxuXHRcdFx0TGF5ZXIucHJvdmlkZShQbHVnaW5Mb2FkZXJTZXJ2aWNlLkRlZmF1bHQpLFxuXHRcdFx0TGF5ZXIucHJvdmlkZShzZXJ2aWNlc0xheWVyKVxuXHRcdCk7XG5cdH1cbn1cbiIsImltcG9ydCB7IGNyZWF0ZVJvdXRlckNsaWVudCB9IGZyb20gXCJAb3JwYy9zZXJ2ZXJcIjtcbmltcG9ydCB7IENhdXNlLCBFZmZlY3QsIEV4aXQsIEhhc2gsIE1hbmFnZWRSdW50aW1lLCBPcHRpb24gfSBmcm9tIFwiZWZmZWN0XCI7XG5pbXBvcnQgdHlwZSB7XG5cdEFueVBsdWdpbixcblx0SW5pdGlhbGl6ZWRQbHVnaW4sXG5cdExvYWRlZFBsdWdpbixcblx0UGx1Z2luQ2xpZW50VHlwZSxcblx0UGx1Z2luQ29uZmlnSW5wdXQsXG5cdFBsdWdpbkluc3RhbmNlLFxuXHRQbHVnaW5SZWdpc3RyeSxcblx0UGx1Z2luUm91dGVyVHlwZSxcblx0UGx1Z2luUnVudGltZUNvbmZpZyxcblx0UmVnaXN0ZXJlZFBsdWdpbixcblx0UmVnaXN0ZXJlZFBsdWdpbnMsXG5cdFVzZVBsdWdpblJlc3VsdFxufSBmcm9tIFwiLi4vdHlwZXNcIjtcbmltcG9ydCB7IFBsdWdpblJ1bnRpbWVFcnJvciB9IGZyb20gXCIuL2Vycm9yc1wiO1xuaW1wb3J0IHsgUGx1Z2luU2VydmljZSB9IGZyb20gXCIuL3NlcnZpY2VzL3BsdWdpbi5zZXJ2aWNlXCI7XG5cbmV4cG9ydCBjbGFzcyBQbHVnaW5SdW50aW1lPFIgZXh0ZW5kcyBSZWdpc3RlcmVkUGx1Z2lucyA9IFJlZ2lzdGVyZWRQbHVnaW5zPiB7XG5cdHByaXZhdGUgcGx1Z2luQ2FjaGUgPSBuZXcgTWFwPHN0cmluZywgRWZmZWN0LkVmZmVjdDxJbml0aWFsaXplZFBsdWdpbjxBbnlQbHVnaW4+LCBQbHVnaW5SdW50aW1lRXJyb3I+PigpO1xuXG5cdGNvbnN0cnVjdG9yKFxuXHRcdHByaXZhdGUgcnVudGltZTogTWFuYWdlZFJ1bnRpbWUuTWFuYWdlZFJ1bnRpbWU8UGx1Z2luU2VydmljZSwgbmV2ZXI+LFxuXHRcdHByaXZhdGUgcmVnaXN0cnk6IFBsdWdpblJlZ2lzdHJ5XG5cdCkgeyB9XG5cblx0cHJpdmF0ZSBnZW5lcmF0ZUNhY2hlS2V5KHBsdWdpbklkOiBzdHJpbmcsIGNvbmZpZzogdW5rbm93bik6IHN0cmluZyB7XG5cdFx0Y29uc3QgY29uZmlnSGFzaCA9IEhhc2guc3RydWN0dXJlKGNvbmZpZyBhcyBvYmplY3QpLnRvU3RyaW5nKCk7XG5cdFx0cmV0dXJuIGAke3BsdWdpbklkfToke2NvbmZpZ0hhc2h9YDtcblx0fVxuXG5cdHByaXZhdGUgdmFsaWRhdGVQbHVnaW5JZChcblx0XHRwbHVnaW5JZDogc3RyaW5nXG5cdCk6IEVmZmVjdC5FZmZlY3Q8c3RyaW5nLCBQbHVnaW5SdW50aW1lRXJyb3I+IHtcblx0XHRpZiAoIShwbHVnaW5JZCBpbiB0aGlzLnJlZ2lzdHJ5KSkge1xuXHRcdFx0cmV0dXJuIEVmZmVjdC5mYWlsKG5ldyBQbHVnaW5SdW50aW1lRXJyb3Ioe1xuXHRcdFx0XHRwbHVnaW5JZDogU3RyaW5nKHBsdWdpbklkKSxcblx0XHRcdFx0b3BlcmF0aW9uOiBcInZhbGlkYXRlLXBsdWdpbi1pZFwiLFxuXHRcdFx0XHRjYXVzZTogbmV3IEVycm9yKGBQbHVnaW4gSUQgJyR7U3RyaW5nKHBsdWdpbklkKX0nIG5vdCBmb3VuZCBpbiByZWdpc3RyeS5gKSxcblx0XHRcdFx0cmV0cnlhYmxlOiBmYWxzZSxcblx0XHRcdH0pKTtcblx0XHR9XG5cdFx0cmV0dXJuIEVmZmVjdC5zdWNjZWVkKFN0cmluZyhwbHVnaW5JZCkpO1xuXHR9XG5cblx0cHJpdmF0ZSBhc3luYyBydW5Qcm9taXNlPEEsIEU+KFxuXHRcdGVmZmVjdDogRWZmZWN0LkVmZmVjdDxBLCBFLCBQbHVnaW5TZXJ2aWNlPlxuXHQpOiBQcm9taXNlPEE+IHtcblx0XHRjb25zdCBleGl0ID0gYXdhaXQgdGhpcy5ydW50aW1lLnJ1blByb21pc2VFeGl0KGVmZmVjdCk7XG5cblx0XHRpZiAoRXhpdC5pc0ZhaWx1cmUoZXhpdCkpIHtcblx0XHRcdGNvbnN0IGVycm9yID0gQ2F1c2UuZmFpbHVyZU9wdGlvbihleGl0LmNhdXNlKTtcblx0XHRcdGlmIChPcHRpb24uaXNTb21lKGVycm9yKSkge1xuXHRcdFx0XHR0aHJvdyBlcnJvci52YWx1ZTtcblx0XHRcdH1cblx0XHRcdHRocm93IENhdXNlLnNxdWFzaChleGl0LmNhdXNlKTtcblx0XHR9XG5cblx0XHRyZXR1cm4gZXhpdC52YWx1ZTtcblx0fVxuXG5cdGFzeW5jIHVzZVBsdWdpbjxLIGV4dGVuZHMga2V5b2YgUmVnaXN0ZXJlZFBsdWdpbnMgJiBzdHJpbmc+KFxuXHRcdHBsdWdpbklkOiBLLFxuXHRcdGNvbmZpZzogUGx1Z2luQ29uZmlnSW5wdXQ8UltLXT5cblx0KTogUHJvbWlzZTxVc2VQbHVnaW5SZXN1bHQ8Sz4+IHtcblx0XHRjb25zdCBjYWNoZUtleSA9IHRoaXMuZ2VuZXJhdGVDYWNoZUtleShwbHVnaW5JZCwgY29uZmlnKTtcblxuXHRcdGxldCBjYWNoZWRQbHVnaW4gPSB0aGlzLnBsdWdpbkNhY2hlLmdldChjYWNoZUtleSk7XG5cdFx0aWYgKCFjYWNoZWRQbHVnaW4pIHtcblx0XHRcdGNvbnN0IG9wZXJhdGlvbiA9IEVmZmVjdC5nZW4odGhpcywgZnVuY3Rpb24qICgpIHtcblx0XHRcdFx0Y29uc3QgcGx1Z2luU2VydmljZSA9IHlpZWxkKiBQbHVnaW5TZXJ2aWNlO1xuXHRcdFx0XHRjb25zdCB2YWxpZGF0ZWRJZCA9IHlpZWxkKiB0aGlzLnZhbGlkYXRlUGx1Z2luSWQocGx1Z2luSWQpO1xuXG5cdFx0XHRcdC8vIExvYWQg4oaSIEluc3RhbnRpYXRlIOKGkiBJbml0aWFsaXplXG5cdFx0XHRcdGNvbnN0IGN0b3IgPSB5aWVsZCogcGx1Z2luU2VydmljZS5sb2FkUGx1Z2luKHZhbGlkYXRlZElkKTtcblx0XHRcdFx0Y29uc3QgaW5zdGFuY2UgPSB5aWVsZCogcGx1Z2luU2VydmljZS5pbnN0YW50aWF0ZVBsdWdpbihwbHVnaW5JZCwgY3Rvcik7XG5cdFx0XHRcdGNvbnN0IGluaXRpYWxpemVkID0geWllbGQqIHBsdWdpblNlcnZpY2UuaW5pdGlhbGl6ZVBsdWdpbihpbnN0YW5jZSwgY29uZmlnKTtcblxuXHRcdFx0XHRyZXR1cm4gaW5pdGlhbGl6ZWQ7XG5cdFx0XHR9KS5waXBlKEVmZmVjdC5wcm92aWRlKHRoaXMucnVudGltZSkpO1xuXG5cdFx0XHRjYWNoZWRQbHVnaW4gPSBFZmZlY3QuY2FjaGVkKG9wZXJhdGlvbikucGlwZShFZmZlY3QuZmxhdHRlbik7XG5cdFx0XHR0aGlzLnBsdWdpbkNhY2hlLnNldChjYWNoZUtleSwgY2FjaGVkUGx1Z2luKTtcblx0XHR9XG5cblx0XHRjb25zdCBpbml0aWFsaXplZCA9IGF3YWl0IHRoaXMucnVuUHJvbWlzZShjYWNoZWRQbHVnaW4pO1xuXHRcdGNvbnN0IHJvdXRlciA9IGluaXRpYWxpemVkLnBsdWdpbi5jcmVhdGVSb3V0ZXIoaW5pdGlhbGl6ZWQuY29udGV4dCk7XG5cdFx0Y29uc3QgY2xpZW50ID0gY3JlYXRlUm91dGVyQ2xpZW50KHJvdXRlcik7XG5cblx0XHRyZXR1cm4ge1xuXHRcdFx0cm91dGVyOiByb3V0ZXIgYXMgUGx1Z2luUm91dGVyVHlwZTxSW0tdPixcblx0XHRcdGNsaWVudDogY2xpZW50IGFzIFBsdWdpbkNsaWVudFR5cGU8UltLXT4sXG5cdFx0XHRtZXRhZGF0YTogaW5pdGlhbGl6ZWQubWV0YWRhdGEsXG5cdFx0XHRpbml0aWFsaXplZDogaW5pdGlhbGl6ZWQgYXMgSW5pdGlhbGl6ZWRQbHVnaW48UmVnaXN0ZXJlZFBsdWdpbjxLPj5cblx0XHR9IGFzIFVzZVBsdWdpblJlc3VsdDxLPjtcblx0fVxuXG5cdGFzeW5jIGxvYWRQbHVnaW48SyBleHRlbmRzIGtleW9mIFJlZ2lzdGVyZWRQbHVnaW5zICYgc3RyaW5nPihcblx0XHRwbHVnaW5JZDogS1xuXHQpOiBQcm9taXNlPExvYWRlZFBsdWdpbjxSZWdpc3RlcmVkUGx1Z2luPEs+Pj4ge1xuXHRcdGNvbnN0IGVmZmVjdCA9IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRcdGNvbnN0IHBsdWdpblNlcnZpY2UgPSB5aWVsZCogUGx1Z2luU2VydmljZTtcblx0XHRcdHJldHVybiB5aWVsZCogcGx1Z2luU2VydmljZS5sb2FkUGx1Z2luKHBsdWdpbklkKTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcy5ydW5Qcm9taXNlKGVmZmVjdCkgYXMgUHJvbWlzZTxMb2FkZWRQbHVnaW48UmVnaXN0ZXJlZFBsdWdpbjxLPj4+O1xuXHR9XG5cblx0YXN5bmMgaW5zdGFudGlhdGVQbHVnaW48SyBleHRlbmRzIGtleW9mIFJlZ2lzdGVyZWRQbHVnaW5zICYgc3RyaW5nPihcblx0XHRwbHVnaW5JZDogSyxcblx0XHRsb2FkZWRQbHVnaW46IExvYWRlZFBsdWdpbjxSZWdpc3RlcmVkUGx1Z2luPEs+PlxuXHQpOiBQcm9taXNlPFBsdWdpbkluc3RhbmNlPFJlZ2lzdGVyZWRQbHVnaW48Sz4+PiB7XG5cdFx0Y29uc3QgZWZmZWN0ID0gRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuXHRcdFx0Y29uc3QgcGx1Z2luU2VydmljZSA9IHlpZWxkKiBQbHVnaW5TZXJ2aWNlO1xuXHRcdFx0cmV0dXJuIHlpZWxkKiBwbHVnaW5TZXJ2aWNlLmluc3RhbnRpYXRlUGx1Z2luKHBsdWdpbklkLCBsb2FkZWRQbHVnaW4pO1xuXHRcdH0pO1xuXHRcdHJldHVybiB0aGlzLnJ1blByb21pc2UoZWZmZWN0KSBhcyBQcm9taXNlPFBsdWdpbkluc3RhbmNlPFJlZ2lzdGVyZWRQbHVnaW48Sz4+Pjtcblx0fVxuXG5cdGFzeW5jIGluaXRpYWxpemVQbHVnaW48VCBleHRlbmRzIEFueVBsdWdpbj4oXG5cdFx0aW5zdGFuY2U6IFBsdWdpbkluc3RhbmNlPFQ+LFxuXHRcdGNvbmZpZzogYW55XG5cdCk6IFByb21pc2U8SW5pdGlhbGl6ZWRQbHVnaW48VD4+IHtcblx0XHRjb25zdCBlZmZlY3QgPSBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG5cdFx0XHRjb25zdCBwbHVnaW5TZXJ2aWNlID0geWllbGQqIFBsdWdpblNlcnZpY2U7XG5cdFx0XHRyZXR1cm4geWllbGQqIHBsdWdpblNlcnZpY2UuaW5pdGlhbGl6ZVBsdWdpbihpbnN0YW5jZSwgY29uZmlnKTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcy5ydW5Qcm9taXNlKGVmZmVjdCk7XG5cdH1cblxuXHRhc3luYyBzaHV0ZG93bigpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCBlZmZlY3QgPSBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG5cdFx0XHRjb25zdCBwbHVnaW5TZXJ2aWNlID0geWllbGQqIFBsdWdpblNlcnZpY2U7XG5cdFx0XHR5aWVsZCogcGx1Z2luU2VydmljZS5jbGVhbnVwKCk7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHRoaXMucnVuUHJvbWlzZShlZmZlY3QpO1xuXHR9XG5cblx0YXN5bmMgZXZpY3RQbHVnaW48SyBleHRlbmRzIGtleW9mIFJlZ2lzdGVyZWRQbHVnaW5zICYgc3RyaW5nPihcblx0XHRwbHVnaW5JZDogSyxcblx0XHRjb25maWc6IFBsdWdpbkNvbmZpZ0lucHV0PFJlZ2lzdGVyZWRQbHVnaW5zW0tdPlxuXHQpOiBQcm9taXNlPHZvaWQ+IHtcblx0XHRjb25zdCBjYWNoZUtleSA9IHRoaXMuZ2VuZXJhdGVDYWNoZUtleShwbHVnaW5JZCwgY29uZmlnKTtcblxuXHRcdGNvbnN0IGVmZmVjdCA9IEVmZmVjdC5nZW4odGhpcywgZnVuY3Rpb24qICgpIHtcblx0XHRcdGNvbnN0IHBsdWdpblNlcnZpY2UgPSB5aWVsZCogUGx1Z2luU2VydmljZTtcblx0XHRcdGNvbnN0IGNhY2hlZFBsdWdpbiA9IHRoaXMucGx1Z2luQ2FjaGUuZ2V0KGNhY2hlS2V5KTtcblxuXHRcdFx0aWYgKGNhY2hlZFBsdWdpbikge1xuXHRcdFx0XHR0aGlzLnBsdWdpbkNhY2hlLmRlbGV0ZShjYWNoZUtleSk7XG5cblx0XHRcdFx0Y29uc3QgcGx1Z2luUmVzdWx0ID0geWllbGQqIGNhY2hlZFBsdWdpbi5waXBlKFxuXHRcdFx0XHRcdEVmZmVjdC5jYXRjaEFsbCgoKSA9PiBFZmZlY3Quc3VjY2VlZChudWxsKSlcblx0XHRcdFx0KTtcblxuXHRcdFx0XHRpZiAocGx1Z2luUmVzdWx0KSB7XG5cdFx0XHRcdFx0eWllbGQqIHBsdWdpblNlcnZpY2Uuc2h1dGRvd25QbHVnaW4ocGx1Z2luUmVzdWx0KS5waXBlKFxuXHRcdFx0XHRcdFx0RWZmZWN0LmNhdGNoQWxsKCgpID0+IEVmZmVjdC52b2lkKVxuXHRcdFx0XHRcdCk7XG5cdFx0XHRcdH1cblx0XHRcdH1cblx0XHR9KS5waXBlKEVmZmVjdC5jYXRjaEFsbCgoKSA9PiBFZmZlY3Qudm9pZCkpO1xuXG5cdFx0cmV0dXJuIHRoaXMucnVuUHJvbWlzZShlZmZlY3QpO1xuXHR9XG59XG5cbi8qKlxuICogTm9ybWFsaXplcyBhIHJlbW90ZSBVUkwgdG8gZW5zdXJlIGl0IHBvaW50cyB0byByZW1vdGVFbnRyeS5qc1xuICogSWYgdGhlIFVSTCBkb2Vzbid0IGVuZCB3aXRoIGEgZmlsZSBleHRlbnNpb24sIGFwcGVuZHMgL3JlbW90ZUVudHJ5LmpzXG4gKi9cbmZ1bmN0aW9uIG5vcm1hbGl6ZVJlbW90ZVVybCh1cmw6IHN0cmluZyk6IHN0cmluZyB7XG5cdGlmICh1cmwuZW5kc1dpdGgoJy5qcycpKSByZXR1cm4gdXJsOyAvLyBBbHJlYWR5IGEgZmlsZVxuXHRyZXR1cm4gYCR7dXJsLmVuZHNXaXRoKCcvJykgPyB1cmwuc2xpY2UoMCwgLTEpIDogdXJsfS9yZW1vdGVFbnRyeS5qc2A7XG59XG5cbmV4cG9ydCBmdW5jdGlvbiBjcmVhdGVQbHVnaW5SdW50aW1lKFxuXHRjb25maWc6IFBsdWdpblJ1bnRpbWVDb25maWdcbik6IFBsdWdpblJ1bnRpbWUge1xuXHRjb25zdCBzZWNyZXRzID0gY29uZmlnLnNlY3JldHMgfHwge307XG5cblx0Ly8gTm9ybWFsaXplIGFsbCByZW1vdGUgVVJMcyBpbiB0aGUgcmVnaXN0cnlcblx0Y29uc3Qgbm9ybWFsaXplZFJlZ2lzdHJ5ID0gT2JqZWN0LmZyb21FbnRyaWVzKFxuXHRcdE9iamVjdC5lbnRyaWVzKGNvbmZpZy5yZWdpc3RyeSkubWFwKChbcGx1Z2luSWQsIGVudHJ5XSkgPT4gW1xuXHRcdFx0cGx1Z2luSWQsXG5cdFx0XHR7XG5cdFx0XHRcdC4uLmVudHJ5LFxuXHRcdFx0XHRyZW1vdGVVcmw6IG5vcm1hbGl6ZVJlbW90ZVVybChlbnRyeS5yZW1vdGVVcmwpXG5cdFx0XHR9XG5cdFx0XSlcblx0KSBhcyBQbHVnaW5SZWdpc3RyeTtcblxuXHRjb25zdCBsYXllciA9IFBsdWdpblNlcnZpY2UuTGl2ZShub3JtYWxpemVkUmVnaXN0cnksIHNlY3JldHMpO1xuXHRjb25zdCBydW50aW1lID0gTWFuYWdlZFJ1bnRpbWUubWFrZShsYXllcik7XG5cblx0cmV0dXJuIG5ldyBQbHVnaW5SdW50aW1lKHJ1bnRpbWUsIG5vcm1hbGl6ZWRSZWdpc3RyeSk7XG59Il0sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7Ozs7QUFJQSxJQUFhLHFCQUFiLGNBQXdDQSxZQUFLLFlBQVkscUJBQXFCLENBTTNFO0FBRUgsSUFBYSx3QkFBYixjQUEyQ0EsWUFBSyxZQUMvQyx3QkFDQSxDQUlFO0FBRUgsSUFBYSxrQkFBYixjQUFxQ0EsWUFBSyxZQUFZLGtCQUFrQixDQUlyRTtBQUdILE1BQWEsdUJBQXVCLFNBQTBCO0FBQzdELFNBQVEsTUFBUjtFQUNDLEtBQUs7RUFDTCxLQUFLO0VBQ0wsS0FBSztFQUNMLEtBQUs7RUFDTCxLQUFLLFVBQ0osUUFBTztFQUNSLFFBQ0MsUUFBTzs7O0FBS1YsTUFBYSxpQkFDWixXQUNBLFVBQ0EsZUFDQSxjQUN3QjtBQUN4QixRQUFPLElBQUksbUJBQW1CO0VBQzdCO0VBQ0E7RUFDQTtFQUNBLFdBQVcsb0JBQW9CLFVBQVUsS0FBSztFQUM5QyxPQUFPO0VBQ1AsQ0FBQzs7QUFJSCxNQUFhLHdCQUNaLE9BQ0EsVUFDQSxlQUNBLFdBQ0EsbUJBQW1CLFVBQ0s7QUFDeEIsS0FBSSxp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