oomi-ai 0.2.49 → 0.3.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/README.md +227 -463
- package/agent_instructions.md +244 -234
- package/bin/oomi-ai.js +4028 -5797
- package/bin/sessionBridgeState.js +78 -78
- package/lib/openclawPaths.js +70 -71
- package/lib/openclawProfile.js +216 -216
- package/lib/personaApiClient.js +133 -303
- package/lib/spokenMetadata.js +137 -137
- package/openclaw.extension.js +341 -341
- package/openclaw.plugin.json +17 -17
- package/package.json +59 -59
- package/persona-app/README.md +27 -0
- package/persona-app/registry/v1.json +63 -0
- package/persona-app/schema/persona-app.v1.schema.json +90 -0
- package/skills/oomi/SKILL.md +165 -182
- package/skills/oomi/agent_instructions.md +99 -80
- package/lib/channelPluginClient.js +0 -119
- package/lib/openclawDevGateway.js +0 -384
- package/lib/personaJobExecutor.js +0 -139
- package/lib/personaJobPoller.js +0 -112
- package/lib/personaPortAllocator.js +0 -36
- package/lib/personaRuntimeManager.js +0 -496
- package/lib/personaRuntimeProcess.js +0 -924
- package/lib/personaRuntimeRegistry.js +0 -67
- package/lib/personaRuntimeSupervisor.js +0 -330
- package/lib/scaffold.js +0 -108
- package/lib/template.js +0 -45
- package/skills/oomi/config.json +0 -3
- package/skills/oomi/scripts/get_avatar_capabilities.py +0 -40
- package/skills/oomi/scripts/get_data.py +0 -49
- package/skills/oomi/scripts/install_agent_instructions.py +0 -78
- package/skills/oomi/scripts/send_goal.py +0 -53
- package/skills/oomi/scripts/sync.py +0 -46
- package/skills/oomi/setup.py +0 -41
- package/templates/persona-app/.env.example +0 -8
- package/templates/persona-app/README.md +0 -47
- package/templates/persona-app/eslint.config.js +0 -28
- package/templates/persona-app/index.html +0 -18
- package/templates/persona-app/oomi.runtime.json +0 -13
- package/templates/persona-app/package.json +0 -44
- package/templates/persona-app/persona/brief.md +0 -14
- package/templates/persona-app/persona.json +0 -14
- package/templates/persona-app/public/manifest.webmanifest +0 -8
- package/templates/persona-app/public/oomi.health.json +0 -6
- package/templates/persona-app/src/App.css +0 -379
- package/templates/persona-app/src/App.tsx +0 -17
- package/templates/persona-app/src/index.css +0 -53
- package/templates/persona-app/src/main.tsx +0 -23
- package/templates/persona-app/src/pages/HomePage.tsx +0 -127
- package/templates/persona-app/src/pages/ScenePage.tsx +0 -158
- package/templates/persona-app/src/persona/config.ts +0 -6
- package/templates/persona-app/src/persona/notes.ts +0 -9
- package/templates/persona-app/src/spatial.ts +0 -82
- package/templates/persona-app/src/vite-env.d.ts +0 -3
- package/templates/persona-app/template.json +0 -13
- package/templates/persona-app/tsconfig.app.json +0 -23
- package/templates/persona-app/tsconfig.json +0 -7
- package/templates/persona-app/tsconfig.node.json +0 -21
- package/templates/persona-app/vendor/webspatial/FORK.md +0 -6
- package/templates/persona-app/vendor/webspatial/core-sdk/LICENSE +0 -21
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.d.ts +0 -906
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.global.js +0 -75
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/iife/index.global.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.d.ts +0 -906
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.js +0 -3131
- package/templates/persona-app/vendor/webspatial/core-sdk/dist/index.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/core-sdk/package.json +0 -45
- package/templates/persona-app/vendor/webspatial/react-sdk/LICENSE +0 -21
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.d.ts +0 -365
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.js +0 -4167
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/default/index.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.d.ts +0 -82
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.js +0 -66
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.d.ts +0 -2
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.js +0 -18
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-dev-runtime.web.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.d.ts +0 -5
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.js +0 -66
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.d.ts +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.js +0 -18
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/jsx/jsx-runtime.web.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.d.ts +0 -365
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.js +0 -4207
- package/templates/persona-app/vendor/webspatial/react-sdk/dist/web/index.js.map +0 -1
- package/templates/persona-app/vendor/webspatial/react-sdk/package.json +0 -94
- package/templates/persona-app/vite.config.ts +0 -31
|
@@ -1,158 +0,0 @@
|
|
|
1
|
-
import { useEffect } from "react";
|
|
2
|
-
import { Link } from "react-router-dom";
|
|
3
|
-
import "../App.css";
|
|
4
|
-
import { personaConfig } from "../persona/config";
|
|
5
|
-
import { personaNotes } from "../persona/notes";
|
|
6
|
-
import {
|
|
7
|
-
WEBSPATIAL_FORK_COMMIT,
|
|
8
|
-
configurePersonaScene,
|
|
9
|
-
detectSpatialEnvironment,
|
|
10
|
-
xrStyle,
|
|
11
|
-
} from "../spatial";
|
|
12
|
-
|
|
13
|
-
const spatialWorkflows = [
|
|
14
|
-
{
|
|
15
|
-
title: "Primary workspace panel",
|
|
16
|
-
body: "Use this as the main operator surface for the persona's task instead of duplicating a generic homepage.",
|
|
17
|
-
},
|
|
18
|
-
{
|
|
19
|
-
title: "Secondary workspace panel",
|
|
20
|
-
body: "Reserve a separate surface for supporting context, previews, or step-by-step controls so the XR scene reads as a composed environment.",
|
|
21
|
-
},
|
|
22
|
-
];
|
|
23
|
-
|
|
24
|
-
const sceneChips = [
|
|
25
|
-
"header surface",
|
|
26
|
-
"workspace panel",
|
|
27
|
-
"status panel",
|
|
28
|
-
"completion panel",
|
|
29
|
-
"tool tray",
|
|
30
|
-
];
|
|
31
|
-
|
|
32
|
-
export function ScenePage() {
|
|
33
|
-
const environment = detectSpatialEnvironment();
|
|
34
|
-
|
|
35
|
-
useEffect(() => {
|
|
36
|
-
configurePersonaScene();
|
|
37
|
-
|
|
38
|
-
const snapshot = detectSpatialEnvironment();
|
|
39
|
-
console.info("[persona] spatial runtime", snapshot);
|
|
40
|
-
}, []);
|
|
41
|
-
|
|
42
|
-
return (
|
|
43
|
-
<main className="scene-shell">
|
|
44
|
-
<header className="scene-header" enable-xr style={xrStyle(14, "thin")}>
|
|
45
|
-
<div>
|
|
46
|
-
<p className="scene-eyebrow">Spatial Scene</p>
|
|
47
|
-
<h1 className="scene-title">{personaConfig.name}</h1>
|
|
48
|
-
<p className="scene-copy">
|
|
49
|
-
{personaConfig.description} This route is the default experience when Oomi opens the
|
|
50
|
-
app inside the WebSpatial runtime, so it should behave like a real XR workspace instead
|
|
51
|
-
of a browser homepage.
|
|
52
|
-
</p>
|
|
53
|
-
</div>
|
|
54
|
-
|
|
55
|
-
<div className="scene-badge-stack">
|
|
56
|
-
<span className="scene-badge">{environment.isWebSpatial ? "WebSpatial active" : "Browser preview"}</span>
|
|
57
|
-
<span className="scene-badge">SDK {environment.sdkVersion}</span>
|
|
58
|
-
<span className="scene-badge">Fork {WEBSPATIAL_FORK_COMMIT.slice(0, 7)}</span>
|
|
59
|
-
</div>
|
|
60
|
-
</header>
|
|
61
|
-
|
|
62
|
-
<section className="scene-workspace-grid">
|
|
63
|
-
<article className="scene-surface scene-workspace-primary" enable-xr style={xrStyle(40, "thick")}>
|
|
64
|
-
<p className="scene-surface-label">Primary Workspace</p>
|
|
65
|
-
<h2 className="scene-surface-title">Make spatial panels the default, not the afterthought</h2>
|
|
66
|
-
<p className="scene-copy">
|
|
67
|
-
The mounted scene component is where the persona should bootstrap the scene, verify the
|
|
68
|
-
runtime, and lay out the main work surfaces. If the scene route only wraps a normal
|
|
69
|
-
home page, the app will still feel flat in-headset even when the SDK is bundled.
|
|
70
|
-
</p>
|
|
71
|
-
|
|
72
|
-
<div className="scene-step-grid">
|
|
73
|
-
{spatialWorkflows.map(workflow => (
|
|
74
|
-
<article key={workflow.title} className="scene-step-card">
|
|
75
|
-
<h3>{workflow.title}</h3>
|
|
76
|
-
<p>{workflow.body}</p>
|
|
77
|
-
</article>
|
|
78
|
-
))}
|
|
79
|
-
</div>
|
|
80
|
-
</article>
|
|
81
|
-
|
|
82
|
-
<div className="scene-secondary-stack">
|
|
83
|
-
<aside className="scene-surface" enable-xr style={xrStyle(24, "thin")}>
|
|
84
|
-
<p className="scene-surface-label">Runtime Diagnostics</p>
|
|
85
|
-
<div className="scene-status-grid">
|
|
86
|
-
<div className="scene-status-row">
|
|
87
|
-
<span>isWebSpatial</span>
|
|
88
|
-
<span>{environment.isWebSpatial ? "true" : "false"}</span>
|
|
89
|
-
</div>
|
|
90
|
-
<div className="scene-status-row">
|
|
91
|
-
<span>hasBridge</span>
|
|
92
|
-
<span>{environment.hasBridge ? "true" : "false"}</span>
|
|
93
|
-
</div>
|
|
94
|
-
<div className="scene-status-row">
|
|
95
|
-
<span>hasWebSpatialData</span>
|
|
96
|
-
<span>{environment.hasWebSpatialData ? "true" : "false"}</span>
|
|
97
|
-
</div>
|
|
98
|
-
<div className="scene-status-row">
|
|
99
|
-
<span>nativeVersion</span>
|
|
100
|
-
<span>{environment.nativeVersion ?? "browser fallback"}</span>
|
|
101
|
-
</div>
|
|
102
|
-
</div>
|
|
103
|
-
</aside>
|
|
104
|
-
|
|
105
|
-
<aside className="scene-surface" enable-xr style={xrStyle(18, "thin")}>
|
|
106
|
-
<p className="scene-surface-label">Tool Tray</p>
|
|
107
|
-
<div className="scene-chip-row">
|
|
108
|
-
{sceneChips.map(chip => (
|
|
109
|
-
<span key={chip} className="scene-tool-chip">
|
|
110
|
-
{chip}
|
|
111
|
-
</span>
|
|
112
|
-
))}
|
|
113
|
-
</div>
|
|
114
|
-
</aside>
|
|
115
|
-
</div>
|
|
116
|
-
</section>
|
|
117
|
-
|
|
118
|
-
<section className="scene-support-grid">
|
|
119
|
-
<article className="scene-surface" enable-xr style={xrStyle(18, "thin")}>
|
|
120
|
-
<p className="scene-surface-label">Spatial Surface Checklist</p>
|
|
121
|
-
<h2 className="scene-surface-title">At least three authored panels</h2>
|
|
122
|
-
<p className="scene-copy">
|
|
123
|
-
Add <code>enable-xr</code> and <code>xrStyle()</code> to meaningful panels like the
|
|
124
|
-
scene header, the primary workspace, and supporting status or completion surfaces.
|
|
125
|
-
</p>
|
|
126
|
-
</article>
|
|
127
|
-
|
|
128
|
-
<article className="scene-surface" enable-xr style={xrStyle(28, "regular")}>
|
|
129
|
-
<p className="scene-surface-label">Completion Panel</p>
|
|
130
|
-
<h2 className="scene-surface-title">Keep the host transparent</h2>
|
|
131
|
-
<p className="scene-copy">
|
|
132
|
-
The XR shell should recede behind the panels. Use <code>html.is-spatial</code> styles
|
|
133
|
-
so the host background stays transparent while the authored panels carry material.
|
|
134
|
-
</p>
|
|
135
|
-
</article>
|
|
136
|
-
|
|
137
|
-
<article className="scene-surface" enable-xr style={xrStyle(22, "thin")}>
|
|
138
|
-
<p className="scene-surface-label">Agent Notes</p>
|
|
139
|
-
<ul className="scene-note-list">
|
|
140
|
-
{personaNotes.map(note => (
|
|
141
|
-
<li key={note}>{note}</li>
|
|
142
|
-
))}
|
|
143
|
-
</ul>
|
|
144
|
-
</article>
|
|
145
|
-
</section>
|
|
146
|
-
|
|
147
|
-
<footer className="scene-footer">
|
|
148
|
-
<p className="scene-footer-copy">
|
|
149
|
-
Browser editing still lives at the non-spatial route while XR mode defaults directly into
|
|
150
|
-
the scene.
|
|
151
|
-
</p>
|
|
152
|
-
<Link className="scene-link" to="/home">
|
|
153
|
-
Open browser route
|
|
154
|
-
</Link>
|
|
155
|
-
</footer>
|
|
156
|
-
</main>
|
|
157
|
-
);
|
|
158
|
-
}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
export const personaNotes = [
|
|
2
|
-
"Keep persona-specific logic inside src/persona/ unless Oomi explicitly instructs otherwise.",
|
|
3
|
-
"Preserve the WebSpatial router basename, and default the index route to ScenePage whenever the runtime is running under the XR base path.",
|
|
4
|
-
"Call configurePersonaScene() from the mounted scene component and log detectSpatialEnvironment() when the scene boots.",
|
|
5
|
-
"Keep using the vendored AndroidXR-enabled WebSpatial fork instead of switching back to the stock npm packages.",
|
|
6
|
-
"Author multiple meaningful surfaces with explicit enable-xr, --xr-back, and --xr-background-material values so the app reads as spatial instead of one captured webpage.",
|
|
7
|
-
"Keep html.is-spatial shell styles transparent so the host recedes and the panels carry the visual material.",
|
|
8
|
-
"Do not remove public/oomi.runtime.json, public/oomi.health.json, or public/manifest.webmanifest.",
|
|
9
|
-
];
|
|
@@ -1,82 +0,0 @@
|
|
|
1
|
-
import type { CSSProperties } from "react";
|
|
2
|
-
import { initScene, version as webSpatialSdkVersion } from "@webspatial/react-sdk";
|
|
3
|
-
|
|
4
|
-
export const PERSONA_SCENE_NAME = "personaScene";
|
|
5
|
-
export const WEBSPATIAL_FORK_REPOSITORY = "https://github.com/zill4/webspatial-sdk";
|
|
6
|
-
export const WEBSPATIAL_FORK_COMMIT = "ac4bd47eb14a894ffef34a4044ddd0bbd47f3e72";
|
|
7
|
-
|
|
8
|
-
type SpatialWindow = Window & {
|
|
9
|
-
webspatialBridge?: unknown;
|
|
10
|
-
__WebSpatialData?: {
|
|
11
|
-
getNativeVersion?: () => string;
|
|
12
|
-
};
|
|
13
|
-
};
|
|
14
|
-
|
|
15
|
-
export type SpatialEnvironmentSnapshot = {
|
|
16
|
-
isWebSpatial: boolean;
|
|
17
|
-
sdkVersion: string;
|
|
18
|
-
nativeVersion: string | null;
|
|
19
|
-
hasBridge: boolean;
|
|
20
|
-
hasWebSpatialData: boolean;
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
export type XrStyle = CSSProperties & {
|
|
24
|
-
"--xr-back"?: number | string;
|
|
25
|
-
"--xr-background-material"?: string;
|
|
26
|
-
};
|
|
27
|
-
|
|
28
|
-
export function xrStyle(back: number, material: string): XrStyle {
|
|
29
|
-
return {
|
|
30
|
-
"--xr-back": String(back),
|
|
31
|
-
"--xr-background-material": material,
|
|
32
|
-
};
|
|
33
|
-
}
|
|
34
|
-
|
|
35
|
-
export function detectSpatialEnvironment(): SpatialEnvironmentSnapshot {
|
|
36
|
-
const typedWindow = window as SpatialWindow;
|
|
37
|
-
const userAgent = navigator.userAgent;
|
|
38
|
-
const userAgentVersion = userAgent.match(/WebSpatial\/([\d.]+)/)?.[1] ?? null;
|
|
39
|
-
const nativeVersion = (() => {
|
|
40
|
-
try {
|
|
41
|
-
return typedWindow.__WebSpatialData?.getNativeVersion?.() ?? userAgentVersion;
|
|
42
|
-
} catch {
|
|
43
|
-
return userAgentVersion;
|
|
44
|
-
}
|
|
45
|
-
})();
|
|
46
|
-
|
|
47
|
-
return {
|
|
48
|
-
isWebSpatial: userAgent.includes("WebSpatial/"),
|
|
49
|
-
sdkVersion: webSpatialSdkVersion,
|
|
50
|
-
nativeVersion,
|
|
51
|
-
hasBridge: typeof typedWindow.webspatialBridge !== "undefined",
|
|
52
|
-
hasWebSpatialData: typeof typedWindow.__WebSpatialData !== "undefined",
|
|
53
|
-
};
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
export function configurePersonaScene() {
|
|
57
|
-
initScene(
|
|
58
|
-
PERSONA_SCENE_NAME,
|
|
59
|
-
previous => ({
|
|
60
|
-
...previous,
|
|
61
|
-
defaultSize: {
|
|
62
|
-
width: 1440,
|
|
63
|
-
height: 960,
|
|
64
|
-
},
|
|
65
|
-
resizability: {
|
|
66
|
-
minWidth: 960,
|
|
67
|
-
minHeight: 720,
|
|
68
|
-
maxWidth: 1800,
|
|
69
|
-
maxHeight: 1280,
|
|
70
|
-
},
|
|
71
|
-
worldAlignment: "gravityAligned",
|
|
72
|
-
worldScaling: "automatic",
|
|
73
|
-
baseplateVisibility: "hidden",
|
|
74
|
-
}),
|
|
75
|
-
{ type: "window" },
|
|
76
|
-
);
|
|
77
|
-
}
|
|
78
|
-
|
|
79
|
-
export function openPersonaScene() {
|
|
80
|
-
configurePersonaScene();
|
|
81
|
-
window.open(`${__XR_ENV_BASE__}/scene`, PERSONA_SCENE_NAME);
|
|
82
|
-
}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"id": "persona-app",
|
|
3
|
-
"version": "v1",
|
|
4
|
-
"displayName": "Oomi Persona App",
|
|
5
|
-
"appKind": "oomi-persona-app",
|
|
6
|
-
"defaultPort": 4789,
|
|
7
|
-
"healthPath": "/webspatial/avp/oomi.health.json",
|
|
8
|
-
"startCommand": "npm run dev:avp",
|
|
9
|
-
"editableZones": [
|
|
10
|
-
"src/persona",
|
|
11
|
-
"persona"
|
|
12
|
-
]
|
|
13
|
-
}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"jsxImportSource": "@webspatial/react-sdk",
|
|
4
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.app.tsbuildinfo",
|
|
5
|
-
"target": "ES2020",
|
|
6
|
-
"useDefineForClassFields": true,
|
|
7
|
-
"lib": ["ES2020", "DOM", "DOM.Iterable"],
|
|
8
|
-
"module": "ESNext",
|
|
9
|
-
"skipLibCheck": true,
|
|
10
|
-
"moduleResolution": "bundler",
|
|
11
|
-
"allowImportingTsExtensions": true,
|
|
12
|
-
"isolatedModules": true,
|
|
13
|
-
"moduleDetection": "force",
|
|
14
|
-
"noEmit": true,
|
|
15
|
-
"jsx": "react-jsx",
|
|
16
|
-
"strict": true,
|
|
17
|
-
"noUnusedLocals": true,
|
|
18
|
-
"noUnusedParameters": true,
|
|
19
|
-
"noFallthroughCasesInSwitch": true,
|
|
20
|
-
"noUncheckedSideEffectImports": true
|
|
21
|
-
},
|
|
22
|
-
"include": ["src"]
|
|
23
|
-
}
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"jsxImportSource": "@webspatial/react-sdk",
|
|
4
|
-
"tsBuildInfoFile": "./node_modules/.tmp/tsconfig.node.tsbuildinfo",
|
|
5
|
-
"target": "ES2022",
|
|
6
|
-
"lib": ["ES2023"],
|
|
7
|
-
"module": "ESNext",
|
|
8
|
-
"skipLibCheck": true,
|
|
9
|
-
"moduleResolution": "bundler",
|
|
10
|
-
"allowImportingTsExtensions": true,
|
|
11
|
-
"isolatedModules": true,
|
|
12
|
-
"moduleDetection": "force",
|
|
13
|
-
"noEmit": true,
|
|
14
|
-
"strict": true,
|
|
15
|
-
"noUnusedLocals": true,
|
|
16
|
-
"noUnusedParameters": true,
|
|
17
|
-
"noFallthroughCasesInSwitch": true,
|
|
18
|
-
"noUncheckedSideEffectImports": true
|
|
19
|
-
},
|
|
20
|
-
"include": ["vite.config.ts"]
|
|
21
|
-
}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
This persona template vendors the AndroidXR-capable WebSpatial runtime packages from:
|
|
2
|
-
|
|
3
|
-
- Repository: https://github.com/zill4/webspatial-sdk
|
|
4
|
-
- Commit: ac4bd47eb14a894ffef34a4044ddd0bbd47f3e72
|
|
5
|
-
|
|
6
|
-
Oomi uses these vendored packages for persona runtimes so OpenClaw installs the AndroidXR-enabled fork instead of the stock npm release.
|
|
@@ -1,21 +0,0 @@
|
|
|
1
|
-
MIT License
|
|
2
|
-
|
|
3
|
-
Copyright (c) 2024 Spatial Web
|
|
4
|
-
|
|
5
|
-
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
-
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
-
in the Software without restriction, including without limitation the rights
|
|
8
|
-
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
-
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
-
furnished to do so, subject to the following conditions:
|
|
11
|
-
|
|
12
|
-
The above copyright notice and this permission notice shall be included in all
|
|
13
|
-
copies or substantial portions of the Software.
|
|
14
|
-
|
|
15
|
-
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
-
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
-
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
-
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
-
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
-
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
-
SOFTWARE.
|