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.
- package/dist/build/rspack/index.cjs +80 -78
- package/dist/build/rspack/index.d.cts +1 -1
- package/dist/build/rspack/index.d.mts +1 -1
- package/dist/build/rspack/index.mjs +80 -78
- package/dist/{index-matrPV4m.d.cts → index-DM9S53Bx.d.cts} +2 -2
- package/dist/{index-qxKsRmCb.d.mts → index-DrOou1Hc.d.mts} +2 -2
- package/dist/index.cjs +2 -2
- package/dist/index.d.cts +1 -1
- package/dist/index.d.mts +1 -1
- package/dist/index.mjs +2 -2
- package/dist/{package-WZ0vKAyb.mjs → package-BoyftHDo.mjs} +2 -2
- package/dist/{package-CMoV9xVN.cjs → package-CgNIVjVe.cjs} +2 -2
- package/dist/runtime/index.cjs +2 -2
- package/dist/runtime/index.d.cts +1 -1
- package/dist/runtime/index.d.mts +1 -1
- package/dist/runtime/index.mjs +2 -2
- package/dist/runtime-BYrdNAff.cjs +524 -0
- package/dist/runtime-BzkHRj0E.mjs +459 -0
- package/dist/testing/index.cjs +2 -2
- package/dist/testing/index.d.cts +1 -1
- package/dist/testing/index.d.mts +1 -1
- package/dist/testing/index.mjs +2 -2
- package/package.json +1 -1
- package/dist/runtime-B4AItsDQ.mjs +0 -458
- package/dist/runtime-D5bSEcHa.cjs +0 -523
|
@@ -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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
|
package/dist/testing/index.cjs
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
const require_chunk = require('../chunk-zltIcp7o.cjs');
|
|
2
|
-
const require_runtime = require('../runtime-
|
|
2
|
+
const require_runtime = require('../runtime-BYrdNAff.cjs');
|
|
3
3
|
require('../normalize-D4Qh0wVk.cjs');
|
|
4
|
-
require('../package-
|
|
4
|
+
require('../package-CgNIVjVe.cjs');
|
|
5
5
|
let effect = require("effect");
|
|
6
6
|
|
|
7
7
|
//#region src/testing/mocks/module-federation.service.ts
|
package/dist/testing/index.d.cts
CHANGED
|
@@ -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-
|
|
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
|
|
package/dist/testing/index.d.mts
CHANGED
|
@@ -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-
|
|
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
|
|
package/dist/testing/index.mjs
CHANGED
|
@@ -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-
|
|
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-
|
|
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
|