every-plugin 0.4.12 → 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,459 @@
1
+ import { i as __toESM } from "./chunk-QQAxy9l9.mjs";
2
+ import { t as getNormalizedRemoteName } from "./normalize-D7nae0Hn.mjs";
3
+ import { t as require_package } from "./package-BoyftHDo.mjs";
4
+ import { Cause, Context, Data, Effect, Exit, Hash, Layer, ManagedRuntime, Option, Ref, Scope } from "effect";
5
+ import { z } from "zod";
6
+ import { createRouterClient } from "@orpc/server";
7
+ import { ORPCError } from "@orpc/contract";
8
+ import { betterFetch } from "@better-fetch/fetch";
9
+ import { createInstance, getInstance } from "@module-federation/enhanced/runtime";
10
+ import { setGlobalFederationInstance } from "@module-federation/runtime-core";
11
+
12
+ //#region src/runtime/errors.ts
13
+ var PluginRuntimeError = class extends Data.TaggedError("PluginRuntimeError") {};
14
+ var ModuleFederationError = class extends Data.TaggedError("ModuleFederationError") {};
15
+ var ValidationError = class extends 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 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__ */ __toESM(require_package(), 1);
50
+ const createModuleFederationInstance = Effect.cached(Effect.sync(() => {
51
+ try {
52
+ let instance = getInstance();
53
+ if (!instance) {
54
+ instance = 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
+ 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.Service()("ModuleFederationService", { effect: Effect.gen(function* () {
113
+ const mf = yield* Effect.flatten(createModuleFederationInstance);
114
+ return {
115
+ registerRemote: (pluginId, url) => 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.tryPromise({
119
+ try: () => 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 : getNormalizedRemoteName(pluginId);
134
+ yield* 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.gen(function* () {
149
+ const remoteName = getNormalizedRemoteName(pluginId);
150
+ console.log(`[MF] Loading remote ${remoteName}`);
151
+ const modulePath = `${remoteName}/plugin`;
152
+ return yield* 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.Service()("PluginLifecycleService", { effect: Effect.gen(function* () {
181
+ const activePlugins = yield* Ref.make(/* @__PURE__ */ new Set());
182
+ return {
183
+ register: (plugin) => Ref.update(activePlugins, (plugins) => new Set(plugins).add(plugin)),
184
+ unregister: (plugin) => Ref.update(activePlugins, (plugins) => {
185
+ const newSet = new Set(plugins);
186
+ newSet.delete(plugin);
187
+ return newSet;
188
+ }),
189
+ shutdown: (plugin) => Effect.gen(function* () {
190
+ yield* 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.mapError((error) => toPluginRuntimeError(error, plugin.plugin.id, void 0, "shutdown-plugin", false)));
196
+ }),
197
+ cleanup: () => Effect.gen(function* () {
198
+ const plugins = yield* Ref.get(activePlugins);
199
+ yield* Effect.forEach(plugins, (plugin) => plugin.plugin.shutdown().pipe(Effect.mapError((error) => toPluginRuntimeError(error, plugin.plugin.id, void 0, "cleanup-shutdown", false)), Effect.catchAll((error) => Effect.logError(`Failed to shutdown plugin ${plugin.plugin.id} during cleanup`, error, { pluginId: plugin.plugin.id }))), { concurrency: "unbounded" });
200
+ yield* Ref.set(activePlugins, /* @__PURE__ */ new Set());
201
+ }).pipe(Effect.catchAll(() => Effect.void))
202
+ };
203
+ }) }) {};
204
+
205
+ //#endregion
206
+ //#region src/runtime/validation.ts
207
+ const validate = (schema, data, pluginId, stage) => Effect.gen(function* () {
208
+ const result = schema.safeParse(data);
209
+ if (result.success) return result.data;
210
+ return yield* 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 = z.object({ secrets: z.record(z.string(), z.unknown()) }).loose();
220
+ var SecretsConfigTag = class extends Context.Tag("SecretsConfig")() {};
221
+ var SecretsService = class extends Effect.Service()("SecretsService", { effect: Effect.gen(function* () {
222
+ const secrets = yield* SecretsConfigTag;
223
+ return { hydrateSecrets: (config) => 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.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 Context.Tag("PluginRegistry")() {};
245
+ var RegistryService = class extends Effect.Service()("RegistryService", { effect: Effect.gen(function* () {
246
+ const registry = yield* PluginRegistryTag;
247
+ return { get: (pluginId) => Effect.fromNullable(registry[pluginId]).pipe(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.Service()("PluginLoaderService", { 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.gen(function* () {
262
+ const metadata = yield* getMetadata(pluginId);
263
+ const url = resolveUrl(metadata.remoteUrl);
264
+ yield* moduleFederationService.registerRemote(pluginId, url).pipe(Effect.mapError((error) => toPluginRuntimeError(error, pluginId, void 0, "register-remote", true)));
265
+ yield* Effect.logDebug("Loading plugin", {
266
+ pluginId,
267
+ url
268
+ });
269
+ return {
270
+ ctor: yield* moduleFederationService.loadRemoteConstructor(pluginId, url).pipe(Effect.mapError((error) => toPluginRuntimeError(error, pluginId, void 0, "load-remote", false))),
271
+ metadata
272
+ };
273
+ }),
274
+ instantiatePlugin: (pluginId, loadedPlugin) => Effect.gen(function* () {
275
+ const instance = yield* Effect.try(() => new loadedPlugin.ctor()).pipe(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.gen(function* () {
283
+ const { plugin } = pluginInstance;
284
+ const validatedVariables = yield* validate(plugin.configSchema.variables, config.variables, plugin.id, "config").pipe(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.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.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* Scope.make();
307
+ const context = yield* plugin.initialize({
308
+ variables: _variables,
309
+ secrets: hydratedConfig.secrets
310
+ }).pipe(Effect.provideService(Scope.Scope, scope), 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.Service()("PluginService", { scoped: 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.gen(function* () {
335
+ yield* plugin.plugin.shutdown().pipe(Effect.catchAll(() => Effect.void));
336
+ yield* Scope.close(plugin.scope, Exit.succeed(void 0));
337
+ yield* lifecycle.unregister(plugin);
338
+ }),
339
+ cleanup: lifecycle.cleanup
340
+ };
341
+ }) }) {
342
+ static Live = (registry, secrets) => {
343
+ const contextLayer = Layer.mergeAll(Layer.succeed(PluginRegistryTag, registry), Layer.succeed(SecretsConfigTag, secrets));
344
+ const servicesLayer = Layer.mergeAll(ModuleFederationService.Default, SecretsService.Default, RegistryService.Default, PluginLifecycleService.Default).pipe(Layer.provide(contextLayer));
345
+ return PluginService.Default.pipe(Layer.provide(PluginLoaderService.Default), 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}:${Hash.structure(config).toString()}`;
359
+ }
360
+ validatePluginId(pluginId) {
361
+ if (!(pluginId in this.registry)) return 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.succeed(String(pluginId));
368
+ }
369
+ async runPromise(effect) {
370
+ const exit = await this.runtime.runPromiseExit(effect);
371
+ if (Exit.isFailure(exit)) {
372
+ const error = Cause.failureOption(exit.cause);
373
+ if (Option.isSome(error)) throw error.value;
374
+ throw 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.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.provide(this.runtime));
389
+ cachedPlugin = Effect.cached(operation).pipe(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: createRouterClient(router),
397
+ metadata: initialized.metadata,
398
+ initialized
399
+ };
400
+ }
401
+ async loadPlugin(pluginId) {
402
+ const effect = Effect.gen(function* () {
403
+ return yield* (yield* PluginService).loadPlugin(pluginId);
404
+ });
405
+ return this.runPromise(effect);
406
+ }
407
+ async instantiatePlugin(pluginId, loadedPlugin) {
408
+ const effect = Effect.gen(function* () {
409
+ return yield* (yield* PluginService).instantiatePlugin(pluginId, loadedPlugin);
410
+ });
411
+ return this.runPromise(effect);
412
+ }
413
+ async initializePlugin(instance, config) {
414
+ const effect = Effect.gen(function* () {
415
+ return yield* (yield* PluginService).initializePlugin(instance, config);
416
+ });
417
+ return this.runPromise(effect);
418
+ }
419
+ async shutdown() {
420
+ const effect = Effect.gen(function* () {
421
+ yield* (yield* PluginService).cleanup();
422
+ });
423
+ return this.runPromise(effect);
424
+ }
425
+ async evictPlugin(pluginId, config) {
426
+ const cacheKey = this.generateCacheKey(pluginId, config);
427
+ const 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.catchAll(() => Effect.succeed(null)));
433
+ if (pluginResult) yield* pluginService.shutdownPlugin(pluginResult).pipe(Effect.catchAll(() => Effect.void));
434
+ }
435
+ }).pipe(Effect.catchAll(() => Effect.void));
436
+ return this.runPromise(effect);
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(ManagedRuntime.make(layer), normalizedRegistry);
455
+ }
456
+
457
+ //#endregion
458
+ export { PluginRegistryTag as a, SecretsService as c, ModuleFederationError as d, PluginLoaderService as i, PluginLifecycleService as l, createPluginRuntime as n, RegistryService as o, PluginService as r, SecretsConfigTag as s, PluginRuntime as t, ModuleFederationService as u };
459
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicnVudGltZS1CemtIUmowRS5tanMiLCJuYW1lcyI6WyJwa2ciLCJlbnRyeVVybDogc3RyaW5nIiwicnVudGltZTogTWFuYWdlZFJ1bnRpbWUuTWFuYWdlZFJ1bnRpbWU8UGx1Z2luU2VydmljZSwgbmV2ZXI+IiwicmVnaXN0cnk6IFBsdWdpblJlZ2lzdHJ5Il0sInNvdXJjZXMiOlsiLi4vc3JjL3J1bnRpbWUvZXJyb3JzLnRzIiwiLi4vc3JjL3J1bnRpbWUvc2VydmljZXMvbW9kdWxlLWZlZGVyYXRpb24uc2VydmljZS50cyIsIi4uL3NyYy9ydW50aW1lL3NlcnZpY2VzL3BsdWdpbi1saWZlY3ljbGUuc2VydmljZS50cyIsIi4uL3NyYy9ydW50aW1lL3ZhbGlkYXRpb24udHMiLCIuLi9zcmMvcnVudGltZS9zZXJ2aWNlcy9zZWNyZXRzLnNlcnZpY2UudHMiLCIuLi9zcmMvcnVudGltZS9zZXJ2aWNlcy9wbHVnaW4tbG9hZGVyLnNlcnZpY2UudHMiLCIuLi9zcmMvcnVudGltZS9zZXJ2aWNlcy9wbHVnaW4uc2VydmljZS50cyIsIi4uL3NyYy9ydW50aW1lL2luZGV4LnRzIl0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCB7IE9SUENFcnJvciB9IGZyb20gXCJAb3JwYy9jb250cmFjdFwiO1xuaW1wb3J0IHsgRGF0YSB9IGZyb20gXCJlZmZlY3RcIjtcbmltcG9ydCB0eXBlIHsgeiB9IGZyb20gXCJ6b2RcIjtcblxuZXhwb3J0IGNsYXNzIFBsdWdpblJ1bnRpbWVFcnJvciBleHRlbmRzIERhdGEuVGFnZ2VkRXJyb3IoXCJQbHVnaW5SdW50aW1lRXJyb3JcIik8e1xuXHRyZWFkb25seSBwbHVnaW5JZD86IHN0cmluZztcblx0cmVhZG9ubHkgb3BlcmF0aW9uPzogc3RyaW5nO1xuXHRyZWFkb25seSBwcm9jZWR1cmVOYW1lPzogc3RyaW5nO1xuXHRyZWFkb25seSBjYXVzZT86IEVycm9yO1xuXHRyZWFkb25seSByZXRyeWFibGU6IGJvb2xlYW47XG59PiB7IH1cblxuZXhwb3J0IGNsYXNzIE1vZHVsZUZlZGVyYXRpb25FcnJvciBleHRlbmRzIERhdGEuVGFnZ2VkRXJyb3IoXG5cdFwiTW9kdWxlRmVkZXJhdGlvbkVycm9yXCIsXG4pPHtcblx0cmVhZG9ubHkgcGx1Z2luSWQ6IHN0cmluZztcblx0cmVhZG9ubHkgcmVtb3RlVXJsOiBzdHJpbmc7XG5cdHJlYWRvbmx5IGNhdXNlPzogRXJyb3I7XG59PiB7IH1cblxuZXhwb3J0IGNsYXNzIFZhbGlkYXRpb25FcnJvciBleHRlbmRzIERhdGEuVGFnZ2VkRXJyb3IoXCJWYWxpZGF0aW9uRXJyb3JcIik8e1xuXHRyZWFkb25seSBwbHVnaW5JZDogc3RyaW5nO1xuXHRyZWFkb25seSBzdGFnZTogXCJjb25maWdcIiB8IFwiaW5wdXRcIiB8IFwib3V0cHV0XCIgfCBcInN0YXRlXCI7XG5cdHJlYWRvbmx5IHpvZEVycm9yOiB6LlpvZEVycm9yO1xufT4geyB9XG5cbi8vIEhlbHBlciB0byBkZXRlcm1pbmUgaWYgYW4gb1JQQyBlcnJvciBjb2RlIGlzIHJldHJ5YWJsZVxuZXhwb3J0IGNvbnN0IGlzUmV0cnlhYmxlT1JQQ0NvZGUgPSAoY29kZTogc3RyaW5nKTogYm9vbGVhbiA9PiB7XG5cdHN3aXRjaCAoY29kZSkge1xuXHRcdGNhc2UgJ1RPT19NQU5ZX1JFUVVFU1RTJzpcblx0XHRjYXNlICdTRVJWSUNFX1VOQVZBSUxBQkxFJzpcblx0XHRjYXNlICdCQURfR0FURVdBWSc6XG5cdFx0Y2FzZSAnR0FURVdBWV9USU1FT1VUJzpcblx0XHRjYXNlICdUSU1FT1VUJzpcblx0XHRcdHJldHVybiB0cnVlO1xuXHRcdGRlZmF1bHQ6XG5cdFx0XHRyZXR1cm4gZmFsc2U7XG5cdH1cbn07XG5cbi8vIENvbnZlcnQgT1JQQyBlcnJvcnMgZnJvbSBwbHVnaW4gcHJvY2VkdXJlcyB0byBQbHVnaW5SdW50aW1lRXJyb3JcbmV4cG9ydCBjb25zdCB3cmFwT1JQQ0Vycm9yID0gKFxuXHRvcnBjRXJyb3I6IE9SUENFcnJvcjxzdHJpbmcsIHVua25vd24+LFxuXHRwbHVnaW5JZD86IHN0cmluZyxcblx0cHJvY2VkdXJlTmFtZT86IHN0cmluZyxcblx0b3BlcmF0aW9uPzogc3RyaW5nXG4pOiBQbHVnaW5SdW50aW1lRXJyb3IgPT4ge1xuXHRyZXR1cm4gbmV3IFBsdWdpblJ1bnRpbWVFcnJvcih7XG5cdFx0cGx1Z2luSWQsXG5cdFx0b3BlcmF0aW9uLFxuXHRcdHByb2NlZHVyZU5hbWUsXG5cdFx0cmV0cnlhYmxlOiBpc1JldHJ5YWJsZU9SUENDb2RlKG9ycGNFcnJvci5jb2RlKSxcblx0XHRjYXVzZTogb3JwY0Vycm9yIGFzIEVycm9yXG5cdH0pO1xufTtcblxuLy8gVW5pdmVyc2FsIGVycm9yIGNvbnZlcnRlciBmb3IgdGhlIHJ1bnRpbWVcbmV4cG9ydCBjb25zdCB0b1BsdWdpblJ1bnRpbWVFcnJvciA9IChcblx0ZXJyb3I6IHVua25vd24sXG5cdHBsdWdpbklkPzogc3RyaW5nLFxuXHRwcm9jZWR1cmVOYW1lPzogc3RyaW5nLFxuXHRvcGVyYXRpb24/OiBzdHJpbmcsXG5cdGRlZmF1bHRSZXRyeWFibGUgPSBmYWxzZVxuKTogUGx1Z2luUnVudGltZUVycm9yID0+IHtcblx0aWYgKGVycm9yIGluc3RhbmNlb2YgT1JQQ0Vycm9yKSB7XG5cdFx0cmV0dXJuIHdyYXBPUlBDRXJyb3IoZXJyb3IsIHBsdWdpbklkLCBwcm9jZWR1cmVOYW1lLCBvcGVyYXRpb24pO1xuXHR9XG5cblx0aWYgKGVycm9yIGluc3RhbmNlb2YgUGx1Z2luUnVudGltZUVycm9yKSB7XG5cdFx0cmV0dXJuIGVycm9yOyAvLyBBbHJlYWR5IGNvbnZlcnRlZFxuXHR9XG5cblx0cmV0dXJuIG5ldyBQbHVnaW5SdW50aW1lRXJyb3Ioe1xuXHRcdHBsdWdpbklkLFxuXHRcdG9wZXJhdGlvbixcblx0XHRwcm9jZWR1cmVOYW1lLFxuXHRcdHJldHJ5YWJsZTogZGVmYXVsdFJldHJ5YWJsZSxcblx0XHRjYXVzZTogZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpXG5cdH0pO1xufTtcbiIsImltcG9ydCB7IGJldHRlckZldGNoIH0gZnJvbSBcIkBiZXR0ZXItZmV0Y2gvZmV0Y2hcIjtcbmltcG9ydCB7XG5cdGNyZWF0ZUluc3RhbmNlLFxuXHRnZXRJbnN0YW5jZSxcbn0gZnJvbSBcIkBtb2R1bGUtZmVkZXJhdGlvbi9lbmhhbmNlZC9ydW50aW1lXCI7XG5pbXBvcnQgeyBzZXRHbG9iYWxGZWRlcmF0aW9uSW5zdGFuY2UgfSBmcm9tIFwiQG1vZHVsZS1mZWRlcmF0aW9uL3J1bnRpbWUtY29yZVwiO1xuaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcImVmZmVjdFwiO1xuaW1wb3J0IHR5cGUgeyBBbnlQbHVnaW4gfSBmcm9tIFwiLi4vLi4vdHlwZXNcIjtcbmltcG9ydCB7IE1vZHVsZUZlZGVyYXRpb25FcnJvciB9IGZyb20gXCIuLi9lcnJvcnNcIjtcbmltcG9ydCB7IGdldE5vcm1hbGl6ZWRSZW1vdGVOYW1lIH0gZnJvbSBcIi4vbm9ybWFsaXplXCI7XG5cbnR5cGUgUmVtb3RlTW9kdWxlID0gXG4gIHwgKG5ldyAoKSA9PiBBbnlQbHVnaW4pXG4gIHwgeyBkZWZhdWx0OiBuZXcgKCkgPT4gQW55UGx1Z2luIH07XG5cbmltcG9ydCBwa2cgZnJvbSBcIi4uLy4uLy4uL3BhY2thZ2UuanNvblwiO1xuXG5jb25zdCBjcmVhdGVNb2R1bGVGZWRlcmF0aW9uSW5zdGFuY2UgPSBFZmZlY3QuY2FjaGVkKFxuXHRFZmZlY3Quc3luYygoKSA9PiB7XG5cdFx0dHJ5IHtcblx0XHRcdGxldCBpbnN0YW5jZSA9IGdldEluc3RhbmNlKCk7XG5cblx0XHRcdGlmICghaW5zdGFuY2UpIHtcblx0XHRcdFx0aW5zdGFuY2UgPSBjcmVhdGVJbnN0YW5jZSh7XG5cdFx0XHRcdFx0bmFtZTogXCJob3N0XCIsXG5cdFx0XHRcdFx0cmVtb3RlczogW10sXG5cdFx0XHRcdFx0c2hhcmVkOiB7XG5cdFx0XHRcdFx0XHRcImV2ZXJ5LXBsdWdpblwiOiB7XG5cdFx0XHRcdFx0XHRcdHZlcnNpb246IHBrZy52ZXJzaW9uLFxuXHRcdFx0XHRcdFx0XHRzaGFyZUNvbmZpZzoge1xuXHRcdFx0XHRcdFx0XHRcdHNpbmdsZXRvbjogdHJ1ZSxcblx0XHRcdFx0XHRcdFx0XHRyZXF1aXJlZFZlcnNpb246IGBeJHtwa2cudmVyc2lvbn1gLFxuXHRcdFx0XHRcdFx0XHRcdGVhZ2VyOiB0cnVlLFxuXHRcdFx0XHRcdFx0XHRcdHN0cmljdFZlcnNpb246IGZhbHNlLCAvLyBBbGxvdyBiaWRpcmVjdGlvbmFsIHZlcnNpb24gY29tcGF0aWJpbGl0eVxuXHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdGVmZmVjdDoge1xuXHRcdFx0XHRcdFx0XHR2ZXJzaW9uOiBwa2cuZGVwZW5kZW5jaWVzLmVmZmVjdCxcblx0XHRcdFx0XHRcdFx0c2hhcmVDb25maWc6IHtcblx0XHRcdFx0XHRcdFx0XHRzaW5nbGV0b246IHRydWUsXG5cdFx0XHRcdFx0XHRcdFx0cmVxdWlyZWRWZXJzaW9uOiBcIl4zLjE4LjBcIiwgLy8gQWxsb3cgYW55IDMuMTgueCBwYXRjaCB2ZXJzaW9uXG5cdFx0XHRcdFx0XHRcdFx0ZWFnZXI6IHRydWUsXG5cdFx0XHRcdFx0XHRcdFx0c3RyaWN0VmVyc2lvbjogZmFsc2UsIC8vIEFsbG93IHZlcnNpb24gZmxleGliaWxpdHkgZm9yIGNvbXBhdGliaWxpdHlcblx0XHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHR6b2Q6IHtcblx0XHRcdFx0XHRcdFx0dmVyc2lvbjogcGtnLmRlcGVuZGVuY2llcy56b2QsXG5cdFx0XHRcdFx0XHRcdHNoYXJlQ29uZmlnOiB7XG5cdFx0XHRcdFx0XHRcdFx0c2luZ2xldG9uOiB0cnVlLFxuXHRcdFx0XHRcdFx0XHRcdHJlcXVpcmVkVmVyc2lvbjogXCJeNC4xLjBcIiwgLy8gQWxsb3cgYW55IDQuMS54IHBhdGNoIHZlcnNpb25cblx0XHRcdFx0XHRcdFx0XHRlYWdlcjogdHJ1ZSxcblx0XHRcdFx0XHRcdFx0XHRzdHJpY3RWZXJzaW9uOiBmYWxzZSwgLy8gQWxsb3cgdmVyc2lvbiBmbGV4aWJpbGl0eSBmb3IgY29tcGF0aWJpbGl0eVxuXHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFwiQG9ycGMvY29udHJhY3RcIjoge1xuXHRcdFx0XHRcdFx0XHR2ZXJzaW9uOiBwa2cuZGVwZW5kZW5jaWVzW1wiQG9ycGMvY29udHJhY3RcIl0sXG5cdFx0XHRcdFx0XHRcdHNoYXJlQ29uZmlnOiB7XG5cdFx0XHRcdFx0XHRcdFx0c2luZ2xldG9uOiB0cnVlLFxuXHRcdFx0XHRcdFx0XHRcdHJlcXVpcmVkVmVyc2lvbjogXCJeMS44LjBcIiwgLy8gQWxsb3cgYW55IDEuOC54IHBhdGNoIHZlcnNpb25cblx0XHRcdFx0XHRcdFx0XHRlYWdlcjogdHJ1ZSxcblx0XHRcdFx0XHRcdFx0XHRzdHJpY3RWZXJzaW9uOiBmYWxzZSwgLy8gQWxsb3cgdmVyc2lvbiBmbGV4aWJpbGl0eSBmb3IgY29tcGF0aWJpbGl0eVxuXHRcdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0fSxcblx0XHRcdFx0XHRcdFwiQG9ycGMvc2VydmVyXCI6IHtcblx0XHRcdFx0XHRcdFx0dmVyc2lvbjogcGtnLmRlcGVuZGVuY2llc1tcIkBvcnBjL3NlcnZlclwiXSxcblx0XHRcdFx0XHRcdFx0c2hhcmVDb25maWc6IHtcblx0XHRcdFx0XHRcdFx0XHRzaW5nbGV0b246IHRydWUsXG5cdFx0XHRcdFx0XHRcdFx0cmVxdWlyZWRWZXJzaW9uOiBcIl4xLjguMFwiLCAvLyBBbGxvdyBhbnkgMS44LnggcGF0Y2ggdmVyc2lvblxuXHRcdFx0XHRcdFx0XHRcdGVhZ2VyOiB0cnVlLFxuXHRcdFx0XHRcdFx0XHRcdHN0cmljdFZlcnNpb246IGZhbHNlLCAvLyBBbGxvdyB2ZXJzaW9uIGZsZXhpYmlsaXR5IGZvciBjb21wYXRpYmlsaXR5XG5cdFx0XHRcdFx0XHRcdH0sXG5cdFx0XHRcdFx0XHR9XG5cdFx0XHRcdFx0fSxcblx0XHRcdFx0fSk7XG5cblx0XHRcdFx0c2V0R2xvYmFsRmVkZXJhdGlvbkluc3RhbmNlKGluc3RhbmNlKTtcblx0XHRcdH1cblxuXHRcdFx0cmV0dXJuIGluc3RhbmNlO1xuXHRcdH0gY2F0Y2ggKGVycm9yKSB7XG5cdFx0XHR0aHJvdyBuZXcgRXJyb3IoYEZhaWxlZCB0byBpbml0aWFsaXplIE1vZHVsZSBGZWRlcmF0aW9uOiAke2Vycm9yfWApO1xuXHRcdH1cblx0fSksXG4pO1xuXG5leHBvcnQgY2xhc3MgTW9kdWxlRmVkZXJhdGlvblNlcnZpY2UgZXh0ZW5kcyBFZmZlY3QuU2VydmljZTxNb2R1bGVGZWRlcmF0aW9uU2VydmljZT4oKShcIk1vZHVsZUZlZGVyYXRpb25TZXJ2aWNlXCIsIHtcblx0ZWZmZWN0OiBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG5cdFx0Y29uc3QgbWYgPSB5aWVsZCogRWZmZWN0LmZsYXR0ZW4oY3JlYXRlTW9kdWxlRmVkZXJhdGlvbkluc3RhbmNlKTtcblxuXHRcdHJldHVybiB7XG5cdFx0XHRyZWdpc3RlclJlbW90ZTogKHBsdWdpbklkOiBzdHJpbmcsIHVybDogc3RyaW5nKSA9PlxuXHRcdFx0XHRFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG5cdFx0XHRcdFx0Y29uc29sZS5sb2coYFtNRl0gUmVnaXN0ZXJpbmcgJHtwbHVnaW5JZH1gKTtcblxuXHRcdFx0XHRcdGNvbnN0IG1hbmlmZXN0VXJsID0gdXJsLmVuZHNXaXRoKCcvJylcblx0XHRcdFx0XHRcdD8gYCR7dXJsfW1mLW1hbmlmZXN0Lmpzb25gXG5cdFx0XHRcdFx0XHQ6IGAke3VybH0vbWYtbWFuaWZlc3QuanNvbmA7XG5cblx0XHRcdFx0XHQvLyBDaGVjayBpZiBtYW5pZmVzdCBpcyBhdmFpbGFibGUgKE1GIDIuMCB3aXRoIG1hbmlmZXN0cylcblx0XHRcdFx0XHRjb25zdCB7IGVycm9yOiBtYW5pZmVzdEVycm9yIH0gPSB5aWVsZCogRWZmZWN0LnRyeVByb21pc2Uoe1xuXHRcdFx0XHRcdFx0dHJ5OiAoKSA9PiBiZXR0ZXJGZXRjaChtYW5pZmVzdFVybCwgeyBtZXRob2Q6IFwiSEVBRFwiIH0pLFxuXHRcdFx0XHRcdFx0Y2F0Y2g6IChlcnJvcikgPT4gZXJyb3IsIC8vIERvbid0IGZhaWwgeWV0LCB0cnkgZmFsbGJhY2tcblx0XHRcdFx0XHR9KTtcblxuXHRcdFx0XHRcdGxldCBlbnRyeVVybDogc3RyaW5nO1xuXHRcdFx0XHRcdGxldCBpc01hbmlmZXN0TW9kZSA9IGZhbHNlO1xuXG5cdFx0XHRcdFx0aWYgKCFtYW5pZmVzdEVycm9yKSB7XG5cdFx0XHRcdFx0XHQvLyBNRiAyLjAgbWFuaWZlc3QgbW9kZSAtIHVzZSBtYW5pZmVzdCBVUkxcblx0XHRcdFx0XHRcdGVudHJ5VXJsID0gbWFuaWZlc3RVcmw7XG5cdFx0XHRcdFx0XHRpc01hbmlmZXN0TW9kZSA9IHRydWU7XG5cdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhgW01GXSBVc2luZyBNRiAyLjAgbWFuaWZlc3QgbW9kZSBmb3IgJHtwbHVnaW5JZH1gKTtcblx0XHRcdFx0XHR9IGVsc2Uge1xuXHRcdFx0XHRcdFx0Ly8gRmFsbGJhY2sgdG8gTUYgMS41IGRpcmVjdCBtb2RlIC0gYXNzdW1lIFVSTCBwb2ludHMgdG8gcmVtb3RlRW50cnkuanNcblx0XHRcdFx0XHRcdGNvbnNvbGUubG9nKGBbTUZdIOKaoO+4jyBNYW5pZmVzdCBub3QgZm91bmQsIGZhbGxpbmcgYmFjayB0byBNRiAxLjUgbW9kZSBmb3IgJHtwbHVnaW5JZH1gKTtcblx0XHRcdFx0XHRcdGVudHJ5VXJsID0gdXJsO1xuXHRcdFx0XHRcdFx0aXNNYW5pZmVzdE1vZGUgPSBmYWxzZTtcblx0XHRcdFx0XHR9XG5cblx0XHRcdFx0XHQvLyBGb3IgTUYgMi4wLCB0aGUgbmFtZSBjYW4gYmUgdGhlIHBsdWdpbklkIChhbGlhcylcblx0XHRcdFx0XHQvLyBUaGUgbWFuaWZlc3Qgd2lsbCBjb250YWluIHRoZSBhY3R1YWwgY29udGFpbmVyIG5hbWVcblx0XHRcdFx0XHRjb25zdCByZW1vdGVOYW1lID0gaXNNYW5pZmVzdE1vZGUgPyBwbHVnaW5JZCA6IGdldE5vcm1hbGl6ZWRSZW1vdGVOYW1lKHBsdWdpbklkKTtcblxuXHRcdFx0XHRcdHlpZWxkKiBFZmZlY3QudHJ5KHtcblx0XHRcdFx0XHRcdHRyeTogKCkgPT4gbWYucmVnaXN0ZXJSZW1vdGVzKFt7XG5cdFx0XHRcdFx0XHRcdG5hbWU6IHJlbW90ZU5hbWUsXG5cdFx0XHRcdFx0XHRcdGVudHJ5OiBlbnRyeVVybCxcblx0XHRcdFx0XHRcdFx0Li4uKGlzTWFuaWZlc3RNb2RlICYmIHsgYWxpYXM6IHBsdWdpbklkIH0pIC8vIEV4cGxpY2l0IGFsaWFzIGZvciBjbGFyaXR5XG5cdFx0XHRcdFx0XHR9XSksXG5cdFx0XHRcdFx0XHRjYXRjaDogKGVycm9yKTogTW9kdWxlRmVkZXJhdGlvbkVycm9yID0+XG5cdFx0XHRcdFx0XHRcdG5ldyBNb2R1bGVGZWRlcmF0aW9uRXJyb3Ioe1xuXHRcdFx0XHRcdFx0XHRcdHBsdWdpbklkLFxuXHRcdFx0XHRcdFx0XHRcdHJlbW90ZVVybDogdXJsLFxuXHRcdFx0XHRcdFx0XHRcdGNhdXNlOlxuXHRcdFx0XHRcdFx0XHRcdFx0ZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IGVycm9yIDogbmV3IEVycm9yKFN0cmluZyhlcnJvcikpLFxuXHRcdFx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHR9KTtcblxuXHRcdFx0XHRcdGNvbnNvbGUubG9nKGBbTUZdIOKchSBSZWdpc3RlcmVkICR7cGx1Z2luSWR9ICgke2lzTWFuaWZlc3RNb2RlID8gJ01GIDIuMCcgOiAnTUYgMS41J30pYCk7XG5cdFx0XHRcdH0pLFxuXG5cdFx0XHRsb2FkUmVtb3RlQ29uc3RydWN0b3I6IChwbHVnaW5JZDogc3RyaW5nLCB1cmw6IHN0cmluZykgPT5cblx0XHRcdFx0RWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuXHRcdFx0XHRcdGNvbnN0IHJlbW90ZU5hbWUgPSBnZXROb3JtYWxpemVkUmVtb3RlTmFtZShwbHVnaW5JZCk7XG5cdFx0XHRcdFx0Y29uc29sZS5sb2coYFtNRl0gTG9hZGluZyByZW1vdGUgJHtyZW1vdGVOYW1lfWApO1xuXHRcdFx0XHRcdGNvbnN0IG1vZHVsZVBhdGggPSBgJHtyZW1vdGVOYW1lfS9wbHVnaW5gO1xuXG5cdFx0XHRcdFx0cmV0dXJuIHlpZWxkKiBFZmZlY3QudHJ5UHJvbWlzZSh7XG5cdFx0XHRcdFx0XHR0cnk6IGFzeW5jICgpID0+IHtcblxuXHRcdFx0XHRcdFx0XHRjb25zdCBjb250YWluZXIgPSBhd2FpdCBtZi5sb2FkUmVtb3RlPFJlbW90ZU1vZHVsZT4obW9kdWxlUGF0aCk7XG5cdFx0XHRcdFx0XHRcdGlmICghY29udGFpbmVyKSB7XG5cdFx0XHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKGBObyBjb250YWluZXIgcmV0dXJuZWQgZm9yICR7bW9kdWxlUGF0aH1gKTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdC8vIFN1cHBvcnQgbXVsdGlwbGUgZXhwb3J0IHBhdHRlcm5zOiBkaXJlY3QgZnVuY3Rpb24sIGRlZmF1bHQgZXhwb3J0LCBuYW1lZCBleHBvcnRzXG5cdFx0XHRcdFx0XHRcdGNvbnN0IENvbnN0cnVjdG9yID1cblx0XHRcdFx0XHRcdFx0XHR0eXBlb2YgY29udGFpbmVyID09PSBcImZ1bmN0aW9uXCJcblx0XHRcdFx0XHRcdFx0XHRcdD8gY29udGFpbmVyICAvLyBEaXJlY3QgZnVuY3Rpb24gZXhwb3J0XG5cdFx0XHRcdFx0XHRcdFx0XHQ6IGNvbnRhaW5lci5kZWZhdWx0XG5cdFx0XHRcdFx0XHRcdFx0XHQ/IGNvbnRhaW5lci5kZWZhdWx0ICAvLyBEZWZhdWx0IGV4cG9ydFxuXHRcdFx0XHRcdFx0XHRcdFx0OiBPYmplY3QudmFsdWVzKGNvbnRhaW5lcikuZmluZCggIC8vIE5hbWVkIGV4cG9ydCBmYWxsYmFja1xuXHRcdFx0XHRcdFx0XHRcdFx0XHRcdChleHApID0+IHR5cGVvZiBleHAgPT09IFwiZnVuY3Rpb25cIiAmJiBleHAucHJvdG90eXBlPy5jb25zdHJ1Y3RvciA9PT0gZXhwXG5cdFx0XHRcdFx0XHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRcdFx0aWYgKCFDb25zdHJ1Y3RvciB8fCB0eXBlb2YgQ29uc3RydWN0b3IgIT09IFwiZnVuY3Rpb25cIikge1xuXHRcdFx0XHRcdFx0XHRcdGNvbnN0IGNvbnRhaW5lckluZm8gPSB0eXBlb2YgY29udGFpbmVyID09PSBcIm9iamVjdFwiXG5cdFx0XHRcdFx0XHRcdFx0XHQ/IGBBdmFpbGFibGUgZXhwb3J0czogJHtPYmplY3Qua2V5cyhjb250YWluZXIpLmpvaW4oJywgJyl9YFxuXHRcdFx0XHRcdFx0XHRcdFx0OiBgQ29udGFpbmVyIHR5cGU6ICR7dHlwZW9mIGNvbnRhaW5lcn1gO1xuXG5cdFx0XHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRcdFx0XHRcdFx0YE5vIHZhbGlkIHBsdWdpbiBjb25zdHJ1Y3RvciBmb3VuZCBmb3IgJyR7cGx1Z2luSWR9Jy5cXG5gICtcblx0XHRcdFx0XHRcdFx0XHRcdGBTdXBwb3J0ZWQgcGF0dGVybnM6XFxuYCArXG5cdFx0XHRcdFx0XHRcdFx0XHRgICAtIGV4cG9ydCBjb25zdCBZb3VyUGx1Z2luID0gY3JlYXRlUGx1Z2luKHsuLi59KVxcbmAgK1xuXHRcdFx0XHRcdFx0XHRcdFx0YCAgLSBleHBvcnQgZGVmYXVsdCBjcmVhdGVQbHVnaW4oey4uLn0pXFxuYCArXG5cdFx0XHRcdFx0XHRcdFx0XHRgJHtjb250YWluZXJJbmZvfWAsXG5cdFx0XHRcdFx0XHRcdFx0KTtcblx0XHRcdFx0XHRcdFx0fVxuXG5cdFx0XHRcdFx0XHRcdC8vIFZhbGlkYXRlIGl0IGxvb2tzIGxpa2UgYSBwbHVnaW4gY29uc3RydWN0b3IgKGhhcyBiaW5kaW5nIHByb3BlcnR5KVxuXHRcdFx0XHRcdFx0XHRpZiAoIShDb25zdHJ1Y3RvciBhcyBhbnkpLmJpbmRpbmcpIHtcblx0XHRcdFx0XHRcdFx0XHRjb25zdCBjb250YWluZXJJbmZvID0gdHlwZW9mIGNvbnRhaW5lciA9PT0gXCJvYmplY3RcIlxuXHRcdFx0XHRcdFx0XHRcdFx0PyBgRm91bmQgZXhwb3J0czogJHtPYmplY3Qua2V5cyhjb250YWluZXIpLmpvaW4oJywgJyl9YFxuXHRcdFx0XHRcdFx0XHRcdFx0OiBgQ29udGFpbmVyIHR5cGU6ICR7dHlwZW9mIGNvbnRhaW5lcn1gO1xuXG5cdFx0XHRcdFx0XHRcdFx0dGhyb3cgbmV3IEVycm9yKFxuXHRcdFx0XHRcdFx0XHRcdFx0YEludmFsaWQgcGx1Z2luIGNvbnN0cnVjdG9yIGZvciAnJHtwbHVnaW5JZH0nLiBgICtcblx0XHRcdFx0XHRcdFx0XHRcdGBUaGUgZXhwb3J0ZWQgdmFsdWUgbXVzdCBiZSBjcmVhdGVkIHdpdGggY3JlYXRlUGx1Z2luKCkuIGAgK1xuXHRcdFx0XHRcdFx0XHRcdFx0YEZvdW5kIGEgZnVuY3Rpb24gYnV0IGl0J3MgbWlzc2luZyB0aGUgcmVxdWlyZWQgJ2JpbmRpbmcnIHByb3BlcnR5LlxcbmAgK1xuXHRcdFx0XHRcdFx0XHRcdFx0YCR7Y29udGFpbmVySW5mb31gLFxuXHRcdFx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0XHRjb25zb2xlLmxvZyhgW01GXSDinIUgTG9hZGVkIGNvbnN0cnVjdG9yIGZvciAke3BsdWdpbklkfWApO1xuXHRcdFx0XHRcdFx0XHRyZXR1cm4gQ29uc3RydWN0b3I7XG5cdFx0XHRcdFx0XHR9LFxuXHRcdFx0XHRcdFx0Y2F0Y2g6IChlcnJvcik6IE1vZHVsZUZlZGVyYXRpb25FcnJvciA9PlxuXHRcdFx0XHRcdFx0XHRuZXcgTW9kdWxlRmVkZXJhdGlvbkVycm9yKHtcblx0XHRcdFx0XHRcdFx0XHRwbHVnaW5JZCxcblx0XHRcdFx0XHRcdFx0XHRyZW1vdGVVcmw6IHVybCxcblx0XHRcdFx0XHRcdFx0XHRjYXVzZTpcblx0XHRcdFx0XHRcdFx0XHRcdGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKSxcblx0XHRcdFx0XHRcdFx0fSksXG5cdFx0XHRcdFx0fSk7XG5cdFx0XHRcdH0pLFxuXHRcdH07XG5cdH0pLFxufSkge31cbiIsImltcG9ydCB7IEVmZmVjdCwgUmVmIH0gZnJvbSBcImVmZmVjdFwiO1xuaW1wb3J0IHR5cGUgeyBBbnlQbHVnaW4sIEluaXRpYWxpemVkUGx1Z2luIH0gZnJvbSBcIi4uLy4uL3R5cGVzXCI7XG5pbXBvcnQgeyB0b1BsdWdpblJ1bnRpbWVFcnJvciB9IGZyb20gXCIuLi9lcnJvcnNcIjtcblxuZXhwb3J0IGNsYXNzIFBsdWdpbkxpZmVjeWNsZVNlcnZpY2UgZXh0ZW5kcyBFZmZlY3QuU2VydmljZTxQbHVnaW5MaWZlY3ljbGVTZXJ2aWNlPigpKFwiUGx1Z2luTGlmZWN5Y2xlU2VydmljZVwiLCB7XG4gIGVmZmVjdDogRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgIGNvbnN0IGFjdGl2ZVBsdWdpbnMgPSB5aWVsZCogUmVmLm1ha2UobmV3IFNldDxJbml0aWFsaXplZFBsdWdpbjxBbnlQbHVnaW4+PigpKTtcblxuICAgIHJldHVybiB7XG4gICAgICByZWdpc3RlcjogPFQgZXh0ZW5kcyBBbnlQbHVnaW4+KHBsdWdpbjogSW5pdGlhbGl6ZWRQbHVnaW48VD4pID0+XG4gICAgICAgIFJlZi51cGRhdGUoYWN0aXZlUGx1Z2lucywgcGx1Z2lucyA9PlxuICAgICAgICAgIG5ldyBTZXQocGx1Z2lucykuYWRkKHBsdWdpbiBhcyBJbml0aWFsaXplZFBsdWdpbjxBbnlQbHVnaW4+KVxuICAgICAgICApLFxuXG4gICAgICB1bnJlZ2lzdGVyOiAocGx1Z2luOiBJbml0aWFsaXplZFBsdWdpbjxBbnlQbHVnaW4+KSA9PlxuICAgICAgICBSZWYudXBkYXRlKGFjdGl2ZVBsdWdpbnMsIHBsdWdpbnMgPT4ge1xuICAgICAgICAgIGNvbnN0IG5ld1NldCA9IG5ldyBTZXQocGx1Z2lucyk7XG4gICAgICAgICAgbmV3U2V0LmRlbGV0ZShwbHVnaW4pO1xuICAgICAgICAgIHJldHVybiBuZXdTZXQ7XG4gICAgICAgIH0pLFxuXG4gICAgICBzaHV0ZG93bjogKHBsdWdpbjogSW5pdGlhbGl6ZWRQbHVnaW48QW55UGx1Z2luPikgPT5cbiAgICAgICAgRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuICAgICAgICAgIC8vIFJlbW92ZSBmcm9tIGFjdGl2ZSBwbHVnaW5zXG4gICAgICAgICAgeWllbGQqIFJlZi51cGRhdGUoYWN0aXZlUGx1Z2lucywgcGx1Z2lucyA9PiB7XG4gICAgICAgICAgICBjb25zdCBuZXdTZXQgPSBuZXcgU2V0KHBsdWdpbnMpO1xuICAgICAgICAgICAgbmV3U2V0LmRlbGV0ZShwbHVnaW4pO1xuICAgICAgICAgICAgcmV0dXJuIG5ld1NldDtcbiAgICAgICAgICB9KTtcblxuICAgICAgICAgIC8vIFNodXRkb3duIHRoZSBwbHVnaW5cbiAgICAgICAgICB5aWVsZCogcGx1Z2luLnBsdWdpbi5zaHV0ZG93bigpLnBpcGUoXG4gICAgICAgICAgICBFZmZlY3QubWFwRXJyb3IoZXJyb3IgPT5cbiAgICAgICAgICAgICAgdG9QbHVnaW5SdW50aW1lRXJyb3IoZXJyb3IsIHBsdWdpbi5wbHVnaW4uaWQsIHVuZGVmaW5lZCwgXCJzaHV0ZG93bi1wbHVnaW5cIiwgZmFsc2UpXG4gICAgICAgICAgICApXG4gICAgICAgICAgKTtcbiAgICAgICAgfSksXG5cbiAgICAgIGNsZWFudXA6ICgpID0+XG4gICAgICAgIEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcbiAgICAgICAgICBjb25zdCBwbHVnaW5zID0geWllbGQqIFJlZi5nZXQoYWN0aXZlUGx1Z2lucyk7XG5cbiAgICAgICAgICAvLyBTaHV0ZG93biBhbGwgYWN0aXZlIHBsdWdpbnMgY29uY3VycmVudGx5XG4gICAgICAgICAgeWllbGQqIEVmZmVjdC5mb3JFYWNoKFxuICAgICAgICAgICAgcGx1Z2lucyxcbiAgICAgICAgICAgIHBsdWdpbiA9PlxuICAgICAgICAgICAgICBwbHVnaW4ucGx1Z2luLnNodXRkb3duKCkucGlwZShcbiAgICAgICAgICAgICAgICBFZmZlY3QubWFwRXJyb3IoZXJyb3IgPT5cbiAgICAgICAgICAgICAgICAgIHRvUGx1Z2luUnVudGltZUVycm9yKGVycm9yLCBwbHVnaW4ucGx1Z2luLmlkLCB1bmRlZmluZWQsIFwiY2xlYW51cC1zaHV0ZG93blwiLCBmYWxzZSlcbiAgICAgICAgICAgICAgICApLFxuICAgICAgICAgICAgICAgIEVmZmVjdC5jYXRjaEFsbChlcnJvciA9PlxuICAgICAgICAgICAgICAgICAgRWZmZWN0LmxvZ0Vycm9yKFxuICAgICAgICAgICAgICAgICAgICBgRmFpbGVkIHRvIHNodXRkb3duIHBsdWdpbiAke3BsdWdpbi5wbHVnaW4uaWR9IGR1cmluZyBjbGVhbnVwYCxcbiAgICAgICAgICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICAgICAgICAgIHsgcGx1Z2luSWQ6IHBsdWdpbi5wbHVnaW4uaWQgfVxuICAgICAgICAgICAgICAgICAgKVxuICAgICAgICAgICAgICAgIClcbiAgICAgICAgICAgICAgKSxcbiAgICAgICAgICAgIHsgY29uY3VycmVuY3k6IFwidW5ib3VuZGVkXCIgfVxuICAgICAgICAgICk7XG5cbiAgICAgICAgICAvLyBDbGVhciB0aGUgYWN0aXZlIHBsdWdpbnMgc2V0XG4gICAgICAgICAgeWllbGQqIFJlZi5zZXQoYWN0aXZlUGx1Z2lucywgbmV3IFNldCgpKTtcbiAgICAgICAgfSkucGlwZShcbiAgICAgICAgICBFZmZlY3QuY2F0Y2hBbGwoKCkgPT4gRWZmZWN0LnZvaWQpIC8vIENvbnZlcnQgZXJyb3JzIHRvIHZvaWQgZm9yIGNsZWFudXBcbiAgICAgICAgKSxcbiAgICB9O1xuICB9KSxcbn0pIHsgfVxuIiwiaW1wb3J0IHsgRWZmZWN0IH0gZnJvbSBcImVmZmVjdFwiO1xuaW1wb3J0IHR5cGUgeyB6IH0gZnJvbSBcInpvZFwiO1xuaW1wb3J0IHsgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5cbmV4cG9ydCBjb25zdCB2YWxpZGF0ZSA9IDxUPihcblx0c2NoZW1hOiB6LlpvZFNjaGVtYTxUPixcblx0ZGF0YTogdW5rbm93bixcblx0cGx1Z2luSWQ6IHN0cmluZyxcblx0c3RhZ2U6IFwiY29uZmlnXCIgfCBcImlucHV0XCIgfCBcIm91dHB1dFwiIHwgXCJzdGF0ZVwiLFxuKTogRWZmZWN0LkVmZmVjdDxULCBWYWxpZGF0aW9uRXJyb3I+ID0+XG5cdEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRjb25zdCByZXN1bHQgPSBzY2hlbWEuc2FmZVBhcnNlKGRhdGEpO1xuXHRcdGlmIChyZXN1bHQuc3VjY2Vzcykge1xuXHRcdFx0cmV0dXJuIHJlc3VsdC5kYXRhO1xuXHRcdH1cblx0XHRyZXR1cm4geWllbGQqIEVmZmVjdC5mYWlsKFxuXHRcdFx0bmV3IFZhbGlkYXRpb25FcnJvcih7XG5cdFx0XHRcdHBsdWdpbklkLFxuXHRcdFx0XHRzdGFnZSxcblx0XHRcdFx0em9kRXJyb3I6IHJlc3VsdC5lcnJvcixcblx0XHRcdH0pLFxuXHRcdCk7XG5cdH0pO1xuIiwiaW1wb3J0IHsgQ29udGV4dCwgRWZmZWN0IH0gZnJvbSBcImVmZmVjdFwiO1xuaW1wb3J0IHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB0eXBlIHsgU2VjcmV0c0NvbmZpZyB9IGZyb20gXCIuLi8uLi90eXBlc1wiO1xuaW1wb3J0IHsgUGx1Z2luUnVudGltZUVycm9yIH0gZnJvbSBcIi4uL2Vycm9yc1wiO1xuXG5jb25zdCBjb25maWdTY2hlbWEgPSB6Lm9iamVjdCh7XG5cdHNlY3JldHM6IHoucmVjb3JkKHouc3RyaW5nKCksIHoudW5rbm93bigpKVxufSkubG9vc2UoKTtcblxuZXhwb3J0IGNsYXNzIFNlY3JldHNDb25maWdUYWcgZXh0ZW5kcyBDb250ZXh0LlRhZyhcIlNlY3JldHNDb25maWdcIik8XG5cdFNlY3JldHNDb25maWdUYWcsXG5cdFNlY3JldHNDb25maWdcbj4oKSB7IH1cblxuZXhwb3J0IGNsYXNzIFNlY3JldHNTZXJ2aWNlIGV4dGVuZHMgRWZmZWN0LlNlcnZpY2U8U2VjcmV0c1NlcnZpY2U+KCkoXCJTZWNyZXRzU2VydmljZVwiLCB7XG5cdGVmZmVjdDogRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuXHRcdGNvbnN0IHNlY3JldHMgPSB5aWVsZCogU2VjcmV0c0NvbmZpZ1RhZztcblxuXHRcdHJldHVybiB7XG5cdFx0XHRoeWRyYXRlU2VjcmV0czogPFQ+KGNvbmZpZzogVCkgPT5cblx0XHRcdFx0RWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuXHRcdFx0XHRcdGNvbnN0IHBhcnNlUmVzdWx0ID0gY29uZmlnU2NoZW1hLnBhcnNlKGNvbmZpZyk7XG5cdFx0XHRcdFx0dHJ5IHtcblx0XHRcdFx0XHRcdGNvbnN0IGNvbmZpZ1N0cmluZyA9IEpTT04uc3RyaW5naWZ5KHBhcnNlUmVzdWx0KTtcblx0XHRcdFx0XHRcdGxldCBoeWRyYXRlZFN0cmluZyA9IGNvbmZpZ1N0cmluZztcblxuXHRcdFx0XHRcdFx0Zm9yIChjb25zdCBba2V5LCB2YWx1ZV0gb2YgT2JqZWN0LmVudHJpZXMoc2VjcmV0cykpIHtcblx0XHRcdFx0XHRcdFx0Y29uc3QgcGF0dGVybiA9IG5ldyBSZWdFeHAoYHt7JHtrZXl9fX1gLCBcImdcIik7XG5cdFx0XHRcdFx0XHRcdGh5ZHJhdGVkU3RyaW5nID0gaHlkcmF0ZWRTdHJpbmcucmVwbGFjZShwYXR0ZXJuLCBTdHJpbmcodmFsdWUpKTtcblx0XHRcdFx0XHRcdH1cblxuXHRcdFx0XHRcdFx0cmV0dXJuIEpTT04ucGFyc2UoaHlkcmF0ZWRTdHJpbmcpIGFzIFQ7XG5cdFx0XHRcdFx0fSBjYXRjaCAoZXJyb3IpIHtcblx0XHRcdFx0XHRcdHJldHVybiB5aWVsZCogRWZmZWN0LmZhaWwoXG5cdFx0XHRcdFx0XHRcdG5ldyBQbHVnaW5SdW50aW1lRXJyb3Ioe1xuXHRcdFx0XHRcdFx0XHRcdG9wZXJhdGlvbjogXCJoeWRyYXRlLXNlY3JldHNcIixcblx0XHRcdFx0XHRcdFx0XHRjYXVzZTpcblx0XHRcdFx0XHRcdFx0XHRcdGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKSxcblx0XHRcdFx0XHRcdFx0XHRyZXRyeWFibGU6IGZhbHNlLFxuXHRcdFx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHRcdCk7XG5cdFx0XHRcdFx0fVxuXHRcdFx0XHR9KSxcblx0XHR9O1xuXHR9KSxcbn0pIHsgfVxuIiwiaW1wb3J0IHR5cGUgeyBJbmZlclNjaGVtYUlucHV0LCBJbmZlclNjaGVtYU91dHB1dCB9IGZyb20gXCJAb3JwYy9jb250cmFjdFwiO1xuaW1wb3J0IHsgQ29udGV4dCwgRWZmZWN0LCBTY29wZSB9IGZyb20gXCJlZmZlY3RcIjtcbmltcG9ydCB0eXBlIHsgeiB9IGZyb20gXCJ6b2RcIjtcbmltcG9ydCB0eXBlIHtcblx0QW55UGx1Z2luLFxuXHRJbml0aWFsaXplZFBsdWdpbixcblx0TG9hZGVkUGx1Z2luLFxuXHRQbHVnaW5JbnN0YW5jZSxcblx0UGx1Z2luUmVnaXN0cnlcbn0gZnJvbSBcIi4uLy4uL3R5cGVzXCI7XG5pbXBvcnQgeyBQbHVnaW5SdW50aW1lRXJyb3IsIHRvUGx1Z2luUnVudGltZUVycm9yIH0gZnJvbSBcIi4uL2Vycm9yc1wiO1xuaW1wb3J0IHsgdmFsaWRhdGUgfSBmcm9tIFwiLi4vdmFsaWRhdGlvblwiO1xuaW1wb3J0IHsgTW9kdWxlRmVkZXJhdGlvblNlcnZpY2UgfSBmcm9tIFwiLi9tb2R1bGUtZmVkZXJhdGlvbi5zZXJ2aWNlXCI7XG5pbXBvcnQgeyBTZWNyZXRzU2VydmljZSB9IGZyb20gXCIuL3NlY3JldHMuc2VydmljZVwiO1xuXG5leHBvcnQgY2xhc3MgUGx1Z2luUmVnaXN0cnlUYWcgZXh0ZW5kcyBDb250ZXh0LlRhZyhcIlBsdWdpblJlZ2lzdHJ5XCIpPFxuXHRQbHVnaW5SZWdpc3RyeVRhZyxcblx0UGx1Z2luUmVnaXN0cnlcbj4oKSB7IH1cblxuZXhwb3J0IGNsYXNzIFJlZ2lzdHJ5U2VydmljZSBleHRlbmRzIEVmZmVjdC5TZXJ2aWNlPFJlZ2lzdHJ5U2VydmljZT4oKShcIlJlZ2lzdHJ5U2VydmljZVwiLCB7XG5cdGVmZmVjdDogRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuXHRcdGNvbnN0IHJlZ2lzdHJ5ID0geWllbGQqIFBsdWdpblJlZ2lzdHJ5VGFnO1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdGdldDogKHBsdWdpbklkOiBzdHJpbmcpID0+XG5cdFx0XHRcdEVmZmVjdC5mcm9tTnVsbGFibGUocmVnaXN0cnlbcGx1Z2luSWRdKS5waXBlKFxuXHRcdFx0XHRcdEVmZmVjdC5tYXBFcnJvcigoKSA9PlxuXHRcdFx0XHRcdFx0bmV3IFBsdWdpblJ1bnRpbWVFcnJvcih7XG5cdFx0XHRcdFx0XHRcdHBsdWdpbklkLFxuXHRcdFx0XHRcdFx0XHRvcGVyYXRpb246IFwidmFsaWRhdGUtcGx1Z2luLWlkXCIsXG5cdFx0XHRcdFx0XHRcdGNhdXNlOiBuZXcgRXJyb3IoYFBsdWdpbiAke3BsdWdpbklkfSBub3QgZm91bmQgaW4gcmVnaXN0cnlgKSxcblx0XHRcdFx0XHRcdFx0cmV0cnlhYmxlOiBmYWxzZSxcblx0XHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdCksXG5cdFx0XHRcdCksXG5cdFx0fTtcblx0fSksXG59KSB7IH1cblxuZXhwb3J0IGNsYXNzIFBsdWdpbkxvYWRlclNlcnZpY2UgZXh0ZW5kcyBFZmZlY3QuU2VydmljZTxQbHVnaW5Mb2FkZXJTZXJ2aWNlPigpKFwiUGx1Z2luTG9hZGVyU2VydmljZVwiLCB7XG5cdGVmZmVjdDogRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuXHRcdGNvbnN0IG1vZHVsZUZlZGVyYXRpb25TZXJ2aWNlID0geWllbGQqIE1vZHVsZUZlZGVyYXRpb25TZXJ2aWNlO1xuXHRcdGNvbnN0IHNlY3JldHNTZXJ2aWNlID0geWllbGQqIFNlY3JldHNTZXJ2aWNlO1xuXHRcdGNvbnN0IHJlZ2lzdHJ5U2VydmljZSA9IHlpZWxkKiBSZWdpc3RyeVNlcnZpY2U7XG5cblx0XHRjb25zdCByZXNvbHZlVXJsID0gKGJhc2VVcmw6IHN0cmluZywgdmVyc2lvbj86IHN0cmluZyk6IHN0cmluZyA9PlxuXHRcdFx0dmVyc2lvbiAmJiB2ZXJzaW9uICE9PSBcImxhdGVzdFwiXG5cdFx0XHRcdD8gYmFzZVVybC5yZXBsYWNlKFwiQGxhdGVzdFwiLCBgQCR7dmVyc2lvbn1gKVxuXHRcdFx0XHQ6IGJhc2VVcmw7XG5cblx0XHRjb25zdCBnZXRNZXRhZGF0YSA9IChwbHVnaW5JZDogc3RyaW5nKSA9PiByZWdpc3RyeVNlcnZpY2UuZ2V0KHBsdWdpbklkKTtcblxuXHRcdHJldHVybiB7XG5cdFx0XHRsb2FkUGx1Z2luOiAocGx1Z2luSWQ6IHN0cmluZykgPT5cblx0XHRcdFx0RWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuXHRcdFx0XHRcdGNvbnN0IG1ldGFkYXRhID0geWllbGQqIGdldE1ldGFkYXRhKHBsdWdpbklkKTtcblx0XHRcdFx0XHRjb25zdCB1cmwgPSByZXNvbHZlVXJsKG1ldGFkYXRhLnJlbW90ZVVybCk7XG5cblx0XHRcdFx0XHR5aWVsZCogbW9kdWxlRmVkZXJhdGlvblNlcnZpY2UucmVnaXN0ZXJSZW1vdGUocGx1Z2luSWQsIHVybCkucGlwZShcblx0XHRcdFx0XHRcdEVmZmVjdC5tYXBFcnJvcigoZXJyb3IpID0+XG5cdFx0XHRcdFx0XHRcdHRvUGx1Z2luUnVudGltZUVycm9yKGVycm9yLCBwbHVnaW5JZCwgdW5kZWZpbmVkLCBcInJlZ2lzdGVyLXJlbW90ZVwiLCB0cnVlKSxcblx0XHRcdFx0XHRcdCksXG5cdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdHlpZWxkKiBFZmZlY3QubG9nRGVidWcoXCJMb2FkaW5nIHBsdWdpblwiLCB7IHBsdWdpbklkLCB1cmwgfSk7XG5cblx0XHRcdFx0XHRjb25zdCBjdG9yID0geWllbGQqIG1vZHVsZUZlZGVyYXRpb25TZXJ2aWNlLmxvYWRSZW1vdGVDb25zdHJ1Y3RvcihwbHVnaW5JZCwgdXJsKS5waXBlKFxuXHRcdFx0XHRcdFx0RWZmZWN0Lm1hcEVycm9yKChlcnJvcikgPT5cblx0XHRcdFx0XHRcdFx0dG9QbHVnaW5SdW50aW1lRXJyb3IoZXJyb3IsIHBsdWdpbklkLCB1bmRlZmluZWQsIFwibG9hZC1yZW1vdGVcIiwgZmFsc2UpLFxuXHRcdFx0XHRcdFx0KSxcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdGN0b3IsXG5cdFx0XHRcdFx0XHRtZXRhZGF0YTogbWV0YWRhdGEsXG5cdFx0XHRcdFx0fSBzYXRpc2ZpZXMgTG9hZGVkUGx1Z2luO1xuXHRcdFx0XHR9KSxcblxuXHRcdFx0aW5zdGFudGlhdGVQbHVnaW46IDxUIGV4dGVuZHMgQW55UGx1Z2luPihcblx0XHRcdFx0cGx1Z2luSWQ6IHN0cmluZyxcblx0XHRcdFx0bG9hZGVkUGx1Z2luOiBMb2FkZWRQbHVnaW48VD4sXG5cdFx0XHQpID0+XG5cdFx0XHRcdEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRcdFx0XHRjb25zdCBpbnN0YW5jZSA9IHlpZWxkKiBFZmZlY3QudHJ5KCgpID0+IG5ldyBsb2FkZWRQbHVnaW4uY3RvcigpKS5waXBlKFxuXHRcdFx0XHRcdFx0RWZmZWN0Lm1hcEVycm9yKChlcnJvcikgPT5cblx0XHRcdFx0XHRcdFx0dG9QbHVnaW5SdW50aW1lRXJyb3IoXG5cdFx0XHRcdFx0XHRcdFx0ZXJyb3IsXG5cdFx0XHRcdFx0XHRcdFx0cGx1Z2luSWQsXG5cdFx0XHRcdFx0XHRcdFx0dW5kZWZpbmVkLFxuXHRcdFx0XHRcdFx0XHRcdFwiaW5zdGFudGlhdGUtcGx1Z2luXCIsXG5cdFx0XHRcdFx0XHRcdFx0ZmFsc2UsXG5cdFx0XHRcdFx0XHRcdCksXG5cdFx0XHRcdFx0XHQpLFxuXHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHQoaW5zdGFuY2UuaWQgYXMgc3RyaW5nKSA9IHBsdWdpbklkO1xuXG5cdFx0XHRcdFx0cmV0dXJuIHtcblx0XHRcdFx0XHRcdHBsdWdpbjogaW5zdGFuY2UsXG5cdFx0XHRcdFx0XHRtZXRhZGF0YTogbG9hZGVkUGx1Z2luLm1ldGFkYXRhLFxuXHRcdFx0XHRcdH0gc2F0aXNmaWVzIFBsdWdpbkluc3RhbmNlPFQ+O1xuXHRcdFx0XHR9KSxcblxuXHRcdFx0aW5pdGlhbGl6ZVBsdWdpbjogPFQgZXh0ZW5kcyBBbnlQbHVnaW4+KFxuXHRcdFx0XHRwbHVnaW5JbnN0YW5jZTogUGx1Z2luSW5zdGFuY2U8VD4sXG5cdFx0XHRcdGNvbmZpZzogeyB2YXJpYWJsZXM6IEluZmVyU2NoZW1hSW5wdXQ8VFtcImNvbmZpZ1NjaGVtYVwiXVtcInZhcmlhYmxlc1wiXT47IHNlY3JldHM6IEluZmVyU2NoZW1hSW5wdXQ8VFtcImNvbmZpZ1NjaGVtYVwiXVtcInNlY3JldHNcIl0+IH0sXG5cdFx0XHQpID0+XG5cdFx0XHRcdEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRcdFx0XHRjb25zdCB7IHBsdWdpbiB9ID0gcGx1Z2luSW5zdGFuY2U7XG5cblx0XHRcdFx0XHQvLyBWYWxpZGF0ZSBhbmQgaHlkcmF0ZSBjb25maWdcblx0XHRcdFx0XHRjb25zdCB2YWxpZGF0ZWRWYXJpYWJsZXMgPSB5aWVsZCogdmFsaWRhdGUoXG5cdFx0XHRcdFx0XHRwbHVnaW4uY29uZmlnU2NoZW1hLnZhcmlhYmxlcyBhcyB6LlpvZFNjaGVtYTxJbmZlclNjaGVtYU91dHB1dDxUW1wiY29uZmlnU2NoZW1hXCJdW1widmFyaWFibGVzXCJdPj4sXG5cdFx0XHRcdFx0XHRjb25maWcudmFyaWFibGVzLFxuXHRcdFx0XHRcdFx0cGx1Z2luLmlkLFxuXHRcdFx0XHRcdFx0XCJjb25maWdcIixcblx0XHRcdFx0XHQpLnBpcGUoXG5cdFx0XHRcdFx0XHRFZmZlY3QubWFwRXJyb3IoKHZhbGlkYXRpb25FcnJvcikgPT5cblx0XHRcdFx0XHRcdFx0bmV3IFBsdWdpblJ1bnRpbWVFcnJvcih7XG5cdFx0XHRcdFx0XHRcdFx0cGx1Z2luSWQ6IHBsdWdpbi5pZCxcblx0XHRcdFx0XHRcdFx0XHRvcGVyYXRpb246IFwidmFsaWRhdGUtY29uZmlnXCIsXG5cdFx0XHRcdFx0XHRcdFx0Y2F1c2U6IHZhbGlkYXRpb25FcnJvci56b2RFcnJvcixcblx0XHRcdFx0XHRcdFx0XHRyZXRyeWFibGU6IGZhbHNlLFxuXHRcdFx0XHRcdFx0XHR9KSxcblx0XHRcdFx0XHRcdCksXG5cdFx0XHRcdFx0KTtcblxuXHRcdFx0XHRcdC8vIFZhbGlkYXRlIHNlY3JldHNcblx0XHRcdFx0XHRjb25zdCB2YWxpZGF0ZWRTZWNyZXRzID0geWllbGQqIHZhbGlkYXRlKFxuXHRcdFx0XHRcdFx0cGx1Z2luLmNvbmZpZ1NjaGVtYS5zZWNyZXRzIGFzIHouWm9kU2NoZW1hPEluZmVyU2NoZW1hT3V0cHV0PFRbXCJjb25maWdTY2hlbWFcIl1bXCJzZWNyZXRzXCJdPj4sXG5cdFx0XHRcdFx0XHRjb25maWcuc2VjcmV0cyxcblx0XHRcdFx0XHRcdHBsdWdpbi5pZCxcblx0XHRcdFx0XHRcdFwiY29uZmlnXCIsXG5cdFx0XHRcdFx0KS5waXBlKFxuXHRcdFx0XHRcdFx0RWZmZWN0Lm1hcEVycm9yKCh2YWxpZGF0aW9uRXJyb3IpID0+XG5cdFx0XHRcdFx0XHRcdG5ldyBQbHVnaW5SdW50aW1lRXJyb3Ioe1xuXHRcdFx0XHRcdFx0XHRcdHBsdWdpbklkOiBwbHVnaW4uaWQsXG5cdFx0XHRcdFx0XHRcdFx0b3BlcmF0aW9uOiBcInZhbGlkYXRlLXNlY3JldHNcIixcblx0XHRcdFx0XHRcdFx0XHRjYXVzZTogdmFsaWRhdGlvbkVycm9yLnpvZEVycm9yLFxuXHRcdFx0XHRcdFx0XHRcdHJldHJ5YWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdFx0KSxcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0Ly8gSHlkcmF0ZSBzZWNyZXRzIGluIHZhcmlhYmxlc1xuXHRcdFx0XHRcdGNvbnN0IGh5ZHJhdGVkQ29uZmlnID0geWllbGQqIHNlY3JldHNTZXJ2aWNlLmh5ZHJhdGVTZWNyZXRzKHtcblx0XHRcdFx0XHRcdHZhcmlhYmxlczogdmFsaWRhdGVkVmFyaWFibGVzLFxuXHRcdFx0XHRcdFx0c2VjcmV0czogdmFsaWRhdGVkU2VjcmV0cyxcblx0XHRcdFx0XHR9KTtcblxuXHRcdFx0XHRcdGNvbnN0IF92YXJpYWJsZXMgPSB5aWVsZCogdmFsaWRhdGUoXG5cdFx0XHRcdFx0XHRwbHVnaW4uY29uZmlnU2NoZW1hLnZhcmlhYmxlcyBhcyB6LlpvZFNjaGVtYTxJbmZlclNjaGVtYU91dHB1dDxUW1wiY29uZmlnU2NoZW1hXCJdW1widmFyaWFibGVzXCJdPj4sXG5cdFx0XHRcdFx0XHRoeWRyYXRlZENvbmZpZy52YXJpYWJsZXMsXG5cdFx0XHRcdFx0XHRwbHVnaW4uaWQsXG5cdFx0XHRcdFx0XHRcImNvbmZpZ1wiLFxuXHRcdFx0XHRcdCkucGlwZShcblx0XHRcdFx0XHRcdEVmZmVjdC5tYXBFcnJvcigodmFsaWRhdGlvbkVycm9yKSA9PlxuXHRcdFx0XHRcdFx0XHRuZXcgUGx1Z2luUnVudGltZUVycm9yKHtcblx0XHRcdFx0XHRcdFx0XHRwbHVnaW5JZDogcGx1Z2luLmlkLFxuXHRcdFx0XHRcdFx0XHRcdG9wZXJhdGlvbjogXCJ2YWxpZGF0ZS1oeWRyYXRlZC1jb25maWdcIixcblx0XHRcdFx0XHRcdFx0XHRjYXVzZTogdmFsaWRhdGlvbkVycm9yLnpvZEVycm9yLFxuXHRcdFx0XHRcdFx0XHRcdHJldHJ5YWJsZTogZmFsc2UsXG5cdFx0XHRcdFx0XHRcdH0pLFxuXHRcdFx0XHRcdFx0KSxcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0Ly8gQ3JlYXRlIGEgbG9uZy1saXZlZCBzY29wZSBmb3IgdGhpcyBwbHVnaW4gaW5zdGFuY2Vcblx0XHRcdFx0XHRjb25zdCBzY29wZSA9IHlpZWxkKiBTY29wZS5tYWtlKCk7XG5cblx0XHRcdFx0XHQvLyBJbml0aWFsaXplIHBsdWdpbiB3aXRoaW4gdGhlIHNjb3BlXG5cdFx0XHRcdFx0Y29uc3QgY29udGV4dCA9IHlpZWxkKiBwbHVnaW4uaW5pdGlhbGl6ZSh7IHZhcmlhYmxlczogX3ZhcmlhYmxlcywgc2VjcmV0czogaHlkcmF0ZWRDb25maWcuc2VjcmV0cyB9KS5waXBlKFxuXHRcdFx0XHRcdFx0RWZmZWN0LnByb3ZpZGVTZXJ2aWNlKFNjb3BlLlNjb3BlLCBzY29wZSksXG5cdFx0XHRcdFx0XHRFZmZlY3QubWFwRXJyb3IoKGVycm9yKSA9PlxuXHRcdFx0XHRcdFx0XHR0b1BsdWdpblJ1bnRpbWVFcnJvcihlcnJvciwgcGx1Z2luLmlkLCB1bmRlZmluZWQsIFwiaW5pdGlhbGl6ZS1wbHVnaW5cIiwgZmFsc2UpLFxuXHRcdFx0XHRcdFx0KVxuXHRcdFx0XHRcdCk7XG5cblx0XHRcdFx0XHRyZXR1cm4ge1xuXHRcdFx0XHRcdFx0cGx1Z2luLFxuXHRcdFx0XHRcdFx0bWV0YWRhdGE6IHBsdWdpbkluc3RhbmNlLm1ldGFkYXRhLFxuXHRcdFx0XHRcdFx0Y29uZmlnOiB7IHZhcmlhYmxlczogX3ZhcmlhYmxlcywgc2VjcmV0czogaHlkcmF0ZWRDb25maWcuc2VjcmV0cyB9LFxuXHRcdFx0XHRcdFx0Y29udGV4dCxcblx0XHRcdFx0XHRcdHNjb3BlLFxuXHRcdFx0XHRcdH0gc2F0aXNmaWVzIEluaXRpYWxpemVkUGx1Z2luPFQ+O1xuXHRcdFx0XHR9KSxcblx0XHR9O1xuXHR9KSxcbn0pIHtcbn1cbiIsImltcG9ydCB7IEVmZmVjdCwgRXhpdCwgTGF5ZXIsIFNjb3BlIH0gZnJvbSBcImVmZmVjdFwiO1xuaW1wb3J0IHR5cGUge1xuXHRBbnlQbHVnaW4sXG5cdEluaXRpYWxpemVkUGx1Z2luLFxuXHRQbHVnaW5SZWdpc3RyeSxcblx0U2VjcmV0c0NvbmZpZ1xufSBmcm9tIFwiLi4vLi4vdHlwZXNcIjtcbmltcG9ydCB7IE1vZHVsZUZlZGVyYXRpb25TZXJ2aWNlIH0gZnJvbSBcIi4vbW9kdWxlLWZlZGVyYXRpb24uc2VydmljZVwiO1xuaW1wb3J0IHsgUGx1Z2luTGlmZWN5Y2xlU2VydmljZSB9IGZyb20gXCIuL3BsdWdpbi1saWZlY3ljbGUuc2VydmljZVwiO1xuaW1wb3J0IHsgUGx1Z2luTG9hZGVyU2VydmljZSwgUGx1Z2luUmVnaXN0cnlUYWcsIFJlZ2lzdHJ5U2VydmljZSB9IGZyb20gXCIuL3BsdWdpbi1sb2FkZXIuc2VydmljZVwiO1xuaW1wb3J0IHsgU2VjcmV0c0NvbmZpZ1RhZywgU2VjcmV0c1NlcnZpY2UgfSBmcm9tIFwiLi9zZWNyZXRzLnNlcnZpY2VcIjtcblxuZXhwb3J0IGNsYXNzIFBsdWdpblNlcnZpY2UgZXh0ZW5kcyBFZmZlY3QuU2VydmljZTxQbHVnaW5TZXJ2aWNlPigpKFwiUGx1Z2luU2VydmljZVwiLCB7XG5cdHNjb3BlZDogRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuXHRcdGNvbnN0IGxvYWRlciA9IHlpZWxkKiBQbHVnaW5Mb2FkZXJTZXJ2aWNlO1xuXHRcdGNvbnN0IGxpZmVjeWNsZSA9IHlpZWxkKiBQbHVnaW5MaWZlY3ljbGVTZXJ2aWNlO1xuXG5cdFx0cmV0dXJuIHtcblx0XHRcdGxvYWRQbHVnaW46IGxvYWRlci5sb2FkUGx1Z2luLFxuXHRcdFx0aW5zdGFudGlhdGVQbHVnaW46IGxvYWRlci5pbnN0YW50aWF0ZVBsdWdpbixcblx0XHRcdGluaXRpYWxpemVQbHVnaW46IGxvYWRlci5pbml0aWFsaXplUGx1Z2luLFxuXHRcdFx0c2h1dGRvd25QbHVnaW46IChwbHVnaW46IEluaXRpYWxpemVkUGx1Z2luPEFueVBsdWdpbj4pID0+XG5cdFx0XHRcdEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRcdFx0XHQvLyBTaHV0ZG93biB0aGUgcGx1Z2luIGZpcnN0IChncmFjZWZ1bCBjbGVhbnVwKVxuXHRcdFx0XHRcdHlpZWxkKiBwbHVnaW4ucGx1Z2luLnNodXRkb3duKCkucGlwZShcblx0XHRcdFx0XHRcdEVmZmVjdC5jYXRjaEFsbCgoKSA9PiBFZmZlY3Qudm9pZClcblx0XHRcdFx0XHQpO1xuXG5cdFx0XHRcdFx0Ly8gQ2xvc2UgdGhlIHBsdWdpbiBzY29wZSB0byBpbnRlcnJ1cHQgZmliZXJzIGFuZCByZWxlYXNlIHJlc291cmNlc1xuXHRcdFx0XHRcdHlpZWxkKiBTY29wZS5jbG9zZShwbHVnaW4uc2NvcGUsIEV4aXQuc3VjY2VlZCh1bmRlZmluZWQpKTtcblxuXHRcdFx0XHRcdC8vIFVucmVnaXN0ZXIgZnJvbSBsaWZlY3ljbGUgdHJhY2tpbmdcblx0XHRcdFx0XHR5aWVsZCogbGlmZWN5Y2xlLnVucmVnaXN0ZXIocGx1Z2luKTtcblx0XHRcdFx0fSksXG5cdFx0XHRjbGVhbnVwOiBsaWZlY3ljbGUuY2xlYW51cCxcblx0XHR9O1xuXHR9KSxcbn0pIHtcblx0c3RhdGljIExpdmUgPSAocmVnaXN0cnk6IFBsdWdpblJlZ2lzdHJ5LCBzZWNyZXRzOiBTZWNyZXRzQ29uZmlnKSA9PiB7XG5cdFx0Y29uc3QgY29udGV4dExheWVyID0gTGF5ZXIubWVyZ2VBbGwoXG5cdFx0XHRMYXllci5zdWNjZWVkKFBsdWdpblJlZ2lzdHJ5VGFnLCByZWdpc3RyeSksXG5cdFx0XHRMYXllci5zdWNjZWVkKFNlY3JldHNDb25maWdUYWcsIHNlY3JldHMpLFxuXHRcdCk7XG5cblx0XHRjb25zdCBzZXJ2aWNlc0xheWVyID0gTGF5ZXIubWVyZ2VBbGwoXG5cdFx0XHRNb2R1bGVGZWRlcmF0aW9uU2VydmljZS5EZWZhdWx0LFxuXHRcdFx0U2VjcmV0c1NlcnZpY2UuRGVmYXVsdCxcblx0XHRcdFJlZ2lzdHJ5U2VydmljZS5EZWZhdWx0LFxuXHRcdFx0UGx1Z2luTGlmZWN5Y2xlU2VydmljZS5EZWZhdWx0LFxuXHRcdCkucGlwZShcblx0XHRcdExheWVyLnByb3ZpZGUoY29udGV4dExheWVyKVxuXHRcdCk7XG5cblx0XHRyZXR1cm4gUGx1Z2luU2VydmljZS5EZWZhdWx0LnBpcGUoXG5cdFx0XHRMYXllci5wcm92aWRlKFBsdWdpbkxvYWRlclNlcnZpY2UuRGVmYXVsdCksXG5cdFx0XHRMYXllci5wcm92aWRlKHNlcnZpY2VzTGF5ZXIpXG5cdFx0KTtcblx0fVxufVxuIiwiaW1wb3J0IHsgY3JlYXRlUm91dGVyQ2xpZW50IH0gZnJvbSBcIkBvcnBjL3NlcnZlclwiO1xuaW1wb3J0IHsgQ2F1c2UsIEVmZmVjdCwgRXhpdCwgSGFzaCwgTWFuYWdlZFJ1bnRpbWUsIE9wdGlvbiB9IGZyb20gXCJlZmZlY3RcIjtcbmltcG9ydCB0eXBlIHtcblx0QW55UGx1Z2luLFxuXHRJbml0aWFsaXplZFBsdWdpbixcblx0TG9hZGVkUGx1Z2luLFxuXHRQbHVnaW5DbGllbnRUeXBlLFxuXHRQbHVnaW5Db25maWdJbnB1dCxcblx0UGx1Z2luSW5zdGFuY2UsXG5cdFBsdWdpblJlZ2lzdHJ5LFxuXHRQbHVnaW5Sb3V0ZXJUeXBlLFxuXHRQbHVnaW5SdW50aW1lQ29uZmlnLFxuXHRSZWdpc3RlcmVkUGx1Z2luLFxuXHRSZWdpc3RlcmVkUGx1Z2lucyxcblx0VXNlUGx1Z2luUmVzdWx0XG59IGZyb20gXCIuLi90eXBlc1wiO1xuaW1wb3J0IHsgUGx1Z2luUnVudGltZUVycm9yIH0gZnJvbSBcIi4vZXJyb3JzXCI7XG5pbXBvcnQgeyBQbHVnaW5TZXJ2aWNlIH0gZnJvbSBcIi4vc2VydmljZXMvcGx1Z2luLnNlcnZpY2VcIjtcblxuZXhwb3J0IGNsYXNzIFBsdWdpblJ1bnRpbWU8UiBleHRlbmRzIFJlZ2lzdGVyZWRQbHVnaW5zID0gUmVnaXN0ZXJlZFBsdWdpbnM+IHtcblx0cHJpdmF0ZSBwbHVnaW5DYWNoZSA9IG5ldyBNYXA8c3RyaW5nLCBFZmZlY3QuRWZmZWN0PEluaXRpYWxpemVkUGx1Z2luPEFueVBsdWdpbj4sIFBsdWdpblJ1bnRpbWVFcnJvcj4+KCk7XG5cblx0Y29uc3RydWN0b3IoXG5cdFx0cHJpdmF0ZSBydW50aW1lOiBNYW5hZ2VkUnVudGltZS5NYW5hZ2VkUnVudGltZTxQbHVnaW5TZXJ2aWNlLCBuZXZlcj4sXG5cdFx0cHJpdmF0ZSByZWdpc3RyeTogUGx1Z2luUmVnaXN0cnlcblx0KSB7IH1cblxuXHRwcml2YXRlIGdlbmVyYXRlQ2FjaGVLZXkocGx1Z2luSWQ6IHN0cmluZywgY29uZmlnOiB1bmtub3duKTogc3RyaW5nIHtcblx0XHRjb25zdCBjb25maWdIYXNoID0gSGFzaC5zdHJ1Y3R1cmUoY29uZmlnIGFzIG9iamVjdCkudG9TdHJpbmcoKTtcblx0XHRyZXR1cm4gYCR7cGx1Z2luSWR9OiR7Y29uZmlnSGFzaH1gO1xuXHR9XG5cblx0cHJpdmF0ZSB2YWxpZGF0ZVBsdWdpbklkKFxuXHRcdHBsdWdpbklkOiBzdHJpbmdcblx0KTogRWZmZWN0LkVmZmVjdDxzdHJpbmcsIFBsdWdpblJ1bnRpbWVFcnJvcj4ge1xuXHRcdGlmICghKHBsdWdpbklkIGluIHRoaXMucmVnaXN0cnkpKSB7XG5cdFx0XHRyZXR1cm4gRWZmZWN0LmZhaWwobmV3IFBsdWdpblJ1bnRpbWVFcnJvcih7XG5cdFx0XHRcdHBsdWdpbklkOiBTdHJpbmcocGx1Z2luSWQpLFxuXHRcdFx0XHRvcGVyYXRpb246IFwidmFsaWRhdGUtcGx1Z2luLWlkXCIsXG5cdFx0XHRcdGNhdXNlOiBuZXcgRXJyb3IoYFBsdWdpbiBJRCAnJHtTdHJpbmcocGx1Z2luSWQpfScgbm90IGZvdW5kIGluIHJlZ2lzdHJ5LmApLFxuXHRcdFx0XHRyZXRyeWFibGU6IGZhbHNlLFxuXHRcdFx0fSkpO1xuXHRcdH1cblx0XHRyZXR1cm4gRWZmZWN0LnN1Y2NlZWQoU3RyaW5nKHBsdWdpbklkKSk7XG5cdH1cblxuXHRwcml2YXRlIGFzeW5jIHJ1blByb21pc2U8QSwgRT4oXG5cdFx0ZWZmZWN0OiBFZmZlY3QuRWZmZWN0PEEsIEUsIFBsdWdpblNlcnZpY2U+XG5cdCk6IFByb21pc2U8QT4ge1xuXHRcdGNvbnN0IGV4aXQgPSBhd2FpdCB0aGlzLnJ1bnRpbWUucnVuUHJvbWlzZUV4aXQoZWZmZWN0KTtcblxuXHRcdGlmIChFeGl0LmlzRmFpbHVyZShleGl0KSkge1xuXHRcdFx0Y29uc3QgZXJyb3IgPSBDYXVzZS5mYWlsdXJlT3B0aW9uKGV4aXQuY2F1c2UpO1xuXHRcdFx0aWYgKE9wdGlvbi5pc1NvbWUoZXJyb3IpKSB7XG5cdFx0XHRcdHRocm93IGVycm9yLnZhbHVlO1xuXHRcdFx0fVxuXHRcdFx0dGhyb3cgQ2F1c2Uuc3F1YXNoKGV4aXQuY2F1c2UpO1xuXHRcdH1cblxuXHRcdHJldHVybiBleGl0LnZhbHVlO1xuXHR9XG5cblx0YXN5bmMgdXNlUGx1Z2luPEsgZXh0ZW5kcyBrZXlvZiBSZWdpc3RlcmVkUGx1Z2lucyAmIHN0cmluZz4oXG5cdFx0cGx1Z2luSWQ6IEssXG5cdFx0Y29uZmlnOiBQbHVnaW5Db25maWdJbnB1dDxSW0tdPlxuXHQpOiBQcm9taXNlPFVzZVBsdWdpblJlc3VsdDxLPj4ge1xuXHRcdGNvbnN0IGNhY2hlS2V5ID0gdGhpcy5nZW5lcmF0ZUNhY2hlS2V5KHBsdWdpbklkLCBjb25maWcpO1xuXG5cdFx0bGV0IGNhY2hlZFBsdWdpbiA9IHRoaXMucGx1Z2luQ2FjaGUuZ2V0KGNhY2hlS2V5KTtcblx0XHRpZiAoIWNhY2hlZFBsdWdpbikge1xuXHRcdFx0Y29uc3Qgb3BlcmF0aW9uID0gRWZmZWN0Lmdlbih0aGlzLCBmdW5jdGlvbiogKCkge1xuXHRcdFx0XHRjb25zdCBwbHVnaW5TZXJ2aWNlID0geWllbGQqIFBsdWdpblNlcnZpY2U7XG5cdFx0XHRcdGNvbnN0IHZhbGlkYXRlZElkID0geWllbGQqIHRoaXMudmFsaWRhdGVQbHVnaW5JZChwbHVnaW5JZCk7XG5cblx0XHRcdFx0Ly8gTG9hZCDihpIgSW5zdGFudGlhdGUg4oaSIEluaXRpYWxpemVcblx0XHRcdFx0Y29uc3QgY3RvciA9IHlpZWxkKiBwbHVnaW5TZXJ2aWNlLmxvYWRQbHVnaW4odmFsaWRhdGVkSWQpO1xuXHRcdFx0XHRjb25zdCBpbnN0YW5jZSA9IHlpZWxkKiBwbHVnaW5TZXJ2aWNlLmluc3RhbnRpYXRlUGx1Z2luKHBsdWdpbklkLCBjdG9yKTtcblx0XHRcdFx0Y29uc3QgaW5pdGlhbGl6ZWQgPSB5aWVsZCogcGx1Z2luU2VydmljZS5pbml0aWFsaXplUGx1Z2luKGluc3RhbmNlLCBjb25maWcpO1xuXG5cdFx0XHRcdHJldHVybiBpbml0aWFsaXplZDtcblx0XHRcdH0pLnBpcGUoRWZmZWN0LnByb3ZpZGUodGhpcy5ydW50aW1lKSk7XG5cblx0XHRcdGNhY2hlZFBsdWdpbiA9IEVmZmVjdC5jYWNoZWQob3BlcmF0aW9uKS5waXBlKEVmZmVjdC5mbGF0dGVuKTtcblx0XHRcdHRoaXMucGx1Z2luQ2FjaGUuc2V0KGNhY2hlS2V5LCBjYWNoZWRQbHVnaW4pO1xuXHRcdH1cblxuXHRcdGNvbnN0IGluaXRpYWxpemVkID0gYXdhaXQgdGhpcy5ydW5Qcm9taXNlKGNhY2hlZFBsdWdpbik7XG5cdFx0Y29uc3Qgcm91dGVyID0gaW5pdGlhbGl6ZWQucGx1Z2luLmNyZWF0ZVJvdXRlcihpbml0aWFsaXplZC5jb250ZXh0KTtcblx0XHRjb25zdCBjbGllbnQgPSBjcmVhdGVSb3V0ZXJDbGllbnQocm91dGVyKTtcblxuXHRcdHJldHVybiB7XG5cdFx0XHRyb3V0ZXI6IHJvdXRlciBhcyBQbHVnaW5Sb3V0ZXJUeXBlPFJbS10+LFxuXHRcdFx0Y2xpZW50OiBjbGllbnQgYXMgUGx1Z2luQ2xpZW50VHlwZTxSW0tdPixcblx0XHRcdG1ldGFkYXRhOiBpbml0aWFsaXplZC5tZXRhZGF0YSxcblx0XHRcdGluaXRpYWxpemVkOiBpbml0aWFsaXplZCBhcyBJbml0aWFsaXplZFBsdWdpbjxSZWdpc3RlcmVkUGx1Z2luPEs+PlxuXHRcdH0gYXMgVXNlUGx1Z2luUmVzdWx0PEs+O1xuXHR9XG5cblx0YXN5bmMgbG9hZFBsdWdpbjxLIGV4dGVuZHMga2V5b2YgUmVnaXN0ZXJlZFBsdWdpbnMgJiBzdHJpbmc+KFxuXHRcdHBsdWdpbklkOiBLXG5cdCk6IFByb21pc2U8TG9hZGVkUGx1Z2luPFJlZ2lzdGVyZWRQbHVnaW48Sz4+PiB7XG5cdFx0Y29uc3QgZWZmZWN0ID0gRWZmZWN0LmdlbihmdW5jdGlvbiogKCkge1xuXHRcdFx0Y29uc3QgcGx1Z2luU2VydmljZSA9IHlpZWxkKiBQbHVnaW5TZXJ2aWNlO1xuXHRcdFx0cmV0dXJuIHlpZWxkKiBwbHVnaW5TZXJ2aWNlLmxvYWRQbHVnaW4ocGx1Z2luSWQpO1xuXHRcdH0pO1xuXHRcdHJldHVybiB0aGlzLnJ1blByb21pc2UoZWZmZWN0KSBhcyBQcm9taXNlPExvYWRlZFBsdWdpbjxSZWdpc3RlcmVkUGx1Z2luPEs+Pj47XG5cdH1cblxuXHRhc3luYyBpbnN0YW50aWF0ZVBsdWdpbjxLIGV4dGVuZHMga2V5b2YgUmVnaXN0ZXJlZFBsdWdpbnMgJiBzdHJpbmc+KFxuXHRcdHBsdWdpbklkOiBLLFxuXHRcdGxvYWRlZFBsdWdpbjogTG9hZGVkUGx1Z2luPFJlZ2lzdGVyZWRQbHVnaW48Sz4+XG5cdCk6IFByb21pc2U8UGx1Z2luSW5zdGFuY2U8UmVnaXN0ZXJlZFBsdWdpbjxLPj4+IHtcblx0XHRjb25zdCBlZmZlY3QgPSBFZmZlY3QuZ2VuKGZ1bmN0aW9uKiAoKSB7XG5cdFx0XHRjb25zdCBwbHVnaW5TZXJ2aWNlID0geWllbGQqIFBsdWdpblNlcnZpY2U7XG5cdFx0XHRyZXR1cm4geWllbGQqIHBsdWdpblNlcnZpY2UuaW5zdGFudGlhdGVQbHVnaW4ocGx1Z2luSWQsIGxvYWRlZFBsdWdpbik7XG5cdFx0fSk7XG5cdFx0cmV0dXJuIHRoaXMucnVuUHJvbWlzZShlZmZlY3QpIGFzIFByb21pc2U8UGx1Z2luSW5zdGFuY2U8UmVnaXN0ZXJlZFBsdWdpbjxLPj4+O1xuXHR9XG5cblx0YXN5bmMgaW5pdGlhbGl6ZVBsdWdpbjxUIGV4dGVuZHMgQW55UGx1Z2luPihcblx0XHRpbnN0YW5jZTogUGx1Z2luSW5zdGFuY2U8VD4sXG5cdFx0Y29uZmlnOiBhbnlcblx0KTogUHJvbWlzZTxJbml0aWFsaXplZFBsdWdpbjxUPj4ge1xuXHRcdGNvbnN0IGVmZmVjdCA9IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRcdGNvbnN0IHBsdWdpblNlcnZpY2UgPSB5aWVsZCogUGx1Z2luU2VydmljZTtcblx0XHRcdHJldHVybiB5aWVsZCogcGx1Z2luU2VydmljZS5pbml0aWFsaXplUGx1Z2luKGluc3RhbmNlLCBjb25maWcpO1xuXHRcdH0pO1xuXHRcdHJldHVybiB0aGlzLnJ1blByb21pc2UoZWZmZWN0KTtcblx0fVxuXG5cdGFzeW5jIHNodXRkb3duKCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IGVmZmVjdCA9IEVmZmVjdC5nZW4oZnVuY3Rpb24qICgpIHtcblx0XHRcdGNvbnN0IHBsdWdpblNlcnZpY2UgPSB5aWVsZCogUGx1Z2luU2VydmljZTtcblx0XHRcdHlpZWxkKiBwbHVnaW5TZXJ2aWNlLmNsZWFudXAoKTtcblx0XHR9KTtcblx0XHRyZXR1cm4gdGhpcy5ydW5Qcm9taXNlKGVmZmVjdCk7XG5cdH1cblxuXHRhc3luYyBldmljdFBsdWdpbjxLIGV4dGVuZHMga2V5b2YgUmVnaXN0ZXJlZFBsdWdpbnMgJiBzdHJpbmc+KFxuXHRcdHBsdWdpbklkOiBLLFxuXHRcdGNvbmZpZzogUGx1Z2luQ29uZmlnSW5wdXQ8UmVnaXN0ZXJlZFBsdWdpbnNbS10+XG5cdCk6IFByb21pc2U8dm9pZD4ge1xuXHRcdGNvbnN0IGNhY2hlS2V5ID0gdGhpcy5nZW5lcmF0ZUNhY2hlS2V5KHBsdWdpbklkLCBjb25maWcpO1xuXG5cdFx0Y29uc3QgZWZmZWN0ID0gRWZmZWN0Lmdlbih0aGlzLCBmdW5jdGlvbiogKCkge1xuXHRcdFx0Y29uc3QgcGx1Z2luU2VydmljZSA9IHlpZWxkKiBQbHVnaW5TZXJ2aWNlO1xuXHRcdFx0Y29uc3QgY2FjaGVkUGx1Z2luID0gdGhpcy5wbHVnaW5DYWNoZS5nZXQoY2FjaGVLZXkpO1xuXG5cdFx0XHRpZiAoY2FjaGVkUGx1Z2luKSB7XG5cdFx0XHRcdHRoaXMucGx1Z2luQ2FjaGUuZGVsZXRlKGNhY2hlS2V5KTtcblxuXHRcdFx0XHRjb25zdCBwbHVnaW5SZXN1bHQgPSB5aWVsZCogY2FjaGVkUGx1Z2luLnBpcGUoXG5cdFx0XHRcdFx0RWZmZWN0LmNhdGNoQWxsKCgpID0+IEVmZmVjdC5zdWNjZWVkKG51bGwpKVxuXHRcdFx0XHQpO1xuXG5cdFx0XHRcdGlmIChwbHVnaW5SZXN1bHQpIHtcblx0XHRcdFx0XHR5aWVsZCogcGx1Z2luU2VydmljZS5zaHV0ZG93blBsdWdpbihwbHVnaW5SZXN1bHQpLnBpcGUoXG5cdFx0XHRcdFx0XHRFZmZlY3QuY2F0Y2hBbGwoKCkgPT4gRWZmZWN0LnZvaWQpXG5cdFx0XHRcdFx0KTtcblx0XHRcdFx0fVxuXHRcdFx0fVxuXHRcdH0pLnBpcGUoRWZmZWN0LmNhdGNoQWxsKCgpID0+IEVmZmVjdC52b2lkKSk7XG5cblx0XHRyZXR1cm4gdGhpcy5ydW5Qcm9taXNlKGVmZmVjdCk7XG5cdH1cbn1cblxuLyoqXG4gKiBOb3JtYWxpemVzIGEgcmVtb3RlIFVSTCB0byBlbnN1cmUgaXQgcG9pbnRzIHRvIHJlbW90ZUVudHJ5LmpzXG4gKiBJZiB0aGUgVVJMIGRvZXNuJ3QgZW5kIHdpdGggYSBmaWxlIGV4dGVuc2lvbiwgYXBwZW5kcyAvcmVtb3RlRW50cnkuanNcbiAqL1xuZnVuY3Rpb24gbm9ybWFsaXplUmVtb3RlVXJsKHVybDogc3RyaW5nKTogc3RyaW5nIHtcblx0aWYgKHVybC5lbmRzV2l0aCgnLmpzJykpIHJldHVybiB1cmw7IC8vIEFscmVhZHkgYSBmaWxlXG5cdHJldHVybiBgJHt1cmwuZW5kc1dpdGgoJy8nKSA/IHVybC5zbGljZSgwLCAtMSkgOiB1cmx9L3JlbW90ZUVudHJ5LmpzYDtcbn1cblxuZXhwb3J0IGZ1bmN0aW9uIGNyZWF0ZVBsdWdpblJ1bnRpbWUoXG5cdGNvbmZpZzogUGx1Z2luUnVudGltZUNvbmZpZ1xuKTogUGx1Z2luUnVudGltZSB7XG5cdGNvbnN0IHNlY3JldHMgPSBjb25maWcuc2VjcmV0cyB8fCB7fTtcblxuXHQvLyBOb3JtYWxpemUgYWxsIHJlbW90ZSBVUkxzIGluIHRoZSByZWdpc3RyeVxuXHRjb25zdCBub3JtYWxpemVkUmVnaXN0cnkgPSBPYmplY3QuZnJvbUVudHJpZXMoXG5cdFx0T2JqZWN0LmVudHJpZXMoY29uZmlnLnJlZ2lzdHJ5KS5tYXAoKFtwbHVnaW5JZCwgZW50cnldKSA9PiBbXG5cdFx0XHRwbHVnaW5JZCxcblx0XHRcdHtcblx0XHRcdFx0Li4uZW50cnksXG5cdFx0XHRcdHJlbW90ZVVybDogbm9ybWFsaXplUmVtb3RlVXJsKGVudHJ5LnJlbW90ZVVybClcblx0XHRcdH1cblx0XHRdKVxuXHQpIGFzIFBsdWdpblJlZ2lzdHJ5O1xuXG5cdGNvbnN0IGxheWVyID0gUGx1Z2luU2VydmljZS5MaXZlKG5vcm1hbGl6ZWRSZWdpc3RyeSwgc2VjcmV0cyk7XG5cdGNvbnN0IHJ1bnRpbWUgPSBNYW5hZ2VkUnVudGltZS5tYWtlKGxheWVyKTtcblxuXHRyZXR1cm4gbmV3IFBsdWdpblJ1bnRpbWUocnVudGltZSwgbm9ybWFsaXplZFJlZ2lzdHJ5KTtcbn0iXSwibWFwcGluZ3MiOiI7Ozs7Ozs7Ozs7OztBQUlBLElBQWEscUJBQWIsY0FBd0MsS0FBSyxZQUFZLHFCQUFxQixDQU0zRTtBQUVILElBQWEsd0JBQWIsY0FBMkMsS0FBSyxZQUMvQyx3QkFDQSxDQUlFO0FBRUgsSUFBYSxrQkFBYixjQUFxQyxLQUFLLFlBQVksa0JBQWtCLENBSXJFO0FBR0gsTUFBYSx1QkFBdUIsU0FBMEI7QUFDN0QsU0FBUSxNQUFSO0VBQ0MsS0FBSztFQUNMLEtBQUs7RUFDTCxLQUFLO0VBQ0wsS0FBSztFQUNMLEtBQUssVUFDSixRQUFPO0VBQ1IsUUFDQyxRQUFPOzs7QUFLVixNQUFhLGlCQUNaLFdBQ0EsVUFDQSxlQUNBLGNBQ3dCO0FBQ3hCLFFBQU8sSUFBSSxtQkFBbUI7RUFDN0I7RUFDQTtFQUNBO0VBQ0EsV0FBVyxvQkFBb0IsVUFBVSxLQUFLO0VBQzlDLE9BQU87RUFDUCxDQUFDOztBQUlILE1BQWEsd0JBQ1osT0FDQSxVQUNBLGVBQ0EsV0FDQSxtQkFBbUIsVUFDSztBQUN4QixLQUFJLGlCQUFpQixVQUNwQixRQUFPLGNBQWMsT0FBTyxVQUFVLGVBQWUsVUFBVTtBQUdoRSxLQUFJLGlCQUFpQixtQkFDcEIsUUFBTztBQUdSLFFBQU8sSUFBSSxtQkFBbUI7RUFDN0I7RUFDQTtFQUNBO0VBQ0EsV0FBVztFQUNYLE9BQU8saUJBQWlCLFFBQVEsUUFBUSxJQUFJLE1BQU0sT0FBTyxNQUFNLENBQUM7RUFDaEUsQ0FBQzs7Ozs7O0FDN0RILE1BQU0saUNBQWlDLE9BQU8sT0FDN0MsT0FBTyxXQUFXO0FB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
@@ -1,7 +1,7 @@
1
1
  const require_chunk = require('../chunk-zltIcp7o.cjs');
2
- const require_runtime = require('../runtime-Ckpw0yAc.cjs');
2
+ const require_runtime = require('../runtime-BYrdNAff.cjs');
3
3
  require('../normalize-D4Qh0wVk.cjs');
4
- require('../package-DawQ8na8.cjs');
4
+ require('../package-CgNIVjVe.cjs');
5
5
  let effect = require("effect");
6
6
 
7
7
  //#region src/testing/mocks/module-federation.service.ts
@@ -1,6 +1,6 @@
1
1
  import "../zod-A7Pti5IV.cjs";
2
2
  import "../errors-DKPPPYYT.cjs";
3
- import { a as EveryPlugin, g as PluginRuntimeConfig, m as PluginRegistry, r as PluginService, t as PluginRuntime, x as LoadedPluginWithBinding, y as RegisteredPlugins } from "../index-matrPV4m.cjs";
3
+ import { a as EveryPlugin, g as PluginRuntimeConfig, m as PluginRegistry, r as PluginService, t as PluginRuntime, x as LoadedPluginWithBinding, y as RegisteredPlugins } from "../index-DM9S53Bx.cjs";
4
4
  import "../normalize-BW7kk8Lk.cjs";
5
5
  import { Layer } from "effect";
6
6
 
@@ -1,6 +1,6 @@
1
1
  import "../zod-Zw8dlP3j.mjs";
2
2
  import "../errors-9sNpYLv5.mjs";
3
- import { a as EveryPlugin, g as PluginRuntimeConfig, m as PluginRegistry, r as PluginService, t as PluginRuntime, x as LoadedPluginWithBinding, y as RegisteredPlugins } from "../index-qxKsRmCb.mjs";
3
+ import { a as EveryPlugin, g as PluginRuntimeConfig, m as PluginRegistry, r as PluginService, t as PluginRuntime, x as LoadedPluginWithBinding, y as RegisteredPlugins } from "../index-DrOou1Hc.mjs";
4
4
  import "../normalize-eB_j86fm.mjs";
5
5
  import { Layer } from "effect";
6
6
 
@@ -1,6 +1,6 @@
1
- import { a as PluginRegistryTag, c as SecretsService, d as ModuleFederationError, i as PluginLoaderService, l as PluginLifecycleService, o as RegistryService, r as PluginService, s as SecretsConfigTag, t as PluginRuntime, u as ModuleFederationService } from "../runtime-Br0wOcuk.mjs";
1
+ import { a as PluginRegistryTag, c as SecretsService, d as ModuleFederationError, i as PluginLoaderService, l as PluginLifecycleService, o as RegistryService, r as PluginService, s as SecretsConfigTag, t as PluginRuntime, u as ModuleFederationService } from "../runtime-BzkHRj0E.mjs";
2
2
  import "../normalize-D7nae0Hn.mjs";
3
- import "../package-OrUVCH-p.mjs";
3
+ import "../package-BoyftHDo.mjs";
4
4
  import { Effect, Layer, ManagedRuntime } from "effect";
5
5
 
6
6
  //#region src/testing/mocks/module-federation.service.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "every-plugin",
3
- "version": "0.4.12",
3
+ "version": "0.4.14",
4
4
  "type": "module",
5
5
  "main": "./dist/index.cjs",
6
6
  "module": "./dist/index.mjs",