@dbx-tools/appkit-mastra 0.6.211 → 0.6.213

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.
@@ -20,11 +20,10 @@
20
20
  *
21
21
  * @module
22
22
  */
23
- import { ValidationError } from "@databricks/appkit";
24
23
  import { log } from "@dbx-tools/shared-core";
25
24
  import { wire, } from "@dbx-tools/shared-mastra";
26
- import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context";
27
25
  import { registerApiRoute } from "@mastra/core/server";
26
+ import { resolveAgentRequestContext, resolveAgentRouteOptions, } from "./_agent-route-context.js";
28
27
  import { clampPerPage, parseIntParam } from "./pagination.js";
29
28
  import { invalidFields } from "./validation.js";
30
29
  const logger = log.logger("mastra/threads");
@@ -177,40 +176,12 @@ export async function renameThread(opts) {
177
176
  * agent) and `/route/threads/:agentId`.
178
177
  */
179
178
  export function threadsRoute(options) {
180
- const { path } = options;
181
- const fixedAgent = "agent" in options ? options.agent : undefined;
182
- if (!fixedAgent && !path.includes(":agentId")) {
183
- throw ValidationError.invalidValue("threadsRoute.path", path, "a path containing `:agentId`, or an explicit `agent`");
184
- }
185
- // Shared by GET / DELETE: resolve the active agent and the caller's
186
- // resource id, returning a JSON error response when either is
187
- // missing. Keeps both handlers thin with identical validation.
188
- const resolveContext = (c) => {
189
- const mastra = c.get("mastra");
190
- const requestContext = c.get("requestContext");
191
- const agentId = fixedAgent ?? c.req.param("agentId");
192
- if (!agentId) {
193
- return { error: c.json({ error: "agentId is required" }, 400) };
194
- }
195
- const agent = mastra.getAgentById(agentId);
196
- if (!agent) {
197
- return {
198
- error: c.json({ error: `Unknown agent "${agentId}"` }, 404),
199
- };
200
- }
201
- const resourceId = requestContext.get(MASTRA_RESOURCE_ID_KEY);
202
- if (!resourceId) {
203
- return {
204
- error: c.json({ error: "resource id missing from request context" }, 400),
205
- };
206
- }
207
- return { agentId, agent, requestContext, resourceId };
208
- };
179
+ const { path, fixedAgent } = resolveAgentRouteOptions(options, "threadsRoute.path");
209
180
  return [
210
181
  registerApiRoute(path, {
211
182
  method: "GET",
212
183
  handler: async (c) => {
213
- const ctx = resolveContext(c);
184
+ const ctx = resolveAgentRequestContext(c, { fixedAgent });
214
185
  if ("error" in ctx)
215
186
  return ctx.error;
216
187
  const payload = await listThreads({
@@ -225,22 +196,18 @@ export function threadsRoute(options) {
225
196
  registerApiRoute(path, {
226
197
  method: "DELETE",
227
198
  handler: async (c) => {
228
- const ctx = resolveContext(c);
199
+ const ctx = resolveAgentRequestContext(c, { fixedAgent, threadId: "required" });
229
200
  if ("error" in ctx)
230
201
  return ctx.error;
231
- const threadId = ctx.requestContext.get(MASTRA_THREAD_ID_KEY);
232
- if (!threadId) {
233
- return c.json({ error: "thread id missing from request context" }, 400);
234
- }
235
202
  const { deleted } = await deleteThread({
236
203
  agent: ctx.agent,
237
- threadId,
204
+ threadId: ctx.threadId,
238
205
  resourceId: ctx.resourceId,
239
206
  });
240
207
  const payload = {
241
208
  ok: true,
242
209
  agentId: ctx.agentId,
243
- threadId,
210
+ threadId: ctx.threadId,
244
211
  deleted,
245
212
  };
246
213
  return c.json(payload);
@@ -249,13 +216,9 @@ export function threadsRoute(options) {
249
216
  registerApiRoute(path, {
250
217
  method: "PATCH",
251
218
  handler: async (c) => {
252
- const ctx = resolveContext(c);
219
+ const ctx = resolveAgentRequestContext(c, { fixedAgent, threadId: "required" });
253
220
  if ("error" in ctx)
254
221
  return ctx.error;
255
- const threadId = ctx.requestContext.get(MASTRA_THREAD_ID_KEY);
256
- if (!threadId) {
257
- return c.json({ error: "thread id missing from request context" }, 400);
258
- }
259
222
  const body = wire.MastraUpdateThreadRequestSchema.safeParse(await c.req.json());
260
223
  if (!body.success) {
261
224
  logger.warn("rename:invalid", { error: body.error.message });
@@ -263,12 +226,12 @@ export function threadsRoute(options) {
263
226
  }
264
227
  const thread = await renameThread({
265
228
  agent: ctx.agent,
266
- threadId,
229
+ threadId: ctx.threadId,
267
230
  resourceId: ctx.resourceId,
268
231
  title: body.data.title,
269
232
  });
270
233
  if (!thread) {
271
- return c.json({ error: `Unknown thread "${threadId}"` }, 404);
234
+ return c.json({ error: `Unknown thread "${ctx.threadId}"` }, 404);
272
235
  }
273
236
  const payload = {
274
237
  ok: true,
@@ -298,4 +261,4 @@ function toIso(value) {
298
261
  const parsed = new Date(value);
299
262
  return Number.isNaN(parsed.getTime()) ? new Date(0).toISOString() : parsed.toISOString();
300
263
  }
301
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyZWFkcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90aHJlYWRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7QUFFSCxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sb0JBQW9CLENBQUM7QUFDckQsT0FBTyxFQUFFLEdBQUcsRUFBRSxNQUFNLHdCQUF3QixDQUFDO0FBQzdDLE9BQU8sRUFDTCxJQUFJLEdBS0wsTUFBTSwwQkFBMEIsQ0FBQztBQUdsQyxPQUFPLEVBQUUsc0JBQXNCLEVBQUUsb0JBQW9CLEVBQUUsTUFBTSw4QkFBOEIsQ0FBQztBQUU1RixPQUFPLEVBQUUsZ0JBQWdCLEVBQUUsTUFBTSxxQkFBcUIsQ0FBQztBQUV2RCxPQUFPLEVBQUUsWUFBWSxFQUFFLGFBQWEsRUFBRSxNQUFNLGlCQUFpQixDQUFDO0FBQzlELE9BQU8sRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUVoRCxNQUFNLE1BQU0sR0FBRyxHQUFHLENBQUMsTUFBTSxDQUFDLGdCQUFnQixDQUFDLENBQUM7QUFFNUMsaUNBQWlDO0FBQ2pDLE1BQU0sZ0JBQWdCLEdBQUcsRUFBRSxDQUFDO0FBQzVCLHlFQUF5RTtBQUN6RSxNQUFNLFlBQVksR0FBRyxHQUFHLENBQUM7QUFDekIsNEVBQTRFO0FBQzVFLE1BQU0sc0JBQXNCLEdBQUcsK0JBQStCLENBQUM7QUFVL0Q7Ozs7Ozs7O0dBUUc7QUFDSCxNQUFNLENBQUMsS0FBSyxVQUFVLFdBQVcsQ0FBQyxJQUF3QjtJQUN4RCxNQUFNLE9BQU8sR0FBRyxZQUFZLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRTtRQUN6QyxRQUFRLEVBQUUsZ0JBQWdCO1FBQzFCLEdBQUcsRUFBRSxZQUFZO0tBQ2xCLENBQUMsQ0FBQztJQUNILE1BQU0sSUFBSSxHQUFHLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMs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LEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0tBQzFELENBQUM7QUFDSixDQUFDO0FBRUQscUVBQXFFO0FBQ3JFLFNBQVMsS0FBSyxDQUFDLEtBQTZCO0lBQzFDLElBQUksS0FBSyxZQUFZLElBQUk7UUFBRSxPQUFPLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN0RCxNQUFNLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvQixPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7QUFDM0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29udmVyc2F0aW9uLXRocmVhZCBsaXN0aW5nIGV4cG9zZWQgYXMgYSBNYXN0cmEgY3VzdG9tIEFQSSByb3V0ZS5cbiAqXG4gKiBCYWNrZWQgZW50aXJlbHkgYnkgbmF0aXZlIE1hc3RyYTogbG9va3MgdXAgdGhlIGFjdGl2ZSBhZ2VudCBieSBpZCxcbiAqIGFza3MgaXRzIGBNZW1vcnlgIGluc3RhbmNlIHRvIGBsaXN0VGhyZWFkc2AgZmlsdGVyZWQgdG8gdGhlIGNhbGxlcidzXG4gKiByZXNvdXJjZSwgYW5kIHNoYXBlcyBlYWNoIGludG8gdGhlIEpTT04tc2FmZSB7QGxpbmsgTWFzdHJhVGhyZWFkfVxuICogd2lyZSB0eXBlLiBBIHNpYmxpbmcgYERFTEVURWAgcmVtb3ZlcyBhIHNpbmdsZSBuYW1lZCB0aHJlYWQuXG4gKlxuICogQSBzaWJsaW5nIGBERUxFVEVgIHJlbW92ZXMgYSBzaW5nbGUgbmFtZWQgdGhyZWFkOyBhIGBQQVRDSGAgcmVuYW1lc1xuICogb25lICh7QGxpbmsgcmVuYW1lVGhyZWFkfSkuXG4gKlxuICogTGlrZSB7QGxpbmsgaGlzdG9yeVJvdXRlfSB0aGlzIHJlZ2lzdGVycyB0aHJvdWdoIE1hc3RyYSdzXG4gKiBgcmVnaXN0ZXJBcGlSb3V0ZWAgc28gaXQgc2hhcmVzIHRoZSBgTWFzdHJhU2VydmVyYCBhdXRoLW1pZGRsZXdhcmVcbiAqIHBpcGVsaW5lIChpbiBgLi9zZXJ2ZXIudHNgKSwgd2hpY2ggaGFzIGFscmVhZHkgc3RhbXBlZCB0aGUgcmVzb3VyY2VcbiAqIGlkIChgTUFTVFJBX1JFU09VUkNFX0lEX0tFWWApIGFuZCB0aGUgdGFyZ2V0ZWQgdGhyZWFkIGlkXG4gKiAoYE1BU1RSQV9USFJFQURfSURfS0VZYCwgcmVzb2x2ZWQgZnJvbSB0aGUgdGhyZWFkLXNlbGVjdGlvbiBoZWFkZXIgL1xuICogY29va2llKSBvbiBgUmVxdWVzdENvbnRleHRgIGJ5IHRoZSB0aW1lIGEgaGFuZGxlciBydW5zLiBSZXNvdXJjZVxuICogc2NvcGluZyBsaXZlcyBoZXJlIHNvIGEgY2FsbGVyIGNhbiBvbmx5IGV2ZXIgc2VlLCByZW5hbWUsIG9yIGRlbGV0ZVxuICogaXRzIG93biB0aHJlYWRzOyBubyBjb29raWUgb3IgdXNlciBsb29rdXBzIGhhcHBlbiBpbiB0aGlzIG1vZHVsZS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgVmFsaWRhdGlvbkVycm9yIH0gZnJvbSBcIkBkYXRhYnJpY2tzL2FwcGtpdFwiO1xuaW1wb3J0IHsgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7XG4gIHdpcmUsXG4gIHR5cGUgTWFzdHJhRGVsZXRlVGhyZWFkUmVzcG9uc2UsXG4gIHR5cGUgTWFzdHJhVGhyZWFkLFxuICB0eXBlIE1hc3RyYVRocmVhZHNSZXNwb25zZSxcbiAgdHlwZSBNYXN0cmFVcGRhdGVUaHJlYWRSZXNwb25zZSxcbn0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1hc3RyYVwiO1xuaW1wb3J0IHR5cGUgeyBBZ2VudCB9IGZyb20gXCJAbWFzdHJhL2NvcmUvYWdlbnRcIjtcbmltcG9ydCB0eXBlIHsgU3RvcmFnZVRocmVhZFR5cGUgfSBmcm9tIFwiQG1hc3RyYS9jb3JlL21lbW9yeVwiO1xuaW1wb3J0IHsgTUFTVFJBX1JFU09VUkNFX0lEX0tFWSwgTUFTVFJBX1RIUkVBRF9JRF9LRVkgfSBmcm9tIFwiQG1hc3RyYS9jb3JlL3JlcXVlc3QtY29udGV4dFwiO1xuaW1wb3J0IHR5cGUgeyBDb250ZXh0V2l0aE1hc3RyYSB9IGZyb20gXCJAbWFzdHJhL2NvcmUvc2VydmVyXCI7XG5pbXBvcnQgeyByZWdpc3RlckFwaVJvdXRlIH0gZnJvbSBcIkBtYXN0cmEvY29yZS9zZXJ2ZXJcIjtcblxuaW1wb3J0IHsgY2xhbXBQZXJQYWdlLCBwYXJzZUludFBhcmFtIH0gZnJvbSBcIi4vcGFnaW5hdGlvbi50c1wiO1xuaW1wb3J0IHsgaW52YWxpZEZpZWxkcyB9IGZyb20gXCIuL3ZhbGlkYXRpb24udHNcIjtcblxuY29uc3QgbG9nZ2VyID0gbG9nLmxvZ2dlcihcIm1hc3RyYS90aHJlYWRzXCIpO1xuXG4vKiogRGVmYXVsdCB0aHJlYWRzIHBhZ2Ugc2l6ZS4gKi9cbmNvbnN0IERFRkFVTFRfUEVSX1BBR0UgPSAzMDtcbi8qKiBIYXJkIGNhcCBzbyBhIG1pc2JlaGF2aW5nIGNsaWVudCBjYW4ndCBmZXRjaCBldmVyeSB0aHJlYWQgYXQgb25jZS4gKi9cbmNvbnN0IE1BWF9QRVJfUEFHRSA9IDIwMDtcbi8qKiBTdGFibGUgY2xpZW50IG1lc3NhZ2UgZm9yIGEgcmVuYW1lIGJvZHkgdGhhdCBmYWlscyBzY2hlbWEgdmFsaWRhdGlvbi4gKi9cbmNvbnN0IElOVkFMSURfUkVOQU1FX01FU1NBR0UgPSBcIkludmFsaWQgdGhyZWFkIHJlbmFtZSByZXF1ZXN0XCI7XG5cbi8qKiBJbnB1dHMgYWNjZXB0ZWQgYnkge0BsaW5rIGxpc3RUaHJlYWRzfS4gKi9cbmV4cG9ydCBpbnRlcmZhY2UgTGlzdFRocmVhZHNPcHRpb25zIHtcbiAgYWdlbnQ6IEFnZW50O1xuICByZXNvdXJjZUlkOiBzdHJpbmc7XG4gIHBhZ2U/OiBudW1iZXI7XG4gIHBlclBhZ2U/OiBudW1iZXI7XG59XG5cbi8qKlxuICogRmV0Y2ggYSBwYWdlIG9mIHRoZSByZXNvdXJjZSdzIGNvbnZlcnNhdGlvbiB0aHJlYWRzLCBuZXdlc3RcbiAqIChgdXBkYXRlZEF0YCBERVNDKSBmaXJzdC5cbiAqXG4gKiBVc2VzIHRoZSBhZ2VudCdzIHJlc29sdmVkIGBNZW1vcnlgIChgZ2V0TWVtb3J5KClgKSBzbyB0aGUgcGVyLWFnZW50XG4gKiBzdG9yYWdlIG5hbWVzcGFjZSAoYG1hc3RyYV88YWdlbnRJZD5gIHNjaGVtYSkgYXBwbGllcyBhdXRvbWF0aWNhbGx5LlxuICogV2hlbiB0aGUgYWdlbnQgaGFzIG5vIG1lbW9yeSBjb25maWd1cmVkIHRoZSByZXNwb25zZSBpcyBhIHN1Y2Nlc3NmdWxcbiAqIGVtcHR5IHBhZ2Ugc28gY2FsbGVycyBkb24ndCBoYXZlIHRvIHNwZWNpYWwtY2FzZSBzdGF0ZWxlc3MgYWdlbnRzLlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gbGlzdFRocmVhZHMob3B0czogTGlzdFRocmVhZHNPcHRpb25zKTogUHJvbWlzZTxNYXN0cmFUaHJlYWRzUmVzcG9uc2U+IHtcbiAgY29uc3QgcGVyUGFnZSA9IGNsYW1wUGVyUGFnZShvcHRzLnBlclBhZ2UsIHtcbiAgICBmYWxsYmFjazogREVGQVVMVF9QRVJfUEFHRSxcbiAgICBtYXg6IE1BWF9QRVJfUEFHRSxcbiAgfSk7XG4gIGNvbnN0IHBhZ2UgPSBNYXRoLm1heCgwLCBNYXRoLnRydW5jKG9wdHMucGFnZSA/PyAwKSk7XG4gIGNvbnN0IG1lbW9yeSA9IGF3YWl0IG9wdHMuYWdlbnQuZ2V0TWVtb3J5KCk7XG4gIGlmICghbWVtb3J5KSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwibGlzdDpuby1tZW1vcnlcIiwgeyBhZ2VudElkOiBvcHRzLmFnZW50LmlkIH0pO1xuICAgIHJldHVybiB7IHRocmVhZHM6IFtdLCBwYWdlLCBwZXJQYWdlLCB0b3RhbDogMCwgaGFzTW9yZTogZmFsc2UgfTtcbiAgfVxuICBjb25zdCBzdGFydGVkQXQgPSBEYXRlLm5vdygpO1xuICBjb25zdCByZXN1bHQgPSBhd2FpdCBtZW1vcnkubGlzdFRocmVhZHMoe1xuICAgIGZpbHRlcjogeyByZXNvdXJjZUlkOiBvcHRzLnJlc291cmNlSWQgfSxcbiAgICBwYWdlLFxuICAgIHBlclBhZ2UsXG4gICAgb3JkZXJCeTogeyBmaWVsZDogXCJ1cGRhdGVkQXRcIiwgZGlyZWN0aW9uOiBcIkRFU0NcIiB9LFxuICB9KTtcbiAgY29uc3QgdGhyZWFkcyA9IHJlc3VsdC50aHJlYWRzLm1hcCh0b1dpcmVUaHJlYWQpO1xuICBsb2dnZXIuZGVidWcoXCJsaXN0OmRvbmVcIiwge1xuICAgIGFnZW50SWQ6IG9wdHMuYWdlbnQuaWQsXG4gICAgcmVzb3VyY2VJZDogb3B0cy5yZXNvdXJjZUlkLFxuICAgIHBhZ2UsXG4gICAgcGVyUGFnZSxcbiAgICByZXR1cm5lZDogdGhyZWFkcy5sZW5ndGgsXG4gICAgdG90YWw6IHJlc3VsdC50b3RhbCxcbiAgICBoYXNNb3JlOiByZXN1bHQuaGFzTW9yZSxcbiAgICBlbGFwc2VkTXM6IERhdGUubm93KCkgLSBzdGFydGVkQXQsXG4gIH0pO1xuICByZXR1cm4ge1xuICAgIHRocmVhZHMsXG4gICAgcGFnZSxcbiAgICBwZXJQYWdlLFxuICAgIHRvdGFsOiByZXN1bHQudG90YWwsXG4gICAgaGFzTW9yZTogcmVzdWx0Lmhhc01vcmUsXG4gIH07XG59XG5cbi8qKiBJbnB1dHMgYWNjZXB0ZWQgYnkge0BsaW5rIGRlbGV0ZVRocmVhZH0uICovXG5leHBvcnQgaW50ZXJmYWNlIERlbGV0ZVRocmVhZE9wdGlvbnMge1xuICBhZ2VudDogQWdlbnQ7XG4gIHRocmVhZElkOiBzdHJpbmc7XG4gIHJlc291cmNlSWQ6IHN0cmluZztcbn1cblxuLyoqXG4gKiBEZWxldGUgYSBzaW5nbGUgbmFtZWQgdGhyZWFkIChhbmQgZXZlcnkgbWVzc2FnZSBvbiBpdCkuXG4gKlxuICogT3duZXJzaGlwIGlzIGVuZm9yY2VkOiB0aGUgdGhyZWFkIGlzIG9ubHkgcmVtb3ZlZCB3aGVuIGl0IGJlbG9uZ3MgdG9cbiAqIHRoZSBjYWxsaW5nIHJlc291cmNlLCBzbyBhIGNsaWVudCBjYW4ndCBkZWxldGUgYW5vdGhlciB1c2VyJ3NcbiAqIGNvbnZlcnNhdGlvbiBieSBndWVzc2luZyBpdHMgaWQuIEEgdGhyZWFkIHRoYXQgZG9lc24ndCBleGlzdCAob3JcbiAqIGlzbid0IG93bmVkIGJ5IHRoZSBjYWxsZXIpIGlzIGEgc3VjY2Vzc2Z1bCBuby1vcCAoYGRlbGV0ZWQ6IGZhbHNlYClcbiAqIHNvIHRoZSBVSSBjYW4gZmlyZS1hbmQtZm9yZ2V0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gZGVsZXRlVGhyZWFkKG9wdHM6IERlbGV0ZVRocmVhZE9wdGlvbnMpOiBQcm9taXNlPHsgZGVsZXRlZDogYm9vbGVhbiB9PiB7XG4gIGNvbnN0IG1lbW9yeSA9IGF3YWl0IG9wdHMuYWdlbnQuZ2V0TWVtb3J5KCk7XG4gIGlmICghbWVtb3J5KSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwiZGVsZXRlOm5vLW1lbW9yeVwiLCB7IGFnZW50SWQ6IG9wdHMuYWdlbnQuaWQgfSk7XG4gICAgcmV0dXJuIHsgZGVsZXRlZDogZmFsc2UgfTtcbiAgfVxuICAvLyBDb25maXJtIHRoZSB0aHJlYWQgZXhpc3RzIGFuZCBpcyBvd25lZCBieSB0aGUgY2FsbGVyIGJlZm9yZVxuICAvLyBkZWxldGluZzsgbmV2ZXIgbGV0IGEgZ3Vlc3NlZCBpZCB0b3VjaCBhbm90aGVyIHJlc291cmNlJ3MgZGF0YS5cbiAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBtZW1vcnkuZ2V0VGhyZWFkQnlJZCh7IHRocmVhZElkOiBvcHRzLnRocmVhZElkIH0pO1xuICBpZiAoIWV4aXN0aW5nIHx8IGV4aXN0aW5nLnJlc291cmNlSWQgIT09IG9wdHMucmVzb3VyY2VJZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImRlbGV0ZTpub3Qtb3duZWRcIiwge1xuICAgICAgYWdlbnRJZDogb3B0cy5hZ2VudC5pZCxcbiAgICAgIHRocmVhZElkOiBvcHRzLnRocmVhZElkLFxuICAgICAgZm91bmQ6IGV4aXN0aW5nICE9PSBudWxsLFxuICAgIH0pO1xuICAgIHJldHVybiB7IGRlbGV0ZWQ6IGZhbHNlIH07XG4gIH1cbiAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgYXdhaXQgbWVtb3J5LmRlbGV0ZVRocmVhZChvcHRzLnRocmVhZElkKTtcbiAgbG9nZ2VyLmluZm8oXCJkZWxldGU6ZG9uZVwiLCB7XG4gICAgYWdlbnRJZDogb3B0cy5hZ2VudC5pZCxcbiAgICB0aHJlYWRJZDogb3B0cy50aHJlYWRJZCxcbiAgICBlbGFwc2VkTXM6IERhdGUubm93KCkgLSBzdGFydGVkQXQsXG4gIH0pO1xuICByZXR1cm4geyBkZWxldGVkOiB0cnVlIH07XG59XG5cbi8qKiBJbnB1dHMgYWNjZXB0ZWQgYnkge0BsaW5rIHJlbmFtZVRocmVhZH0uICovXG5leHBvcnQgaW50ZXJmYWNlIFJlbmFtZVRocmVhZE9wdGlvbnMge1xuICBhZ2VudDogQWdlbnQ7XG4gIHRocmVhZElkOiBzdHJpbmc7XG4gIHJlc291cmNlSWQ6IHN0cmluZztcbiAgdGl0bGU6IHN0cmluZztcbn1cblxuLyoqXG4gKiBSZW5hbWUgYSBzaW5nbGUgdGhyZWFkLCByZXR1cm5pbmcgdGhlIHVwZGF0ZWQgd2lyZSB0aHJlYWQuXG4gKlxuICogT3duZXJzaGlwIGlzIGVuZm9yY2VkIHRoZSBzYW1lIHdheSB7QGxpbmsgZGVsZXRlVGhyZWFkfSBlbmZvcmNlcyBpdDpcbiAqIHRoZSB0aXRsZSBpcyBvbmx5IGNoYW5nZWQgd2hlbiB0aGUgdGhyZWFkIGJlbG9uZ3MgdG8gdGhlIGNhbGxpbmdcbiAqIHJlc291cmNlLCBzbyBhIGNsaWVudCBjYW4ndCByZW5hbWUgYW5vdGhlciB1c2VyJ3MgY29udmVyc2F0aW9uIGJ5XG4gKiBndWVzc2luZyBpdHMgaWQuIEV4aXN0aW5nIHRocmVhZCBgbWV0YWRhdGFgIGlzIHByZXNlcnZlZCB1bnRvdWNoZWRcbiAqIChNYXN0cmEncyBgdXBkYXRlVGhyZWFkYCByZXBsYWNlcyB0aGUgcm93LCBzbyBpdCBtdXN0IGJlIHBhc3NlZCBiYWNrXG4gKiBpbikuIFJldHVybnMgYG51bGxgIHdoZW4gdGhlIHRocmVhZCBkb2Vzbid0IGV4aXN0LCBpc24ndCBvd25lZCBieSB0aGVcbiAqIGNhbGxlciwgb3IgdGhlIGFnZW50IGhhcyBubyBtZW1vcnkgY29uZmlndXJlZCwgbGV0dGluZyB0aGUgcm91dGUgbWFwXG4gKiB0aGF0IHRvIGEgNDA0LlxuICovXG5leHBvcnQgYXN5bmMgZnVuY3Rpb24gcmVuYW1lVGhyZWFkKG9wdHM6IFJlbmFtZVRocmVhZE9wdGlvbnMpOiBQcm9taXNlPE1hc3RyYVRocmVhZCB8IG51bGw+IHtcbiAgY29uc3QgbWVtb3J5ID0gYXdhaXQgb3B0cy5hZ2VudC5nZXRNZW1vcnkoKTtcbiAgaWYgKCFtZW1vcnkpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJyZW5hbWU6bm8tbWVtb3J5XCIsIHsgYWdlbnRJZDogb3B0cy5hZ2VudC5pZCB9KTtcbiAgICByZXR1cm4gbnVsbDtcbiAgfVxuICBjb25zdCBleGlzdGluZyA9IGF3YWl0IG1lbW9yeS5nZXRUaHJlYWRCeUlkKHsgdGhyZWFkSWQ6IG9wdHMudGhyZWFkSWQgfSk7XG4gIGlmICghZXhpc3RpbmcgfHwgZXhpc3RpbmcucmVzb3VyY2VJZCAhPT0gb3B0cy5yZXNvdXJjZUlkKSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwicmVuYW1lOm5vdC1vd25lZFwiLCB7XG4gICAgICBhZ2VudElkOiBvcHRzLmFnZW50LmlkLFxuICAgICAgdGhyZWFkSWQ6IG9wdHMudGhyZWFkSWQsXG4gICAgICBmb3VuZDogZXhpc3RpbmcgIT09IG51bGwsXG4gICAgfSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgdXBkYXRlZCA9IGF3YWl0IG1lbW9yeS51cGRhdGVUaHJlYWQoe1xuICAgIGlkOiBvcHRzLnRocmVhZElkLFxuICAgIHRpdGxlOiBvcHRzLnRpdGxlLFxuICAgIG1ldGFkYXRhOiBleGlzdGluZy5tZXRhZGF0YSA/PyB7fSxcbiAgfSk7XG4gIGxvZ2dlci5pbmZvKFwicmVuYW1lOmRvbmVcIiwge1xuICAgIGFnZW50SWQ6IG9wdHMuYWdlbnQuaWQsXG4gICAgdGhyZWFkSWQ6IG9wdHMudGhyZWFkSWQsXG4gICAgZWxhcHNlZE1zOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0LFxuICB9KTtcbiAgcmV0dXJuIHRvV2lyZVRocmVhZCh1cGRhdGVkKTtcbn1cblxuLyoqIE9wdGlvbnMgYWNjZXB0ZWQgYnkge0BsaW5rIHRocmVhZHNSb3V0ZX0uICovXG5leHBvcnQgdHlwZSBUaHJlYWRzUm91dGVPcHRpb25zID1cbiAgeyBwYXRoOiBgJHtzdHJpbmd9OmFnZW50SWQke3N0cmluZ31gOyBhZ2VudD86IG5ldmVyIH0gfCB7IHBhdGg6IHN0cmluZzsgYWdlbnQ6IHN0cmluZyB9O1xuXG4vKipcbiAqIFJlZ2lzdGVyIHRoZSBgPHBhdGg+YCBNYXN0cmEgY3VzdG9tIEFQSSByb3V0ZS4gSGFuZGxlcyB0aHJlZSBtZXRob2RzXG4gKiBvbiB0aGUgc2FtZSBtb3VudDpcbiAqXG4gKiAgIC0gYEdFVGA6IGEgcGFnZSBvZiB0aGUgcmVzb3VyY2UncyBjb252ZXJzYXRpb24gdGhyZWFkc1xuICogICAgICh7QGxpbmsgbGlzdFRocmVhZHN9KS5cbiAqICAgLSBgREVMRVRFYDogcmVtb3ZlIHRoZSB0aHJlYWQgbmFtZWQgYnkgdGhlIHRocmVhZC1zZWxlY3Rpb24gaGVhZGVyXG4gKiAgICAgLyBgP3RocmVhZElkPWAgcXVlcnkgKHtAbGluayBkZWxldGVUaHJlYWR9KS4gVGhlIGlkIGlzIHJlYWQgZnJvbVxuICogICAgIGBSZXF1ZXN0Q29udGV4dGAgKHRoZSBhdXRoIG1pZGRsZXdhcmUgcmVzb2x2ZXMgaXQgdGhlIHNhbWUgd2F5IGl0XG4gKiAgICAgZG9lcyBmb3Igc3RyZWFtaW5nIGFuZCBoaXN0b3J5KSwgc28gdGhlIGNsaWVudCBkZWxldGVzIGFueSBvZiBpdHNcbiAqICAgICB0aHJlYWRzIGJ5IHN0YW1waW5nIHRoZSB0YXJnZXQgaWQgLSBubyBzZXBhcmF0ZSBwYXRoIHBhcmFtLlxuICogICAtIGBQQVRDSGA6IHJlbmFtZSB0aGUgdGhyZWFkIG5hbWVkIGJ5IHRoZSB0aHJlYWQtc2VsZWN0aW9uIGhlYWRlciAvXG4gKiAgICAgYD90aHJlYWRJZD1gIHF1ZXJ5IHRvIHRoZSBgeyB0aXRsZSB9YCBpbiB0aGUgSlNPTiBib2R5XG4gKiAgICAgKHtAbGluayByZW5hbWVUaHJlYWR9KS4gVGFyZ2V0cyBhIHRocmVhZCB0aGUgc2FtZSB3YXkgYERFTEVURWBcbiAqICAgICBkb2VzOyA0MDRzIHdoZW4gdGhlIHRocmVhZCBpc24ndCBvd25lZCBieSB0aGUgY2FsbGVyLlxuICpcbiAqIEZvbGxvd3MgdGhlIGBAbWFzdHJhL2FpLXNka2AgYWdlbnQtYmluZGluZyBjb252ZW50aW9uOiBwYXNzIGBhZ2VudGBcbiAqIGZvciBhIGZpeGVkLWFnZW50IG1vdW50LCBvciBpbmNsdWRlIGA6YWdlbnRJZGAgaW4gdGhlIHBhdGggZm9yXG4gKiBkeW5hbWljIHJvdXRpbmcuIFRoZSBwbHVnaW4gcmVnaXN0ZXJzIGJvdGggYC9yb3V0ZS90aHJlYWRzYCAoZGVmYXVsdFxuICogYWdlbnQpIGFuZCBgL3JvdXRlL3RocmVhZHMvOmFnZW50SWRgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdGhyZWFkc1JvdXRlKG9wdGlvbnM6IFRocmVhZHNSb3V0ZU9wdGlvbnMpIHtcbiAgY29uc3QgeyBwYXRoIH0gPSBvcHRpb25zO1xuICBjb25zdCBmaXhlZEFnZW50ID0gXCJhZ2VudFwiIGluIG9wdGlvbnMgPyBvcHRpb25zLmFnZW50IDogdW5kZWZpbmVkO1xuICBpZiAoIWZpeGVkQWdlbnQgJiYgIXBhdGguaW5jbHVkZXMoXCI6YWdlbnRJZFwiKSkge1xuICAgIHRocm93IFZhbGlkYXRpb25FcnJvci5pbnZhbGlkVmFsdWUoXG4gICAgICBcInRocmVhZHNSb3V0ZS5wYXRoXCIsXG4gICAgICBwYXRoLFxuICAgICAgXCJhIHBhdGggY29udGFpbmluZyBgOmFnZW50SWRgLCBvciBhbiBleHBsaWNpdCBgYWdlbnRgXCIsXG4gICAgKTtcbiAgfVxuICAvLyBTaGFyZWQgYnkgR0VUIC8gREVMRVRFOiByZXNvbHZlIHRoZSBhY3RpdmUgYWdlbnQgYW5kIHRoZSBjYWxsZXInc1xuICAvLyByZXNvdXJjZSBpZCwgcmV0dXJuaW5nIGEgSlNPTiBlcnJvciByZXNwb25zZSB3aGVuIGVpdGhlciBpc1xuICAvLyBtaXNzaW5nLiBLZWVwcyBib3RoIGhhbmRsZXJzIHRoaW4gd2l0aCBpZGVudGljYWwgdmFsaWRhdGlvbi5cbiAgY29uc3QgcmVzb2x2ZUNvbnRleHQgPSAoYzogQ29udGV4dFdpdGhNYXN0cmEpID0+IHtcbiAgICBjb25zdCBtYXN0cmEgPSBjLmdldChcIm1hc3RyYVwiKTtcbiAgICBjb25zdCByZXF1ZXN0Q29udGV4dCA9IGMuZ2V0KFwicmVxdWVzdENvbnRleHRcIik7XG4gICAgY29uc3QgYWdlbnRJZCA9IGZpeGVkQWdlbnQgPz8gYy5yZXEucGFyYW0oXCJhZ2VudElkXCIpO1xuICAgIGlmICghYWdlbnRJZCkge1xuICAgICAgcmV0dXJuIHsgZXJyb3I6IGMuanNvbih7IGVycm9yOiBcImFnZW50SWQgaXMgcmVxdWlyZWRcIiB9LCA0MDApIH0gYXMgY29uc3Q7XG4gICAgfVxuICAgIGNvbnN0IGFnZW50ID0gbWFzdHJhLmdldEFnZW50QnlJZChhZ2VudElkKTtcbiAgICBpZiAoIWFnZW50KSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlcnJvcjogYy5qc29uKHsgZXJyb3I6IGBVbmtub3duIGFnZW50IFwiJHthZ2VudElkfVwiYCB9LCA0MDQpLFxuICAgICAgfSBhcyBjb25zdDtcbiAgICB9XG4gICAgY29uc3QgcmVzb3VyY2VJZCA9IHJlcXVlc3RDb250ZXh0LmdldChNQVNUUkFfUkVTT1VSQ0VfSURfS0VZKSBhcyBzdHJpbmcgfCB1bmRlZmluZWQ7XG4gICAgaWYgKCFyZXNvdXJjZUlkKSB7XG4gICAgICByZXR1cm4ge1xuICAgICAgICBlcnJvcjogYy5qc29uKHsgZXJyb3I6IFwicmVzb3VyY2UgaWQgbWlzc2luZyBmcm9tIHJlcXVlc3QgY29udGV4dFwiIH0sIDQwMCksXG4gICAgICB9IGFzIGNvbnN0O1xuICAgIH1cbiAgICByZXR1cm4geyBhZ2VudElkLCBhZ2VudCwgcmVxdWVzdENvbnRleHQsIHJlc291cmNlSWQgfSBhcyBjb25zdDtcbiAgfTtcblxuICByZXR1cm4gW1xuICAgIHJlZ2lzdGVyQXBpUm91dGUocGF0aCwge1xuICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKGM6IENvbnRleHRXaXRoTWFzdHJhKSA9PiB7XG4gICAgICAgIGNvbnN0IGN0eCA9IHJlc29sdmVDb250ZXh0KGMpO1xuICAgICAgICBpZiAoXCJlcnJvclwiIGluIGN0eCkgcmV0dXJuIGN0eC5lcnJvcjtcbiAgICAgICAgY29uc3QgcGF5bG9hZCA9IGF3YWl0IGxpc3RUaHJlYWRzKHtcbiAgICAgICAgICBhZ2VudDogY3R4LmFnZW50LFxuICAgICAgICAgIHJlc291cmNlSWQ6IGN0eC5yZXNvdXJjZUlkLFxuICAgICAgICAgIHBhZ2U6IHBhcnNlSW50UGFyYW0oYy5yZXEucXVlcnkoXCJwYWdlXCIpKSxcbiAgICAgICAgICBwZXJQYWdlOiBwYXJzZUludFBhcmFtKGMucmVxLnF1ZXJ5KFwicGVyUGFnZVwiKSksXG4gICAgICAgIH0pO1xuICAgICAgICByZXR1cm4gYy5qc29uKHBheWxvYWQpO1xuICAgICAgfSxcbiAgICB9KSxcbiAgICByZWdpc3RlckFwaVJvdXRlKHBhdGgsIHtcbiAgICAgIG1ldGhvZDogXCJERUxFVEVcIixcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChjOiBDb250ZXh0V2l0aE1hc3RyYSkgPT4ge1xuICAgICAgICBjb25zdCBjdHggPSByZXNvbHZlQ29udGV4dChjKTtcbiAgICAgICAgaWYgKFwiZXJyb3JcIiBpbiBjdHgpIHJldHVybiBjdHguZXJyb3I7XG4gICAgICAgIGNvbnN0IHRocmVhZElkID0gY3R4LnJlcXVlc3RDb250ZXh0LmdldChNQVNUUkFfVEhSRUFEX0lEX0tFWSkgYXMgc3RyaW5nIHwgdW5kZWZpbmVkO1xuICAgICAgICBpZiAoIXRocmVhZElkKSB7XG4gICAgICAgICAgcmV0dXJuIGMuanNvbih7IGVycm9yOiBcInRocmVhZCBpZCBtaXNzaW5nIGZyb20gcmVxdWVzdCBjb250ZXh0XCIgfSwgNDAwKTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCB7IGRlbGV0ZWQgfSA9IGF3YWl0IGRlbGV0ZVRocmVhZCh7XG4gICAgICAgICAgYWdlbnQ6IGN0eC5hZ2VudCxcbiAgICAgICAgICB0aHJlYWRJZCxcbiAgICAgICAgICByZXNvdXJjZUlkOiBjdHgucmVzb3VyY2VJZCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IE1hc3RyYURlbGV0ZVRocmVhZFJlc3BvbnNlID0ge1xuICAgICAgICAgIG9rOiB0cnVlLFxuICAgICAgICAgIGFnZW50SWQ6IGN0eC5hZ2VudElkLFxuICAgICAgICAgIHRocmVhZElkLFxuICAgICAgICAgIGRlbGV0ZWQsXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBjLmpzb24ocGF5bG9hZCk7XG4gICAgICB9LFxuICAgIH0pLFxuICAgIHJlZ2lzdGVyQXBpUm91dGUocGF0aCwge1xuICAgICAgbWV0aG9kOiBcIlBBVENIXCIsXG4gICAgICBoYW5kbGVyOiBhc3luYyAoYzogQ29udGV4dFdpdGhNYXN0cmEpID0+IHtcbiAgICAgICAgY29uc3QgY3R4ID0gcmVzb2x2ZUNvbnRleHQoYyk7XG4gICAgICAgIGlmIChcImVycm9yXCIgaW4gY3R4KSByZXR1cm4gY3R4LmVycm9yO1xuICAgICAgICBjb25zdCB0aHJlYWRJZCA9IGN0eC5yZXF1ZXN0Q29udGV4dC5nZXQoTUFTVFJBX1RIUkVBRF9JRF9LRVkpIGFzIHN0cmluZyB8IHVuZGVmaW5lZDtcbiAgICAgICAgaWYgKCF0aHJlYWRJZCkge1xuICAgICAgICAgIHJldHVybiBjLmpzb24oeyBlcnJvcjogXCJ0aHJlYWQgaWQgbWlzc2luZyBmcm9tIHJlcXVlc3QgY29udGV4dFwiIH0sIDQwMCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgYm9keSA9IHdpcmUuTWFzdHJhVXBkYXRlVGhyZWFkUmVxdWVzdFNjaGVtYS5zYWZlUGFyc2UoYXdhaXQgYy5yZXEuanNvbigpKTtcbiAgICAgICAgaWYgKCFib2R5LnN1Y2Nlc3MpIHtcbiAgICAgICAgICBsb2dnZXIud2FybihcInJlbmFtZTppbnZhbGlkXCIsIHsgZXJyb3I6IGJvZHkuZXJyb3IubWVzc2FnZSB9KTtcbiAgICAgICAgICByZXR1cm4gYy5qc29uKHsgZXJyb3I6IElOVkFMSURfUkVOQU1FX01FU1NBR0UsIGZpZWxkczogaW52YWxpZEZpZWxkcyhib2R5LmVycm9yKSB9LCA0MDApO1xuICAgICAgICB9XG4gICAgICAgIGNvbnN0IHRocmVhZCA9IGF3YWl0IHJlbmFtZVRocmVhZCh7XG4gICAgICAgICAgYWdlbnQ6IGN0eC5hZ2VudCxcbiAgICAgICAgICB0aHJlYWRJZCxcbiAgICAgICAgICByZXNvdXJjZUlkOiBjdHgucmVzb3VyY2VJZCxcbiAgICAgICAgICB0aXRsZTogYm9keS5kYXRhLnRpdGxlLFxuICAgICAgICB9KTtcbiAgICAgICAgaWYgKCF0aHJlYWQpIHtcbiAgICAgICAgICByZXR1cm4gYy5qc29uKHsgZXJyb3I6IGBVbmtub3duIHRocmVhZCBcIiR7dGhyZWFkSWR9XCJgIH0sIDQwNCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgcGF5bG9hZDogTWFzdHJhVXBkYXRlVGhyZWFkUmVzcG9uc2UgPSB7XG4gICAgICAgICAgb2s6IHRydWUsXG4gICAgICAgICAgYWdlbnRJZDogY3R4LmFnZW50SWQsXG4gICAgICAgICAgdGhyZWFkLFxuICAgICAgICB9O1xuICAgICAgICByZXR1cm4gYy5qc29uKHBheWxvYWQpO1xuICAgICAgfSxcbiAgICB9KSxcbiAgXTtcbn1cblxuLyoqIENvZXJjZSBhIE1hc3RyYSBgU3RvcmFnZVRocmVhZFR5cGVgIGludG8gdGhlIEpTT04tc2FmZSB3aXJlIHNoYXBlLiAqL1xuZnVuY3Rpb24gdG9XaXJlVGhyZWFkKHRocmVhZDogU3RvcmFnZVRocmVhZFR5cGUpOiBNYXN0cmFUaHJlYWQge1xuICByZXR1cm4ge1xuICAgIGlkOiB0aHJlYWQuaWQsXG4gICAgLi4uKHRocmVhZC50aXRsZSA/IHsgdGl0bGU6IHRocmVhZC50aXRsZSB9IDoge30pLFxuICAgIHJlc291cmNlSWQ6IHRocmVhZC5yZXNvdXJjZUlkLFxuICAgIGNyZWF0ZWRBdDogdG9Jc28odGhyZWFkLmNyZWF0ZWRBdCksXG4gICAgdXBkYXRlZEF0OiB0b0lzbyh0aHJlYWQudXBkYXRlZEF0KSxcbiAgICAuLi4odGhyZWFkLm1ldGFkYXRhID8geyBtZXRhZGF0YTogdGhyZWFkLm1ldGFkYXRhIH0gOiB7fSksXG4gIH07XG59XG5cbi8qKiBSZW5kZXIgYSBzdG9yYWdlIHRpbWVzdGFtcCBhcyBhbiBJU08tODYwMSBzdHJpbmcgZm9yIHRoZSB3aXJlLiAqL1xuZnVuY3Rpb24gdG9Jc28odmFsdWU6IERhdGUgfCBzdHJpbmcgfCBudW1iZXIpOiBzdHJpbmcge1xuICBpZiAodmFsdWUgaW5zdGFuY2VvZiBEYXRlKSByZXR1cm4gdmFsdWUudG9JU09TdHJpbmcoKTtcbiAgY29uc3QgcGFyc2VkID0gbmV3IERhdGUodmFsdWUpO1xuICByZXR1cm4gTnVtYmVyLmlzTmFOKHBhcnNlZC5nZXRUaW1lKCkpID8gbmV3IERhdGUoMCkudG9JU09TdHJpbmcoKSA6IHBhcnNlZC50b0lTT1N0cmluZygpO1xufVxuIl19
264
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoidGhyZWFkcy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy90aHJlYWRzLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBOzs7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7R0FxQkc7QUFFSCxPQUFPLEVBQUUsR0FBRyxFQUFFLE1BQU0sd0JBQXdCLENBQUM7QUFDN0MsT0FBTyxFQUNMLElBQUksR0FLTCxNQUFNLDBCQUEwQixDQUFDO0FBSWxDLE9BQU8sRUFBRSxnQkFBZ0IsRUFBRSxNQUFNLHFCQUFxQixDQUFDO0FBRXZELE9BQU8sRUFDTCwwQkFBMEIsRUFDMUIsd0JBQXdCLEdBRXpCLE1BQU0sMkJBQTJCLENBQUM7QUFDbkMsT0FBTyxFQUFFLFlBQVksRUFBRSxhQUFhLEVBQUUsTUFBTSxpQkFBaUIsQ0FBQztBQUM5RCxPQUFPLEVBQUUsYUFBYSxFQUFFLE1BQU0saUJBQWlCLENBQUM7QUFFaEQsTUFBTSxNQUFNLEdBQUcsR0FBRyxDQUFDLE1BQU0sQ0FBQyxnQkFBZ0IsQ0FBQyxDQUFDO0FBRTVDLGlDQUFpQztBQUNqQyxNQUFNLGdCQUFnQixHQUFHLEVBQUUsQ0FBQztBQUM1Qix5RUFBeUU7QUFDekUsTUFBTSxZQUFZLEdBQUcsR0FBRyxDQUFDO0FBQ3pCLDRFQUE0RTtBQUM1RSxNQUFNLHNCQUFzQixHQUFHLCtCQUErQixDQUFDO0FBVS9EOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxXQUFXLENBQUMsSUFBd0I7SUFDeEQsTUFBTSxPQUFPLEdBQUcsWUFBWSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUU7UUFDekMsUUFBUSxFQUFFLGdCQUFnQjtRQUMxQixHQUFHLEVBQUUsWUFBWTtLQUNsQixDQUFDLENBQUM7SUFDSCxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsR0FBRyxDQUFDLENBQUMsRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLElBQUksQ0FBQyxJQUFJLElBQUksQ0FBQyxDQUFDLENBQUMsQ0FBQztJQUNyRCxNQUFNLE1BQU0sR0FBRyxNQUFNLElBQUksQ0FBQyxLQUFLLENBQUMsU0FBUyxFQUFFLENBQUM7SUFDNUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ1osTUFBTSxDQUFDLEtBQUssQ0FBQyxnQkFBZ0IsRUFBRSxFQUFFLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUUsRUFBRSxDQUFDLENBQUM7UUFDM0QsT0FBTyxFQUFFLE9BQU8sRUFBRSxFQUFFLEVBQUUsSUFBSSxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUNsRSxDQUFDO0lBQ0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQzdCLE1BQU0sTUFBTSxHQUFHLE1BQU0sTUFBTSxDQUFDLFdBQVcsQ0FBQztRQUN0QyxNQUFNLEVBQUUsRUFBRSxVQUFVLEVBQUUsSUFBSSxDQUFDLFVBQVUsRUFBRTtRQUN2QyxJQUFJO1FBQ0osT0FBTztRQUNQLE9BQU8sRUFBRSxFQUFFLEtBQUssRUFBRSxXQUFXLEVBQUUsU0FBUyxFQUFFLE1BQU0sRUFBRTtLQUNuRCxDQUFDLENBQUM7SUFDSCxNQUFNLE9BQU8sR0FBRyxNQUFNLENBQUMsT0FBTyxDQUFDLEdBQUcsQ0FBQyxZQUFZLENBQUMsQ0FBQztJQUNqRCxNQUFNLENBQUMsS0FBSyxDQUFDLFdBQVcsRUFBRTtRQUN4QixPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO1FBQ3RCLFVBQVUsRUFBRSxJQUFJLENBQUMsVUFBVTtRQUMzQixJQUFJO1FBQ0osT0FBTztRQUNQLFFBQVEsRUFBRSxPQUFPLENBQUMsTUFBTTtRQUN4QixLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUs7UUFDbkIsT0FBTyxFQUFFLE1BQU0sQ0FBQyxPQUFPO1FBQ3ZCLFNBQVMsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUztLQUNsQyxDQUFDLENBQUM7SUFDSCxPQUFPO1FBQ0wsT0FBTztRQUNQLElBQUk7UUFDSixPQUFPO1FBQ1AsS0FBSyxFQUFFLE1BQU0sQ0FBQyxLQUFLO1FBQ25CLE9BQU8sRUFBRSxNQUFNLENBQUMsT0FBTztLQUN4QixDQUFDO0FBQ0osQ0FBQztBQVNEOzs7Ozs7OztHQVFHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxZQUFZLENBQUMsSUFBeUI7SUFDMUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQzVDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzdELE9BQU8sRUFBRSxPQUFPLEVBQUUsS0FBSyxFQUFFLENBQUM7SUFDNUIsQ0FBQztJQUNELDhEQUE4RDtJQUM5RCxrRUFBa0U7SUFDbEUsTUFBTSxRQUFRLEdBQUcsTUFBTSxNQUFNLENBQUMsYUFBYSxDQUFDLEVBQUUsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDO0lBQ3pFLElBQUksQ0FBQyxRQUFRLElBQUksUUFBUSxDQUFDLFVBQVUsS0FBSyxJQUFJLENBQUMsVUFBVSxFQUFFLENBQUM7UUFDekQsTUFBTSxDQUFDLEtBQUssQ0FBQyxrQkFBa0IsRUFBRTtZQUMvQixPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFO1lBQ3RCLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUTtZQUN2QixLQUFLLEVBQUUsUUFBUSxLQUFLLElBQUk7U0FDekIsQ0FBQyxDQUFDO1FBQ0gsT0FBTyxFQUFFLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBQztJQUM1QixDQUFDO0lBQ0QsTUFBTSxTQUFTLEdBQUcsSUFBSSxDQUFDLEdBQUcsRUFBRSxDQUFDO0lBQzdCLE1BQU0sTUFBTSxDQUFDLFlBQVksQ0FBQyxJQUFJLENBQUMsUUFBUSxDQUFDLENBQUM7SUFDekMsTUFBTSxDQUFDLElBQUksQ0FBQyxhQUFhLEVBQUU7UUFDekIsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtRQUN0QixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7UUFDdkIsU0FBUyxFQUFFLElBQUksQ0FBQyxHQUFHLEVBQUUsR0FBRyxTQUFTO0tBQ2xDLENBQUMsQ0FBQztJQUNILE9BQU8sRUFBRSxPQUFPLEVBQUUsSUFBSSxFQUFFLENBQUM7QUFDM0IsQ0FBQztBQVVEOzs7Ozs7Ozs7OztHQVdHO0FBQ0gsTUFBTSxDQUFDLEtBQUssVUFBVSxZQUFZLENBQUMsSUFBeUI7SUFDMUQsTUFBTSxNQUFNLEdBQUcsTUFBTSxJQUFJLENBQUMsS0FBSyxDQUFDLFNBQVMsRUFBRSxDQUFDO0lBQzVDLElBQUksQ0FBQyxNQUFNLEVBQUUsQ0FBQztRQUNaLE1BQU0sQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEVBQUUsRUFBRSxPQUFPLEVBQUUsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsQ0FBQyxDQUFDO1FBQzdELE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELE1BQU0sUUFBUSxHQUFHLE1BQU0sTUFBTSxDQUFDLGFBQWEsQ0FBQyxFQUFFLFFBQVEsRUFBRSxJQUFJLENBQUMsUUFBUSxFQUFFLENBQUMsQ0FBQztJQUN6RSxJQUFJLENBQUMsUUFBUSxJQUFJLFFBQVEsQ0FBQyxVQUFVLEtBQUssSUFBSSxDQUFDLFVBQVUsRUFBRSxDQUFDO1FBQ3pELE1BQU0sQ0FBQyxLQUFLLENBQUMsa0JBQWtCLEVBQUU7WUFDL0IsT0FBTyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsRUFBRTtZQUN0QixRQUFRLEVBQUUsSUFBSSxDQUFDLFFBQVE7WUFDdkIsS0FBSyxFQUFFLFFBQVEsS0FBSyxJQUFJO1NBQ3pCLENBQUMsQ0FBQztRQUNILE9BQU8sSUFBSSxDQUFDO0lBQ2QsQ0FBQztJQUNELE1BQU0sU0FBUyxHQUFHLElBQUksQ0FBQyxHQUFHLEVBQUUsQ0FBQztJQUM3QixNQUFNLE9BQU8sR0FBRyxNQUFNLE1BQU0sQ0FBQyxZQUFZLENBQUM7UUFDeEMsRUFBRSxFQUFFLElBQUksQ0FBQyxRQUFRO1FBQ2pCLEtBQUssRUFBRSxJQUFJLENBQUMsS0FBSztRQUNqQixRQUFRLEVBQUUsUUFBUSxDQUFDLFFBQVEsSUFBSSxFQUFFO0tBQ2xDLENBQUMsQ0FBQztJQUNILE1BQU0sQ0FBQyxJQUFJLENBQUMsYUFBYSxFQUFFO1FBQ3pCLE9BQU8sRUFBRSxJQUFJLENBQUMsS0FBSyxDQUFDLEVBQUU7UUFDdEIsUUFBUSxFQUFFLElBQUksQ0FBQyxRQUFRO1FBQ3ZCLFNBQVMsRUFBRSxJQUFJLENBQUMsR0FBRyxFQUFFLEdBQUcsU0FBUztLQUNsQyxDQUFDLENBQUM7SUFDSCxPQUFPLFlBQVksQ0FBQyxPQUFPLENBQUMsQ0FBQztBQUMvQixDQUFDO0FBS0Q7Ozs7Ozs7Ozs7Ozs7Ozs7Ozs7O0dBb0JHO0FBQ0gsTUFBTSxVQUFVLFlBQVksQ0FBQyxPQUE0QjtJQUN2RCxNQUFNLEVBQUUsSUFBSSxFQUFFLFVBQVUsRUFBRSxHQUFHLHdCQUF3QixDQUFDLE9BQU8sRUFBRSxtQkFBbUIsQ0FBQyxDQUFDO0lBRXBGLE9BQU87UUFDTCxnQkFBZ0IsQ0FBQyxJQUFJLEVBQUU7WUFDckIsTUFBTSxFQUFFLEtBQUs7WUFDYixPQUFPLEVBQUUsS0FBSyxFQUFFLENBQW9CLEVBQUUsRUFBRTtnQkFDdEMsTUFBTSxHQUFHLEdBQUcsMEJBQTBCLENBQUMsQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLENBQUMsQ0FBQztnQkFDMUQsSUFBSSxPQUFPLElBQUksR0FBRztvQkFBRSxPQUFPLEdBQUcsQ0FBQyxLQUFLLENBQUM7Z0JBQ3JDLE1BQU0sT0FBTyxHQUFHLE1BQU0sV0FBVyxDQUFDO29CQUNoQyxLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUs7b0JBQ2hCLFVBQVUsRUFBRSxHQUFHLENBQUMsVUFBVTtvQkFDMUIsSUFBSSxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxNQUFNLENBQUMsQ0FBQztvQkFDeEMsT0FBTyxFQUFFLGFBQWEsQ0FBQyxDQUFDLENBQUMsR0FBRyxDQUFDLEtBQUssQ0FBQyxTQUFTLENBQUMsQ0FBQztpQkFDL0MsQ0FBQyxDQUFDO2dCQUNILE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN6QixDQUFDO1NBQ0YsQ0FBQztRQUNGLGdCQUFnQixDQUFDLElBQUksRUFBRTtZQUNyQixNQUFNLEVBQUUsUUFBUTtZQUNoQixPQUFPLEVBQUUsS0FBSyxFQUFFLENBQW9CLEVBQUUsRUFBRTtnQkFDdEMsTUFBTSxHQUFHLEdBQUcsMEJBQTBCLENBQUMsQ0FBQyxFQUFFLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxVQUFVLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRixJQUFJLE9BQU8sSUFBSSxHQUFHO29CQUFFLE9BQU8sR0FBRyxDQUFDLEtBQUssQ0FBQztnQkFDckMsTUFBTSxFQUFFLE9BQU8sRUFBRSxHQUFHLE1BQU0sWUFBWSxDQUFDO29CQUNyQyxLQUFLLEVBQUUsR0FBRyxDQUFDLEtBQUs7b0JBQ2hCLFFBQVEsRUFBRSxHQUFHLENBQUMsUUFBUTtvQkFDdEIsVUFBVSxFQUFFLEdBQUcsQ0FBQyxVQUFVO2lCQUMzQixDQUFDLENBQUM7Z0JBQ0gsTUFBTSxPQUFPLEdBQStCO29CQUMxQyxFQUFFLEVBQUUsSUFBSTtvQkFDUixPQUFPLEVBQUUsR0FBRyxDQUFDLE9BQU87b0JBQ3BCLFFBQVEsRUFBRSxHQUFHLENBQUMsUUFBUTtvQkFDdEIsT0FBTztpQkFDUixDQUFDO2dCQUNGLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN6QixDQUFDO1NBQ0YsQ0FBQztRQUNGLGdCQUFnQixDQUFDLElBQUksRUFBRTtZQUNyQixNQUFNLEVBQUUsT0FBTztZQUNmLE9BQU8sRUFBRSxLQUFLLEVBQUUsQ0FBb0IsRUFBRSxFQUFFO2dCQUN0QyxNQUFNLEdBQUcsR0FBRywwQkFBMEIsQ0FBQyxDQUFDLEVBQUUsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxDQUFDLENBQUM7Z0JBQ2hGLElBQUksT0FBTyxJQUFJLEdBQUc7b0JBQUUsT0FBTyxHQUFHLENBQUMsS0FBSyxDQUFDO2dCQUNyQyxNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsK0JBQStCLENBQUMsU0FBUyxDQUFDLE1BQU0sQ0FBQyxDQUFDLEdBQUcsQ0FBQyxJQUFJLEVBQUUsQ0FBQyxDQUFDO2dCQUNoRixJQUFJLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDO29CQUNsQixNQUFNLENBQUMsSUFBSSxDQUFDLGdCQUFnQixFQUFFLEVBQUUsS0FBSyxFQUFFLElBQUksQ0FBQyxLQUFLLENBQUMsT0FBTyxFQUFFLENBQUMsQ0FBQztvQkFDN0QsT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLHNCQUFzQixFQUFFLE1BQU0sRUFBRSxhQUFhLENBQUMsSUFBSSxDQUFDLEtBQUssQ0FBQyxFQUFFLEVBQUUsR0FBRyxDQUFDLENBQUM7Z0JBQzNGLENBQUM7Z0JBQ0QsTUFBTSxNQUFNLEdBQUcsTUFBTSxZQUFZLENBQUM7b0JBQ2hDLEtBQUssRUFBRSxHQUFHLENBQUMsS0FBSztvQkFDaEIsUUFBUSxFQUFFLEdBQUcsQ0FBQyxRQUFRO29CQUN0QixVQUFVLEVBQUUsR0FBRyxDQUFDLFVBQVU7b0JBQzFCLEtBQUssRUFBRSxJQUFJLENBQUMsSUFBSSxDQUFDLEtBQUs7aUJBQ3ZCLENBQUMsQ0FBQztnQkFDSCxJQUFJLENBQUMsTUFBTSxFQUFFLENBQUM7b0JBQ1osT0FBTyxDQUFDLENBQUMsSUFBSSxDQUFDLEVBQUUsS0FBSyxFQUFFLG1CQUFtQixHQUFHLENBQUMsUUFBUSxHQUFHLEVBQUUsRUFBRSxHQUFHLENBQUMsQ0FBQztnQkFDcEUsQ0FBQztnQkFDRCxNQUFNLE9BQU8sR0FBK0I7b0JBQzFDLEVBQUUsRUFBRSxJQUFJO29CQUNSLE9BQU8sRUFBRSxHQUFHLENBQUMsT0FBTztvQkFDcEIsTUFBTTtpQkFDUCxDQUFDO2dCQUNGLE9BQU8sQ0FBQyxDQUFDLElBQUksQ0FBQyxPQUFPLENBQUMsQ0FBQztZQUN6QixDQUFDO1NBQ0YsQ0FBQztLQUNILENBQUM7QUFDSixDQUFDO0FBRUQseUVBQXlFO0FBQ3pFLFNBQVMsWUFBWSxDQUFDLE1BQXlCO0lBQzdDLE9BQU87UUFDTCxFQUFFLEVBQUUsTUFBTSxDQUFDLEVBQUU7UUFDYixHQUFHLENBQUMsTUFBTSxDQUFDLEtBQUssQ0FBQyxDQUFDLENBQUMsRUFBRSxLQUFLLEVBQUUsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFDLENBQUMsQ0FBQyxFQUFFLENBQUM7UUFDaEQsVUFBVSxFQUFFLE1BQU0sQ0FBQyxVQUFVO1FBQzdCLFNBQVMsRUFBRSxLQUFLLENBQUMsTUFBTSxDQUFDLFNBQVMsQ0FBQztRQUNsQyxTQUFTLEVBQUUsS0FBSyxDQUFDLE1BQU0sQ0FBQyxTQUFTLENBQUM7UUFDbEMsR0FBRyxDQUFDLE1BQU0sQ0FBQyxRQUFRLENBQUMsQ0FBQyxDQUFDLEVBQUUsUUFBUSxFQUFFLE1BQU0sQ0FBQyxRQUFRLEVBQUUsQ0FBQyxDQUFDLENBQUMsRUFBRSxDQUFDO0tBQzFELENBQUM7QUFDSixDQUFDO0FBRUQscUVBQXFFO0FBQ3JFLFNBQVMsS0FBSyxDQUFDLEtBQTZCO0lBQzFDLElBQUksS0FBSyxZQUFZLElBQUk7UUFBRSxPQUFPLEtBQUssQ0FBQyxXQUFXLEVBQUUsQ0FBQztJQUN0RCxNQUFNLE1BQU0sR0FBRyxJQUFJLElBQUksQ0FBQyxLQUFLLENBQUMsQ0FBQztJQUMvQixPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUMsQ0FBQyxDQUFDLElBQUksSUFBSSxDQUFDLENBQUMsQ0FBQyxDQUFDLFdBQVcsRUFBRSxDQUFDLENBQUMsQ0FBQyxNQUFNLENBQUMsV0FBVyxFQUFFLENBQUM7QUFDM0YsQ0FBQyIsInNvdXJjZXNDb250ZW50IjpbIi8qKlxuICogQ29udmVyc2F0aW9uLXRocmVhZCBsaXN0aW5nIGV4cG9zZWQgYXMgYSBNYXN0cmEgY3VzdG9tIEFQSSByb3V0ZS5cbiAqXG4gKiBCYWNrZWQgZW50aXJlbHkgYnkgbmF0aXZlIE1hc3RyYTogbG9va3MgdXAgdGhlIGFjdGl2ZSBhZ2VudCBieSBpZCxcbiAqIGFza3MgaXRzIGBNZW1vcnlgIGluc3RhbmNlIHRvIGBsaXN0VGhyZWFkc2AgZmlsdGVyZWQgdG8gdGhlIGNhbGxlcidzXG4gKiByZXNvdXJjZSwgYW5kIHNoYXBlcyBlYWNoIGludG8gdGhlIEpTT04tc2FmZSB7QGxpbmsgTWFzdHJhVGhyZWFkfVxuICogd2lyZSB0eXBlLiBBIHNpYmxpbmcgYERFTEVURWAgcmVtb3ZlcyBhIHNpbmdsZSBuYW1lZCB0aHJlYWQuXG4gKlxuICogQSBzaWJsaW5nIGBERUxFVEVgIHJlbW92ZXMgYSBzaW5nbGUgbmFtZWQgdGhyZWFkOyBhIGBQQVRDSGAgcmVuYW1lc1xuICogb25lICh7QGxpbmsgcmVuYW1lVGhyZWFkfSkuXG4gKlxuICogTGlrZSB7QGxpbmsgaGlzdG9yeVJvdXRlfSB0aGlzIHJlZ2lzdGVycyB0aHJvdWdoIE1hc3RyYSdzXG4gKiBgcmVnaXN0ZXJBcGlSb3V0ZWAgc28gaXQgc2hhcmVzIHRoZSBgTWFzdHJhU2VydmVyYCBhdXRoLW1pZGRsZXdhcmVcbiAqIHBpcGVsaW5lIChpbiBgLi9zZXJ2ZXIudHNgKSwgd2hpY2ggaGFzIGFscmVhZHkgc3RhbXBlZCB0aGUgcmVzb3VyY2VcbiAqIGlkIChgTUFTVFJBX1JFU09VUkNFX0lEX0tFWWApIGFuZCB0aGUgdGFyZ2V0ZWQgdGhyZWFkIGlkXG4gKiAoYE1BU1RSQV9USFJFQURfSURfS0VZYCwgcmVzb2x2ZWQgZnJvbSB0aGUgdGhyZWFkLXNlbGVjdGlvbiBoZWFkZXIgL1xuICogY29va2llKSBvbiBgUmVxdWVzdENvbnRleHRgIGJ5IHRoZSB0aW1lIGEgaGFuZGxlciBydW5zLiBSZXNvdXJjZVxuICogc2NvcGluZyBsaXZlcyBoZXJlIHNvIGEgY2FsbGVyIGNhbiBvbmx5IGV2ZXIgc2VlLCByZW5hbWUsIG9yIGRlbGV0ZVxuICogaXRzIG93biB0aHJlYWRzOyBubyBjb29raWUgb3IgdXNlciBsb29rdXBzIGhhcHBlbiBpbiB0aGlzIG1vZHVsZS5cbiAqXG4gKiBAbW9kdWxlXG4gKi9cblxuaW1wb3J0IHsgbG9nIH0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLWNvcmVcIjtcbmltcG9ydCB7XG4gIHdpcmUsXG4gIHR5cGUgTWFzdHJhRGVsZXRlVGhyZWFkUmVzcG9uc2UsXG4gIHR5cGUgTWFzdHJhVGhyZWFkLFxuICB0eXBlIE1hc3RyYVRocmVhZHNSZXNwb25zZSxcbiAgdHlwZSBNYXN0cmFVcGRhdGVUaHJlYWRSZXNwb25zZSxcbn0gZnJvbSBcIkBkYngtdG9vbHMvc2hhcmVkLW1hc3RyYVwiO1xuaW1wb3J0IHR5cGUgeyBBZ2VudCB9IGZyb20gXCJAbWFzdHJhL2NvcmUvYWdlbnRcIjtcbmltcG9ydCB0eXBlIHsgU3RvcmFnZVRocmVhZFR5cGUgfSBmcm9tIFwiQG1hc3RyYS9jb3JlL21lbW9yeVwiO1xuaW1wb3J0IHR5cGUgeyBDb250ZXh0V2l0aE1hc3RyYSB9IGZyb20gXCJAbWFzdHJhL2NvcmUvc2VydmVyXCI7XG5pbXBvcnQgeyByZWdpc3RlckFwaVJvdXRlIH0gZnJvbSBcIkBtYXN0cmEvY29yZS9zZXJ2ZXJcIjtcblxuaW1wb3J0IHtcbiAgcmVzb2x2ZUFnZW50UmVxdWVzdENvbnRleHQsXG4gIHJlc29sdmVBZ2VudFJvdXRlT3B0aW9ucyxcbiAgdHlwZSBBZ2VudFJvdXRlT3B0aW9ucyxcbn0gZnJvbSBcIi4vX2FnZW50LXJvdXRlLWNvbnRleHQudHNcIjtcbmltcG9ydCB7IGNsYW1wUGVyUGFnZSwgcGFyc2VJbnRQYXJhbSB9IGZyb20gXCIuL3BhZ2luYXRpb24udHNcIjtcbmltcG9ydCB7IGludmFsaWRGaWVsZHMgfSBmcm9tIFwiLi92YWxpZGF0aW9uLnRzXCI7XG5cbmNvbnN0IGxvZ2dlciA9IGxvZy5sb2dnZXIoXCJtYXN0cmEvdGhyZWFkc1wiKTtcblxuLyoqIERlZmF1bHQgdGhyZWFkcyBwYWdlIHNpemUuICovXG5jb25zdCBERUZBVUxUX1BFUl9QQUdFID0gMzA7XG4vKiogSGFyZCBjYXAgc28gYSBtaXNiZWhhdmluZyBjbGllbnQgY2FuJ3QgZmV0Y2ggZXZlcnkgdGhyZWFkIGF0IG9uY2UuICovXG5jb25zdCBNQVhfUEVSX1BBR0UgPSAyMDA7XG4vKiogU3RhYmxlIGNsaWVudCBtZXNzYWdlIGZvciBhIHJlbmFtZSBib2R5IHRoYXQgZmFpbHMgc2NoZW1hIHZhbGlkYXRpb24uICovXG5jb25zdCBJTlZBTElEX1JFTkFNRV9NRVNTQUdFID0gXCJJbnZhbGlkIHRocmVhZCByZW5hbWUgcmVxdWVzdFwiO1xuXG4vKiogSW5wdXRzIGFjY2VwdGVkIGJ5IHtAbGluayBsaXN0VGhyZWFkc30uICovXG5leHBvcnQgaW50ZXJmYWNlIExpc3RUaHJlYWRzT3B0aW9ucyB7XG4gIGFnZW50OiBBZ2VudDtcbiAgcmVzb3VyY2VJZDogc3RyaW5nO1xuICBwYWdlPzogbnVtYmVyO1xuICBwZXJQYWdlPzogbnVtYmVyO1xufVxuXG4vKipcbiAqIEZldGNoIGEgcGFnZSBvZiB0aGUgcmVzb3VyY2UncyBjb252ZXJzYXRpb24gdGhyZWFkcywgbmV3ZXN0XG4gKiAoYHVwZGF0ZWRBdGAgREVTQykgZmlyc3QuXG4gKlxuICogVXNlcyB0aGUgYWdlbnQncyByZXNvbHZlZCBgTWVtb3J5YCAoYGdldE1lbW9yeSgpYCkgc28gdGhlIHBlci1hZ2VudFxuICogc3RvcmFnZSBuYW1lc3BhY2UgKGBtYXN0cmFfPGFnZW50SWQ+YCBzY2hlbWEpIGFwcGxpZXMgYXV0b21hdGljYWxseS5cbiAqIFdoZW4gdGhlIGFnZW50IGhhcyBubyBtZW1vcnkgY29uZmlndXJlZCB0aGUgcmVzcG9uc2UgaXMgYSBzdWNjZXNzZnVsXG4gKiBlbXB0eSBwYWdlIHNvIGNhbGxlcnMgZG9uJ3QgaGF2ZSB0byBzcGVjaWFsLWNhc2Ugc3RhdGVsZXNzIGFnZW50cy5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGxpc3RUaHJlYWRzKG9wdHM6IExpc3RUaHJlYWRzT3B0aW9ucyk6IFByb21pc2U8TWFzdHJhVGhyZWFkc1Jlc3BvbnNlPiB7XG4gIGNvbnN0IHBlclBhZ2UgPSBjbGFtcFBlclBhZ2Uob3B0cy5wZXJQYWdlLCB7XG4gICAgZmFsbGJhY2s6IERFRkFVTFRfUEVSX1BBR0UsXG4gICAgbWF4OiBNQVhfUEVSX1BBR0UsXG4gIH0pO1xuICBjb25zdCBwYWdlID0gTWF0aC5tYXgoMCwgTWF0aC50cnVuYyhvcHRzLnBhZ2UgPz8gMCkpO1xuICBjb25zdCBtZW1vcnkgPSBhd2FpdCBvcHRzLmFnZW50LmdldE1lbW9yeSgpO1xuICBpZiAoIW1lbW9yeSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImxpc3Q6bm8tbWVtb3J5XCIsIHsgYWdlbnRJZDogb3B0cy5hZ2VudC5pZCB9KTtcbiAgICByZXR1cm4geyB0aHJlYWRzOiBbXSwgcGFnZSwgcGVyUGFnZSwgdG90YWw6IDAsIGhhc01vcmU6IGZhbHNlIH07XG4gIH1cbiAgY29uc3Qgc3RhcnRlZEF0ID0gRGF0ZS5ub3coKTtcbiAgY29uc3QgcmVzdWx0ID0gYXdhaXQgbWVtb3J5Lmxpc3RUaHJlYWRzKHtcbiAgICBmaWx0ZXI6IHsgcmVzb3VyY2VJZDogb3B0cy5yZXNvdXJjZUlkIH0sXG4gICAgcGFnZSxcbiAgICBwZXJQYWdlLFxuICAgIG9yZGVyQnk6IHsgZmllbGQ6IFwidXBkYXRlZEF0XCIsIGRpcmVjdGlvbjogXCJERVNDXCIgfSxcbiAgfSk7XG4gIGNvbnN0IHRocmVhZHMgPSByZXN1bHQudGhyZWFkcy5tYXAodG9XaXJlVGhyZWFkKTtcbiAgbG9nZ2VyLmRlYnVnKFwibGlzdDpkb25lXCIsIHtcbiAgICBhZ2VudElkOiBvcHRzLmFnZW50LmlkLFxuICAgIHJlc291cmNlSWQ6IG9wdHMucmVzb3VyY2VJZCxcbiAgICBwYWdlLFxuICAgIHBlclBhZ2UsXG4gICAgcmV0dXJuZWQ6IHRocmVhZHMubGVuZ3RoLFxuICAgIHRvdGFsOiByZXN1bHQudG90YWwsXG4gICAgaGFzTW9yZTogcmVzdWx0Lmhhc01vcmUsXG4gICAgZWxhcHNlZE1zOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0LFxuICB9KTtcbiAgcmV0dXJuIHtcbiAgICB0aHJlYWRzLFxuICAgIHBhZ2UsXG4gICAgcGVyUGFnZSxcbiAgICB0b3RhbDogcmVzdWx0LnRvdGFsLFxuICAgIGhhc01vcmU6IHJlc3VsdC5oYXNNb3JlLFxuICB9O1xufVxuXG4vKiogSW5wdXRzIGFjY2VwdGVkIGJ5IHtAbGluayBkZWxldGVUaHJlYWR9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBEZWxldGVUaHJlYWRPcHRpb25zIHtcbiAgYWdlbnQ6IEFnZW50O1xuICB0aHJlYWRJZDogc3RyaW5nO1xuICByZXNvdXJjZUlkOiBzdHJpbmc7XG59XG5cbi8qKlxuICogRGVsZXRlIGEgc2luZ2xlIG5hbWVkIHRocmVhZCAoYW5kIGV2ZXJ5IG1lc3NhZ2Ugb24gaXQpLlxuICpcbiAqIE93bmVyc2hpcCBpcyBlbmZvcmNlZDogdGhlIHRocmVhZCBpcyBvbmx5IHJlbW92ZWQgd2hlbiBpdCBiZWxvbmdzIHRvXG4gKiB0aGUgY2FsbGluZyByZXNvdXJjZSwgc28gYSBjbGllbnQgY2FuJ3QgZGVsZXRlIGFub3RoZXIgdXNlcidzXG4gKiBjb252ZXJzYXRpb24gYnkgZ3Vlc3NpbmcgaXRzIGlkLiBBIHRocmVhZCB0aGF0IGRvZXNuJ3QgZXhpc3QgKG9yXG4gKiBpc24ndCBvd25lZCBieSB0aGUgY2FsbGVyKSBpcyBhIHN1Y2Nlc3NmdWwgbm8tb3AgKGBkZWxldGVkOiBmYWxzZWApXG4gKiBzbyB0aGUgVUkgY2FuIGZpcmUtYW5kLWZvcmdldC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIGRlbGV0ZVRocmVhZChvcHRzOiBEZWxldGVUaHJlYWRPcHRpb25zKTogUHJvbWlzZTx7IGRlbGV0ZWQ6IGJvb2xlYW4gfT4ge1xuICBjb25zdCBtZW1vcnkgPSBhd2FpdCBvcHRzLmFnZW50LmdldE1lbW9yeSgpO1xuICBpZiAoIW1lbW9yeSkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcImRlbGV0ZTpuby1tZW1vcnlcIiwgeyBhZ2VudElkOiBvcHRzLmFnZW50LmlkIH0pO1xuICAgIHJldHVybiB7IGRlbGV0ZWQ6IGZhbHNlIH07XG4gIH1cbiAgLy8gQ29uZmlybSB0aGUgdGhyZWFkIGV4aXN0cyBhbmQgaXMgb3duZWQgYnkgdGhlIGNhbGxlciBiZWZvcmVcbiAgLy8gZGVsZXRpbmc7IG5ldmVyIGxldCBhIGd1ZXNzZWQgaWQgdG91Y2ggYW5vdGhlciByZXNvdXJjZSdzIGRhdGEuXG4gIGNvbnN0IGV4aXN0aW5nID0gYXdhaXQgbWVtb3J5LmdldFRocmVhZEJ5SWQoeyB0aHJlYWRJZDogb3B0cy50aHJlYWRJZCB9KTtcbiAgaWYgKCFleGlzdGluZyB8fCBleGlzdGluZy5yZXNvdXJjZUlkICE9PSBvcHRzLnJlc291cmNlSWQpIHtcbiAgICBsb2dnZXIuZGVidWcoXCJkZWxldGU6bm90LW93bmVkXCIsIHtcbiAgICAgIGFnZW50SWQ6IG9wdHMuYWdlbnQuaWQsXG4gICAgICB0aHJlYWRJZDogb3B0cy50aHJlYWRJZCxcbiAgICAgIGZvdW5kOiBleGlzdGluZyAhPT0gbnVsbCxcbiAgICB9KTtcbiAgICByZXR1cm4geyBkZWxldGVkOiBmYWxzZSB9O1xuICB9XG4gIGNvbnN0IHN0YXJ0ZWRBdCA9IERhdGUubm93KCk7XG4gIGF3YWl0IG1lbW9yeS5kZWxldGVUaHJlYWQob3B0cy50aHJlYWRJZCk7XG4gIGxvZ2dlci5pbmZvKFwiZGVsZXRlOmRvbmVcIiwge1xuICAgIGFnZW50SWQ6IG9wdHMuYWdlbnQuaWQsXG4gICAgdGhyZWFkSWQ6IG9wdHMudGhyZWFkSWQsXG4gICAgZWxhcHNlZE1zOiBEYXRlLm5vdygpIC0gc3RhcnRlZEF0LFxuICB9KTtcbiAgcmV0dXJuIHsgZGVsZXRlZDogdHJ1ZSB9O1xufVxuXG4vKiogSW5wdXRzIGFjY2VwdGVkIGJ5IHtAbGluayByZW5hbWVUaHJlYWR9LiAqL1xuZXhwb3J0IGludGVyZmFjZSBSZW5hbWVUaHJlYWRPcHRpb25zIHtcbiAgYWdlbnQ6IEFnZW50O1xuICB0aHJlYWRJZDogc3RyaW5nO1xuICByZXNvdXJjZUlkOiBzdHJpbmc7XG4gIHRpdGxlOiBzdHJpbmc7XG59XG5cbi8qKlxuICogUmVuYW1lIGEgc2luZ2xlIHRocmVhZCwgcmV0dXJuaW5nIHRoZSB1cGRhdGVkIHdpcmUgdGhyZWFkLlxuICpcbiAqIE93bmVyc2hpcCBpcyBlbmZvcmNlZCB0aGUgc2FtZSB3YXkge0BsaW5rIGRlbGV0ZVRocmVhZH0gZW5mb3JjZXMgaXQ6XG4gKiB0aGUgdGl0bGUgaXMgb25seSBjaGFuZ2VkIHdoZW4gdGhlIHRocmVhZCBiZWxvbmdzIHRvIHRoZSBjYWxsaW5nXG4gKiByZXNvdXJjZSwgc28gYSBjbGllbnQgY2FuJ3QgcmVuYW1lIGFub3RoZXIgdXNlcidzIGNvbnZlcnNhdGlvbiBieVxuICogZ3Vlc3NpbmcgaXRzIGlkLiBFeGlzdGluZyB0aHJlYWQgYG1ldGFkYXRhYCBpcyBwcmVzZXJ2ZWQgdW50b3VjaGVkXG4gKiAoTWFzdHJhJ3MgYHVwZGF0ZVRocmVhZGAgcmVwbGFjZXMgdGhlIHJvdywgc28gaXQgbXVzdCBiZSBwYXNzZWQgYmFja1xuICogaW4pLiBSZXR1cm5zIGBudWxsYCB3aGVuIHRoZSB0aHJlYWQgZG9lc24ndCBleGlzdCwgaXNuJ3Qgb3duZWQgYnkgdGhlXG4gKiBjYWxsZXIsIG9yIHRoZSBhZ2VudCBoYXMgbm8gbWVtb3J5IGNvbmZpZ3VyZWQsIGxldHRpbmcgdGhlIHJvdXRlIG1hcFxuICogdGhhdCB0byBhIDQwNC5cbiAqL1xuZXhwb3J0IGFzeW5jIGZ1bmN0aW9uIHJlbmFtZVRocmVhZChvcHRzOiBSZW5hbWVUaHJlYWRPcHRpb25zKTogUHJvbWlzZTxNYXN0cmFUaHJlYWQgfCBudWxsPiB7XG4gIGNvbnN0IG1lbW9yeSA9IGF3YWl0IG9wdHMuYWdlbnQuZ2V0TWVtb3J5KCk7XG4gIGlmICghbWVtb3J5KSB7XG4gICAgbG9nZ2VyLmRlYnVnKFwicmVuYW1lOm5vLW1lbW9yeVwiLCB7IGFnZW50SWQ6IG9wdHMuYWdlbnQuaWQgfSk7XG4gICAgcmV0dXJuIG51bGw7XG4gIH1cbiAgY29uc3QgZXhpc3RpbmcgPSBhd2FpdCBtZW1vcnkuZ2V0VGhyZWFkQnlJZCh7IHRocmVhZElkOiBvcHRzLnRocmVhZElkIH0pO1xuICBpZiAoIWV4aXN0aW5nIHx8IGV4aXN0aW5nLnJlc291cmNlSWQgIT09IG9wdHMucmVzb3VyY2VJZCkge1xuICAgIGxvZ2dlci5kZWJ1ZyhcInJlbmFtZTpub3Qtb3duZWRcIiwge1xuICAgICAgYWdlbnRJZDogb3B0cy5hZ2VudC5pZCxcbiAgICAgIHRocmVhZElkOiBvcHRzLnRocmVhZElkLFxuICAgICAgZm91bmQ6IGV4aXN0aW5nICE9PSBudWxsLFxuICAgIH0pO1xuICAgIHJldHVybiBudWxsO1xuICB9XG4gIGNvbnN0IHN0YXJ0ZWRBdCA9IERhdGUubm93KCk7XG4gIGNvbnN0IHVwZGF0ZWQgPSBhd2FpdCBtZW1vcnkudXBkYXRlVGhyZWFkKHtcbiAgICBpZDogb3B0cy50aHJlYWRJZCxcbiAgICB0aXRsZTogb3B0cy50aXRsZSxcbiAgICBtZXRhZGF0YTogZXhpc3RpbmcubWV0YWRhdGEgPz8ge30sXG4gIH0pO1xuICBsb2dnZXIuaW5mbyhcInJlbmFtZTpkb25lXCIsIHtcbiAgICBhZ2VudElkOiBvcHRzLmFnZW50LmlkLFxuICAgIHRocmVhZElkOiBvcHRzLnRocmVhZElkLFxuICAgIGVsYXBzZWRNczogRGF0ZS5ub3coKSAtIHN0YXJ0ZWRBdCxcbiAgfSk7XG4gIHJldHVybiB0b1dpcmVUaHJlYWQodXBkYXRlZCk7XG59XG5cbi8qKiBPcHRpb25zIGFjY2VwdGVkIGJ5IHtAbGluayB0aHJlYWRzUm91dGV9LiAqL1xuZXhwb3J0IHR5cGUgVGhyZWFkc1JvdXRlT3B0aW9ucyA9IEFnZW50Um91dGVPcHRpb25zO1xuXG4vKipcbiAqIFJlZ2lzdGVyIHRoZSBgPHBhdGg+YCBNYXN0cmEgY3VzdG9tIEFQSSByb3V0ZS4gSGFuZGxlcyB0aHJlZSBtZXRob2RzXG4gKiBvbiB0aGUgc2FtZSBtb3VudDpcbiAqXG4gKiAgIC0gYEdFVGA6IGEgcGFnZSBvZiB0aGUgcmVzb3VyY2UncyBjb252ZXJzYXRpb24gdGhyZWFkc1xuICogICAgICh7QGxpbmsgbGlzdFRocmVhZHN9KS5cbiAqICAgLSBgREVMRVRFYDogcmVtb3ZlIHRoZSB0aHJlYWQgbmFtZWQgYnkgdGhlIHRocmVhZC1zZWxlY3Rpb24gaGVhZGVyXG4gKiAgICAgLyBgP3RocmVhZElkPWAgcXVlcnkgKHtAbGluayBkZWxldGVUaHJlYWR9KS4gVGhlIGlkIGlzIHJlYWQgZnJvbVxuICogICAgIGBSZXF1ZXN0Q29udGV4dGAgKHRoZSBhdXRoIG1pZGRsZXdhcmUgcmVzb2x2ZXMgaXQgdGhlIHNhbWUgd2F5IGl0XG4gKiAgICAgZG9lcyBmb3Igc3RyZWFtaW5nIGFuZCBoaXN0b3J5KSwgc28gdGhlIGNsaWVudCBkZWxldGVzIGFueSBvZiBpdHNcbiAqICAgICB0aHJlYWRzIGJ5IHN0YW1waW5nIHRoZSB0YXJnZXQgaWQgLSBubyBzZXBhcmF0ZSBwYXRoIHBhcmFtLlxuICogICAtIGBQQVRDSGA6IHJlbmFtZSB0aGUgdGhyZWFkIG5hbWVkIGJ5IHRoZSB0aHJlYWQtc2VsZWN0aW9uIGhlYWRlciAvXG4gKiAgICAgYD90aHJlYWRJZD1gIHF1ZXJ5IHRvIHRoZSBgeyB0aXRsZSB9YCBpbiB0aGUgSlNPTiBib2R5XG4gKiAgICAgKHtAbGluayByZW5hbWVUaHJlYWR9KS4gVGFyZ2V0cyBhIHRocmVhZCB0aGUgc2FtZSB3YXkgYERFTEVURWBcbiAqICAgICBkb2VzOyA0MDRzIHdoZW4gdGhlIHRocmVhZCBpc24ndCBvd25lZCBieSB0aGUgY2FsbGVyLlxuICpcbiAqIEZvbGxvd3MgdGhlIGBAbWFzdHJhL2FpLXNka2AgYWdlbnQtYmluZGluZyBjb252ZW50aW9uOiBwYXNzIGBhZ2VudGBcbiAqIGZvciBhIGZpeGVkLWFnZW50IG1vdW50LCBvciBpbmNsdWRlIGA6YWdlbnRJZGAgaW4gdGhlIHBhdGggZm9yXG4gKiBkeW5hbWljIHJvdXRpbmcuIFRoZSBwbHVnaW4gcmVnaXN0ZXJzIGJvdGggYC9yb3V0ZS90aHJlYWRzYCAoZGVmYXVsdFxuICogYWdlbnQpIGFuZCBgL3JvdXRlL3RocmVhZHMvOmFnZW50SWRgLlxuICovXG5leHBvcnQgZnVuY3Rpb24gdGhyZWFkc1JvdXRlKG9wdGlvbnM6IFRocmVhZHNSb3V0ZU9wdGlvbnMpIHtcbiAgY29uc3QgeyBwYXRoLCBmaXhlZEFnZW50IH0gPSByZXNvbHZlQWdlbnRSb3V0ZU9wdGlvbnMob3B0aW9ucywgXCJ0aHJlYWRzUm91dGUucGF0aFwiKTtcblxuICByZXR1cm4gW1xuICAgIHJlZ2lzdGVyQXBpUm91dGUocGF0aCwge1xuICAgICAgbWV0aG9kOiBcIkdFVFwiLFxuICAgICAgaGFuZGxlcjogYXN5bmMgKGM6IENvbnRleHRXaXRoTWFzdHJhKSA9PiB7XG4gICAgICAgIGNvbnN0IGN0eCA9IHJlc29sdmVBZ2VudFJlcXVlc3RDb250ZXh0KGMsIHsgZml4ZWRBZ2VudCB9KTtcbiAgICAgICAgaWYgKFwiZXJyb3JcIiBpbiBjdHgpIHJldHVybiBjdHguZXJyb3I7XG4gICAgICAgIGNvbnN0IHBheWxvYWQgPSBhd2FpdCBsaXN0VGhyZWFkcyh7XG4gICAgICAgICAgYWdlbnQ6IGN0eC5hZ2VudCxcbiAgICAgICAgICByZXNvdXJjZUlkOiBjdHgucmVzb3VyY2VJZCxcbiAgICAgICAgICBwYWdlOiBwYXJzZUludFBhcmFtKGMucmVxLnF1ZXJ5KFwicGFnZVwiKSksXG4gICAgICAgICAgcGVyUGFnZTogcGFyc2VJbnRQYXJhbShjLnJlcS5xdWVyeShcInBlclBhZ2VcIikpLFxuICAgICAgICB9KTtcbiAgICAgICAgcmV0dXJuIGMuanNvbihwYXlsb2FkKTtcbiAgICAgIH0sXG4gICAgfSksXG4gICAgcmVnaXN0ZXJBcGlSb3V0ZShwYXRoLCB7XG4gICAgICBtZXRob2Q6IFwiREVMRVRFXCIsXG4gICAgICBoYW5kbGVyOiBhc3luYyAoYzogQ29udGV4dFdpdGhNYXN0cmEpID0+IHtcbiAgICAgICAgY29uc3QgY3R4ID0gcmVzb2x2ZUFnZW50UmVxdWVzdENvbnRleHQoYywgeyBmaXhlZEFnZW50LCB0aHJlYWRJZDogXCJyZXF1aXJlZFwiIH0pO1xuICAgICAgICBpZiAoXCJlcnJvclwiIGluIGN0eCkgcmV0dXJuIGN0eC5lcnJvcjtcbiAgICAgICAgY29uc3QgeyBkZWxldGVkIH0gPSBhd2FpdCBkZWxldGVUaHJlYWQoe1xuICAgICAgICAgIGFnZW50OiBjdHguYWdlbnQsXG4gICAgICAgICAgdGhyZWFkSWQ6IGN0eC50aHJlYWRJZCxcbiAgICAgICAgICByZXNvdXJjZUlkOiBjdHgucmVzb3VyY2VJZCxcbiAgICAgICAgfSk7XG4gICAgICAgIGNvbnN0IHBheWxvYWQ6IE1hc3RyYURlbGV0ZVRocmVhZFJlc3BvbnNlID0ge1xuICAgICAgICAgIG9rOiB0cnVlLFxuICAgICAgICAgIGFnZW50SWQ6IGN0eC5hZ2VudElkLFxuICAgICAgICAgIHRocmVhZElkOiBjdHgudGhyZWFkSWQsXG4gICAgICAgICAgZGVsZXRlZCxcbiAgICAgICAgfTtcbiAgICAgICAgcmV0dXJuIGMuanNvbihwYXlsb2FkKTtcbiAgICAgIH0sXG4gICAgfSksXG4gICAgcmVnaXN0ZXJBcGlSb3V0ZShwYXRoLCB7XG4gICAgICBtZXRob2Q6IFwiUEFUQ0hcIixcbiAgICAgIGhhbmRsZXI6IGFzeW5jIChjOiBDb250ZXh0V2l0aE1hc3RyYSkgPT4ge1xuICAgICAgICBjb25zdCBjdHggPSByZXNvbHZlQWdlbnRSZXF1ZXN0Q29udGV4dChjLCB7IGZpeGVkQWdlbnQsIHRocmVhZElkOiBcInJlcXVpcmVkXCIgfSk7XG4gICAgICAgIGlmIChcImVycm9yXCIgaW4gY3R4KSByZXR1cm4gY3R4LmVycm9yO1xuICAgICAgICBjb25zdCBib2R5ID0gd2lyZS5NYXN0cmFVcGRhdGVUaHJlYWRSZXF1ZXN0U2NoZW1hLnNhZmVQYXJzZShhd2FpdCBjLnJlcS5qc29uKCkpO1xuICAgICAgICBpZiAoIWJvZHkuc3VjY2Vzcykge1xuICAgICAgICAgIGxvZ2dlci53YXJuKFwicmVuYW1lOmludmFsaWRcIiwgeyBlcnJvcjogYm9keS5lcnJvci5tZXNzYWdlIH0pO1xuICAgICAgICAgIHJldHVybiBjLmpzb24oeyBlcnJvcjogSU5WQUxJRF9SRU5BTUVfTUVTU0FHRSwgZmllbGRzOiBpbnZhbGlkRmllbGRzKGJvZHkuZXJyb3IpIH0sIDQwMCk7XG4gICAgICAgIH1cbiAgICAgICAgY29uc3QgdGhyZWFkID0gYXdhaXQgcmVuYW1lVGhyZWFkKHtcbiAgICAgICAgICBhZ2VudDogY3R4LmFnZW50LFxuICAgICAgICAgIHRocmVhZElkOiBjdHgudGhyZWFkSWQsXG4gICAgICAgICAgcmVzb3VyY2VJZDogY3R4LnJlc291cmNlSWQsXG4gICAgICAgICAgdGl0bGU6IGJvZHkuZGF0YS50aXRsZSxcbiAgICAgICAgfSk7XG4gICAgICAgIGlmICghdGhyZWFkKSB7XG4gICAgICAgICAgcmV0dXJuIGMuanNvbih7IGVycm9yOiBgVW5rbm93biB0aHJlYWQgXCIke2N0eC50aHJlYWRJZH1cImAgfSwgNDA0KTtcbiAgICAgICAgfVxuICAgICAgICBjb25zdCBwYXlsb2FkOiBNYXN0cmFVcGRhdGVUaHJlYWRSZXNwb25zZSA9IHtcbiAgICAgICAgICBvazogdHJ1ZSxcbiAgICAgICAgICBhZ2VudElkOiBjdHguYWdlbnRJZCxcbiAgICAgICAgICB0aHJlYWQsXG4gICAgICAgIH07XG4gICAgICAgIHJldHVybiBjLmpzb24ocGF5bG9hZCk7XG4gICAgICB9LFxuICAgIH0pLFxuICBdO1xufVxuXG4vKiogQ29lcmNlIGEgTWFzdHJhIGBTdG9yYWdlVGhyZWFkVHlwZWAgaW50byB0aGUgSlNPTi1zYWZlIHdpcmUgc2hhcGUuICovXG5mdW5jdGlvbiB0b1dpcmVUaHJlYWQodGhyZWFkOiBTdG9yYWdlVGhyZWFkVHlwZSk6IE1hc3RyYVRocmVhZCB7XG4gIHJldHVybiB7XG4gICAgaWQ6IHRocmVhZC5pZCxcbiAgICAuLi4odGhyZWFkLnRpdGxlID8geyB0aXRsZTogdGhyZWFkLnRpdGxlIH0gOiB7fSksXG4gICAgcmVzb3VyY2VJZDogdGhyZWFkLnJlc291cmNlSWQsXG4gICAgY3JlYXRlZEF0OiB0b0lzbyh0aHJlYWQuY3JlYXRlZEF0KSxcbiAgICB1cGRhdGVkQXQ6IHRvSXNvKHRocmVhZC51cGRhdGVkQXQpLFxuICAgIC4uLih0aHJlYWQubWV0YWRhdGEgPyB7IG1ldGFkYXRhOiB0aHJlYWQubWV0YWRhdGEgfSA6IHt9KSxcbiAgfTtcbn1cblxuLyoqIFJlbmRlciBhIHN0b3JhZ2UgdGltZXN0YW1wIGFzIGFuIElTTy04NjAxIHN0cmluZyBmb3IgdGhlIHdpcmUuICovXG5mdW5jdGlvbiB0b0lzbyh2YWx1ZTogRGF0ZSB8IHN0cmluZyB8IG51bWJlcik6IHN0cmluZyB7XG4gIGlmICh2YWx1ZSBpbnN0YW5jZW9mIERhdGUpIHJldHVybiB2YWx1ZS50b0lTT1N0cmluZygpO1xuICBjb25zdCBwYXJzZWQgPSBuZXcgRGF0ZSh2YWx1ZSk7XG4gIHJldHVybiBOdW1iZXIuaXNOYU4ocGFyc2VkLmdldFRpbWUoKSkgPyBuZXcgRGF0ZSgwKS50b0lTT1N0cmluZygpIDogcGFyc2VkLnRvSVNPU3RyaW5nKCk7XG59XG4iXX0=
@@ -1 +1 @@
1
- {"root":["../src/agents.ts","../src/chart.ts","../src/config.ts","../src/defaults.ts","../src/filesystems.ts","../src/genie.ts","../src/history.ts","../src/identity.ts","../src/mcp.ts","../src/memory.ts","../src/mlflow.ts","../src/model.ts","../src/observability.ts","../src/pagination.ts","../src/plugin.ts","../src/processors.ts","../src/remote-skills.ts","../src/rest.ts","../src/server.ts","../src/serving-sanitize.ts","../src/serving.ts","../src/skill-paths.ts","../src/statement.ts","../src/storage-schema.ts","../src/style.ts","../src/summarize.ts","../src/threads.ts","../src/trace-io.ts","../src/validation.ts","../src/workspaces.ts","../src/writer.ts","../index.ts"],"version":"5.9.3"}
1
+ {"root":["../src/_agent-route-context.ts","../src/agents.ts","../src/chart.ts","../src/config.ts","../src/defaults.ts","../src/filesystems.ts","../src/genie.ts","../src/history.ts","../src/identity.ts","../src/mcp.ts","../src/memory.ts","../src/mlflow.ts","../src/model.ts","../src/observability.ts","../src/pagination.ts","../src/plugin.ts","../src/processors.ts","../src/remote-skills.ts","../src/rest.ts","../src/server.ts","../src/serving-sanitize.ts","../src/serving.ts","../src/skill-paths.ts","../src/statement.ts","../src/storage-schema.ts","../src/style.ts","../src/summarize.ts","../src/threads.ts","../src/trace-io.ts","../src/validation.ts","../src/workspaces.ts","../src/writer.ts","../index.ts"],"version":"5.9.3"}
package/package.json CHANGED
@@ -1,5 +1,6 @@
1
1
  {
2
2
  "name": "@dbx-tools/appkit-mastra",
3
+ "description": "AppKit plugin and server-side toolkit for hosting Mastra agents in Databricks Apps",
3
4
  "repository": {
4
5
  "type": "git",
5
6
  "url": "git+https://github.com/reggie-db/dbx-tools.git",
@@ -30,18 +31,18 @@
30
31
  },
31
32
  "dependencies": {
32
33
  "@databricks/appkit": "^0.60.0",
33
- "@dbx-tools/appkit": "0.6.211",
34
- "@dbx-tools/core": "0.6.211",
35
- "@dbx-tools/databricks": "0.6.211",
36
- "@dbx-tools/fs": "0.6.211",
37
- "@dbx-tools/genie": "0.6.211",
38
- "@dbx-tools/model": "0.6.211",
39
- "@dbx-tools/path": "0.6.211",
40
- "@dbx-tools/shared-core": "0.6.211",
41
- "@dbx-tools/shared-fs": "0.6.211",
42
- "@dbx-tools/shared-genie": "0.6.211",
43
- "@dbx-tools/shared-mastra": "0.6.211",
44
- "@dbx-tools/shared-model": "0.6.211",
34
+ "@dbx-tools/appkit": "0.6.213",
35
+ "@dbx-tools/core": "0.6.213",
36
+ "@dbx-tools/databricks": "0.6.213",
37
+ "@dbx-tools/fs": "0.6.213",
38
+ "@dbx-tools/genie": "0.6.213",
39
+ "@dbx-tools/model": "0.6.213",
40
+ "@dbx-tools/path": "0.6.213",
41
+ "@dbx-tools/shared-core": "0.6.213",
42
+ "@dbx-tools/shared-fs": "0.6.213",
43
+ "@dbx-tools/shared-genie": "0.6.213",
44
+ "@dbx-tools/shared-mastra": "0.6.213",
45
+ "@dbx-tools/shared-model": "0.6.213",
45
46
  "@mastra/ai-sdk": "1.6.0",
46
47
  "@mastra/core": "1.47.0",
47
48
  "@mastra/express": "1.4.2",
@@ -58,7 +59,7 @@
58
59
  "zod": "4.3.6"
59
60
  },
60
61
  "main": "./lib/index.js",
61
- "license": "UNLICENSED",
62
+ "license": "Apache-2.0",
62
63
  "publishConfig": {
63
64
  "access": "public",
64
65
  "main": "./lib/index.js",
@@ -71,7 +72,7 @@
71
72
  "./package.json": "./package.json"
72
73
  }
73
74
  },
74
- "version": "0.6.211",
75
+ "version": "0.6.213",
75
76
  "types": "./lib/index.d.ts",
76
77
  "type": "module",
77
78
  "exports": {
@@ -0,0 +1,100 @@
1
+ /**
2
+ * Shared agent binding and request-context resolution for Mastra custom routes.
3
+ *
4
+ * @module
5
+ */
6
+
7
+ import { ValidationError } from "@databricks/appkit";
8
+ import type { Agent } from "@mastra/core/agent";
9
+ import {
10
+ MASTRA_RESOURCE_ID_KEY,
11
+ MASTRA_THREAD_ID_KEY,
12
+ type RequestContext,
13
+ } from "@mastra/core/request-context";
14
+ import type { ContextWithMastra } from "@mastra/core/server";
15
+
16
+ /** Fixed-agent or dynamic `:agentId` binding accepted by custom agent routes. */
17
+ export type AgentRouteOptions =
18
+ { path: `${string}:agentId${string}`; agent?: never } | { path: string; agent: string };
19
+
20
+ /** Validated route path and optional fixed agent binding. */
21
+ export interface ResolvedAgentRouteOptions {
22
+ path: string;
23
+ fixedAgent: string | undefined;
24
+ }
25
+
26
+ /** Resolve and validate a fixed or dynamic agent route declaration. */
27
+ export function resolveAgentRouteOptions(
28
+ options: AgentRouteOptions,
29
+ field: string,
30
+ ): ResolvedAgentRouteOptions {
31
+ const fixedAgent = "agent" in options ? options.agent : undefined;
32
+ if (!fixedAgent && !options.path.includes(":agentId")) {
33
+ throw ValidationError.invalidValue(
34
+ field,
35
+ options.path,
36
+ "a path containing `:agentId`, or an explicit `agent`",
37
+ );
38
+ }
39
+ return { path: options.path, fixedAgent };
40
+ }
41
+
42
+ interface ResolvedAgentRequestContext {
43
+ agentId: string;
44
+ agent: Agent;
45
+ requestContext: RequestContext;
46
+ resourceId: string;
47
+ }
48
+
49
+ interface AgentRequestContextError {
50
+ error: Response;
51
+ }
52
+
53
+ interface ResolveAgentRequestContextOptions {
54
+ fixedAgent?: string;
55
+ threadId?: "optional" | "required";
56
+ }
57
+
58
+ /** Resolve an agent plus the caller-scoped Mastra request context. */
59
+ export function resolveAgentRequestContext(
60
+ context: ContextWithMastra,
61
+ options: ResolveAgentRequestContextOptions & { threadId: "required" },
62
+ ): (ResolvedAgentRequestContext & { threadId: string }) | AgentRequestContextError;
63
+ export function resolveAgentRequestContext(
64
+ context: ContextWithMastra,
65
+ options?: ResolveAgentRequestContextOptions,
66
+ ): (ResolvedAgentRequestContext & { threadId?: string }) | AgentRequestContextError;
67
+ export function resolveAgentRequestContext(
68
+ context: ContextWithMastra,
69
+ options: ResolveAgentRequestContextOptions = {},
70
+ ): (ResolvedAgentRequestContext & { threadId?: string }) | AgentRequestContextError {
71
+ const mastra = context.get("mastra");
72
+ const requestContext = context.get("requestContext");
73
+ const agentId = options.fixedAgent ?? context.req.param("agentId");
74
+ if (!agentId) {
75
+ return { error: context.json({ error: "agentId is required" }, 400) };
76
+ }
77
+ const agent = mastra.getAgentById(agentId);
78
+ if (!agent) {
79
+ return { error: context.json({ error: `Unknown agent "${agentId}"` }, 404) };
80
+ }
81
+ const resourceId = requestContext.get(MASTRA_RESOURCE_ID_KEY) as string | undefined;
82
+ if (!resourceId) {
83
+ return {
84
+ error: context.json({ error: "resource id missing from request context" }, 400),
85
+ };
86
+ }
87
+ const threadId = requestContext.get(MASTRA_THREAD_ID_KEY) as string | undefined;
88
+ if (options.threadId === "required" && !threadId) {
89
+ return {
90
+ error: context.json({ error: "thread id missing from request context" }, 400),
91
+ };
92
+ }
93
+ return {
94
+ agentId,
95
+ agent,
96
+ requestContext,
97
+ resourceId,
98
+ ...(threadId ? { threadId } : {}),
99
+ };
100
+ }
package/src/config.ts CHANGED
@@ -386,6 +386,13 @@ export interface MastraPluginConfig extends BasePluginConfig {
386
386
  * spaces config in two places.
387
387
  */
388
388
  genieSpaces?: GenieSpacesConfig;
389
+ /**
390
+ * Use the streaming Genie Agent Mode API for `ask_genie`. Defaults to `true`.
391
+ * Set `false` to force the legacy Conversation API polling driver. A
392
+ * pre-stream feature-disabled or preview-toggle response falls back
393
+ * automatically.
394
+ */
395
+ genieAgentMode?: boolean;
389
396
  /**
390
397
  * TTL for the in-memory Genie space metadata cache, in
391
398
  * milliseconds. Defaults to 5 minutes. The Genie agent calls
@@ -665,6 +672,11 @@ export const MASTRA_CONFIG_SCHEMA: ConfigSchema = {
665
672
  description:
666
673
  "Genie spaces the agents can delegate to, keyed by alias (the tool-name suffix). Each value is a space id or `{ spaceId, hint }`. Falls back to the `genie` plugin's own `spaces` config, then DATABRICKS_GENIE_SPACE_ID under the `default` alias.",
667
674
  },
675
+ genieAgentMode: {
676
+ type: "boolean",
677
+ description:
678
+ "Use the streaming Genie Agent Mode API for ask_genie. Defaults to true; false forces legacy polling. Feature-disabled or preview-toggle responses fall back automatically before streaming.",
679
+ },
668
680
  genieSpaceCacheTtlMs: {
669
681
  type: "number",
670
682
  description: "TTL in ms for the Genie space metadata cache. Defaults to 5 minutes.",
package/src/genie.ts CHANGED
@@ -375,8 +375,13 @@ function stripSuggestedQuestions(message: GenieMessage): GenieMessage {
375
375
  return { ...message, attachments: filtered };
376
376
  }
377
377
 
378
- function buildAskGenieTool(opts: { spaceId: string; alias: string; hint?: string }) {
379
- const { spaceId, alias, hint } = opts;
378
+ function buildAskGenieTool(opts: {
379
+ spaceId: string;
380
+ alias: string;
381
+ hint?: string;
382
+ agentMode?: boolean;
383
+ }) {
384
+ const { spaceId, alias, hint, agentMode } = opts;
380
385
  const toolId = `ask_genie${aliasSuffix(alias)}`;
381
386
  const hintLine = hint ? ` (${hint})` : "";
382
387
  return createTool({
@@ -395,16 +400,17 @@ function buildAskGenieTool(opts: { spaceId: string; alias: string; hint?: string
395
400
  Do NOT try to cram a multi-part question into a single
396
401
  call; decompose first, then ask each piece.
397
402
 
398
- Returns the final \`GenieMessage\`. Rows are NOT included -
399
- the Genie wire response carries the \`statement_id\` for any
400
- SQL that ran (at \`message.query_result.statement_id\` or the
401
- first attachment's \`query.statement_id\`); call
403
+ Returns the final \`GenieMessage\`. Agent Mode includes the
404
+ synthesized answer and can include SQL result values as a
405
+ Markdown text attachment. A legacy polling result instead
406
+ carries a \`statement_id\` (at
407
+ \`message.query_result.statement_id\` or the first
408
+ attachment's \`query.statement_id\`); call
402
409
  \`get_statement\` with that id only when you need to read
403
- the underlying values to reason about them. If you just
404
- want to display the rows to the user, embed a
405
- \`[data:<statement_id>]\` marker in your prose instead -
406
- the host UI fetches and renders the rows on its own. Wire
407
- events (status, thinking, sql) stream to the user
410
+ the underlying values to reason about them. If you just want
411
+ to display a legacy result, embed a
412
+ \`[data:<statement_id>]\` marker in prose. Wire events
413
+ (status, reasoning, SQL, query output, answer text) stream
408
414
  automatically while the call is in flight.
409
415
  `),
410
416
  inputSchema: z.object({
@@ -475,6 +481,7 @@ function buildAskGenieTool(opts: { spaceId: string; alias: string; hint?: string
475
481
  let finalMessage: GenieMessage | undefined;
476
482
  for await (const event of chat.genieEventChat(spaceId, question, {
477
483
  workspaceClient: client,
484
+ ...(agentMode !== undefined ? { agentMode } : {}),
478
485
  ...(seedConversationId ? { conversationId: seedConversationId } : {}),
479
486
  ...(signal ? { context: signal } : {}),
480
487
  })) {
@@ -815,8 +822,10 @@ export const GENIE_INSTRUCTIONS = string.toDescription([
815
822
  `,
816
823
  `
817
824
  Each \`ask_genie\` call returns the terminal \`GenieMessage\`.
818
- When the turn ran SQL the result has a \`statement_id\` - read
819
- it from \`message.query_result.statement_id\` (or the first
825
+ Read Agent Mode's synthesized answer and Markdown query output
826
+ directly from its text attachments. A legacy polling result may
827
+ instead expose a \`statement_id\` at
828
+ \`message.query_result.statement_id\` (or the first
820
829
  attachment's \`query.statement_id\`).
821
830
  `,
822
831
  [
@@ -1021,6 +1030,9 @@ export function buildGenieTools(opts: {
1021
1030
  const askTool = buildAskGenieTool({
1022
1031
  spaceId: space.spaceId,
1023
1032
  alias,
1033
+ ...(opts.config.genieAgentMode !== undefined
1034
+ ? { agentMode: opts.config.genieAgentMode }
1035
+ : {}),
1024
1036
  ...(space.hint ? { hint: space.hint } : {}),
1025
1037
  });
1026
1038
  const descTool = buildSpaceDescriptionTool({ spaceId: space.spaceId, alias });
package/src/history.ts CHANGED
@@ -18,7 +18,6 @@
18
18
  * @module
19
19
  */
20
20
 
21
- import { ValidationError } from "@databricks/appkit";
22
21
  import { error, log } from "@dbx-tools/shared-core";
23
22
  import type {
24
23
  MastraClearHistoryResponse,
@@ -28,10 +27,14 @@ import type {
28
27
  import { toAISdkV5Messages } from "@mastra/ai-sdk/ui";
29
28
  import type { Agent } from "@mastra/core/agent";
30
29
  import type { MastraDBMessage } from "@mastra/core/agent/message-list";
31
- import { MASTRA_RESOURCE_ID_KEY, MASTRA_THREAD_ID_KEY } from "@mastra/core/request-context";
32
30
  import type { ContextWithMastra } from "@mastra/core/server";
33
31
  import { registerApiRoute } from "@mastra/core/server";
34
32
 
33
+ import {
34
+ resolveAgentRequestContext,
35
+ resolveAgentRouteOptions,
36
+ type AgentRouteOptions,
37
+ } from "./_agent-route-context.ts";
35
38
  import { clampPerPage, parseIntParam } from "./pagination.ts";
36
39
 
37
40
  const logger = log.logger("mastra/history");
@@ -180,8 +183,7 @@ export async function clearHistory(opts: ClearHistoryOptions): Promise<{ cleared
180
183
  }
181
184
 
182
185
  /** Options accepted by {@link historyRoute}. */
183
- export type HistoryRouteOptions =
184
- { path: `${string}:agentId${string}`; agent?: never } | { path: string; agent: string };
186
+ export type HistoryRouteOptions = AgentRouteOptions;
185
187
 
186
188
  /**
187
189
  * Register the `<path>` Mastra custom API route. Handles two
@@ -204,52 +206,13 @@ export type HistoryRouteOptions =
204
206
  * no cookie or user lookups happen here.
205
207
  */
206
208
  export function historyRoute(options: HistoryRouteOptions) {
207
- const { path } = options;
208
- const fixedAgent = "agent" in options ? options.agent : undefined;
209
- if (!fixedAgent && !path.includes(":agentId")) {
210
- throw ValidationError.invalidValue(
211
- "historyRoute.path",
212
- path,
213
- "a path containing `:agentId`, or an explicit `agent`",
214
- );
215
- }
216
- // Tiny resolver shared by GET / DELETE: derive the active agent
217
- // and thread id, returning a JSON error response when either is
218
- // missing. Keeps both handlers thin and gives them identical
219
- // validation behaviour.
220
- const resolveContext = (c: ContextWithMastra) => {
221
- const mastra = c.get("mastra");
222
- const requestContext = c.get("requestContext");
223
- const agentId = fixedAgent ?? c.req.param("agentId");
224
- if (!agentId) {
225
- return { error: c.json({ error: "agentId is required" }, 400) } as const;
226
- }
227
- const agent = mastra.getAgentById(agentId);
228
- if (!agent) {
229
- return {
230
- error: c.json({ error: `Unknown agent "${agentId}"` }, 404),
231
- } as const;
232
- }
233
- const threadId = requestContext.get(MASTRA_THREAD_ID_KEY) as string | undefined;
234
- if (!threadId) {
235
- return {
236
- error: c.json({ error: "thread id missing from request context" }, 400),
237
- } as const;
238
- }
239
- const resourceId = requestContext.get(MASTRA_RESOURCE_ID_KEY) as string | undefined;
240
- if (!resourceId) {
241
- return {
242
- error: c.json({ error: "resource id missing from request context" }, 400),
243
- } as const;
244
- }
245
- return { agentId, agent, threadId, resourceId } as const;
246
- };
209
+ const { path, fixedAgent } = resolveAgentRouteOptions(options, "historyRoute.path");
247
210
 
248
211
  return [
249
212
  registerApiRoute(path, {
250
213
  method: "GET",
251
214
  handler: async (c: ContextWithMastra) => {
252
- const ctx = resolveContext(c);
215
+ const ctx = resolveAgentRequestContext(c, { fixedAgent, threadId: "required" });
253
216
  if ("error" in ctx) return ctx.error;
254
217
  const payload = await loadHistory({
255
218
  agent: ctx.agent,
@@ -264,7 +227,7 @@ export function historyRoute(options: HistoryRouteOptions) {
264
227
  registerApiRoute(path, {
265
228
  method: "DELETE",
266
229
  handler: async (c: ContextWithMastra) => {
267
- const ctx = resolveContext(c);
230
+ const ctx = resolveAgentRequestContext(c, { fixedAgent, threadId: "required" });
268
231
  if ("error" in ctx) return ctx.error;
269
232
  const { cleared } = await clearHistory({
270
233
  agent: ctx.agent,