@kiberon-labs/behave-graph-scene 1.0.0 → 2.0.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/.storybook/main.ts +18 -0
- package/.storybook/preview.ts +16 -0
- package/.storybook/vscode.css +822 -0
- package/.turbo/turbo-build.log +8 -0
- package/CHANGELOG.md +84 -0
- package/LICENSE +6 -0
- package/README.md +13 -0
- package/dist/Abstractions/Drivers/DummyScene.d.ts +64 -0
- package/dist/Abstractions/Drivers/DummyScene.d.ts.map +1 -0
- package/dist/Abstractions/Drivers/DummyScene.js +115 -0
- package/dist/Abstractions/Drivers/DummyScene.js.map +1 -0
- package/dist/Abstractions/IScene.d.ts +75 -0
- package/dist/Abstractions/IScene.d.ts.map +1 -0
- package/dist/Abstractions/IScene.js +19 -0
- package/dist/Abstractions/IScene.js.map +1 -0
- package/dist/GLTFJson.d.ts +33 -0
- package/dist/GLTFJson.d.ts.map +1 -0
- package/dist/Nodes/Actions/AddLight.d.ts +21 -0
- package/dist/Nodes/Actions/AddLight.d.ts.map +1 -0
- package/dist/Nodes/Actions/AddLight.js +38 -0
- package/dist/Nodes/Actions/AddLight.js.map +1 -0
- package/dist/Nodes/Actions/CloneMesh.d.ts +16 -0
- package/dist/Nodes/Actions/CloneMesh.d.ts.map +1 -0
- package/dist/Nodes/Actions/CloneMesh.js +28 -0
- package/dist/Nodes/Actions/CloneMesh.js.map +1 -0
- package/dist/Nodes/Actions/CreateMesh.d.ts +22 -0
- package/dist/Nodes/Actions/CreateMesh.d.ts.map +1 -0
- package/dist/Nodes/Actions/CreateMesh.js +44 -0
- package/dist/Nodes/Actions/CreateMesh.js.map +1 -0
- package/dist/Nodes/Actions/DeleteMesh.d.ts +15 -0
- package/dist/Nodes/Actions/DeleteMesh.d.ts.map +1 -0
- package/dist/Nodes/Actions/DeleteMesh.js +27 -0
- package/dist/Nodes/Actions/DeleteMesh.js.map +1 -0
- package/dist/Nodes/Actions/EaseSceneProperty.d.ts +23 -0
- package/dist/Nodes/Actions/EaseSceneProperty.d.ts.map +1 -0
- package/dist/Nodes/Actions/EaseSceneProperty.js +73 -0
- package/dist/Nodes/Actions/EaseSceneProperty.js.map +1 -0
- package/dist/Nodes/Actions/LookAt.d.ts +16 -0
- package/dist/Nodes/Actions/LookAt.d.ts.map +1 -0
- package/dist/Nodes/Actions/LookAt.js +35 -0
- package/dist/Nodes/Actions/LookAt.js.map +1 -0
- package/dist/Nodes/Actions/MoveTowards.d.ts +21 -0
- package/dist/Nodes/Actions/MoveTowards.d.ts.map +1 -0
- package/dist/Nodes/Actions/MoveTowards.js +46 -0
- package/dist/Nodes/Actions/MoveTowards.js.map +1 -0
- package/dist/Nodes/Actions/RemoveLight.d.ts +15 -0
- package/dist/Nodes/Actions/RemoveLight.d.ts.map +1 -0
- package/dist/Nodes/Actions/RemoveLight.js +27 -0
- package/dist/Nodes/Actions/RemoveLight.js.map +1 -0
- package/dist/Nodes/Actions/SetLightProperty.d.ts +25 -0
- package/dist/Nodes/Actions/SetLightProperty.d.ts.map +1 -0
- package/dist/Nodes/Actions/SetLightProperty.js +64 -0
- package/dist/Nodes/Actions/SetLightProperty.js.map +1 -0
- package/dist/Nodes/Actions/SetMaterialProperty.d.ts +25 -0
- package/dist/Nodes/Actions/SetMaterialProperty.d.ts.map +1 -0
- package/dist/Nodes/Actions/SetMaterialProperty.js +69 -0
- package/dist/Nodes/Actions/SetMaterialProperty.js.map +1 -0
- package/dist/Nodes/Actions/SetMeshPosition.d.ts +18 -0
- package/dist/Nodes/Actions/SetMeshPosition.d.ts.map +1 -0
- package/dist/Nodes/Actions/SetMeshPosition.js +34 -0
- package/dist/Nodes/Actions/SetMeshPosition.js.map +1 -0
- package/dist/Nodes/Actions/SetMeshVisible.d.ts +16 -0
- package/dist/Nodes/Actions/SetMeshVisible.d.ts.map +1 -0
- package/dist/Nodes/Actions/SetMeshVisible.js +28 -0
- package/dist/Nodes/Actions/SetMeshVisible.js.map +1 -0
- package/dist/Nodes/Actions/SetSceneProperty.d.ts +16 -0
- package/dist/Nodes/Actions/SetSceneProperty.d.ts.map +1 -0
- package/dist/Nodes/Actions/SetSceneProperty.js +28 -0
- package/dist/Nodes/Actions/SetSceneProperty.js.map +1 -0
- package/dist/Nodes/Events/OnAnyMeshClicked.d.ts +13 -0
- package/dist/Nodes/Events/OnAnyMeshClicked.d.ts.map +1 -0
- package/dist/Nodes/Events/OnAnyMeshClicked.js +34 -0
- package/dist/Nodes/Events/OnAnyMeshClicked.js.map +1 -0
- package/dist/Nodes/Events/OnSceneChanged.d.ts +12 -0
- package/dist/Nodes/Events/OnSceneChanged.d.ts.map +1 -0
- package/dist/Nodes/Events/OnSceneChanged.js +28 -0
- package/dist/Nodes/Events/OnSceneChanged.js.map +1 -0
- package/dist/Nodes/Events/OnSceneNodeClick.d.ts +18 -0
- package/dist/Nodes/Events/OnSceneNodeClick.d.ts.map +1 -0
- package/dist/Nodes/Events/OnSceneNodeClick.js +39 -0
- package/dist/Nodes/Events/OnSceneNodeClick.js.map +1 -0
- package/dist/Nodes/Logic/ColorNodes.d.ts +23 -0
- package/dist/Nodes/Logic/ColorNodes.d.ts.map +1 -0
- package/dist/Nodes/Logic/ColorNodes.js +137 -0
- package/dist/Nodes/Logic/ColorNodes.js.map +1 -0
- package/dist/Nodes/Logic/EulerNodes.d.ts +22 -0
- package/dist/Nodes/Logic/EulerNodes.d.ts.map +1 -0
- package/dist/Nodes/Logic/EulerNodes.js +132 -0
- package/dist/Nodes/Logic/EulerNodes.js.map +1 -0
- package/dist/Nodes/Logic/Mat3Nodes.d.ts +31 -0
- package/dist/Nodes/Logic/Mat3Nodes.d.ts.map +1 -0
- package/dist/Nodes/Logic/Mat3Nodes.js +199 -0
- package/dist/Nodes/Logic/Mat3Nodes.js.map +1 -0
- package/dist/Nodes/Logic/Mat4Nodes.d.ts +38 -0
- package/dist/Nodes/Logic/Mat4Nodes.d.ts.map +1 -0
- package/dist/Nodes/Logic/Mat4Nodes.js +267 -0
- package/dist/Nodes/Logic/Mat4Nodes.js.map +1 -0
- package/dist/Nodes/Logic/QuatNodes.d.ts +28 -0
- package/dist/Nodes/Logic/QuatNodes.d.ts.map +1 -0
- package/dist/Nodes/Logic/QuatNodes.js +173 -0
- package/dist/Nodes/Logic/QuatNodes.js.map +1 -0
- package/dist/Nodes/Logic/Vec2Nodes.d.ts +22 -0
- package/dist/Nodes/Logic/Vec2Nodes.d.ts.map +1 -0
- package/dist/Nodes/Logic/Vec2Nodes.js +115 -0
- package/dist/Nodes/Logic/Vec2Nodes.js.map +1 -0
- package/dist/Nodes/Logic/Vec3Nodes.d.ts +23 -0
- package/dist/Nodes/Logic/Vec3Nodes.d.ts.map +1 -0
- package/dist/Nodes/Logic/Vec3Nodes.js +137 -0
- package/dist/Nodes/Logic/Vec3Nodes.js.map +1 -0
- package/dist/Nodes/Logic/Vec4Nodes.d.ts +22 -0
- package/dist/Nodes/Logic/Vec4Nodes.d.ts.map +1 -0
- package/dist/Nodes/Logic/Vec4Nodes.js +132 -0
- package/dist/Nodes/Logic/Vec4Nodes.js.map +1 -0
- package/dist/Nodes/Logic/VecElements.d.ts +9 -0
- package/dist/Nodes/Logic/VecElements.d.ts.map +1 -0
- package/dist/Nodes/Logic/VecElements.js +22 -0
- package/dist/Nodes/Logic/VecElements.js.map +1 -0
- package/dist/Nodes/Queries/GetDistanceBetween.d.ts +18 -0
- package/dist/Nodes/Queries/GetDistanceBetween.d.ts.map +1 -0
- package/dist/Nodes/Queries/GetDistanceBetween.js +30 -0
- package/dist/Nodes/Queries/GetDistanceBetween.js.map +1 -0
- package/dist/Nodes/Queries/GetLightProperty.d.ts +23 -0
- package/dist/Nodes/Queries/GetLightProperty.d.ts.map +1 -0
- package/dist/Nodes/Queries/GetLightProperty.js +68 -0
- package/dist/Nodes/Queries/GetLightProperty.js.map +1 -0
- package/dist/Nodes/Queries/GetMaterialProperty.d.ts +23 -0
- package/dist/Nodes/Queries/GetMaterialProperty.d.ts.map +1 -0
- package/dist/Nodes/Queries/GetMaterialProperty.js +69 -0
- package/dist/Nodes/Queries/GetMaterialProperty.js.map +1 -0
- package/dist/Nodes/Queries/GetMeshPosition.d.ts +16 -0
- package/dist/Nodes/Queries/GetMeshPosition.d.ts.map +1 -0
- package/dist/Nodes/Queries/GetMeshPosition.js +29 -0
- package/dist/Nodes/Queries/GetMeshPosition.js.map +1 -0
- package/dist/Nodes/Queries/GetSceneProperty.d.ts +14 -0
- package/dist/Nodes/Queries/GetSceneProperty.d.ts.map +1 -0
- package/dist/Nodes/Queries/GetSceneProperty.js +23 -0
- package/dist/Nodes/Queries/GetSceneProperty.js.map +1 -0
- package/dist/Values/ColorValue.d.ts +7 -0
- package/dist/Values/ColorValue.d.ts.map +1 -0
- package/dist/Values/ColorValue.js +20 -0
- package/dist/Values/ColorValue.js.map +1 -0
- package/dist/Values/EulerValue.d.ts +7 -0
- package/dist/Values/EulerValue.d.ts.map +1 -0
- package/dist/Values/EulerValue.js +20 -0
- package/dist/Values/EulerValue.js.map +1 -0
- package/dist/Values/Internal/Mat3.d.ts +43 -0
- package/dist/Values/Internal/Mat3.d.ts.map +1 -0
- package/dist/Values/Internal/Mat3.js +276 -0
- package/dist/Values/Internal/Mat3.js.map +1 -0
- package/dist/Values/Internal/Mat4.d.ts +53 -0
- package/dist/Values/Internal/Mat4.d.ts.map +1 -0
- package/dist/Values/Internal/Mat4.js +443 -0
- package/dist/Values/Internal/Mat4.js.map +1 -0
- package/dist/Values/Internal/Vec2.d.ts +25 -0
- package/dist/Values/Internal/Vec2.d.ts.map +1 -0
- package/dist/Values/Internal/Vec2.js +64 -0
- package/dist/Values/Internal/Vec2.js.map +1 -0
- package/dist/Values/Internal/Vec3.d.ts +38 -0
- package/dist/Values/Internal/Vec3.d.ts.map +1 -0
- package/dist/Values/Internal/Vec3.js +157 -0
- package/dist/Values/Internal/Vec3.js.map +1 -0
- package/dist/Values/Internal/Vec4.d.ts +49 -0
- package/dist/Values/Internal/Vec4.d.ts.map +1 -0
- package/dist/Values/Internal/Vec4.js +190 -0
- package/dist/Values/Internal/Vec4.js.map +1 -0
- package/dist/Values/Mat3Value.d.ts +7 -0
- package/dist/Values/Mat3Value.d.ts.map +1 -0
- package/dist/Values/Mat3Value.js +16 -0
- package/dist/Values/Mat3Value.js.map +1 -0
- package/dist/Values/Mat4Value.d.ts +7 -0
- package/dist/Values/Mat4Value.d.ts.map +1 -0
- package/dist/Values/Mat4Value.js +16 -0
- package/dist/Values/Mat4Value.js.map +1 -0
- package/dist/Values/QuatValue.d.ts +7 -0
- package/dist/Values/QuatValue.d.ts.map +1 -0
- package/dist/Values/QuatValue.js +21 -0
- package/dist/Values/QuatValue.js.map +1 -0
- package/dist/Values/Vec2Value.d.ts +7 -0
- package/dist/Values/Vec2Value.d.ts.map +1 -0
- package/dist/Values/Vec2Value.js +16 -0
- package/dist/Values/Vec2Value.js.map +1 -0
- package/dist/Values/Vec3Value.d.ts +7 -0
- package/dist/Values/Vec3Value.d.ts.map +1 -0
- package/dist/Values/Vec3Value.js +20 -0
- package/dist/Values/Vec3Value.js.map +1 -0
- package/dist/Values/Vec4Value.d.ts +7 -0
- package/dist/Values/Vec4Value.d.ts.map +1 -0
- package/dist/Values/Vec4Value.js +21 -0
- package/dist/Values/Vec4Value.js.map +1 -0
- package/dist/_virtual/rolldown_runtime.js +35 -0
- package/dist/behave-graph.manifest.json +6082 -0
- package/dist/buildScene.d.ts +74 -0
- package/dist/buildScene.d.ts.map +1 -0
- package/dist/buildScene.js +304 -0
- package/dist/buildScene.js.map +1 -0
- package/dist/index.d.ts +57 -0
- package/dist/index.d.ts.map +1 -0
- package/dist/index.js +49 -0
- package/dist/manifest.source.d.ts +7 -0
- package/dist/manifest.source.d.ts.map +1 -0
- package/dist/manifest.source.js +54 -0
- package/dist/manifest.source.js.map +1 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react-jsx-runtime.development.js +207 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react-jsx-runtime.development.js.map +1 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react-jsx-runtime.production.js +40 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react-jsx-runtime.production.js.map +1 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react.development.js +766 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react.development.js.map +1 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react.production.js +367 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/cjs/react.production.js.map +1 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/index.js +15 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/index.js.map +1 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-runtime.js +15 -0
- package/dist/node_modules/.pnpm/react@19.2.3/node_modules/react/jsx-runtime.js.map +1 -0
- package/dist/packages/nodes/scene/package.js +7 -0
- package/dist/packages/nodes/scene/package.js.map +1 -0
- package/dist/registerSceneProfile.d.ts +10 -0
- package/dist/registerSceneProfile.d.ts.map +1 -0
- package/dist/registerSceneProfile.js +112 -0
- package/dist/registerSceneProfile.js.map +1 -0
- package/dist/ui/controls/vec3.d.ts +9 -0
- package/dist/ui/controls/vec3.d.ts.map +1 -0
- package/dist/ui/controls/vec3.js +99 -0
- package/dist/ui/controls/vec3.js.map +1 -0
- package/package.json +42 -13
- package/src/Abstractions/Drivers/DummyScene.ts +110 -2
- package/src/Abstractions/IScene.ts +74 -3
- package/src/Nodes/Actions/AddLight.ts +46 -0
- package/src/Nodes/Actions/CloneMesh.ts +31 -0
- package/src/Nodes/Actions/CreateMesh.ts +47 -0
- package/src/Nodes/Actions/DeleteMesh.ts +29 -0
- package/src/Nodes/Actions/EaseSceneProperty.ts +6 -2
- package/src/Nodes/Actions/LookAt.ts +34 -0
- package/src/Nodes/Actions/MoveTowards.ts +55 -0
- package/src/Nodes/Actions/RemoveLight.ts +29 -0
- package/src/Nodes/Actions/SetLightProperty.ts +60 -0
- package/src/Nodes/Actions/SetMaterialProperty.ts +62 -0
- package/src/Nodes/Actions/SetMeshPosition.ts +37 -0
- package/src/Nodes/Actions/SetMeshVisible.ts +31 -0
- package/src/Nodes/Actions/SetSceneProperty.ts +3 -5
- package/src/Nodes/Events/OnAnyMeshClicked.ts +48 -0
- package/src/Nodes/Events/OnSceneChanged.ts +43 -0
- package/src/Nodes/Events/OnSceneNodeClick.ts +3 -3
- package/src/Nodes/Logic/Mat3Nodes.ts +0 -10
- package/src/Nodes/Logic/QuatNodes.ts +11 -11
- package/src/Nodes/Queries/GetDistanceBetween.ts +37 -0
- package/src/Nodes/Queries/GetLightProperty.ts +53 -0
- package/src/Nodes/Queries/GetMaterialProperty.ts +55 -0
- package/src/Nodes/Queries/GetMeshPosition.ts +32 -0
- package/src/Nodes/Queries/GetSceneProperty.ts +4 -5
- package/src/Values/Internal/Mat3.ts +3 -3
- package/src/Values/Internal/Mat4.ts +5 -4
- package/src/Values/Internal/Vec3.ts +5 -4
- package/src/Values/Internal/Vec4.ts +3 -2
- package/src/buildScene.ts +36 -2
- package/src/index.ts +26 -2
- package/src/manifest.source.ts +61 -0
- package/src/registerSceneProfile.ts +41 -4
- package/src/ui/controls/vec3.tsx +69 -0
- package/stories/click.stories.tsx +112 -0
- package/stories/components/DemoScene.ts +610 -0
- package/stories/components/SceneViewer.tsx +204 -0
- package/stories/components/SceneViewerPanel.tsx +41 -0
- package/stories/data/clickDemo.json +94 -0
- package/stories/data/rotate.json +402 -0
- package/stories/index.stories.tsx +90 -0
- package/stories/plugin/sceneViewerPlugin.tsx +88 -0
- package/tests/graphs/logic/Color.json +53 -53
- package/tests/graphs/logic/Euler.json +53 -53
- package/tests/graphs/logic/Quaternion.json +56 -56
- package/tests/graphs/logic/Vector2.json +50 -50
- package/tests/graphs/logic/Vector3.json +53 -53
- package/tests/graphs/logic/Vector4.json +56 -56
- package/tests/manifest.test.ts +65 -0
- package/tests/readSceneGraphs.test.ts +8 -1
- package/tests/registerSceneProfile.test.ts +6 -5
- package/tests/tsconfig.json +10 -10
- package/tsconfig.json +61 -54
- package/tsdown.config.ts +5 -1
- package/vite.config.js +7 -0
- package/src/Values/Internal/Mat2.ts +0 -214
- package/src/loadScene.ts +0 -81
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
|
|
2
|
+
> @kiberon-labs/behave-graph-scene@2.0.0 build /home/runner/work/behave-graph/behave-graph/packages/nodes/scene
|
|
3
|
+
> tsdown && behave-graph-manifest dist/manifest.source.js --out dist
|
|
4
|
+
|
|
5
|
+
[34mℹ[39m tsdown [2mv0.16.5[22m powered by rolldown [2mv1.0.0-beta.50[22m
|
|
6
|
+
[34mℹ[39m Using tsdown config: [4m/home/runner/work/behave-graph/behave-graph/packages/nodes/scene/tsdown.config.ts[24m
|
|
7
|
+
[34mℹ[39m Build start
|
|
8
|
+
Wrote 191 nodes, 8 value types to /home/runner/work/behave-graph/behave-graph/packages/nodes/scene/dist/behave-graph.manifest.json
|
package/CHANGELOG.md
ADDED
|
@@ -0,0 +1,84 @@
|
|
|
1
|
+
# @kiberon-labs/behave-graph-scene
|
|
2
|
+
|
|
3
|
+
## 2.0.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- cf72d27: Static package-manifest system: let editors and tooling discover the nodes,
|
|
8
|
+
value types, UI contributions and host requirements a package provides
|
|
9
|
+
**without importing or executing the package's code**.
|
|
10
|
+
|
|
11
|
+
Previously the only way to learn what a package offered was to call its
|
|
12
|
+
`registerProfile`, which imports and runs every node implementation (closures,
|
|
13
|
+
side effects, even WASM init) — a security and performance cost just to list
|
|
14
|
+
nodes. A manifest is the persisted, on-disk form of the static projection the
|
|
15
|
+
editor already renders from (`NodeSpecJSON` + value display metadata), so the
|
|
16
|
+
executable half (node `exec`, value serializers, React components, a persistent
|
|
17
|
+
backend) is loaded only by a runner or on explicit, trust-gated demand.
|
|
18
|
+
|
|
19
|
+
## `@kiberon-labs/behave-graph`
|
|
20
|
+
|
|
21
|
+
New `Manifest/` module (exported from the package root), all additive:
|
|
22
|
+
|
|
23
|
+
- **Schema** (`ManifestJSON`): function-free `ValueTypeSpecJSON`, `NodeManifestEntry`
|
|
24
|
+
(the existing `NodeSpecJSON` plus optional authoring extras), `ContributionSpec`
|
|
25
|
+
/ `ContributionKind` (control, specific, panel, socketGenerator, conversion,
|
|
26
|
+
command, contextMenu, valueType), open-ended `categories` (`PackageCategory`
|
|
27
|
+
constants are advisory), and `requirements` (`PackageRequirement`, discriminated
|
|
28
|
+
by `kind` with known `backendService` / `config` kinds **plus an open escape
|
|
29
|
+
hatch** so hosts tolerate kinds not yet modelled).
|
|
30
|
+
- **Generation** (build time): `writeManifest` (reuses `writeNodeSpecsToJSON`, so
|
|
31
|
+
node specs are identical to runtime), `writeValueTypesToJSON` (function-free
|
|
32
|
+
display + `serialize(creator())` default), `defineManifestSource` /
|
|
33
|
+
`runManifestSource`, and a `behave-graph-manifest` CLI bin.
|
|
34
|
+
- **Validation**: `parseManifest`, a dependency-free well-formedness gate a host
|
|
35
|
+
runs on an untrusted manifest before consuming it.
|
|
36
|
+
- **Conventions**: `MANIFEST_FILE_NAME` (`behave-graph.manifest.json` — a plain
|
|
37
|
+
`.json` file, the canonical name; a directory `--out` writes it there) and
|
|
38
|
+
`MANIFEST_PACKAGE_FIELD` (`behaveGraph`, the `package.json` field pointing at
|
|
39
|
+
the manifest).
|
|
40
|
+
|
|
41
|
+
## `@kiberon-labs/behave-graph-flow`
|
|
42
|
+
|
|
43
|
+
New `manifest/` module for consuming a manifest in the editor:
|
|
44
|
+
|
|
45
|
+
- `loadManifest` / `manifestPlugin`: always register node specs + value types from
|
|
46
|
+
JSON with **zero code execution** (the palette renders from JSON alone); surface
|
|
47
|
+
declared host requirements via `onRequirement`; and load code contributions
|
|
48
|
+
**only under an explicit `trust` flag + a host-provided `resolve`r** (the host
|
|
49
|
+
owns module resolution because a bundler must know the concrete module). A
|
|
50
|
+
failing contribution is logged and skipped, never aborting the rest.
|
|
51
|
+
- `passthroughValueType`: synthesises a working `ValueTypeMetadata` from a
|
|
52
|
+
function-free spec (identity (de)serialize, cloned default) so existing UI call
|
|
53
|
+
sites keep working until a trusted `valueType` contribution swaps in the real
|
|
54
|
+
implementation.
|
|
55
|
+
- `contributionRegistry`: maps each `ContributionKind` to its editor store.
|
|
56
|
+
|
|
57
|
+
## `@kiberon-labs/behave-graph-nodes-image` and `@kiberon-labs/behave-graph-scene`
|
|
58
|
+
|
|
59
|
+
Both packages now generate a `behave-graph.manifest.json` at build time as
|
|
60
|
+
reference implementations:
|
|
61
|
+
|
|
62
|
+
- A side-effect-light `src/manifest.source.ts` (`defineManifestSource`) declares
|
|
63
|
+
the registry builder, `runtime` entry, category and contributions; the package
|
|
64
|
+
`build` runs `behave-graph-manifest`, and `package.json#behaveGraph.manifest`
|
|
65
|
+
points at the output. Spec generation runs no node code (image needs no WASM
|
|
66
|
+
init; scene is fed a `DummyScene` for `IScene`).
|
|
67
|
+
- **image**: 13 nodes + the `image` value type, with control / specific / panel /
|
|
68
|
+
valueType contributions. `ui.tsx` now re-exports `ImageControl`,
|
|
69
|
+
`imagePreviewSpecific` and an extracted `imageOutputTab` loader so a host can
|
|
70
|
+
resolve them from the manifest.
|
|
71
|
+
- **scene**: ~191 nodes + 8 value types (`vec2`…`mat4`), the `vec3` control and a
|
|
72
|
+
`valueType` contribution per scene type.
|
|
73
|
+
|
|
74
|
+
Also (private packages, no version bump): the VS Code extension gains
|
|
75
|
+
`discoverManifests`, which statically scans `node_modules` for
|
|
76
|
+
`package.json#behaveGraph.manifest` and reads/validates the JSON without importing
|
|
77
|
+
package code; and the documentation site gains a dedicated "Package Manifests"
|
|
78
|
+
section.
|
|
79
|
+
|
|
80
|
+
### Patch Changes
|
|
81
|
+
|
|
82
|
+
- Updated dependencies [cf72d27]
|
|
83
|
+
- Updated dependencies [cf72d27]
|
|
84
|
+
- @kiberon-labs/behave-graph@1.2.0
|
package/LICENSE
ADDED
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
Internet Systems Consortium license
|
|
2
|
+
Copyright (c) 2022 behave-graph authors
|
|
3
|
+
|
|
4
|
+
Permission to use, copy, modify, and/or distribute this software for any purpose with or without fee is hereby granted, provided that the above copyright notice and this permission notice appear in all copies.
|
|
5
|
+
|
|
6
|
+
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
package/README.md
ADDED
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
# Behave-Graph Scene
|
|
2
|
+
|
|
3
|
+
[](https://github.com/kiberon-labs/behave-graph/blob/master/LICENSE) [](https://www.npmjs.com/package/@kiberon-labs/behave-graph-scene)
|
|
4
|
+
|
|
5
|
+
This is a set of 3D nodes for threejs when working with [behave graphs](https://www.npmjs.com/package/@kiberon-labs/behave-graph)
|
|
6
|
+
|
|
7
|
+
## Documentation
|
|
8
|
+
|
|
9
|
+
See the dedicated documentation site [here](https://behave-graph.kiberon-labs.co.za)
|
|
10
|
+
|
|
11
|
+
## Licence
|
|
12
|
+
|
|
13
|
+
ISC. See [here](./LICENSE)
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { GeometryType, IScene, LightType } from "../IScene.js";
|
|
2
|
+
import { EventEmitter } from "@kiberon-labs/behave-graph";
|
|
3
|
+
|
|
4
|
+
//#region src/Abstractions/Drivers/DummyScene.d.ts
|
|
5
|
+
declare class DummyScene implements IScene {
|
|
6
|
+
onSceneChanged: EventEmitter<void>;
|
|
7
|
+
private valueRegistry;
|
|
8
|
+
constructor();
|
|
9
|
+
getProperty(jsonPath: string, valueTypeName: string): unknown;
|
|
10
|
+
setProperty(): void;
|
|
11
|
+
addOnClickedListener(jsonPath: string, callback: (jsonPath: string) => void): void;
|
|
12
|
+
removeOnClickedListener(jsonPath: string, callback: (jsonPath: string) => void): void;
|
|
13
|
+
getQueryableProperties(): never[];
|
|
14
|
+
getRaycastableProperties(): never[];
|
|
15
|
+
getProperties(): never[];
|
|
16
|
+
addOnSceneChangedListener(): void;
|
|
17
|
+
removeOnSceneChangedListener(): void;
|
|
18
|
+
createMesh(_name: string, _geometryType: GeometryType, _size: {
|
|
19
|
+
x: number;
|
|
20
|
+
y: number;
|
|
21
|
+
z: number;
|
|
22
|
+
}): void;
|
|
23
|
+
deleteMesh(_name: string): void;
|
|
24
|
+
getMeshNames(): never[];
|
|
25
|
+
addLight(_name: string, _lightType: LightType, _color: {
|
|
26
|
+
r: number;
|
|
27
|
+
g: number;
|
|
28
|
+
b: number;
|
|
29
|
+
}, _intensity: number): void;
|
|
30
|
+
removeLight(_name: string): void;
|
|
31
|
+
setLightProperty(_name: string, _property: string, _value: unknown): void;
|
|
32
|
+
getLightProperty(_name: string, _property: string): unknown;
|
|
33
|
+
getLightNames(): never[];
|
|
34
|
+
setMaterialProperty(_meshName: string, _property: string, _value: unknown): void;
|
|
35
|
+
getMaterialProperty(_meshName: string, _property: string): unknown;
|
|
36
|
+
addOnAnyMeshClickedListener(_callback: (meshName: string) => void): void;
|
|
37
|
+
removeOnAnyMeshClickedListener(_callback: (meshName: string) => void): void;
|
|
38
|
+
getMeshPosition(_meshName: string): {
|
|
39
|
+
x: number;
|
|
40
|
+
y: number;
|
|
41
|
+
z: number;
|
|
42
|
+
} | undefined;
|
|
43
|
+
setMeshPosition(_meshName: string, _position: {
|
|
44
|
+
x: number;
|
|
45
|
+
y: number;
|
|
46
|
+
z: number;
|
|
47
|
+
}): void;
|
|
48
|
+
getDistanceBetween(_meshA: string, _meshB: string): number;
|
|
49
|
+
lookAt(_meshName: string, _target: {
|
|
50
|
+
x: number;
|
|
51
|
+
y: number;
|
|
52
|
+
z: number;
|
|
53
|
+
}): void;
|
|
54
|
+
moveTowards(_meshName: string, _target: {
|
|
55
|
+
x: number;
|
|
56
|
+
y: number;
|
|
57
|
+
z: number;
|
|
58
|
+
}, _speed: number, _deltaSeconds: number): boolean;
|
|
59
|
+
cloneMesh(_sourceName: string, _newName: string): void;
|
|
60
|
+
setMeshVisible(_meshName: string, _visible: boolean): void;
|
|
61
|
+
}
|
|
62
|
+
//#endregion
|
|
63
|
+
export { DummyScene };
|
|
64
|
+
//# sourceMappingURL=DummyScene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DummyScene.d.ts","names":[],"sources":["../../../src/Abstractions/Drivers/DummyScene.ts"],"sourcesContent":[],"mappings":";;;;cAiBa,UAAA,YAAsB;kBACZ;EADV,QAAA,aAAW;EACD,WAAA,CAAA;EAgEJ,WAAA,CAAA,QAAA,EAAA,MAAA,EAAA,aAAA,EAAA,MAAA,CAAA,EAAA,OAAA;EAiBH,WAAA,CAAA,CAAA,EAAA,IAAA;EAlFmB,oBAAA,CAAA,QAAA,EAAA,MAAA,EAAA,QAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,GAAA,IAAA,CAAA,EAAA,IAAA;EAAM,uBAAA,CAAA,QAAA,EAAA,MAAA,EAAA,QAAA,EAAA,CAAA,QAAA,EAAA,MAAA,EAAA,GAAA,IAAA,CAAA,EAAA,IAAA;;;;;;2CAiEtB;;;;;;;sCAiBH"}
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
import { ColorValue } from "../../Values/ColorValue.js";
|
|
2
|
+
import { EulerValue } from "../../Values/EulerValue.js";
|
|
3
|
+
import { QuatValue } from "../../Values/QuatValue.js";
|
|
4
|
+
import { Vec2Value } from "../../Values/Vec2Value.js";
|
|
5
|
+
import { Vec3Value } from "../../Values/Vec3Value.js";
|
|
6
|
+
import { Vec4Value } from "../../Values/Vec4Value.js";
|
|
7
|
+
import { BooleanValue, EventEmitter, FloatValue, IntegerValue, StringValue } from "@kiberon-labs/behave-graph";
|
|
8
|
+
|
|
9
|
+
//#region src/Abstractions/Drivers/DummyScene.ts
|
|
10
|
+
var DummyScene = class {
|
|
11
|
+
onSceneChanged = new EventEmitter();
|
|
12
|
+
valueRegistry;
|
|
13
|
+
constructor() {
|
|
14
|
+
this.valueRegistry = Object.fromEntries([
|
|
15
|
+
BooleanValue,
|
|
16
|
+
StringValue,
|
|
17
|
+
IntegerValue,
|
|
18
|
+
FloatValue,
|
|
19
|
+
Vec2Value,
|
|
20
|
+
Vec3Value,
|
|
21
|
+
Vec4Value,
|
|
22
|
+
ColorValue,
|
|
23
|
+
EulerValue,
|
|
24
|
+
QuatValue
|
|
25
|
+
].map((valueType) => [valueType.name, valueType]));
|
|
26
|
+
}
|
|
27
|
+
getProperty(jsonPath, valueTypeName) {
|
|
28
|
+
return this.valueRegistry[valueTypeName]?.creator();
|
|
29
|
+
}
|
|
30
|
+
setProperty() {
|
|
31
|
+
this.onSceneChanged.emit();
|
|
32
|
+
}
|
|
33
|
+
addOnClickedListener(jsonPath, callback) {
|
|
34
|
+
console.log("added on clicked listener");
|
|
35
|
+
}
|
|
36
|
+
removeOnClickedListener(jsonPath, callback) {
|
|
37
|
+
console.log("removed on clicked listener");
|
|
38
|
+
}
|
|
39
|
+
getQueryableProperties() {
|
|
40
|
+
return [];
|
|
41
|
+
}
|
|
42
|
+
getRaycastableProperties() {
|
|
43
|
+
return [];
|
|
44
|
+
}
|
|
45
|
+
getProperties() {
|
|
46
|
+
return [];
|
|
47
|
+
}
|
|
48
|
+
addOnSceneChangedListener() {
|
|
49
|
+
console.log("added on scene changed listener");
|
|
50
|
+
}
|
|
51
|
+
removeOnSceneChangedListener() {
|
|
52
|
+
console.log("removed on scene changed listener");
|
|
53
|
+
}
|
|
54
|
+
createMesh(_name, _geometryType, _size) {
|
|
55
|
+
console.log("created mesh (dummy)");
|
|
56
|
+
}
|
|
57
|
+
deleteMesh(_name) {
|
|
58
|
+
console.log("deleted mesh (dummy)");
|
|
59
|
+
}
|
|
60
|
+
getMeshNames() {
|
|
61
|
+
return [];
|
|
62
|
+
}
|
|
63
|
+
addLight(_name, _lightType, _color, _intensity) {
|
|
64
|
+
console.log("added light (dummy)");
|
|
65
|
+
}
|
|
66
|
+
removeLight(_name) {
|
|
67
|
+
console.log("removed light (dummy)");
|
|
68
|
+
}
|
|
69
|
+
setLightProperty(_name, _property, _value) {
|
|
70
|
+
console.log("set light property (dummy)");
|
|
71
|
+
}
|
|
72
|
+
getLightProperty(_name, _property) {}
|
|
73
|
+
getLightNames() {
|
|
74
|
+
return [];
|
|
75
|
+
}
|
|
76
|
+
setMaterialProperty(_meshName, _property, _value) {
|
|
77
|
+
console.log("set material property (dummy)");
|
|
78
|
+
}
|
|
79
|
+
getMaterialProperty(_meshName, _property) {}
|
|
80
|
+
addOnAnyMeshClickedListener(_callback) {
|
|
81
|
+
console.log("added on any mesh clicked listener (dummy)");
|
|
82
|
+
}
|
|
83
|
+
removeOnAnyMeshClickedListener(_callback) {
|
|
84
|
+
console.log("removed on any mesh clicked listener (dummy)");
|
|
85
|
+
}
|
|
86
|
+
getMeshPosition(_meshName) {
|
|
87
|
+
return {
|
|
88
|
+
x: 0,
|
|
89
|
+
y: 0,
|
|
90
|
+
z: 0
|
|
91
|
+
};
|
|
92
|
+
}
|
|
93
|
+
setMeshPosition(_meshName, _position) {
|
|
94
|
+
console.log("set mesh position (dummy)");
|
|
95
|
+
}
|
|
96
|
+
getDistanceBetween(_meshA, _meshB) {
|
|
97
|
+
return 0;
|
|
98
|
+
}
|
|
99
|
+
lookAt(_meshName, _target) {
|
|
100
|
+
console.log("lookAt (dummy)");
|
|
101
|
+
}
|
|
102
|
+
moveTowards(_meshName, _target, _speed, _deltaSeconds) {
|
|
103
|
+
return true;
|
|
104
|
+
}
|
|
105
|
+
cloneMesh(_sourceName, _newName) {
|
|
106
|
+
console.log("cloned mesh (dummy)");
|
|
107
|
+
}
|
|
108
|
+
setMeshVisible(_meshName, _visible) {
|
|
109
|
+
console.log("set mesh visible (dummy)");
|
|
110
|
+
}
|
|
111
|
+
};
|
|
112
|
+
|
|
113
|
+
//#endregion
|
|
114
|
+
export { DummyScene };
|
|
115
|
+
//# sourceMappingURL=DummyScene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"DummyScene.js","names":[],"sources":["../../../src/Abstractions/Drivers/DummyScene.ts"],"sourcesContent":["import {\n BooleanValue,\n EventEmitter,\n FloatValue,\n IntegerValue,\n StringValue,\n type ValueType\n} from '@kiberon-labs/behave-graph';\n\nimport { ColorValue } from '../../Values/ColorValue.js';\nimport { EulerValue } from '../../Values/EulerValue.js';\nimport { QuatValue } from '../../Values/QuatValue.js';\nimport { Vec2Value } from '../../Values/Vec2Value.js';\nimport { Vec3Value } from '../../Values/Vec3Value.js';\nimport { Vec4Value } from '../../Values/Vec4Value.js';\nimport type { GeometryType, IScene, LightType } from '../IScene.js';\n\nexport class DummyScene implements IScene {\n public onSceneChanged = new EventEmitter<void>();\n\n private valueRegistry: Record<string, ValueType>;\n\n constructor() {\n this.valueRegistry = Object.fromEntries(\n [\n BooleanValue,\n StringValue,\n IntegerValue,\n FloatValue,\n Vec2Value,\n Vec3Value,\n Vec4Value,\n ColorValue,\n EulerValue,\n QuatValue\n ].map((valueType) => [valueType.name, valueType])\n );\n // pull in value type nodes\n }\n\n getProperty(jsonPath: string, valueTypeName: string): unknown {\n return this.valueRegistry[valueTypeName]?.creator();\n }\n setProperty(): void {\n this.onSceneChanged.emit();\n }\n addOnClickedListener(\n jsonPath: string,\n callback: (jsonPath: string) => void\n ): void {\n console.log('added on clicked listener');\n }\n removeOnClickedListener(\n jsonPath: string,\n callback: (jsonPath: string) => void\n ): void {\n console.log('removed on clicked listener');\n }\n\n getQueryableProperties() {\n return [];\n }\n\n getRaycastableProperties() {\n return [];\n }\n\n getProperties() {\n return [];\n }\n\n addOnSceneChangedListener() {\n console.log('added on scene changed listener');\n }\n\n removeOnSceneChangedListener(): void {\n console.log('removed on scene changed listener');\n }\n\n // --- mesh lifecycle ---\n createMesh(\n _name: string,\n _geometryType: GeometryType,\n _size: { x: number; y: number; z: number }\n ): void {\n console.log('created mesh (dummy)');\n }\n\n deleteMesh(_name: string): void {\n console.log('deleted mesh (dummy)');\n }\n\n getMeshNames() {\n return [];\n }\n\n // --- lighting ---\n addLight(\n _name: string,\n _lightType: LightType,\n _color: { r: number; g: number; b: number },\n _intensity: number\n ): void {\n console.log('added light (dummy)');\n }\n\n removeLight(_name: string): void {\n console.log('removed light (dummy)');\n }\n\n setLightProperty(_name: string, _property: string, _value: unknown): void {\n console.log('set light property (dummy)');\n }\n\n getLightProperty(_name: string, _property: string): unknown {\n return undefined;\n }\n\n getLightNames() {\n return [];\n }\n\n // --- material ---\n setMaterialProperty(\n _meshName: string,\n _property: string,\n _value: unknown\n ): void {\n console.log('set material property (dummy)');\n }\n\n getMaterialProperty(_meshName: string, _property: string): unknown {\n return undefined;\n }\n\n // --- global click ---\n addOnAnyMeshClickedListener(_callback: (meshName: string) => void): void {\n console.log('added on any mesh clicked listener (dummy)');\n }\n\n removeOnAnyMeshClickedListener(_callback: (meshName: string) => void): void {\n console.log('removed on any mesh clicked listener (dummy)');\n }\n\n // --- spatial helpers ---\n getMeshPosition(\n _meshName: string\n ): { x: number; y: number; z: number } | undefined {\n return { x: 0, y: 0, z: 0 };\n }\n\n setMeshPosition(\n _meshName: string,\n _position: { x: number; y: number; z: number }\n ): void {\n console.log('set mesh position (dummy)');\n }\n\n getDistanceBetween(_meshA: string, _meshB: string): number {\n return 0;\n }\n\n lookAt(\n _meshName: string,\n _target: { x: number; y: number; z: number }\n ): void {\n console.log('lookAt (dummy)');\n }\n\n moveTowards(\n _meshName: string,\n _target: { x: number; y: number; z: number },\n _speed: number,\n _deltaSeconds: number\n ): boolean {\n return true;\n }\n\n // --- mesh utilities ---\n cloneMesh(_sourceName: string, _newName: string): void {\n console.log('cloned mesh (dummy)');\n }\n\n setMeshVisible(_meshName: string, _visible: boolean): void {\n console.log('set mesh visible (dummy)');\n }\n}\n"],"mappings":";;;;;;;;;AAiBA,IAAa,aAAb,MAA0C;CACxC,AAAO,iBAAiB,IAAI,cAAoB;CAEhD,AAAQ;CAER,cAAc;AACZ,OAAK,gBAAgB,OAAO,YAC1B;GACE;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACA;GACD,CAAC,KAAK,cAAc,CAAC,UAAU,MAAM,UAAU,CAAC,CAClD;;CAIH,YAAY,UAAkB,eAAgC;AAC5D,SAAO,KAAK,cAAc,gBAAgB,SAAS;;CAErD,cAAoB;AAClB,OAAK,eAAe,MAAM;;CAE5B,qBACE,UACA,UACM;AACN,UAAQ,IAAI,4BAA4B;;CAE1C,wBACE,UACA,UACM;AACN,UAAQ,IAAI,8BAA8B;;CAG5C,yBAAyB;AACvB,SAAO,EAAE;;CAGX,2BAA2B;AACzB,SAAO,EAAE;;CAGX,gBAAgB;AACd,SAAO,EAAE;;CAGX,4BAA4B;AAC1B,UAAQ,IAAI,kCAAkC;;CAGhD,+BAAqC;AACnC,UAAQ,IAAI,oCAAoC;;CAIlD,WACE,OACA,eACA,OACM;AACN,UAAQ,IAAI,uBAAuB;;CAGrC,WAAW,OAAqB;AAC9B,UAAQ,IAAI,uBAAuB;;CAGrC,eAAe;AACb,SAAO,EAAE;;CAIX,SACE,OACA,YACA,QACA,YACM;AACN,UAAQ,IAAI,sBAAsB;;CAGpC,YAAY,OAAqB;AAC/B,UAAQ,IAAI,wBAAwB;;CAGtC,iBAAiB,OAAe,WAAmB,QAAuB;AACxE,UAAQ,IAAI,6BAA6B;;CAG3C,iBAAiB,OAAe,WAA4B;CAI5D,gBAAgB;AACd,SAAO,EAAE;;CAIX,oBACE,WACA,WACA,QACM;AACN,UAAQ,IAAI,gCAAgC;;CAG9C,oBAAoB,WAAmB,WAA4B;CAKnE,4BAA4B,WAA6C;AACvE,UAAQ,IAAI,6CAA6C;;CAG3D,+BAA+B,WAA6C;AAC1E,UAAQ,IAAI,+CAA+C;;CAI7D,gBACE,WACiD;AACjD,SAAO;GAAE,GAAG;GAAG,GAAG;GAAG,GAAG;GAAG;;CAG7B,gBACE,WACA,WACM;AACN,UAAQ,IAAI,4BAA4B;;CAG1C,mBAAmB,QAAgB,QAAwB;AACzD,SAAO;;CAGT,OACE,WACA,SACM;AACN,UAAQ,IAAI,iBAAiB;;CAG/B,YACE,WACA,SACA,QACA,eACS;AACT,SAAO;;CAIT,UAAU,aAAqB,UAAwB;AACrD,UAAQ,IAAI,sBAAsB;;CAGpC,eAAe,WAAmB,UAAyB;AACzD,UAAQ,IAAI,2BAA2B"}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
import { Choices } from "@kiberon-labs/behave-graph";
|
|
2
|
+
|
|
3
|
+
//#region src/Abstractions/IScene.d.ts
|
|
4
|
+
declare const GeometryType: {
|
|
5
|
+
readonly Box: "box";
|
|
6
|
+
readonly Sphere: "sphere";
|
|
7
|
+
readonly Cylinder: "cylinder";
|
|
8
|
+
readonly Torus: "torus";
|
|
9
|
+
readonly Plane: "plane";
|
|
10
|
+
readonly Cone: "cone";
|
|
11
|
+
};
|
|
12
|
+
type GeometryType = (typeof GeometryType)[keyof typeof GeometryType];
|
|
13
|
+
declare const LightType: {
|
|
14
|
+
readonly Point: "point";
|
|
15
|
+
readonly Directional: "directional";
|
|
16
|
+
readonly Spot: "spot";
|
|
17
|
+
readonly Ambient: "ambient";
|
|
18
|
+
};
|
|
19
|
+
type LightType = (typeof LightType)[keyof typeof LightType];
|
|
20
|
+
interface IScene {
|
|
21
|
+
getProperty(jsonPath: string, valueTypeName: string): unknown;
|
|
22
|
+
setProperty(jsonPath: string, valueTypeName: string, value: unknown): void;
|
|
23
|
+
addOnClickedListener(jsonPath: string, callback: (jsonPath: string) => void): void;
|
|
24
|
+
removeOnClickedListener(jsonPath: string, callback: (jsonPath: string) => void): void;
|
|
25
|
+
getRaycastableProperties: () => Choices;
|
|
26
|
+
getProperties: (valueFilter?: string) => Choices;
|
|
27
|
+
addOnSceneChangedListener(listener: () => void): void;
|
|
28
|
+
removeOnSceneChangedListener(listener: () => void): void;
|
|
29
|
+
createMesh(name: string, geometryType: GeometryType, size: {
|
|
30
|
+
x: number;
|
|
31
|
+
y: number;
|
|
32
|
+
z: number;
|
|
33
|
+
}): void;
|
|
34
|
+
deleteMesh(name: string): void;
|
|
35
|
+
getMeshNames: () => Choices;
|
|
36
|
+
addLight(name: string, lightType: LightType, color: {
|
|
37
|
+
r: number;
|
|
38
|
+
g: number;
|
|
39
|
+
b: number;
|
|
40
|
+
}, intensity: number): void;
|
|
41
|
+
removeLight(name: string): void;
|
|
42
|
+
setLightProperty(name: string, property: string, value: unknown): void;
|
|
43
|
+
getLightProperty(name: string, property: string): unknown;
|
|
44
|
+
getLightNames: () => Choices;
|
|
45
|
+
setMaterialProperty(meshName: string, property: string, value: unknown): void;
|
|
46
|
+
getMaterialProperty(meshName: string, property: string): unknown;
|
|
47
|
+
addOnAnyMeshClickedListener(callback: (meshName: string) => void): void;
|
|
48
|
+
removeOnAnyMeshClickedListener(callback: (meshName: string) => void): void;
|
|
49
|
+
getMeshPosition(meshName: string): {
|
|
50
|
+
x: number;
|
|
51
|
+
y: number;
|
|
52
|
+
z: number;
|
|
53
|
+
} | undefined;
|
|
54
|
+
setMeshPosition(meshName: string, position: {
|
|
55
|
+
x: number;
|
|
56
|
+
y: number;
|
|
57
|
+
z: number;
|
|
58
|
+
}): void;
|
|
59
|
+
getDistanceBetween(meshA: string, meshB: string): number;
|
|
60
|
+
lookAt(meshName: string, target: {
|
|
61
|
+
x: number;
|
|
62
|
+
y: number;
|
|
63
|
+
z: number;
|
|
64
|
+
}): void;
|
|
65
|
+
moveTowards(meshName: string, target: {
|
|
66
|
+
x: number;
|
|
67
|
+
y: number;
|
|
68
|
+
z: number;
|
|
69
|
+
}, speed: number, deltaSeconds: number): boolean;
|
|
70
|
+
cloneMesh(sourceName: string, newName: string): void;
|
|
71
|
+
setMeshVisible(meshName: string, visible: boolean): void;
|
|
72
|
+
}
|
|
73
|
+
//#endregion
|
|
74
|
+
export { GeometryType, IScene, LightType };
|
|
75
|
+
//# sourceMappingURL=IScene.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IScene.d.ts","names":[],"sources":["../../src/Abstractions/IScene.ts"],"sourcesContent":[],"mappings":";;;cAEa;;EAAA,SAAA,MAOH,EAAA,QAAA;EAEE,SAAA,QAAY,EAAA,UAAW;EAEtB,SAAA,KAKH,EAAA,OAAA;EAEE,SAAA,KAAS,EAAA,OAAA;EAEJ,SAAM,IAAA,EAAA,MAAA;CAYW;AACS,KAxB/B,YAAA,GAwB+B,CAAA,OAxBR,YAwBQ,CAAA,CAAA,MAAA,OAxBmB,YAwBnB,CAAA;AAOzB,cA7BL,SA6BK,EAAA;EAII,SAAA,KAAA,EAAA,OAAA;EAKP,SAAA,WAAA,EAAA,aAAA;EAOQ,SAAA,IAAA,EAAA,MAAA;EAAO,SAAA,OAAA,EAAA,SAAA;;KAtClB,SAAA,WAAoB,wBAAwB;UAEvC,MAAA;;;;;kCAYiB;2CACS;;;yCAOzB;;;;;;sBAII;oCAKP;;;;;;;;uBAOQ"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
//#region src/Abstractions/IScene.ts
|
|
2
|
+
const GeometryType = {
|
|
3
|
+
Box: "box",
|
|
4
|
+
Sphere: "sphere",
|
|
5
|
+
Cylinder: "cylinder",
|
|
6
|
+
Torus: "torus",
|
|
7
|
+
Plane: "plane",
|
|
8
|
+
Cone: "cone"
|
|
9
|
+
};
|
|
10
|
+
const LightType = {
|
|
11
|
+
Point: "point",
|
|
12
|
+
Directional: "directional",
|
|
13
|
+
Spot: "spot",
|
|
14
|
+
Ambient: "ambient"
|
|
15
|
+
};
|
|
16
|
+
|
|
17
|
+
//#endregion
|
|
18
|
+
export { GeometryType, LightType };
|
|
19
|
+
//# sourceMappingURL=IScene.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"IScene.js","names":[],"sources":["../../src/Abstractions/IScene.ts"],"sourcesContent":["import type { Choices } from '@kiberon-labs/behave-graph';\n\nexport const GeometryType = {\n Box: 'box',\n Sphere: 'sphere',\n Cylinder: 'cylinder',\n Torus: 'torus',\n Plane: 'plane',\n Cone: 'cone'\n} as const;\n\nexport type GeometryType = (typeof GeometryType)[keyof typeof GeometryType];\n\nexport const LightType = {\n Point: 'point',\n Directional: 'directional',\n Spot: 'spot',\n Ambient: 'ambient'\n} as const;\n\nexport type LightType = (typeof LightType)[keyof typeof LightType];\n\nexport interface IScene {\n // --- existing property accessors ---\n getProperty(jsonPath: string, valueTypeName: string): unknown;\n setProperty(jsonPath: string, valueTypeName: string, value: unknown): void;\n addOnClickedListener(\n jsonPath: string,\n callback: (jsonPath: string) => void\n ): void;\n removeOnClickedListener(\n jsonPath: string,\n callback: (jsonPath: string) => void\n ): void;\n getRaycastableProperties: () => Choices;\n getProperties: (valueFilter?: string) => Choices;\n addOnSceneChangedListener(listener: () => void): void;\n removeOnSceneChangedListener(listener: () => void): void;\n\n // --- mesh lifecycle ---\n createMesh(\n name: string,\n geometryType: GeometryType,\n size: { x: number; y: number; z: number }\n ): void;\n deleteMesh(name: string): void;\n getMeshNames: () => Choices;\n\n // --- lighting ---\n addLight(\n name: string,\n lightType: LightType,\n color: { r: number; g: number; b: number },\n intensity: number\n ): void;\n removeLight(name: string): void;\n setLightProperty(name: string, property: string, value: unknown): void;\n getLightProperty(name: string, property: string): unknown;\n getLightNames: () => Choices;\n\n // --- material ---\n setMaterialProperty(meshName: string, property: string, value: unknown): void;\n getMaterialProperty(meshName: string, property: string): unknown;\n\n // --- global click (returns which mesh was hit) ---\n addOnAnyMeshClickedListener(callback: (meshName: string) => void): void;\n removeOnAnyMeshClickedListener(callback: (meshName: string) => void): void;\n\n // --- spatial helpers ---\n getMeshPosition(\n meshName: string\n ): { x: number; y: number; z: number } | undefined;\n setMeshPosition(\n meshName: string,\n position: { x: number; y: number; z: number }\n ): void;\n getDistanceBetween(meshA: string, meshB: string): number;\n lookAt(meshName: string, target: { x: number; y: number; z: number }): void;\n moveTowards(\n meshName: string,\n target: { x: number; y: number; z: number },\n speed: number,\n deltaSeconds: number\n ): boolean; // returns true when arrived\n\n // --- mesh utilities ---\n cloneMesh(sourceName: string, newName: string): void;\n setMeshVisible(meshName: string, visible: boolean): void;\n}\n"],"mappings":";AAEA,MAAa,eAAe;CAC1B,KAAK;CACL,QAAQ;CACR,UAAU;CACV,OAAO;CACP,OAAO;CACP,MAAM;CACP;AAID,MAAa,YAAY;CACvB,OAAO;CACP,aAAa;CACb,MAAM;CACN,SAAS;CACV"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
//#region src/GLTFJson.d.ts
|
|
2
|
+
type GLTFAssetJson = {
|
|
3
|
+
generator: string;
|
|
4
|
+
version: string;
|
|
5
|
+
};
|
|
6
|
+
type GLTFSceneJson = {
|
|
7
|
+
name: string;
|
|
8
|
+
nodes: number[];
|
|
9
|
+
};
|
|
10
|
+
type GLTFNodeJson = {
|
|
11
|
+
name?: string;
|
|
12
|
+
mesh?: number;
|
|
13
|
+
translation?: number[];
|
|
14
|
+
children?: number[];
|
|
15
|
+
};
|
|
16
|
+
type GLTFMaterialJson = {
|
|
17
|
+
name?: string;
|
|
18
|
+
doubleSided?: boolean;
|
|
19
|
+
};
|
|
20
|
+
type GLTFMeshJson = {
|
|
21
|
+
name?: string;
|
|
22
|
+
};
|
|
23
|
+
type GLTFJson = {
|
|
24
|
+
asset: GLTFAssetJson;
|
|
25
|
+
scene: number;
|
|
26
|
+
scenes: GLTFSceneJson[];
|
|
27
|
+
nodes: GLTFNodeJson[];
|
|
28
|
+
materials: GLTFMaterialJson[];
|
|
29
|
+
meshes: GLTFMeshJson[];
|
|
30
|
+
};
|
|
31
|
+
//#endregion
|
|
32
|
+
export { GLTFJson };
|
|
33
|
+
//# sourceMappingURL=GLTFJson.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"GLTFJson.d.ts","names":[],"sources":["../src/GLTFJson.ts"],"sourcesContent":[],"mappings":";KAAY,aAAA;EAAA,SAAA,EAAA,MAAa;EAKb,OAAA,EAAA,MAAA;AAKZ,CAAA;AAOY,KAZA,aAAA,GAYgB;EAKhB,IAAA,EAAA,MAAA;EAIA,KAAA,EAAA,MAAQ,EAAA;CACX;AAEC,KAnBE,YAAA,GAmBF;EACD,IAAA,CAAA,EAAA,MAAA;EACI,IAAA,CAAA,EAAA,MAAA;EACH,WAAA,CAAA,EAAA,MAAA,EAAA;EAAY,QAAA,CAAA,EAAA,MAAA,EAAA;;KAfV,gBAAA;;;;KAKA,YAAA;;;KAIA,QAAA;SACH;;UAEC;SACD;aACI;UACH"}
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import * as _kiberon_labs_behave_graph5 from "@kiberon-labs/behave-graph";
|
|
2
|
+
|
|
3
|
+
//#region src/Nodes/Actions/AddLight.d.ts
|
|
4
|
+
declare const AddLight: _kiberon_labs_behave_graph5.IFlowNodeDefinition<{
|
|
5
|
+
flow: string;
|
|
6
|
+
name: string;
|
|
7
|
+
lightType: (_: _kiberon_labs_behave_graph5.NodeConfiguration) => {
|
|
8
|
+
valueType: string;
|
|
9
|
+
choices: {
|
|
10
|
+
text: "point" | "directional" | "spot" | "ambient";
|
|
11
|
+
value: "point" | "directional" | "spot" | "ambient";
|
|
12
|
+
}[];
|
|
13
|
+
};
|
|
14
|
+
color: string;
|
|
15
|
+
intensity: string;
|
|
16
|
+
}, {
|
|
17
|
+
flow: string;
|
|
18
|
+
}, _kiberon_labs_behave_graph5.NodeConfigurationDescription, undefined>;
|
|
19
|
+
//#endregion
|
|
20
|
+
export { AddLight };
|
|
21
|
+
//# sourceMappingURL=AddLight.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddLight.d.ts","names":[],"sources":["../../../src/Nodes/Actions/AddLight.ts"],"sourcesContent":[],"mappings":";;;cAYa,sCAAQ;;;EAAR,SAAA,EAiCX,CAAA,CAAA,EAAA,2BAAA,CAAA,iBAAA,EAAA,GAAA;IAAA,SAAA,EAAA,MAAA;;mCAjCmB,GAAA,MAAA,GAAA,SAAA;MAAA,KAAA,EAAA,OAAA,GAAA,aAAA,GAAA,MAAA,GAAA,SAAA"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
import { LightType } from "../../Abstractions/IScene.js";
|
|
2
|
+
import { NodeCategory, makeFlowNodeDefinition } from "@kiberon-labs/behave-graph";
|
|
3
|
+
|
|
4
|
+
//#region src/Nodes/Actions/AddLight.ts
|
|
5
|
+
const lightTypeChoices = Object.values(LightType).map((v) => ({
|
|
6
|
+
text: v,
|
|
7
|
+
value: v
|
|
8
|
+
}));
|
|
9
|
+
const AddLight = makeFlowNodeDefinition({
|
|
10
|
+
typeName: "scene/addLight",
|
|
11
|
+
category: NodeCategory.Effect,
|
|
12
|
+
label: "Add Light",
|
|
13
|
+
in: {
|
|
14
|
+
flow: "flow",
|
|
15
|
+
name: "string",
|
|
16
|
+
lightType: (_) => ({
|
|
17
|
+
valueType: "string",
|
|
18
|
+
choices: lightTypeChoices
|
|
19
|
+
}),
|
|
20
|
+
color: "color",
|
|
21
|
+
intensity: "float"
|
|
22
|
+
},
|
|
23
|
+
out: { flow: "flow" },
|
|
24
|
+
initialState: void 0,
|
|
25
|
+
triggered: ({ commit, read, graph }) => {
|
|
26
|
+
const scene = graph.getDependency("IScene");
|
|
27
|
+
const name = read("name");
|
|
28
|
+
const lightType = read("lightType");
|
|
29
|
+
const color = read("color");
|
|
30
|
+
const intensity = read("intensity");
|
|
31
|
+
scene?.addLight(name, lightType, color, intensity);
|
|
32
|
+
commit("flow");
|
|
33
|
+
}
|
|
34
|
+
});
|
|
35
|
+
|
|
36
|
+
//#endregion
|
|
37
|
+
export { AddLight };
|
|
38
|
+
//# sourceMappingURL=AddLight.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"AddLight.js","names":[],"sources":["../../../src/Nodes/Actions/AddLight.ts"],"sourcesContent":["import {\n makeFlowNodeDefinition,\n NodeCategory\n} from '@kiberon-labs/behave-graph';\n\nimport { LightType } from '../../Abstractions/IScene.js';\n\nconst lightTypeChoices = Object.values(LightType).map((v) => ({\n text: v,\n value: v\n}));\n\nexport const AddLight = makeFlowNodeDefinition({\n typeName: 'scene/addLight',\n category: NodeCategory.Effect,\n label: 'Add Light',\n in: {\n flow: 'flow',\n name: 'string',\n lightType: (_) => ({\n valueType: 'string',\n choices: lightTypeChoices\n }),\n color: 'color',\n intensity: 'float'\n },\n out: {\n flow: 'flow'\n },\n initialState: undefined,\n triggered: ({ commit, read, graph }) => {\n const scene = graph.getDependency('IScene');\n const name = read<string>('name');\n const lightType = read<string>('lightType');\n const color = read<{ r: number; g: number; b: number }>('color');\n const intensity = read<number>('intensity');\n\n scene?.addLight(\n name,\n lightType as (typeof LightType)[keyof typeof LightType],\n color,\n intensity\n );\n commit('flow');\n }\n});\n"],"mappings":";;;;AAOA,MAAM,mBAAmB,OAAO,OAAO,UAAU,CAAC,KAAK,OAAO;CAC5D,MAAM;CACN,OAAO;CACR,EAAE;AAEH,MAAa,WAAW,uBAAuB;CAC7C,UAAU;CACV,UAAU,aAAa;CACvB,OAAO;CACP,IAAI;EACF,MAAM;EACN,MAAM;EACN,YAAY,OAAO;GACjB,WAAW;GACX,SAAS;GACV;EACD,OAAO;EACP,WAAW;EACZ;CACD,KAAK,EACH,MAAM,QACP;CACD,cAAc;CACd,YAAY,EAAE,QAAQ,MAAM,YAAY;EACtC,MAAM,QAAQ,MAAM,cAAc,SAAS;EAC3C,MAAM,OAAO,KAAa,OAAO;EACjC,MAAM,YAAY,KAAa,YAAY;EAC3C,MAAM,QAAQ,KAA0C,QAAQ;EAChE,MAAM,YAAY,KAAa,YAAY;AAE3C,SAAO,SACL,MACA,WACA,OACA,UACD;AACD,SAAO,OAAO;;CAEjB,CAAC"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import * as _kiberon_labs_behave_graph8 from "@kiberon-labs/behave-graph";
|
|
2
|
+
|
|
3
|
+
//#region src/Nodes/Actions/CloneMesh.d.ts
|
|
4
|
+
declare const CloneMesh: _kiberon_labs_behave_graph8.IFlowNodeDefinition<{
|
|
5
|
+
flow: string;
|
|
6
|
+
sourceName: (_: _kiberon_labs_behave_graph8.NodeConfiguration, graphApi: _kiberon_labs_behave_graph8.IGraph) => {
|
|
7
|
+
valueType: string;
|
|
8
|
+
choices: _kiberon_labs_behave_graph8.Choices | undefined;
|
|
9
|
+
};
|
|
10
|
+
newName: string;
|
|
11
|
+
}, {
|
|
12
|
+
flow: string;
|
|
13
|
+
}, _kiberon_labs_behave_graph8.NodeConfigurationDescription, undefined>;
|
|
14
|
+
//#endregion
|
|
15
|
+
export { CloneMesh };
|
|
16
|
+
//# sourceMappingURL=CloneMesh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CloneMesh.d.ts","names":[],"sources":["../../../src/Nodes/Actions/CloneMesh.ts"],"sourcesContent":[],"mappings":";;;cAMa,uCAAS;;kBAwBpB,2BAAA,CAAA;IAxBW,SAwBX,EAAA,MAAA;IAAA,OAAA,wCAAA,SAAA;;;;;CAxBoB,4DAAA,SAAA,CAAA"}
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { NodeCategory, makeFlowNodeDefinition } from "@kiberon-labs/behave-graph";
|
|
2
|
+
|
|
3
|
+
//#region src/Nodes/Actions/CloneMesh.ts
|
|
4
|
+
const CloneMesh = makeFlowNodeDefinition({
|
|
5
|
+
typeName: "scene/cloneMesh",
|
|
6
|
+
category: NodeCategory.Effect,
|
|
7
|
+
label: "Clone Mesh",
|
|
8
|
+
in: {
|
|
9
|
+
flow: "flow",
|
|
10
|
+
sourceName: (_, graphApi) => {
|
|
11
|
+
return {
|
|
12
|
+
valueType: "string",
|
|
13
|
+
choices: graphApi.getDependency("IScene")?.getMeshNames()
|
|
14
|
+
};
|
|
15
|
+
},
|
|
16
|
+
newName: "string"
|
|
17
|
+
},
|
|
18
|
+
out: { flow: "flow" },
|
|
19
|
+
initialState: void 0,
|
|
20
|
+
triggered: ({ commit, read, graph }) => {
|
|
21
|
+
graph.getDependency("IScene")?.cloneMesh(read("sourceName"), read("newName"));
|
|
22
|
+
commit("flow");
|
|
23
|
+
}
|
|
24
|
+
});
|
|
25
|
+
|
|
26
|
+
//#endregion
|
|
27
|
+
export { CloneMesh };
|
|
28
|
+
//# sourceMappingURL=CloneMesh.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CloneMesh.js","names":[],"sources":["../../../src/Nodes/Actions/CloneMesh.ts"],"sourcesContent":["import {\n makeFlowNodeDefinition,\n NodeCategory\n} from '@kiberon-labs/behave-graph';\n\n// Clone an existing mesh under a new name.\nexport const CloneMesh = makeFlowNodeDefinition({\n typeName: 'scene/cloneMesh',\n category: NodeCategory.Effect,\n label: 'Clone Mesh',\n in: {\n flow: 'flow',\n sourceName: (_, graphApi) => {\n const scene = graphApi.getDependency('IScene');\n return {\n valueType: 'string',\n choices: scene?.getMeshNames()\n };\n },\n newName: 'string'\n },\n out: {\n flow: 'flow'\n },\n initialState: undefined,\n triggered: ({ commit, read, graph }) => {\n const scene = graph.getDependency('IScene');\n scene?.cloneMesh(read<string>('sourceName'), read<string>('newName'));\n commit('flow');\n }\n});\n"],"mappings":";;;AAMA,MAAa,YAAY,uBAAuB;CAC9C,UAAU;CACV,UAAU,aAAa;CACvB,OAAO;CACP,IAAI;EACF,MAAM;EACN,aAAa,GAAG,aAAa;AAE3B,UAAO;IACL,WAAW;IACX,SAHY,SAAS,cAAc,SAAS,EAG5B,cAAc;IAC/B;;EAEH,SAAS;EACV;CACD,KAAK,EACH,MAAM,QACP;CACD,cAAc;CACd,YAAY,EAAE,QAAQ,MAAM,YAAY;AAEtC,EADc,MAAM,cAAc,SAAS,EACpC,UAAU,KAAa,aAAa,EAAE,KAAa,UAAU,CAAC;AACrE,SAAO,OAAO;;CAEjB,CAAC"}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import * as _kiberon_labs_behave_graph13 from "@kiberon-labs/behave-graph";
|
|
2
|
+
|
|
3
|
+
//#region src/Nodes/Actions/CreateMesh.d.ts
|
|
4
|
+
declare const CreateMesh: _kiberon_labs_behave_graph13.IFlowNodeDefinition<{
|
|
5
|
+
flow: string;
|
|
6
|
+
name: string;
|
|
7
|
+
geometryType: (_: _kiberon_labs_behave_graph13.NodeConfiguration) => {
|
|
8
|
+
valueType: string;
|
|
9
|
+
choices: {
|
|
10
|
+
text: "box" | "sphere" | "cylinder" | "torus" | "plane" | "cone";
|
|
11
|
+
value: "box" | "sphere" | "cylinder" | "torus" | "plane" | "cone";
|
|
12
|
+
}[];
|
|
13
|
+
};
|
|
14
|
+
sizeX: string;
|
|
15
|
+
sizeY: string;
|
|
16
|
+
sizeZ: string;
|
|
17
|
+
}, {
|
|
18
|
+
flow: string;
|
|
19
|
+
}, _kiberon_labs_behave_graph13.NodeConfigurationDescription, undefined>;
|
|
20
|
+
//#endregion
|
|
21
|
+
export { CreateMesh };
|
|
22
|
+
//# sourceMappingURL=CreateMesh.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"CreateMesh.d.ts","names":[],"sources":["../../../src/Nodes/Actions/CreateMesh.ts"],"sourcesContent":[],"mappings":";;;cAYa,yCAAU;;;EAAV,YAAA,EAkCX,CAAA,CAAA,EAAA,4BAAA,CAAA,iBAAA,EAAA,GAAA;IAAA,SAAA,EAAA,MAAA;;4BAlCqB,GAAA,UAAA,GAAA,OAAA,GAAA,OAAA,GAAA,MAAA;MAAA,KAAA,EAAA,KAAA,GAAA,QAAA,GAAA,UAAA,GAAA,OAAA,GAAA,OAAA,GAAA,MAAA"}
|