@kumwe/studio-testkit 0.1.0-alpha.2

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.
Files changed (101) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +39 -0
  3. package/conformance/rich-text/blocks.structural.json +57 -0
  4. package/conformance/rich-text/document.multi-block.json +74 -0
  5. package/conformance/rich-text/embed.hard-break.json +24 -0
  6. package/conformance/rich-text/marks.nested.json +29 -0
  7. package/conformance/rich-text/offsets.astral.json +24 -0
  8. package/conformance/rich-text/paragraph.plain.json +20 -0
  9. package/conformance/rich-text/spans.adjacent.json +27 -0
  10. package/dist/host-testbed.d.ts +40 -0
  11. package/dist/host-testbed.d.ts.map +1 -0
  12. package/dist/host-testbed.js +390 -0
  13. package/dist/host-testbed.js.map +1 -0
  14. package/dist/index.d.ts +29 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +139 -0
  17. package/dist/index.js.map +1 -0
  18. package/fixtures/block.grid.example.json +76 -0
  19. package/fixtures/block.price.example.json +69 -0
  20. package/fixtures/blueprint.product.example.json +92 -0
  21. package/fixtures/command.move-node.example.json +18 -0
  22. package/fixtures/content-model.product.example.json +141 -0
  23. package/fixtures/entry.product.example.json +55 -0
  24. package/fixtures/host-capabilities.example.json +36 -0
  25. package/fixtures/host-error.conflict.example.json +23 -0
  26. package/fixtures/media-asset.example.json +29 -0
  27. package/fixtures/media-asset.processing.example.json +15 -0
  28. package/fixtures/media-reference.example.json +26 -0
  29. package/fixtures/media-upload-session.transferring.example.json +22 -0
  30. package/fixtures/pattern.example.json +49 -0
  31. package/fixtures/plugin.example.json +49 -0
  32. package/fixtures/preview.render.example.json +14 -0
  33. package/fixtures/provenance.example.json +38 -0
  34. package/fixtures/rich-text.example.json +48 -0
  35. package/fixtures/studio-config.example.json +139 -0
  36. package/fixtures/theme.example.json +123 -0
  37. package/fixtures/unresolved-contribution.example.json +23 -0
  38. package/invalid/blueprint.control-character-member.json +59 -0
  39. package/invalid/blueprint.forbidden-property-member.json +61 -0
  40. package/invalid/blueprint.invalid-node-id.json +57 -0
  41. package/invalid/blueprint.invalid-slot-name.json +59 -0
  42. package/invalid/blueprint.published-empty-roots.json +45 -0
  43. package/invalid/blueprint.unknown-member.json +58 -0
  44. package/invalid/command-vector.unknown-error-code.json +103 -0
  45. package/invalid/command.empty-batch.json +17 -0
  46. package/invalid/command.forbidden-id-map-member.json +20 -0
  47. package/invalid/command.negative-position.json +20 -0
  48. package/invalid/command.nested-batch.json +24 -0
  49. package/invalid/command.pattern-in-batch.json +40 -0
  50. package/invalid/command.reset-inherited-property-in-batch.json +24 -0
  51. package/invalid/command.unknown-member.json +23 -0
  52. package/invalid/command.wrong-contract-version.json +22 -0
  53. package/invalid/content-model.published-empty.json +22 -0
  54. package/invalid/entry.forbidden-value-member.json +23 -0
  55. package/invalid/entry.invalid-locale.json +59 -0
  56. package/invalid/host-capabilities.invalid-protocol-version.json +40 -0
  57. package/invalid/media-reference.missing-accessibility.json +25 -0
  58. package/invalid/media-upload-session.complete-without-asset.json +20 -0
  59. package/invalid/preview-message.invalid-digest.json +18 -0
  60. package/invalid/rich-text.embedded-html.json +13 -0
  61. package/invalid/rich-text.unknown-mark.json +19 -0
  62. package/invalid/theme.unknown-member.json +128 -0
  63. package/package.json +48 -0
  64. package/vectors/command/apply-pattern.colliding-id.error.json +97 -0
  65. package/vectors/command/apply-pattern.incomplete-id-map.error.json +111 -0
  66. package/vectors/command/apply-pattern.two-roots.json +259 -0
  67. package/vectors/command/batch.atomic-failure.error.json +100 -0
  68. package/vectors/command/batch.insert-and-configure.json +197 -0
  69. package/vectors/command/duplicate-node.existing-id.error.json +88 -0
  70. package/vectors/command/duplicate-node.explicit-destination.json +183 -0
  71. package/vectors/command/duplicate-node.incomplete-id-map.error.json +91 -0
  72. package/vectors/command/duplicate-node.subtree.json +201 -0
  73. package/vectors/command/insert-node.duplicate-id.error.json +87 -0
  74. package/vectors/command/insert-node.inner-duplicate-id.error.json +115 -0
  75. package/vectors/command/insert-node.invalid-index.error.json +87 -0
  76. package/vectors/command/insert-node.root.json +162 -0
  77. package/vectors/command/insert-node.slot.json +167 -0
  78. package/vectors/command/move-node.into-self.error.json +95 -0
  79. package/vectors/command/move-node.reparent.json +196 -0
  80. package/vectors/command/move-node.within-roots.json +188 -0
  81. package/vectors/command/remove-binding.base.json +159 -0
  82. package/vectors/command/remove-binding.missing.error.json +75 -0
  83. package/vectors/command/remove-node.empties-slot.json +167 -0
  84. package/vectors/command/remove-node.missing.error.json +74 -0
  85. package/vectors/command/remove-node.nested.json +192 -0
  86. package/vectors/command/reorder-children.not-permutation.error.json +85 -0
  87. package/vectors/command/reorder-children.roots.json +182 -0
  88. package/vectors/command/reorder-children.slot.json +192 -0
  89. package/vectors/command/reset-inherited-property.missing.error.json +82 -0
  90. package/vectors/command/reset-inherited-property.single-viewport.json +151 -0
  91. package/vectors/command/reset-inherited-property.two-viewports.json +168 -0
  92. package/vectors/command/restore-node.inner-duplicate-id.error.json +115 -0
  93. package/vectors/command/restore-node.subtree-into-slot.json +195 -0
  94. package/vectors/command/set-binding.add.json +159 -0
  95. package/vectors/command/set-binding.replace.json +178 -0
  96. package/vectors/command/set-property.add.json +143 -0
  97. package/vectors/command/set-property.replace.json +146 -0
  98. package/vectors/command/set-property.viewport-add.json +148 -0
  99. package/vectors/command/unset-property.base.json +143 -0
  100. package/vectors/command/unset-property.missing.error.json +75 -0
  101. package/vectors/command/unset-property.viewport.json +154 -0
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Kumwe Studio contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,39 @@
1
+ # `@kumwe/studio-testkit`
2
+
3
+ Status: pre-Gate-A foundation alpha. Its conformance helpers do not by themselves constitute gate evidence.
4
+
5
+ The current alpha exports three builders—`createBlueprintFixture`, `defineTestBlock`, and
6
+ `createStudioConfigurationFixture`—plus `assertBlueprintConforms` and its structured
7
+ `StudioConformanceError`. The assertion checks a Blueprint against supplied block definitions through
8
+ the current core validator. It does not yet prove host, plugin, theme, preview, media, accessibility,
9
+ security, lifecycle, or cross-language conformance.
10
+
11
+ Package subpaths under `@kumwe/studio-testkit/fixtures/<filename>` contain byte-identical copies of the
12
+ canonical valid examples, including separate MediaAsset and persisted MediaReference examples. There
13
+ is no aggregate runtime `fixtures` export. The helpers do not depend on Vitest or another test runner,
14
+ so consumers may call the current assertion from any JavaScript test environment.
15
+
16
+ ## Host testbed
17
+
18
+ `createTestbedHost(options)` builds a deterministic, fully in-memory `HostAdapter` reference host
19
+ for conformance and failure testing. Every standard port except `model` is implemented against
20
+ seeded fixtures (`documents`, `resources`, `mediaAssets`, `messages`, `permissions`, and an
21
+ optional preview `render` callback). Each operation first checks connectivity and injected
22
+ failures, then validates the `HostRequestContext` envelope structurally (wrong wire protocol
23
+ versions reject as `incompatible`), then enforces the current session generation. Every failure
24
+ rejects with `TestbedHostError`, whose `error` document satisfies `isHostPortError`; `not-found`
25
+ messages never disclose which identifiers exist. Revisions advance as deterministic counters
26
+ (`<id>-r<n>`), optimistic-concurrency conflicts return the safe current revision without changing
27
+ stored state, and search/media pagination uses opaque cursors. The returned `controls` drive
28
+ failure scenarios: `disconnect()`/`reconnect()` for retryable `unavailable` outages,
29
+ `failNext(port, operation, category)` for exactly one injected failure (retryable only for
30
+ `unavailable` and `rate-limited`), and `setPermissions(...)`, which replaces the permission list
31
+ and bumps the session generation so stale contexts reject as `invalid-request`. `revisionOf(id)`,
32
+ the `sessionGeneration` getter, and the recorded `telemetryEvents` support assertions.
33
+ `createHostRequestContextFixture` builds conforming request envelopes. The testbed uses no clocks,
34
+ randomness, or timers, so runs are fully reproducible.
35
+
36
+ Gate A requires valid and invalid fixture corpora plus runner-neutral assertions for block, theme,
37
+ plugin, host-port, command, preview, media, compatibility, migration, lifecycle, security,
38
+ accessibility, localization, and TypeScript/Dart equivalence. Those remain target deliverables; this
39
+ foundation alpha must not be cited as their evidence.
@@ -0,0 +1,57 @@
1
+ {
2
+ "description": "Blockquotes and ordered lists flatten to their leaf blocks, a horizontal rule projects as an empty leaf block, and adjacent text nodes with an identical mark set merge into one span.",
3
+ "document": {
4
+ "type": "doc",
5
+ "content": [
6
+ {
7
+ "type": "blockquote",
8
+ "content": [
9
+ {
10
+ "type": "paragraph",
11
+ "content": [
12
+ { "type": "text", "text": "Quoted " },
13
+ { "type": "text", "text": "wis", "marks": [{ "type": "bold" }] },
14
+ { "type": "text", "text": "dom", "marks": [{ "type": "bold" }] }
15
+ ]
16
+ }
17
+ ]
18
+ },
19
+ { "type": "horizontalRule" },
20
+ {
21
+ "type": "orderedList",
22
+ "attrs": { "start": 3 },
23
+ "content": [
24
+ {
25
+ "type": "listItem",
26
+ "content": [
27
+ {
28
+ "type": "paragraph",
29
+ "content": [{ "type": "text", "text": "Third step first." }]
30
+ }
31
+ ]
32
+ }
33
+ ]
34
+ }
35
+ ]
36
+ },
37
+ "projection": [
38
+ {
39
+ "type": "paragraph",
40
+ "text": "Quoted wisdom",
41
+ "spans": [{ "start": 7, "end": 13, "marks": ["bold"] }],
42
+ "embeds": []
43
+ },
44
+ {
45
+ "type": "horizontalRule",
46
+ "text": "",
47
+ "spans": [],
48
+ "embeds": []
49
+ },
50
+ {
51
+ "type": "paragraph",
52
+ "text": "Third step first.",
53
+ "spans": [],
54
+ "embeds": []
55
+ }
56
+ ]
57
+ }
@@ -0,0 +1,74 @@
1
+ {
2
+ "description": "A heading, a paragraph, and a bullet list flatten to leaf block projections in document order; list containers contribute no entries of their own.",
3
+ "document": {
4
+ "type": "doc",
5
+ "content": [
6
+ {
7
+ "type": "heading",
8
+ "attrs": { "level": 2 },
9
+ "content": [{ "type": "text", "text": "Care guide" }]
10
+ },
11
+ {
12
+ "type": "paragraph",
13
+ "content": [
14
+ { "type": "text", "text": "Wash with " },
15
+ { "type": "text", "text": "cold water", "marks": [{ "type": "bold" }] },
16
+ { "type": "text", "text": " only." }
17
+ ]
18
+ },
19
+ {
20
+ "type": "bulletList",
21
+ "content": [
22
+ {
23
+ "type": "listItem",
24
+ "content": [
25
+ {
26
+ "type": "paragraph",
27
+ "content": [{ "type": "text", "text": "Empty all pockets." }]
28
+ }
29
+ ]
30
+ },
31
+ {
32
+ "type": "listItem",
33
+ "content": [
34
+ {
35
+ "type": "paragraph",
36
+ "content": [
37
+ { "type": "text", "text": "Brush off " },
38
+ { "type": "text", "text": "dry mud", "marks": [{ "type": "italic" }] },
39
+ { "type": "text", "text": "." }
40
+ ]
41
+ }
42
+ ]
43
+ }
44
+ ]
45
+ }
46
+ ]
47
+ },
48
+ "projection": [
49
+ {
50
+ "type": "heading",
51
+ "text": "Care guide",
52
+ "spans": [],
53
+ "embeds": []
54
+ },
55
+ {
56
+ "type": "paragraph",
57
+ "text": "Wash with cold water only.",
58
+ "spans": [{ "start": 10, "end": 20, "marks": ["bold"] }],
59
+ "embeds": []
60
+ },
61
+ {
62
+ "type": "paragraph",
63
+ "text": "Empty all pockets.",
64
+ "spans": [],
65
+ "embeds": []
66
+ },
67
+ {
68
+ "type": "paragraph",
69
+ "text": "Brush off dry mud.",
70
+ "spans": [{ "start": 10, "end": 17, "marks": ["italic"] }],
71
+ "embeds": []
72
+ }
73
+ ]
74
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "description": "A hard break is the portable inline embed: it contributes no characters, anchors at its code-point offset, and does not interrupt a span whose mark set continues across it.",
3
+ "document": {
4
+ "type": "doc",
5
+ "content": [
6
+ {
7
+ "type": "paragraph",
8
+ "content": [
9
+ { "type": "text", "text": "first line", "marks": [{ "type": "italic" }] },
10
+ { "type": "hardBreak" },
11
+ { "type": "text", "text": "second line", "marks": [{ "type": "italic" }] }
12
+ ]
13
+ }
14
+ ]
15
+ },
16
+ "projection": [
17
+ {
18
+ "type": "paragraph",
19
+ "text": "first linesecond line",
20
+ "spans": [{ "start": 0, "end": 21, "marks": ["italic"] }],
21
+ "embeds": [{ "index": 10, "kind": "hardBreak" }]
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,29 @@
1
+ {
2
+ "description": "Nested marks (bold inside an italic run) project to maximal runs whose mark names are sorted lexicographically regardless of the document's mark order, and spans are sorted by (start, end, marks).",
3
+ "document": {
4
+ "type": "doc",
5
+ "content": [
6
+ {
7
+ "type": "paragraph",
8
+ "content": [
9
+ { "type": "text", "text": "The ", "marks": [{ "type": "italic" }] },
10
+ { "type": "text", "text": "quick", "marks": [{ "type": "italic" }, { "type": "bold" }] },
11
+ { "type": "text", "text": " fox", "marks": [{ "type": "italic" }] },
12
+ { "type": "text", "text": " runs." }
13
+ ]
14
+ }
15
+ ]
16
+ },
17
+ "projection": [
18
+ {
19
+ "type": "paragraph",
20
+ "text": "The quick fox runs.",
21
+ "spans": [
22
+ { "start": 0, "end": 4, "marks": ["italic"] },
23
+ { "start": 4, "end": 9, "marks": ["bold", "italic"] },
24
+ { "start": 9, "end": 13, "marks": ["italic"] }
25
+ ],
26
+ "embeds": []
27
+ }
28
+ ]
29
+ }
@@ -0,0 +1,24 @@
1
+ {
2
+ "description": "Astral-plane characters count as one position each: every offset is a Unicode code-point index, never a UTF-16 code-unit or byte index.",
3
+ "document": {
4
+ "type": "doc",
5
+ "content": [
6
+ {
7
+ "type": "paragraph",
8
+ "content": [
9
+ { "type": "text", "text": "𝄞𝄞 " },
10
+ { "type": "text", "text": "G🎼clef", "marks": [{ "type": "bold" }] },
11
+ { "type": "text", "text": " coda𐐷" }
12
+ ]
13
+ }
14
+ ]
15
+ },
16
+ "projection": [
17
+ {
18
+ "type": "paragraph",
19
+ "text": "𝄞𝄞 G🎼clef coda𐐷",
20
+ "spans": [{ "start": 3, "end": 9, "marks": ["bold"] }],
21
+ "embeds": []
22
+ }
23
+ ]
24
+ }
@@ -0,0 +1,20 @@
1
+ {
2
+ "description": "A single plain paragraph projects to one block with its text, no spans, and no embeds.",
3
+ "document": {
4
+ "type": "doc",
5
+ "content": [
6
+ {
7
+ "type": "paragraph",
8
+ "content": [{ "type": "text", "text": "Portable text stays plain." }]
9
+ }
10
+ ]
11
+ },
12
+ "projection": [
13
+ {
14
+ "type": "paragraph",
15
+ "text": "Portable text stays plain.",
16
+ "spans": [],
17
+ "embeds": []
18
+ }
19
+ ]
20
+ }
@@ -0,0 +1,27 @@
1
+ {
2
+ "description": "Adjacent but non-overlapping marks produce separate half-open spans that share a boundary offset: the first span's exclusive end equals the next span's inclusive start.",
3
+ "document": {
4
+ "type": "doc",
5
+ "content": [
6
+ {
7
+ "type": "paragraph",
8
+ "content": [
9
+ { "type": "text", "text": "alpha", "marks": [{ "type": "bold" }] },
10
+ { "type": "text", "text": "beta", "marks": [{ "type": "italic" }] },
11
+ { "type": "text", "text": " tail" }
12
+ ]
13
+ }
14
+ ]
15
+ },
16
+ "projection": [
17
+ {
18
+ "type": "paragraph",
19
+ "text": "alphabeta tail",
20
+ "spans": [
21
+ { "start": 0, "end": 5, "marks": ["bold"] },
22
+ { "start": 5, "end": 9, "marks": ["italic"] }
23
+ ],
24
+ "embeds": []
25
+ }
26
+ ]
27
+ }
@@ -0,0 +1,40 @@
1
+ import { type HostAdapter, type HostErrorCategory, type HostPortError, type HostRequestContext, type MediaAsset, type PreviewRenderPayload, type PreviewRenderedPayload, type QualifiedName, type ResourceSearchHit, type Revision, type StableId, type StudioArtifact, type StudioWireProtocolVersion, type TelemetryEvent } from '@kumwe/studio-protocol';
2
+ export type TestbedPortName = 'artifact' | 'localization' | 'media' | 'permission' | 'preview' | 'recovery' | 'resource' | 'telemetry';
3
+ export interface TestbedHostOptions {
4
+ documents?: StudioArtifact[];
5
+ mediaAssets?: MediaAsset[];
6
+ messages?: Record<string, Record<QualifiedName, string>>;
7
+ permissions?: QualifiedName[];
8
+ render?: (payload: PreviewRenderPayload) => PreviewRenderedPayload;
9
+ resources?: ResourceSearchHit[];
10
+ }
11
+ export interface TestbedControls {
12
+ disconnect(): void;
13
+ failNext(portName: TestbedPortName, operation: string, category: HostErrorCategory): void;
14
+ reconnect(): void;
15
+ revisionOf(id: StableId): Revision | undefined;
16
+ readonly sessionGeneration: Revision;
17
+ setPermissions(permissions: QualifiedName[]): void;
18
+ readonly telemetryEvents: readonly TelemetryEvent[];
19
+ }
20
+ export interface TestbedHost {
21
+ controls: TestbedControls;
22
+ host: HostAdapter;
23
+ }
24
+ export interface HostRequestContextFixtureOptions {
25
+ expectedRevision?: Revision;
26
+ idempotencyKey?: StableId;
27
+ locale?: string;
28
+ operationId?: QualifiedName;
29
+ protocolVersion?: StudioWireProtocolVersion;
30
+ requestId?: StableId;
31
+ resourceContextKey?: StableId;
32
+ sessionGeneration?: Revision;
33
+ }
34
+ export declare class TestbedHostError extends Error {
35
+ readonly error: HostPortError;
36
+ constructor(error: HostPortError);
37
+ }
38
+ export declare function createHostRequestContextFixture(options?: HostRequestContextFixtureOptions): HostRequestContext;
39
+ export declare function createTestbedHost(options?: TestbedHostOptions): TestbedHost;
40
+ //# sourceMappingURL=host-testbed.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"host-testbed.d.ts","sourceRoot":"","sources":["../src/host-testbed.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,KAAK,WAAW,EAChB,KAAK,iBAAiB,EACtB,KAAK,aAAa,EAElB,KAAK,kBAAkB,EAGvB,KAAK,UAAU,EAEf,KAAK,oBAAoB,EACzB,KAAK,sBAAsB,EAC3B,KAAK,aAAa,EAClB,KAAK,iBAAiB,EACtB,KAAK,QAAQ,EACb,KAAK,QAAQ,EACb,KAAK,cAAc,EACnB,KAAK,yBAAyB,EAC9B,KAAK,cAAc,EACpB,MAAM,wBAAwB,CAAC;AAEhC,MAAM,MAAM,eAAe,GACvB,UAAU,GACV,cAAc,GACd,OAAO,GACP,YAAY,GACZ,SAAS,GACT,UAAU,GACV,UAAU,GACV,WAAW,CAAC;AAEhB,MAAM,WAAW,kBAAkB;IACjC,SAAS,CAAC,EAAE,cAAc,EAAE,CAAC;IAC7B,WAAW,CAAC,EAAE,UAAU,EAAE,CAAC;IAC3B,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,aAAa,EAAE,MAAM,CAAC,CAAC,CAAC;IACzD,WAAW,CAAC,EAAE,aAAa,EAAE,CAAC;IAC9B,MAAM,CAAC,EAAE,CAAC,OAAO,EAAE,oBAAoB,KAAK,sBAAsB,CAAC;IACnE,SAAS,CAAC,EAAE,iBAAiB,EAAE,CAAC;CACjC;AAED,MAAM,WAAW,eAAe;IAC9B,UAAU,IAAI,IAAI,CAAC;IACnB,QAAQ,CAAC,QAAQ,EAAE,eAAe,EAAE,SAAS,EAAE,MAAM,EAAE,QAAQ,EAAE,iBAAiB,GAAG,IAAI,CAAC;IAC1F,SAAS,IAAI,IAAI,CAAC;IAClB,UAAU,CAAC,EAAE,EAAE,QAAQ,GAAG,QAAQ,GAAG,SAAS,CAAC;IAC/C,QAAQ,CAAC,iBAAiB,EAAE,QAAQ,CAAC;IACrC,cAAc,CAAC,WAAW,EAAE,aAAa,EAAE,GAAG,IAAI,CAAC;IACnD,QAAQ,CAAC,eAAe,EAAE,SAAS,cAAc,EAAE,CAAC;CACrD;AAED,MAAM,WAAW,WAAW;IAC1B,QAAQ,EAAE,eAAe,CAAC;IAC1B,IAAI,EAAE,WAAW,CAAC;CACnB;AAED,MAAM,WAAW,gCAAgC;IAC/C,gBAAgB,CAAC,EAAE,QAAQ,CAAC;IAC5B,cAAc,CAAC,EAAE,QAAQ,CAAC;IAC1B,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,WAAW,CAAC,EAAE,aAAa,CAAC;IAC5B,eAAe,CAAC,EAAE,yBAAyB,CAAC;IAC5C,SAAS,CAAC,EAAE,QAAQ,CAAC;IACrB,kBAAkB,CAAC,EAAE,QAAQ,CAAC;IAC9B,iBAAiB,CAAC,EAAE,QAAQ,CAAC;CAC9B;AAED,qBAAa,gBAAiB,SAAQ,KAAK;IACzC,SAAgB,KAAK,EAAE,aAAa,CAAC;gBAElB,KAAK,EAAE,aAAa;CAKxC;AAED,wBAAgB,+BAA+B,CAC7C,OAAO,GAAE,gCAAqC,GAC7C,kBAAkB,CAapB;AAED,wBAAgB,iBAAiB,CAAC,OAAO,GAAE,kBAAuB,GAAG,WAAW,CAuW/E"}