@vgai/engine 0.5.14 → 0.5.16
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/adapter/adapter-module.d.ts +228 -17
- package/dist/adapter/adapter-module.d.ts.map +1 -1
- package/dist/adapter/adapter-module.js +224 -42
- package/dist/adapter/authoring-seam-contract.d.ts +530 -0
- package/dist/adapter/authoring-seam-contract.d.ts.map +1 -0
- package/dist/adapter/authoring-seam-contract.js +162 -0
- package/dist/adapter/authoring.d.ts +237 -50
- package/dist/adapter/authoring.d.ts.map +1 -1
- package/dist/adapter/authoring.js +2 -1
- package/dist/adapter/entrypoint-selection-source.d.ts +35 -0
- package/dist/adapter/entrypoint-selection-source.d.ts.map +1 -0
- package/dist/adapter/entrypoint-selection-source.js +151 -0
- package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts +7 -1
- package/dist/adapter/finders/scenes-from-entrypoint-selection.d.ts.map +1 -1
- package/dist/adapter/finders/scenes-from-entrypoint-selection.js +142 -21
- package/dist/adapter/first-party-systems.d.ts +13 -3
- package/dist/adapter/first-party-systems.d.ts.map +1 -1
- package/dist/adapter/first-party-systems.js +10 -3
- package/dist/adapter/index.d.ts +7 -2
- package/dist/adapter/index.d.ts.map +1 -1
- package/dist/adapter/index.js +4 -0
- package/dist/adapter/ingest/contract-system-adapters.d.ts +1 -1
- package/dist/adapter/ingest/contract-system-adapters.d.ts.map +1 -1
- package/dist/adapter/ingest/contract-system-adapters.js +13 -25
- package/dist/adapter/ingest/game-contract-seams.d.ts +214 -0
- package/dist/adapter/ingest/game-contract-seams.d.ts.map +1 -0
- package/dist/adapter/ingest/game-contract-seams.js +62 -0
- package/dist/adapter/ingest/game-contract.d.ts +5 -3
- package/dist/adapter/ingest/game-contract.d.ts.map +1 -1
- package/dist/adapter/ingest/game-contract.js +4 -1
- package/dist/adapter/ingest/merge-debug-adapters.d.ts +52 -0
- package/dist/adapter/ingest/merge-debug-adapters.d.ts.map +1 -0
- package/dist/adapter/ingest/merge-debug-adapters.js +141 -0
- package/dist/adapter/ingest/observation-debug-adapter.d.ts +56 -0
- package/dist/adapter/ingest/observation-debug-adapter.d.ts.map +1 -0
- package/dist/adapter/ingest/observation-debug-adapter.js +131 -0
- package/dist/adapter/ingest/scene-capture.d.ts +38 -13
- package/dist/adapter/ingest/scene-capture.d.ts.map +1 -1
- package/dist/adapter/ingest/scene-capture.js +101 -24
- package/dist/adapter/ingest/visible-capture-window.d.ts +22 -5
- package/dist/adapter/ingest/visible-capture-window.d.ts.map +1 -1
- package/dist/adapter/ingest/visible-capture-window.js +46 -7
- package/dist/adapter/native-debug-module.d.ts +43 -0
- package/dist/adapter/native-debug-module.d.ts.map +1 -0
- package/dist/adapter/native-debug-module.js +230 -0
- package/dist/adapter/object3d-authoring-subject.d.ts +32 -0
- package/dist/adapter/object3d-authoring-subject.d.ts.map +1 -0
- package/dist/adapter/object3d-authoring-subject.js +25 -0
- package/dist/adapter/root-adapter.d.ts +21 -56
- package/dist/adapter/root-adapter.d.ts.map +1 -1
- package/dist/adapter/root-adapter.js +4 -20
- package/dist/adapter/root-seam-contract.d.ts +124 -0
- package/dist/adapter/root-seam-contract.d.ts.map +1 -0
- package/dist/adapter/root-seam-contract.js +36 -0
- package/dist/adapter/seam-evidence.d.ts +118 -0
- package/dist/adapter/seam-evidence.d.ts.map +1 -0
- package/dist/adapter/seam-evidence.js +231 -0
- package/dist/adapter/setup-three-root-adapter.d.ts +2 -3
- package/dist/adapter/setup-three-root-adapter.d.ts.map +1 -1
- package/dist/adapter/setup-three-root-adapter.js +2 -3
- package/dist/adapter/system-adapter.d.ts +6 -1
- package/dist/adapter/system-adapter.d.ts.map +1 -1
- package/dist/adapter/system-seam-contract.d.ts +354 -0
- package/dist/adapter/system-seam-contract.d.ts.map +1 -0
- package/dist/adapter/system-seam-contract.js +95 -0
- package/dist/animation/xstate-animation-binding.d.ts +6 -0
- package/dist/animation/xstate-animation-binding.d.ts.map +1 -1
- package/dist/animation/xstate-animation-binding.js +142 -4
- package/dist/asset-formats/collider.d.ts +1 -1
- package/dist/asset-formats/mesh.d.ts +2 -2
- package/dist/asset-formats/particles.d.ts +1 -1
- package/dist/canvas-react/engine-bridge.d.ts +6 -6
- package/dist/canvas-react/engine-bridge.d.ts.map +1 -1
- package/dist/canvas-react/engine-bridge.js +2 -2
- package/dist/canvas-react/index.d.ts +2 -2
- package/dist/canvas-react/index.d.ts.map +1 -1
- package/dist/canvas-react/index.js +1 -1
- package/dist/canvas-react/pixi-react-adapter.d.ts +15 -9
- package/dist/canvas-react/pixi-react-adapter.d.ts.map +1 -1
- package/dist/canvas-react/pixi-react-adapter.js +43 -29
- package/dist/canvas-react/pixi-react-root-factory.d.ts.map +1 -1
- package/dist/canvas-react/pixi-react-root-factory.js +4 -0
- package/dist/canvas-react/world-context.d.ts +22 -12
- package/dist/canvas-react/world-context.d.ts.map +1 -1
- package/dist/canvas-react/world-context.js +12 -51
- package/dist/ecs/user-data.d.ts +5 -0
- package/dist/ecs/user-data.d.ts.map +1 -1
- package/dist/ecs/user-data.js +3 -0
- package/dist/input/input-manager.d.ts +49 -0
- package/dist/input/input-manager.d.ts.map +1 -1
- package/dist/input/input-manager.js +127 -0
- package/dist/manifest/schema.d.ts +9 -9
- package/dist/manifest/schema.js +1 -1
- package/dist/pixi/authoring.d.ts.map +1 -1
- package/dist/pixi/authoring.js +220 -1
- package/dist/pixi/ingest.d.ts +2 -1
- package/dist/pixi/ingest.d.ts.map +1 -1
- package/dist/pixi/ingest.js +4 -2
- package/dist/pixi/scene-capture.d.ts +9 -1
- package/dist/pixi/scene-capture.d.ts.map +1 -1
- package/dist/pixi/scene-capture.js +9 -6
- package/dist/render/particles-factory.d.ts +13 -6
- package/dist/render/particles-factory.d.ts.map +1 -1
- package/dist/render/particles-factory.js +6 -3
- package/dist/runtime/create-runtime.d.ts +23 -46
- package/dist/runtime/create-runtime.d.ts.map +1 -1
- package/dist/runtime/create-runtime.js +22 -67
- package/dist/runtime/game.d.ts +29 -71
- package/dist/runtime/game.d.ts.map +1 -1
- package/dist/runtime/game.js +15 -54
- package/dist/runtime/mount-game.d.ts.map +1 -1
- package/dist/runtime/mount-game.js +12 -1
- package/dist/runtime/mount-manifest.d.ts.map +1 -1
- package/dist/runtime/mount-manifest.js +4 -5
- package/dist/runtime/types.d.ts +18 -0
- package/dist/runtime/types.d.ts.map +1 -1
- package/dist/setup/setup-renderer.d.ts +3 -4
- package/dist/setup/setup-renderer.d.ts.map +1 -1
- package/dist/setup/setup-renderer.js +3 -4
- package/dist/world3d-react/engine-bridge.d.ts +1 -1
- package/dist/world3d-react/engine-bridge.js +1 -1
- package/dist/world3d-react/r3f-adapter.d.ts +7 -0
- package/dist/world3d-react/r3f-adapter.d.ts.map +1 -1
- package/dist/world3d-react/r3f-adapter.js +50 -21
- package/dist/world3d-react/r3f-root-factory.d.ts.map +1 -1
- package/dist/world3d-react/r3f-root-factory.js +4 -0
- package/dist/world3d-react/world-context.d.ts +9 -3
- package/dist/world3d-react/world-context.d.ts.map +1 -1
- package/dist/world3d-react/world-context.js +5 -18
- package/package.json +1 -1
- package/schemas/engine-capabilities.json +8 -8
- package/schemas/vgai-project.schema.json +1 -1
- package/src/adapter/adapter-module.ts +407 -50
- package/src/adapter/authoring-seam-contract.ts +211 -0
- package/src/adapter/authoring.ts +242 -50
- package/src/adapter/entrypoint-selection-source.ts +159 -0
- package/src/adapter/finders/scenes-from-entrypoint-selection.ts +159 -28
- package/src/adapter/first-party-systems.ts +17 -3
- package/src/adapter/index.ts +51 -1
- package/src/adapter/ingest/contract-system-adapters.ts +26 -30
- package/src/adapter/ingest/game-contract-seams.ts +85 -0
- package/src/adapter/ingest/game-contract.ts +9 -4
- package/src/adapter/ingest/merge-debug-adapters.ts +193 -0
- package/src/adapter/ingest/observation-debug-adapter.ts +158 -0
- package/src/adapter/ingest/scene-capture.ts +126 -23
- package/src/adapter/ingest/visible-capture-window.ts +63 -9
- package/src/adapter/native-debug-module.ts +307 -0
- package/src/adapter/object3d-authoring-subject.ts +50 -0
- package/src/adapter/root-adapter.ts +21 -56
- package/src/adapter/root-seam-contract.ts +56 -0
- package/src/adapter/seam-evidence.ts +336 -0
- package/src/adapter/setup-three-root-adapter.ts +4 -6
- package/src/adapter/system-adapter.ts +6 -1
- package/src/adapter/system-seam-contract.ts +121 -0
- package/src/animation/xstate-animation-binding.ts +151 -4
- package/src/canvas-react/engine-bridge.ts +6 -6
- package/src/canvas-react/index.ts +2 -1
- package/src/canvas-react/pixi-react-adapter.tsx +55 -34
- package/src/canvas-react/pixi-react-root-factory.tsx +4 -0
- package/src/canvas-react/world-context.ts +26 -101
- package/src/ecs/user-data.ts +5 -0
- package/src/input/input-manager.ts +122 -0
- package/src/manifest/schema.ts +1 -1
- package/src/pixi/authoring.ts +236 -1
- package/src/pixi/ingest.ts +9 -2
- package/src/pixi/scene-capture.ts +20 -5
- package/src/render/particles-factory.ts +16 -6
- package/src/runtime/create-runtime.ts +41 -106
- package/src/runtime/game.ts +41 -111
- package/src/runtime/mount-game.ts +19 -1
- package/src/runtime/mount-manifest.ts +4 -5
- package/src/runtime/types.ts +22 -0
- package/src/setup/setup-renderer.ts +3 -4
- package/src/world3d-react/engine-bridge.ts +1 -1
- package/src/world3d-react/r3f-adapter.tsx +64 -24
- package/src/world3d-react/r3f-root-factory.tsx +4 -0
- package/src/world3d-react/world-context.ts +11 -36
|
@@ -0,0 +1,214 @@
|
|
|
1
|
+
/** Exhaustive proof requirements for the game→host contract. Declarations are
|
|
2
|
+
* intentionally insufficient for lifecycle, navigation, commands, state, and
|
|
3
|
+
* system carriers: their consumers must produce stronger receipts. */
|
|
4
|
+
export declare const GAME_CONTRACT_SHAPE: {
|
|
5
|
+
readonly contractVersion: {
|
|
6
|
+
readonly optional: false;
|
|
7
|
+
readonly kind: "value";
|
|
8
|
+
readonly required: "shape";
|
|
9
|
+
};
|
|
10
|
+
readonly root: {
|
|
11
|
+
readonly optional: true;
|
|
12
|
+
readonly kind: "value";
|
|
13
|
+
readonly required: "effect";
|
|
14
|
+
};
|
|
15
|
+
readonly presentation: {
|
|
16
|
+
readonly optional: true;
|
|
17
|
+
readonly kind: "value";
|
|
18
|
+
readonly required: "effect";
|
|
19
|
+
};
|
|
20
|
+
readonly world: {
|
|
21
|
+
readonly optional: true;
|
|
22
|
+
readonly kind: "value";
|
|
23
|
+
readonly required: "effect";
|
|
24
|
+
};
|
|
25
|
+
readonly ready: {
|
|
26
|
+
readonly optional: true;
|
|
27
|
+
readonly kind: "value";
|
|
28
|
+
readonly required: "effect";
|
|
29
|
+
};
|
|
30
|
+
readonly lifecycle: {
|
|
31
|
+
readonly optional: true;
|
|
32
|
+
readonly kind: "value";
|
|
33
|
+
readonly required: "effect";
|
|
34
|
+
};
|
|
35
|
+
readonly scenes: {
|
|
36
|
+
readonly optional: true;
|
|
37
|
+
readonly kind: "value";
|
|
38
|
+
readonly required: "effect";
|
|
39
|
+
};
|
|
40
|
+
readonly systems: {
|
|
41
|
+
readonly optional: true;
|
|
42
|
+
readonly kind: "value";
|
|
43
|
+
readonly required: "operation";
|
|
44
|
+
};
|
|
45
|
+
};
|
|
46
|
+
export declare const GAME_LIFECYCLE_SHAPE: {
|
|
47
|
+
readonly start: {
|
|
48
|
+
readonly optional: true;
|
|
49
|
+
readonly kind: "function";
|
|
50
|
+
readonly required: "effect";
|
|
51
|
+
};
|
|
52
|
+
readonly pause: {
|
|
53
|
+
readonly optional: true;
|
|
54
|
+
readonly kind: "function";
|
|
55
|
+
readonly required: "effect";
|
|
56
|
+
};
|
|
57
|
+
readonly resume: {
|
|
58
|
+
readonly optional: true;
|
|
59
|
+
readonly kind: "function";
|
|
60
|
+
readonly required: "effect";
|
|
61
|
+
};
|
|
62
|
+
};
|
|
63
|
+
export declare const GAME_SCENES_SHAPE: {
|
|
64
|
+
readonly list: {
|
|
65
|
+
readonly optional: false;
|
|
66
|
+
readonly kind: "function";
|
|
67
|
+
readonly required: "operation";
|
|
68
|
+
};
|
|
69
|
+
readonly current: {
|
|
70
|
+
readonly optional: false;
|
|
71
|
+
readonly kind: "function";
|
|
72
|
+
readonly required: "operation";
|
|
73
|
+
};
|
|
74
|
+
readonly goTo: {
|
|
75
|
+
readonly optional: false;
|
|
76
|
+
readonly kind: "function";
|
|
77
|
+
readonly required: "effect";
|
|
78
|
+
};
|
|
79
|
+
};
|
|
80
|
+
export declare const GAME_SCENE_SHAPE: {
|
|
81
|
+
readonly id: {
|
|
82
|
+
readonly optional: false;
|
|
83
|
+
readonly kind: "value";
|
|
84
|
+
readonly required: "shape";
|
|
85
|
+
};
|
|
86
|
+
readonly label: {
|
|
87
|
+
readonly optional: false;
|
|
88
|
+
readonly kind: "value";
|
|
89
|
+
readonly required: "shape";
|
|
90
|
+
};
|
|
91
|
+
};
|
|
92
|
+
export declare const GAME_COMMAND_SHAPE: {
|
|
93
|
+
readonly name: {
|
|
94
|
+
readonly optional: false;
|
|
95
|
+
readonly kind: "value";
|
|
96
|
+
readonly required: "shape";
|
|
97
|
+
};
|
|
98
|
+
readonly description: {
|
|
99
|
+
readonly optional: true;
|
|
100
|
+
readonly kind: "value";
|
|
101
|
+
readonly required: "shape";
|
|
102
|
+
};
|
|
103
|
+
readonly argsJsonSchema: {
|
|
104
|
+
readonly optional: true;
|
|
105
|
+
readonly kind: "value";
|
|
106
|
+
readonly required: "shape";
|
|
107
|
+
};
|
|
108
|
+
readonly run: {
|
|
109
|
+
readonly optional: false;
|
|
110
|
+
readonly kind: "function";
|
|
111
|
+
readonly required: "effect";
|
|
112
|
+
};
|
|
113
|
+
};
|
|
114
|
+
export declare const GAME_STATE_PROVIDER_SHAPE: {
|
|
115
|
+
readonly name: {
|
|
116
|
+
readonly optional: false;
|
|
117
|
+
readonly kind: "value";
|
|
118
|
+
readonly required: "shape";
|
|
119
|
+
};
|
|
120
|
+
readonly tier: {
|
|
121
|
+
readonly optional: true;
|
|
122
|
+
readonly kind: "value";
|
|
123
|
+
readonly required: "shape";
|
|
124
|
+
};
|
|
125
|
+
readonly read: {
|
|
126
|
+
readonly optional: false;
|
|
127
|
+
readonly kind: "function";
|
|
128
|
+
readonly required: "operation";
|
|
129
|
+
};
|
|
130
|
+
};
|
|
131
|
+
export declare const GAME_HIERARCHY_GROUP_SHAPE: {
|
|
132
|
+
readonly id: {
|
|
133
|
+
readonly optional: false;
|
|
134
|
+
readonly kind: "value";
|
|
135
|
+
readonly required: "shape";
|
|
136
|
+
};
|
|
137
|
+
readonly label: {
|
|
138
|
+
readonly optional: false;
|
|
139
|
+
readonly kind: "value";
|
|
140
|
+
readonly required: "shape";
|
|
141
|
+
};
|
|
142
|
+
readonly count: {
|
|
143
|
+
readonly optional: false;
|
|
144
|
+
readonly kind: "value";
|
|
145
|
+
readonly required: "operation";
|
|
146
|
+
};
|
|
147
|
+
};
|
|
148
|
+
export declare const GAME_SYSTEMS_SHAPE: {
|
|
149
|
+
readonly commands: {
|
|
150
|
+
readonly optional: true;
|
|
151
|
+
readonly kind: "value";
|
|
152
|
+
readonly required: "operation";
|
|
153
|
+
};
|
|
154
|
+
readonly state: {
|
|
155
|
+
readonly optional: true;
|
|
156
|
+
readonly kind: "value";
|
|
157
|
+
readonly required: "operation";
|
|
158
|
+
};
|
|
159
|
+
readonly hierarchy: {
|
|
160
|
+
readonly optional: true;
|
|
161
|
+
readonly kind: "function";
|
|
162
|
+
readonly required: "operation";
|
|
163
|
+
};
|
|
164
|
+
readonly systemAdapters: {
|
|
165
|
+
readonly optional: true;
|
|
166
|
+
readonly kind: "value";
|
|
167
|
+
readonly required: "operation";
|
|
168
|
+
};
|
|
169
|
+
};
|
|
170
|
+
export declare const GAME_SYSTEM_ADAPTERS_SHAPE: {
|
|
171
|
+
readonly physics: {
|
|
172
|
+
readonly optional: true;
|
|
173
|
+
readonly kind: "value";
|
|
174
|
+
readonly required: "effect";
|
|
175
|
+
};
|
|
176
|
+
readonly networking: {
|
|
177
|
+
readonly optional: true;
|
|
178
|
+
readonly kind: "value";
|
|
179
|
+
readonly required: "operation";
|
|
180
|
+
};
|
|
181
|
+
readonly navigation: {
|
|
182
|
+
readonly optional: true;
|
|
183
|
+
readonly kind: "value";
|
|
184
|
+
readonly required: "operation";
|
|
185
|
+
};
|
|
186
|
+
readonly audio: {
|
|
187
|
+
readonly optional: true;
|
|
188
|
+
readonly kind: "value";
|
|
189
|
+
readonly required: "effect";
|
|
190
|
+
};
|
|
191
|
+
readonly camera: {
|
|
192
|
+
readonly optional: true;
|
|
193
|
+
readonly kind: "value";
|
|
194
|
+
readonly required: "effect";
|
|
195
|
+
};
|
|
196
|
+
readonly renderDebug: {
|
|
197
|
+
readonly optional: true;
|
|
198
|
+
readonly kind: "value";
|
|
199
|
+
readonly required: "effect";
|
|
200
|
+
};
|
|
201
|
+
};
|
|
202
|
+
export declare const GAME_SYSTEM_EMPTY_SHAPE: {
|
|
203
|
+
readonly present: {
|
|
204
|
+
readonly optional: false;
|
|
205
|
+
readonly kind: "value";
|
|
206
|
+
readonly required: "shape";
|
|
207
|
+
};
|
|
208
|
+
readonly evidence: {
|
|
209
|
+
readonly optional: false;
|
|
210
|
+
readonly kind: "value";
|
|
211
|
+
readonly required: "claim";
|
|
212
|
+
};
|
|
213
|
+
};
|
|
214
|
+
//# sourceMappingURL=game-contract-seams.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"game-contract-seams.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/game-contract-seams.ts"],"names":[],"mappings":"AAAA;;sEAEsE;AAgBtE,eAAO,MAAM,mBAAmB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAS9B,CAAC;AAEH,eAAO,MAAM,oBAAoB;;;;;;;;;;;;;;;;CAI/B,CAAC;AAEH,eAAO,MAAM,iBAAiB;;;;;;;;;;;;;;;;CAI5B,CAAC;AAEH,eAAO,MAAM,gBAAgB;;;;;;;;;;;CAG3B,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;CAK7B,CAAC;AAEH,eAAO,MAAM,yBAAyB;;;;;;;;;;;;;;;;CAIpC,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;CAIrC,CAAC;AAEH,eAAO,MAAM,kBAAkB;;;;;;;;;;;;;;;;;;;;;CAK7B,CAAC;AAEH,eAAO,MAAM,0BAA0B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;CAOrC,CAAC;AAEH,eAAO,MAAM,uBAAuB;;;;;;;;;;;CAGlC,CAAC"}
|
|
@@ -0,0 +1,62 @@
|
|
|
1
|
+
/** Exhaustive proof requirements for the game→host contract. Declarations are
|
|
2
|
+
* intentionally insufficient for lifecycle, navigation, commands, state, and
|
|
3
|
+
* system carriers: their consumers must produce stronger receipts. */
|
|
4
|
+
import { defineSeamShape } from '../seam-evidence';
|
|
5
|
+
export const GAME_CONTRACT_SHAPE = defineSeamShape()({
|
|
6
|
+
contractVersion: { optional: false, kind: 'value', required: 'shape' },
|
|
7
|
+
root: { optional: true, kind: 'value', required: 'effect' },
|
|
8
|
+
presentation: { optional: true, kind: 'value', required: 'effect' },
|
|
9
|
+
world: { optional: true, kind: 'value', required: 'effect' },
|
|
10
|
+
ready: { optional: true, kind: 'value', required: 'effect' },
|
|
11
|
+
lifecycle: { optional: true, kind: 'value', required: 'effect' },
|
|
12
|
+
scenes: { optional: true, kind: 'value', required: 'effect' },
|
|
13
|
+
systems: { optional: true, kind: 'value', required: 'operation' },
|
|
14
|
+
});
|
|
15
|
+
export const GAME_LIFECYCLE_SHAPE = defineSeamShape()({
|
|
16
|
+
start: { optional: true, kind: 'function', required: 'effect' },
|
|
17
|
+
pause: { optional: true, kind: 'function', required: 'effect' },
|
|
18
|
+
resume: { optional: true, kind: 'function', required: 'effect' },
|
|
19
|
+
});
|
|
20
|
+
export const GAME_SCENES_SHAPE = defineSeamShape()({
|
|
21
|
+
list: { optional: false, kind: 'function', required: 'operation' },
|
|
22
|
+
current: { optional: false, kind: 'function', required: 'operation' },
|
|
23
|
+
goTo: { optional: false, kind: 'function', required: 'effect' },
|
|
24
|
+
});
|
|
25
|
+
export const GAME_SCENE_SHAPE = defineSeamShape()({
|
|
26
|
+
id: { optional: false, kind: 'value', required: 'shape' },
|
|
27
|
+
label: { optional: false, kind: 'value', required: 'shape' },
|
|
28
|
+
});
|
|
29
|
+
export const GAME_COMMAND_SHAPE = defineSeamShape()({
|
|
30
|
+
name: { optional: false, kind: 'value', required: 'shape' },
|
|
31
|
+
description: { optional: true, kind: 'value', required: 'shape' },
|
|
32
|
+
argsJsonSchema: { optional: true, kind: 'value', required: 'shape' },
|
|
33
|
+
run: { optional: false, kind: 'function', required: 'effect' },
|
|
34
|
+
});
|
|
35
|
+
export const GAME_STATE_PROVIDER_SHAPE = defineSeamShape()({
|
|
36
|
+
name: { optional: false, kind: 'value', required: 'shape' },
|
|
37
|
+
tier: { optional: true, kind: 'value', required: 'shape' },
|
|
38
|
+
read: { optional: false, kind: 'function', required: 'operation' },
|
|
39
|
+
});
|
|
40
|
+
export const GAME_HIERARCHY_GROUP_SHAPE = defineSeamShape()({
|
|
41
|
+
id: { optional: false, kind: 'value', required: 'shape' },
|
|
42
|
+
label: { optional: false, kind: 'value', required: 'shape' },
|
|
43
|
+
count: { optional: false, kind: 'value', required: 'operation' },
|
|
44
|
+
});
|
|
45
|
+
export const GAME_SYSTEMS_SHAPE = defineSeamShape()({
|
|
46
|
+
commands: { optional: true, kind: 'value', required: 'operation' },
|
|
47
|
+
state: { optional: true, kind: 'value', required: 'operation' },
|
|
48
|
+
hierarchy: { optional: true, kind: 'function', required: 'operation' },
|
|
49
|
+
systemAdapters: { optional: true, kind: 'value', required: 'operation' },
|
|
50
|
+
});
|
|
51
|
+
export const GAME_SYSTEM_ADAPTERS_SHAPE = defineSeamShape()({
|
|
52
|
+
physics: { optional: true, kind: 'value', required: 'effect' },
|
|
53
|
+
networking: { optional: true, kind: 'value', required: 'operation' },
|
|
54
|
+
navigation: { optional: true, kind: 'value', required: 'operation' },
|
|
55
|
+
audio: { optional: true, kind: 'value', required: 'effect' },
|
|
56
|
+
camera: { optional: true, kind: 'value', required: 'effect' },
|
|
57
|
+
renderDebug: { optional: true, kind: 'value', required: 'effect' },
|
|
58
|
+
});
|
|
59
|
+
export const GAME_SYSTEM_EMPTY_SHAPE = defineSeamShape()({
|
|
60
|
+
present: { optional: false, kind: 'value', required: 'shape' },
|
|
61
|
+
evidence: { optional: false, kind: 'value', required: 'claim' },
|
|
62
|
+
});
|
|
@@ -25,9 +25,11 @@ import type { AudioAdapter, CameraAdapter, NavigationAdapter, NetworkingAdapter,
|
|
|
25
25
|
* executes, the game may defer its session side-effects (backend connections,
|
|
26
26
|
* narrative, audio) and render a quiet, inspectable scene; the host calls
|
|
27
27
|
* `start()` — at most once per mount — when the user presses ▶. Declaring
|
|
28
|
-
* `pause`/`resume` means the game can genuinely freeze/unfreeze itself
|
|
29
|
-
*
|
|
30
|
-
*
|
|
28
|
+
* `pause`/`resume` means the game can genuinely freeze/unfreeze itself. They
|
|
29
|
+
* are one indivisible pair: the ingest adapter binds that pair as its mounted
|
|
30
|
+
* lifecycle control, or binds its outside-in loop gate when neither is
|
|
31
|
+
* declared. Host consumers see only the bound control; they never mix one
|
|
32
|
+
* declared half with a fallback half.
|
|
31
33
|
*/
|
|
32
34
|
export interface VgaiGameLifecycle {
|
|
33
35
|
start?(): void;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"game-contract.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/game-contract.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;GAmBG;AAEH,OAAO,KAAK,EACV,YAAY,EACZ,aAAa,EACb,iBAAiB,EACjB,iBAAiB,EACjB,cAAc,EACd,kBAAkB,EACnB,MAAM,mBAAmB,CAAC;
|
|
1
|
+
{"version":3,"file":"game-contract.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/game-contract.ts"],"names":[],"mappings":"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"}
|
|
@@ -18,6 +18,7 @@
|
|
|
18
18
|
* Origin (root), F17+F21 (lifecycle), WO-SYS1 (systems), WO-SYS2
|
|
19
19
|
* (`systems.systemAdapters`).
|
|
20
20
|
*/
|
|
21
|
+
import { GAME_SCENES_SHAPE } from './game-contract-seams';
|
|
21
22
|
/**
|
|
22
23
|
* Read the declared contract, if any. The `contractVersion` gate is the
|
|
23
24
|
* forward-compatibility hinge: a future v2 game on a v1 host is ignored
|
|
@@ -38,7 +39,9 @@ export function readGameContract(scope = typeof window === 'undefined' ? null :
|
|
|
38
39
|
}
|
|
39
40
|
/** The endpoints a scene surface must carry: every one of them is called by the
|
|
40
41
|
* projection, so a declaration missing any cannot be honoured. */
|
|
41
|
-
const SCENES_REQUIRED_MEMBERS =
|
|
42
|
+
const SCENES_REQUIRED_MEMBERS = Object.entries(GAME_SCENES_SHAPE)
|
|
43
|
+
.filter(([, spec]) => !spec.optional)
|
|
44
|
+
.map(([member]) => member);
|
|
42
45
|
/**
|
|
43
46
|
* Read the declared {@link VgaiGameScenes}, refusing a malformed one BY NAME.
|
|
44
47
|
*
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONE `DebugAdapter` out of several projections of the same mount.
|
|
3
|
+
*
|
|
4
|
+
* Two feeders exist today and they are peers, not layers: the game's own
|
|
5
|
+
* declared system surface (`contract-debug-adapter.ts`, from
|
|
6
|
+
* `window.vgaiGame.systems`) and its adapter module's observation table
|
|
7
|
+
* (`observation-debug-adapter.ts`). Both project onto the ONE runtime door the
|
|
8
|
+
* editor and `vgai eval` already read (`SystemAdapters.debug`), so the merge
|
|
9
|
+
* belongs here rather than in a second slot — a consumer must not be able to
|
|
10
|
+
* tell a name's provenance, which is the whole point of both projections.
|
|
11
|
+
*
|
|
12
|
+
* ## A collision REFUSES the name; it never shadows it
|
|
13
|
+
*
|
|
14
|
+
* When two feeders declare the same provider or command name, one of them would
|
|
15
|
+
* otherwise win silently and an agent would read the wrong thing with every log
|
|
16
|
+
* line still saying success. So the merged adapter:
|
|
17
|
+
*
|
|
18
|
+
* - LISTS the name once (it is declared, and hiding it would be its own lie);
|
|
19
|
+
* - REFUSES to answer it with a coded `DEBUG_NAME_COLLISION` naming BOTH
|
|
20
|
+
* sources, at `state()` / `invoke()` and per-key inside `stateAll()`;
|
|
21
|
+
* - reports the collisions to the caller ({@link MergedDebugAdapters}) so the
|
|
22
|
+
* mount can say so out loud where a person will see it, instead of the
|
|
23
|
+
* refusal waiting to be discovered by whoever calls the name first.
|
|
24
|
+
*
|
|
25
|
+
* The refusal is per-NAME, not per-mount, deliberately: killing the mount would
|
|
26
|
+
* cost a user their whole game to protect against one ambiguous read, and the
|
|
27
|
+
* per-name refusal already gives the same guarantee — nothing is silently
|
|
28
|
+
* shadowed — with none of the collateral.
|
|
29
|
+
*/
|
|
30
|
+
import type { DebugAdapter } from '../system-adapter';
|
|
31
|
+
/** One feeder, with the words a collision message names it by. */
|
|
32
|
+
export interface DebugAdapterSource {
|
|
33
|
+
/** How this projection is named to a reader — its provenance, in prose. */
|
|
34
|
+
readonly label: string;
|
|
35
|
+
/** `null` when this feeder projected nothing (the honest floor both return). */
|
|
36
|
+
readonly adapter: DebugAdapter | null;
|
|
37
|
+
}
|
|
38
|
+
export interface MergedDebugAdapters {
|
|
39
|
+
/** The one door, or `null` when no feeder projected anything. */
|
|
40
|
+
readonly adapter: DebugAdapter | null;
|
|
41
|
+
/** One sentence per colliding name, naming both sources. Empty is the norm. */
|
|
42
|
+
readonly collisions: readonly string[];
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Fold every projection of one mount onto a single {@link DebugAdapter}.
|
|
46
|
+
*
|
|
47
|
+
* `events()` concatenates, because an event ring is append-only and two rings
|
|
48
|
+
* genuinely both happened — there is no name to collide on. Everything else is
|
|
49
|
+
* name-keyed and therefore goes through the collision rule above.
|
|
50
|
+
*/
|
|
51
|
+
export declare function mergeDebugAdapters(sources: readonly DebugAdapterSource[]): MergedDebugAdapters;
|
|
52
|
+
//# sourceMappingURL=merge-debug-adapters.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"merge-debug-adapters.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/merge-debug-adapters.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4BG;AAGH,OAAO,KAAK,EAAE,YAAY,EAAsC,MAAM,mBAAmB,CAAC;AAE1F,kEAAkE;AAClE,MAAM,WAAW,kBAAkB;IACjC,2EAA2E;IAC3E,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;IACvB,gFAAgF;IAChF,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;CACvC;AAED,MAAM,WAAW,mBAAmB;IAClC,iEAAiE;IACjE,QAAQ,CAAC,OAAO,EAAE,YAAY,GAAG,IAAI,CAAC;IACtC,+EAA+E;IAC/E,QAAQ,CAAC,UAAU,EAAE,SAAS,MAAM,EAAE,CAAC;CACxC;AAsCD;;;;;;GAMG;AACH,wBAAgB,kBAAkB,CAAC,OAAO,EAAE,SAAS,kBAAkB,EAAE,GAAG,mBAAmB,CA0F9F"}
|
|
@@ -0,0 +1,141 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ONE `DebugAdapter` out of several projections of the same mount.
|
|
3
|
+
*
|
|
4
|
+
* Two feeders exist today and they are peers, not layers: the game's own
|
|
5
|
+
* declared system surface (`contract-debug-adapter.ts`, from
|
|
6
|
+
* `window.vgaiGame.systems`) and its adapter module's observation table
|
|
7
|
+
* (`observation-debug-adapter.ts`). Both project onto the ONE runtime door the
|
|
8
|
+
* editor and `vgai eval` already read (`SystemAdapters.debug`), so the merge
|
|
9
|
+
* belongs here rather than in a second slot — a consumer must not be able to
|
|
10
|
+
* tell a name's provenance, which is the whole point of both projections.
|
|
11
|
+
*
|
|
12
|
+
* ## A collision REFUSES the name; it never shadows it
|
|
13
|
+
*
|
|
14
|
+
* When two feeders declare the same provider or command name, one of them would
|
|
15
|
+
* otherwise win silently and an agent would read the wrong thing with every log
|
|
16
|
+
* line still saying success. So the merged adapter:
|
|
17
|
+
*
|
|
18
|
+
* - LISTS the name once (it is declared, and hiding it would be its own lie);
|
|
19
|
+
* - REFUSES to answer it with a coded `DEBUG_NAME_COLLISION` naming BOTH
|
|
20
|
+
* sources, at `state()` / `invoke()` and per-key inside `stateAll()`;
|
|
21
|
+
* - reports the collisions to the caller ({@link MergedDebugAdapters}) so the
|
|
22
|
+
* mount can say so out loud where a person will see it, instead of the
|
|
23
|
+
* refusal waiting to be discovered by whoever calls the name first.
|
|
24
|
+
*
|
|
25
|
+
* The refusal is per-NAME, not per-mount, deliberately: killing the mount would
|
|
26
|
+
* cost a user their whole game to protect against one ambiguous read, and the
|
|
27
|
+
* per-name refusal already gives the same guarantee — nothing is silently
|
|
28
|
+
* shadowed — with none of the collateral.
|
|
29
|
+
*/
|
|
30
|
+
import { DebugError } from '../../runtime/debug-registry';
|
|
31
|
+
function collisionError(name, labels) {
|
|
32
|
+
return new DebugError('DEBUG_NAME_COLLISION', `"${name}" is declared by more than one source (${labels.join(' and ')}) — refusing to ` +
|
|
33
|
+
'answer rather than picking one silently. Rename it in whichever source you own.', { name, sources: [...labels] });
|
|
34
|
+
}
|
|
35
|
+
/** Names each feeder claims, in listing order, de-duplicated within a feeder. */
|
|
36
|
+
function claimedNames(sources, face) {
|
|
37
|
+
const order = [];
|
|
38
|
+
const labelsByName = new Map();
|
|
39
|
+
for (const source of sources) {
|
|
40
|
+
if (!source.adapter)
|
|
41
|
+
continue;
|
|
42
|
+
const names = face === 'state'
|
|
43
|
+
? source.adapter.providers().map((provider) => provider.name)
|
|
44
|
+
: source.adapter.commands().map((command) => command.name);
|
|
45
|
+
for (const name of new Set(names)) {
|
|
46
|
+
if (!labelsByName.has(name)) {
|
|
47
|
+
labelsByName.set(name, []);
|
|
48
|
+
order.push(name);
|
|
49
|
+
}
|
|
50
|
+
labelsByName.get(name)?.push(source.label);
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
return { order, labelsByName };
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Fold every projection of one mount onto a single {@link DebugAdapter}.
|
|
57
|
+
*
|
|
58
|
+
* `events()` concatenates, because an event ring is append-only and two rings
|
|
59
|
+
* genuinely both happened — there is no name to collide on. Everything else is
|
|
60
|
+
* name-keyed and therefore goes through the collision rule above.
|
|
61
|
+
*/
|
|
62
|
+
export function mergeDebugAdapters(sources) {
|
|
63
|
+
const live = sources.filter((source) => source.adapter !== null);
|
|
64
|
+
if (live.length === 0)
|
|
65
|
+
return { adapter: null, collisions: [] };
|
|
66
|
+
if (live.length === 1)
|
|
67
|
+
return { adapter: live[0].adapter, collisions: [] };
|
|
68
|
+
const providers = claimedNames(live, 'state');
|
|
69
|
+
const commands = claimedNames(live, 'command');
|
|
70
|
+
const collisions = [];
|
|
71
|
+
for (const [face, claimed] of [
|
|
72
|
+
['state provider', providers],
|
|
73
|
+
['command', commands],
|
|
74
|
+
]) {
|
|
75
|
+
for (const name of claimed.order) {
|
|
76
|
+
const labels = claimed.labelsByName.get(name) ?? [];
|
|
77
|
+
if (labels.length > 1) {
|
|
78
|
+
collisions.push(`${face} "${name}" is declared by ${labels.join(' and ')}`);
|
|
79
|
+
}
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
/** The feeder that owns `name`, or a thrown collision error when several do. */
|
|
83
|
+
const ownerOf = (claimed, name, face) => {
|
|
84
|
+
const labels = claimed.labelsByName.get(name);
|
|
85
|
+
if (!labels)
|
|
86
|
+
return null;
|
|
87
|
+
if (labels.length > 1)
|
|
88
|
+
throw collisionError(name, labels);
|
|
89
|
+
return (live.find((source) => {
|
|
90
|
+
const owned = face === 'state'
|
|
91
|
+
? source.adapter?.providers().some((provider) => provider.name === name)
|
|
92
|
+
: source.adapter?.commands().some((command) => command.name === name);
|
|
93
|
+
return owned === true;
|
|
94
|
+
})?.adapter ?? null);
|
|
95
|
+
};
|
|
96
|
+
return {
|
|
97
|
+
adapter: {
|
|
98
|
+
providers: () => live.flatMap((source) => source.adapter?.providers() ?? []).filter(uniqueByName()),
|
|
99
|
+
state: (name) => {
|
|
100
|
+
const owner = ownerOf(providers, name, 'state');
|
|
101
|
+
if (!owner) {
|
|
102
|
+
throw new DebugError('STATE_PROVIDER_NOT_FOUND', `No state provider named "${name}" is declared by this game.`, { registered: providers.order });
|
|
103
|
+
}
|
|
104
|
+
return owner.state(name);
|
|
105
|
+
},
|
|
106
|
+
stateAll: () => {
|
|
107
|
+
const out = {};
|
|
108
|
+
for (const name of providers.order) {
|
|
109
|
+
try {
|
|
110
|
+
out[name] = ownerOf(providers, name, 'state')?.state(name);
|
|
111
|
+
}
|
|
112
|
+
catch (err) {
|
|
113
|
+
out[name] = { __error: String(err) };
|
|
114
|
+
}
|
|
115
|
+
}
|
|
116
|
+
return out;
|
|
117
|
+
},
|
|
118
|
+
commands: () => live.flatMap((source) => source.adapter?.commands() ?? []).filter(uniqueByName()),
|
|
119
|
+
invoke: async (name, args) => {
|
|
120
|
+
const owner = ownerOf(commands, name, 'command');
|
|
121
|
+
if (!owner) {
|
|
122
|
+
throw new DebugError('DEBUG_COMMAND_NOT_REGISTERED', `No command named "${name}" is declared by this game.`, { registered: commands.order });
|
|
123
|
+
}
|
|
124
|
+
return owner.invoke(name, args);
|
|
125
|
+
},
|
|
126
|
+
events: (sinceSeq) => live.flatMap((source) => source.adapter?.events(sinceSeq) ?? []),
|
|
127
|
+
},
|
|
128
|
+
collisions,
|
|
129
|
+
};
|
|
130
|
+
}
|
|
131
|
+
/** Keep the FIRST listing of each name — the merged listing advertises a name
|
|
132
|
+
* once, whatever `state()`/`invoke()` then decide to do with it. */
|
|
133
|
+
function uniqueByName() {
|
|
134
|
+
const seen = new Set();
|
|
135
|
+
return (value) => {
|
|
136
|
+
if (seen.has(value.name))
|
|
137
|
+
return false;
|
|
138
|
+
seen.add(value.name);
|
|
139
|
+
return true;
|
|
140
|
+
};
|
|
141
|
+
}
|
|
@@ -0,0 +1,56 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Projects an ADAPTER's declared observation slots
|
|
3
|
+
* (`AdapterDefinition.observation`, `adapter/adapter-module.ts`) onto the host's
|
|
4
|
+
* existing {@link DebugAdapter} — the one seam `game.providers()` /
|
|
5
|
+
* `game.state()` / `game.commands()` already read through
|
|
6
|
+
* (`command-listener.ts`'s `dispatchBridgeMethod` → `getActiveSystems().debug`).
|
|
7
|
+
*
|
|
8
|
+
* This is the SIBLING of `contract-debug-adapter.ts` and deliberately the same
|
|
9
|
+
* shape: a projection rather than a second door. The two differ only in WHO
|
|
10
|
+
* declared the surface — the game itself, on `window.vgaiGame.systems`, or the
|
|
11
|
+
* game's adapter module beside it — and a consumer downstream must not be able
|
|
12
|
+
* to tell them apart. `merge-debug-adapters.ts` is what folds both onto the one
|
|
13
|
+
* slot.
|
|
14
|
+
*
|
|
15
|
+
* ## What `game` is
|
|
16
|
+
*
|
|
17
|
+
* The host's to hand over, and for an INGEST mount it is the REALM the game's
|
|
18
|
+
* own modules ran in. That is not a convenience: an ingest mount runs the game
|
|
19
|
+
* in the editor's own realm (`game-contract.ts`'s `readGameContract` says so —
|
|
20
|
+
* "the realm every ingest mount runs the game's modules in, where the game and
|
|
21
|
+
* the host share one global"), a vendored bundle's adapter is HOST-realm by the
|
|
22
|
+
* placement rule, and the only handles such a game publishes are the ones on
|
|
23
|
+
* that realm — its runtime's own public registry, or a host-build seam beside
|
|
24
|
+
* it. Handing the realm is therefore handing the game everything it actually
|
|
25
|
+
* exposes; handing anything narrower would make the adapter reach for `window`
|
|
26
|
+
* itself, which is the same read with the provenance hidden.
|
|
27
|
+
*
|
|
28
|
+
* ## The two-state rule, kept
|
|
29
|
+
*
|
|
30
|
+
* Declaring a slot and answering it are separate facts. A declaration with NO
|
|
31
|
+
* `answer` is still listed and refuses BY NAME when read — never omitted,
|
|
32
|
+
* because omitting it would report "the game has no such state" when the truth
|
|
33
|
+
* is "the table declared it and nothing binds it yet". Same for a throwing
|
|
34
|
+
* `answer`: it propagates (exactly as a first-party provider's does), and only
|
|
35
|
+
* `stateAll()` isolates it per key.
|
|
36
|
+
*
|
|
37
|
+
* ## What this deliberately does NOT do
|
|
38
|
+
*
|
|
39
|
+
* - **Validate arguments.** A declared command's `answer` receives the invoked
|
|
40
|
+
* argument list after the game handle; there is no Zod tuple beside a foreign
|
|
41
|
+
* game, so a verb validates itself and throws its own error, surfaced wrapped
|
|
42
|
+
* as `DEBUG_COMMAND_FAILED`. Identical to the contract projection's stance.
|
|
43
|
+
* - **Fabricate an event ring.** Nothing emits behind a declaration, so
|
|
44
|
+
* `events()` is empty — accurate, not a stub.
|
|
45
|
+
*/
|
|
46
|
+
import type { ObservationDeclaration } from '../adapter-module';
|
|
47
|
+
import type { DebugAdapter } from '../system-adapter';
|
|
48
|
+
/**
|
|
49
|
+
* Build a {@link DebugAdapter} over an adapter's observation declarations, or
|
|
50
|
+
* `null` when it declares none. `null` is the honest floor — the same one
|
|
51
|
+
* `createContractDebugAdapter` returns — so a game that declared nothing keeps
|
|
52
|
+
* reporting `DEBUG_ADAPTER_UNAVAILABLE` rather than serving an empty adapter
|
|
53
|
+
* that reads as "this game has no state".
|
|
54
|
+
*/
|
|
55
|
+
export declare function createObservationDebugAdapter(declarations: readonly ObservationDeclaration[] | undefined | null, game: unknown): DebugAdapter | null;
|
|
56
|
+
//# sourceMappingURL=observation-debug-adapter.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"observation-debug-adapter.d.ts","sourceRoot":"","sources":["../../../src/adapter/ingest/observation-debug-adapter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA4CG;AAGH,OAAO,KAAK,EAAE,sBAAsB,EAAE,MAAM,mBAAmB,CAAC;AAChE,OAAO,KAAK,EAAE,YAAY,EAAsC,MAAM,mBAAmB,CAAC;AAoB1F;;;;;;GAMG;AACH,wBAAgB,6BAA6B,CAC3C,YAAY,EAAE,SAAS,sBAAsB,EAAE,GAAG,SAAS,GAAG,IAAI,EAClE,IAAI,EAAE,OAAO,GACZ,YAAY,GAAG,IAAI,CA+ErB"}
|