@reveldigital/mcp-graphql-proxy 2.0.0 → 2.2.0
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/core/system-prompt.d.ts.map +1 -1
- package/dist/core/system-prompt.js +62 -9
- package/dist/core/system-prompt.js.map +1 -1
- package/dist/index.js +650 -0
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
- package/src/types/schema.graphql +389 -27
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,eAAe,EAAE,MAAM,CAAC;IACxB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"system-prompt.d.ts","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,MAAM,WAAW,kBAAkB;IACjC,2CAA2C;IAC3C,eAAe,EAAE,MAAM,CAAC;IACxB,iDAAiD;IACjD,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,4CAA4C;IAC5C,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAED;;GAEG;AACH,wBAAgB,oBAAoB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CA8hBxE;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,OAAO,EAAE,kBAAkB,GAAG,MAAM,CA0HzE"}
|
|
@@ -219,6 +219,17 @@ Dedicated tools for managing structured data tables (e.g., menu boards, pricing,
|
|
|
219
219
|
| \`send_device_command\` | Send one or more commands to a specific device. Params: \`deviceId\`, \`commands\` (array of \`{name, arg?}\`). Known commands: restart, reboot, screenshot, refresh, display_on, display_off, volume (arg: 0-100), clear_cache, update. |
|
|
220
220
|
| \`send_bulk_device_commands\` | Send commands to multiple devices at once. Params: \`deviceIds\` (array), \`commands\` (array of \`{name, arg?}\`). |
|
|
221
221
|
|
|
222
|
+
### Group Management
|
|
223
|
+
Organizational folders for each resource type. All five tools take the same params: \`name\`, \`parentId?\` (encrypted id of an existing group to nest under; omit to create at the root). Each returns the new \`Group\` (\`id\`, \`name\`, \`parentId\`).
|
|
224
|
+
|
|
225
|
+
| Tool | Description |
|
|
226
|
+
|------|-------------|
|
|
227
|
+
| \`create_device_group\` | Create a new device group (folder for player devices). |
|
|
228
|
+
| \`create_media_group\` | Create a new media group (folder for uploaded content files). |
|
|
229
|
+
| \`create_playlist_group\` | Create a new playlist group (folder for playlists). |
|
|
230
|
+
| \`create_schedule_group\` | Create a new schedule group (folder for schedules). |
|
|
231
|
+
| \`create_template_group\` | Create a new template group (folder for screen layouts/templates). |
|
|
232
|
+
|
|
222
233
|
### Media Management
|
|
223
234
|
| Tool | Description |
|
|
224
235
|
|------|-------------|
|
|
@@ -236,6 +247,21 @@ Dedicated tools for managing structured data tables (e.g., menu boards, pricing,
|
|
|
236
247
|
| \`remove_playlist_source\` | Remove a source from a playlist. Params: \`playlistId\`, \`sourceId\`. |
|
|
237
248
|
| \`reorder_playlist_sources\` | Reorder sources within a playlist. Params: \`playlistId\`, \`sourceIds\` (ordered array). |
|
|
238
249
|
|
|
250
|
+
### Template Management
|
|
251
|
+
Templates are screen layouts composed of **modules** (also called **zones** or **regions**) — rectangular areas that display content from a playlist. The terms "module" and "zone" are interchangeable. Module positions (\`left\`, \`top\`, \`width\`, \`height\`) are in pixels; \`sequence\` is the z-order (higher appears in front). Each module can carry **options** (key-value pairs) for type-specific settings (e.g., \`timezone\` for a Clock zone, \`location\` for a Weather zone).
|
|
252
|
+
|
|
253
|
+
| Tool | Description |
|
|
254
|
+
|------|-------------|
|
|
255
|
+
| \`update_template\` | Update a template's properties. Params: \`templateId\`, plus any of \`name?\`, \`groupId?\`, \`tags?\` (newline-delimited), \`script?\`, \`backColor?\` (e.g. \`#000000\`), \`width?\`, \`height?\`, \`orientation?\` (0=Landscape, 1=Portrait, 2=Landscape Reversed, 3=Portrait Reversed). |
|
|
256
|
+
| \`add_template_module\` | Add a new module/zone to a template. Params: \`templateId\`, \`module\` (object: \`name?\`, \`type?\`, \`left?\`, \`top?\`, \`width?\`, \`height?\`, \`playlistId?\`, \`sequence?\`). |
|
|
257
|
+
| \`update_template_module\` | Update a module within a template (partial). Params: \`templateId\`, \`moduleId\`, plus any of \`name?\`, \`type?\`, \`left?\`, \`top?\`, \`width?\`, \`height?\`, \`playlistId?\`, \`sequence?\`. |
|
|
258
|
+
| \`remove_template_module\` | Remove a module from a template. Params: \`templateId\`, \`moduleId\`. |
|
|
259
|
+
| \`reorder_template_modules\` | Reorder modules by z-order. Params: \`templateId\`, \`moduleSequences\` (array of \`{moduleId, sequence}\`). |
|
|
260
|
+
| \`batch_update_template_modules\` | Update multiple modules at once. Params: \`templateId\`, \`modules\` (array of \`{moduleId, ...partial fields}\`). Returns per-module success/failure counts. |
|
|
261
|
+
| \`set_module_options\` | Replace all options for a module. Params: \`templateId\`, \`moduleId\`, \`options\` (array of \`{name, value}\`). |
|
|
262
|
+
| \`upsert_module_option\` | Add or update a single option (matched by name). Params: \`templateId\`, \`moduleId\`, \`option\` (\`{name, value}\`). |
|
|
263
|
+
| \`remove_module_option\` | Remove an option by name. Params: \`templateId\`, \`moduleId\`, \`optionName\`. |
|
|
264
|
+
|
|
239
265
|
### Data Table Management
|
|
240
266
|
| Tool | Description |
|
|
241
267
|
|------|-------------|
|
|
@@ -303,9 +329,16 @@ Playlist sources support optional \`conditions\` to control when/where they play
|
|
|
303
329
|
2. Operator object: \`{"<columnKey>": {"op": "<operator>", ...args}}\`
|
|
304
330
|
|
|
305
331
|
**Supported operators:**
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
332
|
+
|
|
333
|
+
| Operator | Args | Notes |
|
|
334
|
+
|----------|------|-------|
|
|
335
|
+
| \`eq\`, \`neq\` | \`value\` | Equality on any scalar column |
|
|
336
|
+
| \`contains\`, \`notContains\` | \`value\` | String substring match |
|
|
337
|
+
| \`gt\`, \`gte\`, \`lt\`, \`lte\` | \`value\` | Numbers and dates |
|
|
338
|
+
| \`inRange\`, \`outOfRange\` | \`from\`, \`to\` | Inclusive range |
|
|
339
|
+
| \`isEmpty\`, \`isNotEmpty\` | — | Null / empty check |
|
|
340
|
+
| \`positive\`, \`negative\` | — | Numeric sign |
|
|
341
|
+
| \`beforeNow\`, \`afterNow\`, \`isToday\` | — | Date columns, evaluated in UTC |
|
|
309
342
|
|
|
310
343
|
**Examples:**
|
|
311
344
|
- \`{"active": true}\` — equality shortcut
|
|
@@ -313,10 +346,10 @@ Playlist sources support optional \`conditions\` to control when/where they play
|
|
|
313
346
|
- \`{"name": {"op": "contains", "value": "pizza"}}\` — substring
|
|
314
347
|
- \`{"score": {"op": "inRange", "from": 0, "to": 100}}\` — range
|
|
315
348
|
- \`{"deletedAt": {"op": "isEmpty"}}\` — null check
|
|
316
|
-
- \`{"publishAt": {"op": "beforeNow"}}\` — date relative to now
|
|
349
|
+
- \`{"publishAt": {"op": "beforeNow"}}\` — date relative to now (UTC)
|
|
317
350
|
- \`{"$or": [{"category": "Entree"}, {"price": {"op": "lt", "value": 10}}]}\` — disjunction
|
|
318
351
|
|
|
319
|
-
Invalid JSON, unknown
|
|
352
|
+
Invalid filters (bad JSON, unknown operator, missing args) return a GraphQL error with \`extensions.code = "BAD_REQUEST"\` and a plain-English message — no stack trace.
|
|
320
353
|
|
|
321
354
|
---
|
|
322
355
|
|
|
@@ -438,13 +471,21 @@ get_data_table({ "tableId": "table-id" })
|
|
|
438
471
|
\`\`\`
|
|
439
472
|
list_data_table_rows({
|
|
440
473
|
"tableId": "table-id",
|
|
441
|
-
"filter": "{\\"status\\":\\"active\\"}",
|
|
474
|
+
"filter": "{\\"status\\":\\"active\\",\\"price\\":{\\"op\\":\\"gte\\",\\"value\\":25}}",
|
|
442
475
|
"sort": "price",
|
|
443
476
|
"sortDir": "asc",
|
|
444
477
|
"pageSize": 50
|
|
445
478
|
})
|
|
446
479
|
\`\`\`
|
|
447
480
|
|
|
481
|
+
**Query table rows with \`$or\` composition:**
|
|
482
|
+
\`\`\`
|
|
483
|
+
list_data_table_rows({
|
|
484
|
+
"tableId": "table-id",
|
|
485
|
+
"filter": "{\\"$or\\":[{\\"category\\":\\"Entree\\"},{\\"price\\":{\\"op\\":\\"lt\\",\\"value\\":10}}]}"
|
|
486
|
+
})
|
|
487
|
+
\`\`\`
|
|
488
|
+
|
|
448
489
|
**Create a data table (after user confirmation):**
|
|
449
490
|
\`\`\`
|
|
450
491
|
create_data_table({
|
|
@@ -493,9 +534,15 @@ send_device_command({ "deviceId": "abc123", "commands": [{ "name": "reboot" }] }
|
|
|
493
534
|
- **Group**: Organizational container for devices, media, schedules, etc.
|
|
494
535
|
- **OTS (Opportunity To See)**: Audience measurement metric - the percentage of impressions where audience had opportunity to see content (dwell time > threshold)
|
|
495
536
|
- **Data Table**: A structured data store with a defined column schema. Used for dynamic content like menu boards, pricing lists, event schedules, and inventory. Supports row versioning, CSV import/export, batch operations, and optimistic concurrency via ETags.
|
|
496
|
-
- **Column Types
|
|
537
|
+
- **Column Types** (GraphQL enum values, case-sensitive): \`STRING\` (text ≤ 1000 chars), \`NUMBER\` (JSON number, not numeric string), \`BOOLEAN\` (true/false, not the strings "true"/"false"), \`DATE\` (ISO 8601 date or date-time), \`SELECT\` (one of the column's \`options\`; \`options\` is required at create time), \`MEDIA\` (see **MEDIA column value shape** below), \`URL\` (absolute URL with scheme), \`RICHTEXT\` (rich-text HTML/markdown string), \`TIME\` (TimeSpan-parseable string like "14:30"), \`HIDDEN\` (same rules as STRING, hidden from default UI). Each column has a unique \`key\` used in row data objects.
|
|
538
|
+
- **MEDIA column value shape**: A \`MEDIA\` row value may be supplied in any of three forms; the API normalizes them server-side to a canonical object before storage:
|
|
539
|
+
1. **Encrypted media id (string)** — e.g. \`"AbCd1234..."\`. The server resolves it via the media library and expands it into the canonical shape. **Recommended.**
|
|
540
|
+
2. **Id-bearing object** — \`{ "mediaId": "<encrypted id>" }\`. Extra fields you include (e.g. \`caption\`) are preserved.
|
|
541
|
+
3. **Canonical object** (what the CMS UI writes) — \`{ "url": "<absolute CDN URL>", "thumbnailUrl": "<absolute thumb URL>", "name": "<display name>", "mimeType": "<MIME type, e.g. image/jpeg or video/mp4>" }\`. Passed through unchanged when \`url\` is already populated.
|
|
542
|
+
After normalization the stored object has \`url\` (what the player fetches), \`thumbnailUrl\` (what the grid renders), \`name\`, \`mimeType\`, and \`mediaId\`. For Revel-hosted videos \`url\` is the \`.zc.mp4\` transcoded variant. If an id cannot be resolved (asset not found / not in account) the original value is left as-is and required-field validation will surface the failure. \`null\` or \`{}\` clears the cell.
|
|
497
543
|
- **Row Versioning**: Data table rows track version history. Each change creates a new version recording the action, changed fields, and previous values. Rows can be rolled back to any previous version.
|
|
498
|
-
- **Row
|
|
544
|
+
- **Row ETag**: Each \`DataTableRowModel\` carries an \`eTag\` value used for optimistic concurrency. Pass the latest \`eTag\` to \`update_data_table_row\` to fail fast if another writer changed the row in between read and write.
|
|
545
|
+
- **Structured Validation Errors**: Data table row mutations return a \`structuredValidationErrors\` list alongside the legacy \`validationErrors\` strings. Each entry has \`field\`, \`code\` (\`Required\` / \`InvalidType\` / \`OutOfRange\` / \`InvalidFormat\` / \`Invalid\`), and \`message\`. Use the structured form when surfacing actionable per-field feedback to the user.
|
|
499
546
|
- **Media Approval**: Media assets carry an approval state — \`isApproved\` (true=approved, false=declined, null=pending). Use \`approve_media\` / \`decline_media\` (reversible) to set state; declines may include a \`reason\` recorded for audit.
|
|
500
547
|
- **Display Command**: A named command that can be sent to devices (e.g., reboot, screenshot, volume)
|
|
501
548
|
- **Source Condition**: A rule on a playlist source that controls when/where it plays (date range, time range, day of week, device targeting)
|
|
@@ -579,9 +626,11 @@ Types: \`device\`, \`template\`, \`schedule\`, \`playlist\`, \`media\`, \`device
|
|
|
579
626
|
**CRITICAL: Never execute a mutation without first describing the action to the user and receiving explicit approval.** Mutations modify live data affecting devices and content.
|
|
580
627
|
|
|
581
628
|
**Device Commands**: \`send_device_command\` (single device), \`send_bulk_device_commands\` (multiple devices)
|
|
629
|
+
**Groups**: \`create_device_group\`, \`create_media_group\`, \`create_playlist_group\`, \`create_schedule_group\`, \`create_template_group\` — params: \`name\`, optional \`parentId\` to nest.
|
|
582
630
|
**Media**: \`create_media_from_url\`, \`update_media\`, \`approve_media\` (id), \`decline_media\` (id, reason?) — both reversible — \`delete_media\` (currently no-op)
|
|
583
631
|
**Playlists**: \`add_playlist_source\`, \`update_playlist_source\`, \`remove_playlist_source\`, \`reorder_playlist_sources\`
|
|
584
632
|
Playlist sources support optional \`conditions\` (array) to control when/where they play — e.g., \`DATE_RANGE\`, \`TIME_RANGE\`, \`DAYS_OF_WEEK\`, \`SPECIFIC_DEVICE\`, \`DEVICE_BY_GROUP\`. Each condition has \`type\`, optional \`operator\` (AND/OR/AND_NOT/OR_NOT), and \`value1\`–\`value4\`.
|
|
633
|
+
**Templates**: \`update_template\` (name, group, tags, dimensions, backColor, orientation, script), \`add_template_module\`, \`update_template_module\`, \`remove_template_module\`, \`reorder_template_modules\`, \`batch_update_template_modules\`, \`set_module_options\`, \`upsert_module_option\`, \`remove_module_option\`. Modules (aka zones) are rectangular content areas: \`left\`/\`top\`/\`width\`/\`height\` in px, \`sequence\` = z-order, \`playlistId\` = content; options are \`{name, value}\` key-value settings.
|
|
585
634
|
**Data Tables**: \`create_data_table\` (column types: STRING, NUMBER, BOOLEAN, DATE, SELECT, MEDIA, URL, RICHTEXT, TIME, HIDDEN), \`update_data_table\`, \`delete_data_table\`, \`create_data_table_row\`, \`update_data_table_row\` (supports \`eTag\` for optimistic concurrency), \`delete_data_table_row\`, \`batch_create_data_table_rows\`, \`batch_delete_data_table_rows\`, \`import_data_table_rows\` (CSV), \`reorder_data_table_rows\`, \`rollback_data_table_row\`. Row mutations return \`structuredValidationErrors\` on validation failure.
|
|
586
635
|
|
|
587
636
|
**Workflow**: Check permissions → describe action to user → get confirmation → execute → report result
|
|
@@ -593,7 +642,11 @@ Playlist sources support optional \`conditions\` (array) to control when/where t
|
|
|
593
642
|
|
|
594
643
|
Example: \`{ "isOnline": { "eq": true }, "name": { "contains": "store" } }\`
|
|
595
644
|
|
|
596
|
-
**Data table row filter (different syntax)**: \`list_data_table_rows\` takes a JSON-string \`filter\` with \`{column: {op, value|from,to}}\` shape. Ops: \`eq\`, \`neq\`, \`contains\`, \`notContains\`, \`gt\`/\`gte\`/\`lt\`/\`lte\`, \`inRange\`/\`outOfRange\` (from+to), \`isEmpty\`, \`isNotEmpty\`, \`positive\`, \`negative\`, \`beforeNow
|
|
645
|
+
**Data table row filter (different syntax)**: \`list_data_table_rows\` takes a JSON-string \`filter\` with \`{column: {op, value|from,to}}\` shape. Ops: \`eq\`, \`neq\`, \`contains\`, \`notContains\`, \`gt\`/\`gte\`/\`lt\`/\`lte\`, \`inRange\`/\`outOfRange\` (from+to), \`isEmpty\`, \`isNotEmpty\`, \`positive\`, \`negative\`, \`beforeNow\`/\`afterNow\`/\`isToday\` (UTC). Equality shortcut: \`{"status":"active"}\`. Use top-level \`$or\` for disjunction. Example with mix: \`{"status":"active","price":{"op":"gte","value":25}}\`. Invalid filter → GraphQL \`BAD_REQUEST\` with plain-English message.
|
|
646
|
+
|
|
647
|
+
**MEDIA column value**: accepts 3 forms — (1) encrypted media id string (recommended), (2) \`{"mediaId":"..."}\`, (3) canonical \`{url,thumbnailUrl,name,mimeType}\`. Server normalizes to canonical with \`mediaId\`. \`null\`/\`{}\` clears.
|
|
648
|
+
|
|
649
|
+
**Row mutation errors**: \`structuredValidationErrors[]\` with \`{field, code, message}\`; codes are \`Required\` / \`InvalidType\` / \`OutOfRange\` / \`InvalidFormat\` / \`Invalid\`.
|
|
597
650
|
|
|
598
651
|
---
|
|
599
652
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA2B;IAC9D,MAAM,EAAE,eAAe,EAAE,QAAQ,GAAG,KAAK,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAEnE,wCAAwC;IACxC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAErF,OAAO;;;mBAGU,eAAe;kBAChB,QAAQ;eACX,KAAK;mBACD,SAAS;kBACV,OAAO;mBACN,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,oBAAoB,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE
|
|
1
|
+
{"version":3,"file":"system-prompt.js","sourceRoot":"","sources":["../../src/core/system-prompt.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAWH;;GAEG;AACH,MAAM,UAAU,oBAAoB,CAAC,OAA2B;IAC9D,MAAM,EAAE,eAAe,EAAE,QAAQ,GAAG,KAAK,EAAE,WAAW,EAAE,GAAG,OAAO,CAAC;IAEnE,wCAAwC;IACxC,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,SAAS,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACjF,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAErF,OAAO;;;mBAGU,eAAe;kBAChB,QAAQ;eACX,KAAK;mBACD,SAAS;kBACV,OAAO;mBACN,QAAQ,GAAG,WAAW,CAAC,CAAC,CAAC,oBAAoB,WAAW,EAAE,CAAC,CAAC,CAAC,EAAE;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBA6XlE,OAAO;cACT,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;gBAwCH,OAAO;cACT,KAAK;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;0GAoGuF,CAAC;AAC3G,CAAC;AAED;;GAEG;AACH,MAAM,UAAU,qBAAqB,CAAC,OAA2B;IAC/D,MAAM,EAAE,eAAe,EAAE,QAAQ,GAAG,KAAK,EAAE,GAAG,OAAO,CAAC;IACtD,MAAM,GAAG,GAAG,IAAI,IAAI,CAAC,eAAe,CAAC,CAAC;IACtC,MAAM,KAAK,GAAG,GAAG,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAC9C,MAAM,OAAO,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,CAAC,GAAG,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IACnF,MAAM,QAAQ,GAAG,IAAI,IAAI,CAAC,GAAG,CAAC,OAAO,EAAE,GAAG,EAAE,GAAG,QAAQ,CAAC,CAAC,WAAW,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC,CAAC,CAAC;IAErF,OAAO;;eAEM,eAAe,KAAK,QAAQ;mBACxB,KAAK,aAAa,OAAO,cAAc,QAAQ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;kEA+GA,CAAC;AACnE,CAAC"}
|