@nodetool-ai/video-nodes 0.8.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (152) hide show
  1. package/README.md +58 -0
  2. package/dist/.nodetool-build-stamp +1 -0
  3. package/dist/index.d.ts +9 -0
  4. package/dist/index.d.ts.map +1 -0
  5. package/dist/index.js +11 -0
  6. package/dist/index.js.map +1 -0
  7. package/dist/nodes/ffmpeg-helpers.d.ts +77 -0
  8. package/dist/nodes/ffmpeg-helpers.d.ts.map +1 -0
  9. package/dist/nodes/ffmpeg-helpers.js +220 -0
  10. package/dist/nodes/ffmpeg-helpers.js.map +1 -0
  11. package/dist/nodes/lib-video-download.d.ts +29 -0
  12. package/dist/nodes/lib-video-download.d.ts.map +1 -0
  13. package/dist/nodes/lib-video-download.js +353 -0
  14. package/dist/nodes/lib-video-download.js.map +1 -0
  15. package/dist/nodes/model3d/analysis.d.ts +16 -0
  16. package/dist/nodes/model3d/analysis.d.ts.map +1 -0
  17. package/dist/nodes/model3d/analysis.js +38 -0
  18. package/dist/nodes/model3d/analysis.js.map +1 -0
  19. package/dist/nodes/model3d/base.d.ts +28 -0
  20. package/dist/nodes/model3d/base.d.ts.map +1 -0
  21. package/dist/nodes/model3d/base.js +20 -0
  22. package/dist/nodes/model3d/base.js.map +1 -0
  23. package/dist/nodes/model3d/boolean-ops.d.ts +2 -0
  24. package/dist/nodes/model3d/boolean-ops.d.ts.map +1 -0
  25. package/dist/nodes/model3d/boolean-ops.js +172 -0
  26. package/dist/nodes/model3d/boolean-ops.js.map +1 -0
  27. package/dist/nodes/model3d/cleanup.d.ts +56 -0
  28. package/dist/nodes/model3d/cleanup.d.ts.map +1 -0
  29. package/dist/nodes/model3d/cleanup.js +144 -0
  30. package/dist/nodes/model3d/cleanup.js.map +1 -0
  31. package/dist/nodes/model3d/convert.d.ts +27 -0
  32. package/dist/nodes/model3d/convert.d.ts.map +1 -0
  33. package/dist/nodes/model3d/convert.js +66 -0
  34. package/dist/nodes/model3d/convert.js.map +1 -0
  35. package/dist/nodes/model3d/defaults.d.ts +34 -0
  36. package/dist/nodes/model3d/defaults.d.ts.map +1 -0
  37. package/dist/nodes/model3d/defaults.js +28 -0
  38. package/dist/nodes/model3d/defaults.js.map +1 -0
  39. package/dist/nodes/model3d/document-ops.d.ts +4 -0
  40. package/dist/nodes/model3d/document-ops.d.ts.map +1 -0
  41. package/dist/nodes/model3d/document-ops.js +40 -0
  42. package/dist/nodes/model3d/document-ops.js.map +1 -0
  43. package/dist/nodes/model3d/generation.d.ts +56 -0
  44. package/dist/nodes/model3d/generation.d.ts.map +1 -0
  45. package/dist/nodes/model3d/generation.js +203 -0
  46. package/dist/nodes/model3d/generation.js.map +1 -0
  47. package/dist/nodes/model3d/glb.d.ts +29 -0
  48. package/dist/nodes/model3d/glb.d.ts.map +1 -0
  49. package/dist/nodes/model3d/glb.js +255 -0
  50. package/dist/nodes/model3d/glb.js.map +1 -0
  51. package/dist/nodes/model3d/index.d.ts +22 -0
  52. package/dist/nodes/model3d/index.d.ts.map +1 -0
  53. package/dist/nodes/model3d/index.js +41 -0
  54. package/dist/nodes/model3d/index.js.map +1 -0
  55. package/dist/nodes/model3d/io.d.ts +81 -0
  56. package/dist/nodes/model3d/io.d.ts.map +1 -0
  57. package/dist/nodes/model3d/io.js +162 -0
  58. package/dist/nodes/model3d/io.js.map +1 -0
  59. package/dist/nodes/model3d/mesh-ops.d.ts +40 -0
  60. package/dist/nodes/model3d/mesh-ops.d.ts.map +1 -0
  61. package/dist/nodes/model3d/mesh-ops.js +775 -0
  62. package/dist/nodes/model3d/mesh-ops.js.map +1 -0
  63. package/dist/nodes/model3d/nodes.d.ts +2 -0
  64. package/dist/nodes/model3d/nodes.d.ts.map +1 -0
  65. package/dist/nodes/model3d/nodes.js +2 -0
  66. package/dist/nodes/model3d/nodes.js.map +1 -0
  67. package/dist/nodes/model3d/ops.d.ts +44 -0
  68. package/dist/nodes/model3d/ops.d.ts.map +1 -0
  69. package/dist/nodes/model3d/ops.js +142 -0
  70. package/dist/nodes/model3d/ops.js.map +1 -0
  71. package/dist/nodes/model3d/render.d.ts +51 -0
  72. package/dist/nodes/model3d/render.d.ts.map +1 -0
  73. package/dist/nodes/model3d/render.js +124 -0
  74. package/dist/nodes/model3d/render.js.map +1 -0
  75. package/dist/nodes/model3d/render3d-core.d.ts +177 -0
  76. package/dist/nodes/model3d/render3d-core.d.ts.map +1 -0
  77. package/dist/nodes/model3d/render3d-core.js +366 -0
  78. package/dist/nodes/model3d/render3d-core.js.map +1 -0
  79. package/dist/nodes/model3d/render3d-headless.d.ts +75 -0
  80. package/dist/nodes/model3d/render3d-headless.d.ts.map +1 -0
  81. package/dist/nodes/model3d/render3d-headless.js +190 -0
  82. package/dist/nodes/model3d/render3d-headless.js.map +1 -0
  83. package/dist/nodes/model3d/render3d-page.d.ts +16 -0
  84. package/dist/nodes/model3d/render3d-page.d.ts.map +1 -0
  85. package/dist/nodes/model3d/render3d-page.js +51 -0
  86. package/dist/nodes/model3d/render3d-page.js.map +1 -0
  87. package/dist/nodes/model3d/transforms.d.ts +56 -0
  88. package/dist/nodes/model3d/transforms.d.ts.map +1 -0
  89. package/dist/nodes/model3d/transforms.js +148 -0
  90. package/dist/nodes/model3d/transforms.js.map +1 -0
  91. package/dist/nodes/model3d/types.d.ts +82 -0
  92. package/dist/nodes/model3d/types.d.ts.map +1 -0
  93. package/dist/nodes/model3d/types.js +2 -0
  94. package/dist/nodes/model3d/types.js.map +1 -0
  95. package/dist/nodes/model3d/utils.d.ts +46 -0
  96. package/dist/nodes/model3d/utils.d.ts.map +1 -0
  97. package/dist/nodes/model3d/utils.js +190 -0
  98. package/dist/nodes/model3d/utils.js.map +1 -0
  99. package/dist/nodes/model3d.d.ts +2 -0
  100. package/dist/nodes/model3d.d.ts.map +1 -0
  101. package/dist/nodes/model3d.js +2 -0
  102. package/dist/nodes/model3d.js.map +1 -0
  103. package/dist/nodes/placeholder-values.d.ts +10 -0
  104. package/dist/nodes/placeholder-values.d.ts.map +1 -0
  105. package/dist/nodes/placeholder-values.js +19 -0
  106. package/dist/nodes/placeholder-values.js.map +1 -0
  107. package/dist/nodes/script.d.ts +161 -0
  108. package/dist/nodes/script.d.ts.map +1 -0
  109. package/dist/nodes/script.js +673 -0
  110. package/dist/nodes/script.js.map +1 -0
  111. package/dist/nodes/storyboard.d.ts +269 -0
  112. package/dist/nodes/storyboard.d.ts.map +1 -0
  113. package/dist/nodes/storyboard.js +1017 -0
  114. package/dist/nodes/storyboard.js.map +1 -0
  115. package/dist/nodes/timeline/assetFiles.d.ts +19 -0
  116. package/dist/nodes/timeline/assetFiles.d.ts.map +1 -0
  117. package/dist/nodes/timeline/assetFiles.js +52 -0
  118. package/dist/nodes/timeline/assetFiles.js.map +1 -0
  119. package/dist/nodes/timeline/compositeRender.d.ts +60 -0
  120. package/dist/nodes/timeline/compositeRender.d.ts.map +1 -0
  121. package/dist/nodes/timeline/compositeRender.js +508 -0
  122. package/dist/nodes/timeline/compositeRender.js.map +1 -0
  123. package/dist/nodes/timeline/contactSheet.d.ts +43 -0
  124. package/dist/nodes/timeline/contactSheet.d.ts.map +1 -0
  125. package/dist/nodes/timeline/contactSheet.js +78 -0
  126. package/dist/nodes/timeline/contactSheet.js.map +1 -0
  127. package/dist/nodes/timeline/outputFormats.d.ts +69 -0
  128. package/dist/nodes/timeline/outputFormats.d.ts.map +1 -0
  129. package/dist/nodes/timeline/outputFormats.js +173 -0
  130. package/dist/nodes/timeline/outputFormats.js.map +1 -0
  131. package/dist/nodes/timeline/pngSequence.d.ts +44 -0
  132. package/dist/nodes/timeline/pngSequence.d.ts.map +1 -0
  133. package/dist/nodes/timeline/pngSequence.js +172 -0
  134. package/dist/nodes/timeline/pngSequence.js.map +1 -0
  135. package/dist/nodes/timeline/rasterizers.d.ts +47 -0
  136. package/dist/nodes/timeline/rasterizers.d.ts.map +1 -0
  137. package/dist/nodes/timeline/rasterizers.js +103 -0
  138. package/dist/nodes/timeline/rasterizers.js.map +1 -0
  139. package/dist/nodes/timeline/rawFrames.d.ts +149 -0
  140. package/dist/nodes/timeline/rawFrames.d.ts.map +1 -0
  141. package/dist/nodes/timeline/rawFrames.js +598 -0
  142. package/dist/nodes/timeline/rawFrames.js.map +1 -0
  143. package/dist/nodes/timeline.d.ts +206 -0
  144. package/dist/nodes/timeline.d.ts.map +1 -0
  145. package/dist/nodes/timeline.js +1395 -0
  146. package/dist/nodes/timeline.js.map +1 -0
  147. package/dist/nodes/video.d.ts +705 -0
  148. package/dist/nodes/video.d.ts.map +1 -0
  149. package/dist/nodes/video.js +2672 -0
  150. package/dist/nodes/video.js.map +1 -0
  151. package/dist/render3d-page.js +4118 -0
  152. package/package.json +95 -0
@@ -0,0 +1,190 @@
1
+ /**
2
+ * Node-side driver for `nodetool.model3d.RenderToImage`.
3
+ *
4
+ * The backend has no WebGL, so it launches a headless Chromium, injects the
5
+ * self-contained render bundle (`dist/render3d-page.js`, built by
6
+ * `scripts/bundle-render3d-page.mjs`), and calls `__nodetoolRenderGlbFrames`
7
+ * over CDP. SwiftShader flags keep WebGL working on GPU-less servers.
8
+ *
9
+ * Chrome discovery follows the automation nodes: `CHROME_PATH` when set,
10
+ * otherwise chrome-launcher's platform search. Everything here is
11
+ * lazy-imported so merely registering the node never requires Chrome.
12
+ */
13
+ import { readFile } from "node:fs/promises";
14
+ import { resolvePackageAssetPath } from "@nodetool-ai/config";
15
+ import { renderFrameFromRender3DOptions, sessionOptionsFromRender3DOptions } from "./render3d-core.js";
16
+ import { isNonEmptyString } from "@nodetool-ai/node-sdk";
17
+ /** Budget for the first frame, which pays the model load and the GL warm-up. */
18
+ const RENDER_TIMEOUT_MS = 120_000;
19
+ /** Added to the budget for every frame after the first. */
20
+ const EXTRA_FRAME_TIMEOUT_MS = 30_000;
21
+ /** How long to keep trying to attach to the debug port before giving up. */
22
+ const CDP_CONNECT_TIMEOUT_MS = 10_000;
23
+ /** Gap between attach attempts. */
24
+ const CDP_CONNECT_RETRY_MS = 100;
25
+ const CHROME_FLAGS = [
26
+ "--headless=new",
27
+ "--no-sandbox",
28
+ "--disable-setuid-sandbox",
29
+ "--disable-dev-shm-usage",
30
+ // Software WebGL: ANGLE on SwiftShader, explicitly allowed (Chrome 137+
31
+ // refuses software WebGL in headless without the unsafe opt-in).
32
+ "--use-angle=swiftshader",
33
+ "--enable-unsafe-swiftshader",
34
+ "--hide-scrollbars",
35
+ "--mute-audio"
36
+ ];
37
+ let bundlePromise = null;
38
+ /** Load (and cache) the self-contained render page bundle. */
39
+ async function loadRenderBundle() {
40
+ if (!bundlePromise) {
41
+ bundlePromise = (async () => {
42
+ const path = resolvePackageAssetPath({ pkg: "@nodetool-ai/video-nodes", path: "render3d-page.js" }, import.meta.url);
43
+ return readFile(path, "utf-8");
44
+ })().catch((err) => {
45
+ bundlePromise = null;
46
+ throw err;
47
+ });
48
+ }
49
+ return bundlePromise;
50
+ }
51
+ function throwOnException(result, stage) {
52
+ if (!result.exceptionDetails)
53
+ return;
54
+ const exception = result.exceptionDetails.exception;
55
+ const detail = exception?.description ??
56
+ (exception?.value !== undefined ? String(exception.value) : undefined) ??
57
+ result.exceptionDetails.text ??
58
+ "unknown error";
59
+ throw new Error(`RenderToImage (${stage}): ${detail}`);
60
+ }
61
+ async function withTimeout(promise, label, timeoutMs) {
62
+ let timer;
63
+ const timeout = new Promise((_, reject) => {
64
+ timer = setTimeout(() => reject(new Error(`RenderToImage: ${label} timed out after ${timeoutMs}ms`)), timeoutMs);
65
+ });
66
+ try {
67
+ return await Promise.race([promise, timeout]);
68
+ }
69
+ finally {
70
+ clearTimeout(timer);
71
+ }
72
+ }
73
+ /**
74
+ * Attach to a freshly launched Chrome's debug port, retrying while it refuses.
75
+ *
76
+ * `chrome-launcher` resolves as soon as the port accepts a TCP connection, but
77
+ * `chrome-remote-interface` then issues an HTTP request to `/json/list` that a
78
+ * still-initializing Chrome refuses outright. A single attempt loses that race
79
+ * on a loaded machine — it turned up as an `ECONNREFUSED` on CI while several
80
+ * other Chrome-driving suites were running — so poll until the endpoint is
81
+ * actually serving.
82
+ *
83
+ * Exported for tests.
84
+ */
85
+ export async function connectCdp(port, { timeoutMs = CDP_CONNECT_TIMEOUT_MS, retryMs = CDP_CONNECT_RETRY_MS } = {}) {
86
+ const CDP = (await import("chrome-remote-interface")).default;
87
+ const deadline = Date.now() + timeoutMs;
88
+ let lastError;
89
+ for (;;) {
90
+ try {
91
+ // SAFETY: `CdpClient` is the `Runtime.enable`/`Runtime.evaluate`/`close`
92
+ // subset this renderer drives; chrome-remote-interface types every
93
+ // domain dynamically.
94
+ return (await CDP({ port }));
95
+ }
96
+ catch (err) {
97
+ lastError = err;
98
+ // Stop once another wait would take us past the deadline, so the loop
99
+ // never overruns the budget it was given.
100
+ if (Date.now() + retryMs >= deadline)
101
+ break;
102
+ await new Promise((resolve) => setTimeout(resolve, retryMs));
103
+ }
104
+ }
105
+ const detail = lastError instanceof Error ? lastError.message : String(lastError);
106
+ throw new Error(`RenderToImage: could not attach to headless Chrome on port ${port} ` +
107
+ `within ${timeoutMs}ms: ${detail}`, { cause: lastError });
108
+ }
109
+ /**
110
+ * Launch Chrome, retrying once after a beat. `chrome-launcher` rejects with
111
+ * its port poll's raw error (an `ECONNREFUSED`) when Chromium is too slow to
112
+ * open its debug port on a loaded machine — the same transient race the CDP
113
+ * attach retry above covers, one step earlier. A machine that cannot run
114
+ * Chrome at all fails the same way twice and the second error propagates.
115
+ *
116
+ * Exported for tests.
117
+ */
118
+ export async function launchChromeWithRetry(launch, retryDelayMs = 1_000) {
119
+ try {
120
+ return await launch();
121
+ }
122
+ catch {
123
+ // The first failure leaves any half-started Chrome behind; a fresh launch
124
+ // picks a fresh port, so the two never contend.
125
+ await new Promise((resolve) => setTimeout(resolve, retryDelayMs));
126
+ return await launch();
127
+ }
128
+ }
129
+ /**
130
+ * Render one session's worth of frames in a fresh headless Chromium: one
131
+ * launch, one model load, one PNG per frame. One Chrome per call keeps the
132
+ * node stateless; launch cost (~1s) is negligible next to a typical
133
+ * workflow's model-generation steps.
134
+ */
135
+ export async function renderGlbFramesHeadless(glb, options, frames) {
136
+ if (frames.length === 0)
137
+ return [];
138
+ const bundle = await loadRenderBundle();
139
+ const { launch } = await import("chrome-launcher");
140
+ const chrome = await launchChromeWithRetry(() => launch({
141
+ chromeFlags: CHROME_FLAGS,
142
+ chromePath: process.env.CHROME_PATH || undefined
143
+ }));
144
+ let client = null;
145
+ try {
146
+ client = await connectCdp(chrome.port);
147
+ await client.Runtime.enable();
148
+ const injected = await client.Runtime.evaluate({ expression: bundle });
149
+ throwOnException(injected, "inject bundle");
150
+ const glbBase64 = Buffer.from(glb).toString("base64");
151
+ const call = await withTimeout(client.Runtime.evaluate({
152
+ expression: `globalThis.__nodetoolRenderGlbFrames(${JSON.stringify(glbBase64)}, ${JSON.stringify(JSON.stringify(options))}, ${JSON.stringify(JSON.stringify(frames))})`,
153
+ awaitPromise: true,
154
+ returnByValue: true
155
+ }), "render", RENDER_TIMEOUT_MS + EXTRA_FRAME_TIMEOUT_MS * (frames.length - 1));
156
+ throwOnException(call, "render");
157
+ const pngsBase64 = call.result?.value;
158
+ if (!Array.isArray(pngsBase64) || pngsBase64.length !== frames.length) {
159
+ throw new Error(`RenderToImage: headless render returned ${Array.isArray(pngsBase64) ? pngsBase64.length : "no"} images for ${frames.length} frames`);
160
+ }
161
+ return pngsBase64.map((png) => {
162
+ if (!isNonEmptyString(png)) {
163
+ throw new Error("RenderToImage: headless render returned no image data");
164
+ }
165
+ return new Uint8Array(Buffer.from(png, "base64"));
166
+ });
167
+ }
168
+ finally {
169
+ if (client) {
170
+ try {
171
+ await client.close();
172
+ }
173
+ catch {
174
+ // Chrome is being killed right after; a failed CDP close is harmless.
175
+ }
176
+ }
177
+ try {
178
+ await chrome.kill();
179
+ }
180
+ catch {
181
+ // Process may already be gone.
182
+ }
183
+ }
184
+ }
185
+ /** Render GLB bytes to PNG bytes: the one-frame case of the above. */
186
+ export async function renderGlbHeadless(glb, options) {
187
+ const [png] = await renderGlbFramesHeadless(glb, sessionOptionsFromRender3DOptions(options), [renderFrameFromRender3DOptions(options)]);
188
+ return png;
189
+ }
190
+ //# sourceMappingURL=render3d-headless.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render3d-headless.js","sourceRoot":"","sources":["../../../src/nodes/model3d/render3d-headless.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,16 @@
1
+ /**
2
+ * Headless-page entry for `nodetool.model3d.RenderToImage` and for the
3
+ * timeline's `model3d` layers.
4
+ *
5
+ * esbuild bundles this file (plus three.js) into `dist/render3d-page.js`
6
+ * (see `scripts/bundle-render3d-page.mjs`). The Node-side driver
7
+ * (`render3d-headless.ts`) evaluates the bundle in a blank headless-Chromium
8
+ * page, then calls `__nodetoolRenderGlbFrames` over CDP — one session, one
9
+ * PNG per requested frame. Every argument and result is base64 or JSON text,
10
+ * the only data shapes that survive `Runtime.evaluate` round-trips.
11
+ */
12
+ declare global {
13
+ var __nodetoolRenderGlbFrames: ((glbBase64: string, optionsJson: string, framesJson: string) => Promise<string[]>) | undefined;
14
+ }
15
+ export {};
16
+ //# sourceMappingURL=render3d-page.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render3d-page.d.ts","sourceRoot":"","sources":["../../../src/nodes/model3d/render3d-page.ts"],"names":[],"mappings":"AACA;;;;;;;;;;GAUG;AA2BH,OAAO,CAAC,MAAM,CAAC;IACb,IAAI,yBAAyB,EACzB,CAAC,CACC,SAAS,EAAE,MAAM,EACjB,WAAW,EAAE,MAAM,EACnB,UAAU,EAAE,MAAM,KACf,OAAO,CAAC,MAAM,EAAE,CAAC,CAAC,GACvB,SAAS,CAAC;CACf"}
@@ -0,0 +1,51 @@
1
+ /// <reference lib="dom" />
2
+ /**
3
+ * Headless-page entry for `nodetool.model3d.RenderToImage` and for the
4
+ * timeline's `model3d` layers.
5
+ *
6
+ * esbuild bundles this file (plus three.js) into `dist/render3d-page.js`
7
+ * (see `scripts/bundle-render3d-page.mjs`). The Node-side driver
8
+ * (`render3d-headless.ts`) evaluates the bundle in a blank headless-Chromium
9
+ * page, then calls `__nodetoolRenderGlbFrames` over CDP — one session, one
10
+ * PNG per requested frame. Every argument and result is base64 or JSON text,
11
+ * the only data shapes that survive `Runtime.evaluate` round-trips.
12
+ */
13
+ import { createModel3DRenderSession } from "./render3d-core.js";
14
+ function base64ToBytes(base64) {
15
+ const binary = atob(base64);
16
+ const bytes = new Uint8Array(binary.length);
17
+ for (let i = 0; i < binary.length; i++) {
18
+ bytes[i] = binary.charCodeAt(i);
19
+ }
20
+ return bytes;
21
+ }
22
+ function bytesToBase64(bytes) {
23
+ // Chunked to stay clear of argument-count limits on large images.
24
+ const chunkSize = 0x8000;
25
+ let binary = "";
26
+ for (let i = 0; i < bytes.length; i += chunkSize) {
27
+ binary += String.fromCharCode(...bytes.subarray(i, i + chunkSize));
28
+ }
29
+ return btoa(binary);
30
+ }
31
+ globalThis.__nodetoolRenderGlbFrames = async (glbBase64, optionsJson, framesJson) => {
32
+ const options = JSON.parse(optionsJson);
33
+ const frames = JSON.parse(framesJson);
34
+ const session = await createModel3DRenderSession(base64ToBytes(glbBase64), options);
35
+ try {
36
+ const pngs = [];
37
+ for (const frame of frames) {
38
+ // Serial on purpose: one canvas and one WebGL context per session, so a
39
+ // frame has to be encoded before the next one overwrites it.
40
+ const blob = await session
41
+ .render(frame)
42
+ .convertToBlob({ type: "image/png" });
43
+ pngs.push(bytesToBase64(new Uint8Array(await blob.arrayBuffer())));
44
+ }
45
+ return pngs;
46
+ }
47
+ finally {
48
+ session.dispose();
49
+ }
50
+ };
51
+ //# sourceMappingURL=render3d-page.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render3d-page.js","sourceRoot":"","sources":["../../../src/nodes/model3d/render3d-page.ts"],"names":[],"mappings":"AAAA,2BAA2B;AAC3B;;;;;;;;;;GAUG;AAEH,OAAO,EACL,0BAA0B,EAG3B,MAAM,oBAAoB,CAAC;AAE5B,SAAS,aAAa,CAAC,MAAc;IACnC,MAAM,MAAM,GAAG,IAAI,CAAC,MAAM,CAAC,CAAC;IAC5B,MAAM,KAAK,GAAG,IAAI,UAAU,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC;IAC5C,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,MAAM,CAAC,MAAM,EAAE,CAAC,EAAE,EAAE,CAAC;QACvC,KAAK,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC;IAClC,CAAC;IACD,OAAO,KAAK,CAAC;AACf,CAAC;AAED,SAAS,aAAa,CAAC,KAAiB;IACtC,kEAAkE;IAClE,MAAM,SAAS,GAAG,MAAM,CAAC;IACzB,IAAI,MAAM,GAAG,EAAE,CAAC;IAChB,KAAK,IAAI,CAAC,GAAG,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,MAAM,EAAE,CAAC,IAAI,SAAS,EAAE,CAAC;QACjD,MAAM,IAAI,MAAM,CAAC,YAAY,CAAC,GAAG,KAAK,CAAC,QAAQ,CAAC,CAAC,EAAE,CAAC,GAAG,SAAS,CAAC,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,IAAI,CAAC,MAAM,CAAC,CAAC;AACtB,CAAC;AAYD,UAAU,CAAC,yBAAyB,GAAG,KAAK,EAC1C,SAAiB,EACjB,WAAmB,EACnB,UAAkB,EACC,EAAE;IACrB,MAAM,OAAO,GAAG,IAAI,CAAC,KAAK,CAAC,WAAW,CAA0B,CAAC;IACjE,MAAM,MAAM,GAAG,IAAI,CAAC,KAAK,CAAC,UAAU,CAAyB,CAAC;IAC9D,MAAM,OAAO,GAAG,MAAM,0BAA0B,CAC9C,aAAa,CAAC,SAAS,CAAC,EACxB,OAAO,CACR,CAAC;IACF,IAAI,CAAC;QACH,MAAM,IAAI,GAAa,EAAE,CAAC;QAC1B,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;YAC3B,wEAAwE;YACxE,6DAA6D;YAC7D,MAAM,IAAI,GAAG,MAAM,OAAO;iBACvB,MAAM,CAAC,KAAK,CAAC;iBACb,aAAa,CAAC,EAAE,IAAI,EAAE,WAAW,EAAE,CAAC,CAAC;YACxC,IAAI,CAAC,IAAI,CAAC,aAAa,CAAC,IAAI,UAAU,CAAC,MAAM,IAAI,CAAC,WAAW,EAAE,CAAC,CAAC,CAAC,CAAC;QACrE,CAAC;QACD,OAAO,IAAI,CAAC;IACd,CAAC;YAAS,CAAC;QACT,OAAO,CAAC,OAAO,EAAE,CAAC;IACpB,CAAC;AACH,CAAC,CAAC"}
@@ -0,0 +1,56 @@
1
+ import { GlbTransformNode } from "./base.js";
2
+ import type { Model3DRefLike } from "./types.js";
3
+ export declare class Transform3DNode extends GlbTransformNode {
4
+ static readonly nodeType = "nodetool.model3d.Transform3D";
5
+ static readonly title = "Transform 3D";
6
+ static readonly description = "Apply translation, rotation, and scaling to a 3D model.\n 3d, mesh, model, transform, translate, rotate, scale, move\n\n Use cases:\n - Position models in 3D space\n - Scale models to specific dimensions\n - Rotate models for proper orientation";
7
+ static readonly metadataOutputTypes: {
8
+ output: string;
9
+ };
10
+ static readonly inlineFields: never[];
11
+ static readonly inputFields: string[];
12
+ model: Model3DRefLike;
13
+ translate_x: number;
14
+ translate_y: number;
15
+ translate_z: number;
16
+ rotate_x: number;
17
+ rotate_y: number;
18
+ rotate_z: number;
19
+ scale_x: number;
20
+ scale_y: number;
21
+ scale_z: number;
22
+ uniform_scale: number;
23
+ protected transform(bytes: Uint8Array): Uint8Array | null;
24
+ }
25
+ export declare class CenterMeshNode extends GlbTransformNode {
26
+ static readonly nodeType = "nodetool.model3d.CenterMesh";
27
+ static readonly title = "Center Mesh";
28
+ static readonly description = "Center a mesh at the origin.\n 3d, mesh, model, center, origin, align\n\n Use cases:\n - Center models for consistent positioning\n - Prepare models for rotation\n - Align multiple models";
29
+ static readonly metadataOutputTypes: {
30
+ output: string;
31
+ };
32
+ static readonly inlineFields: never[];
33
+ static readonly inputFields: string[];
34
+ model: Model3DRefLike;
35
+ use_centroid: boolean;
36
+ protected transform(bytes: Uint8Array): Uint8Array | null;
37
+ }
38
+ export declare class NormalizeModel3DNode extends GlbTransformNode {
39
+ static readonly nodeType = "nodetool.model3d.NormalizeModel3D";
40
+ static readonly title = "Normalize Model 3D";
41
+ static readonly description = "Normalize a 3D model with explicit axis cleanup, centering, optional uniform scaling, and optional ground placement.\n 3d, mesh, model, normalize, center, scale, orient, ground\n\n Current limits:\n - First honest pass supports GLB geometry cleanup only\n - Axis normalization is explicit (`keep`, `z_to_y`, `y_to_z`), not auto-detected\n\n Use cases:\n - Standardize imported GLB orientation\n - Fit meshes into a predictable size box\n - Center models before downstream processing\n - Place meshes onto a chosen ground axis";
42
+ static readonly metadataOutputTypes: {
43
+ output: string;
44
+ };
45
+ static readonly inlineFields: never[];
46
+ static readonly inputFields: string[];
47
+ model: Model3DRefLike;
48
+ center_mode: "bounds" | "centroid" | "none";
49
+ axis_preset: "keep" | "z_to_y" | "y_to_z";
50
+ scale_to_size: boolean;
51
+ target_size: number;
52
+ place_on_ground: boolean;
53
+ ground_axis: "y" | "z";
54
+ protected transform(bytes: Uint8Array): Uint8Array | null;
55
+ }
56
+ //# sourceMappingURL=transforms.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transforms.d.ts","sourceRoot":"","sources":["../../../src/nodes/model3d/transforms.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,gBAAgB,EAAE,MAAM,WAAW,CAAC;AAC7C,OAAO,KAAK,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AAIjD,qBAAa,eAAgB,SAAQ,gBAAgB;IACnD,MAAM,CAAC,QAAQ,CAAC,QAAQ,kCAAkC;IAC1D,MAAM,CAAC,QAAQ,CAAC,KAAK,kBAAkB;IACvC,MAAM,CAAC,QAAQ,CAAC,WAAW,yQAC6O;IACxQ,MAAM,CAAC,QAAQ,CAAC,mBAAmB;QACjC,MAAM;MACN;IACF,MAAM,CAAC,QAAQ,CAAC,YAAY,UAAM;IAClC,MAAM,CAAC,QAAQ,CAAC,WAAW,WAAa;IAQhC,KAAK,EAAE,cAAc,CAAC;IAGtB,WAAW,EAAE,MAAM,CAAC;IAGpB,WAAW,EAAE,MAAM,CAAC;IAGpB,WAAW,EAAE,MAAM,CAAC;IAGpB,QAAQ,EAAE,MAAM,CAAC;IAGjB,QAAQ,EAAE,MAAM,CAAC;IAGjB,QAAQ,EAAE,MAAM,CAAC;IAGjB,OAAO,EAAE,MAAM,CAAC;IAGhB,OAAO,EAAE,MAAM,CAAC;IAGhB,OAAO,EAAE,MAAM,CAAC;IAGhB,aAAa,EAAE,MAAM,CAAC;IAE9B,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAaxD;CACF;AAED,qBAAa,cAAe,SAAQ,gBAAgB;IAClD,MAAM,CAAC,QAAQ,CAAC,QAAQ,iCAAiC;IACzD,MAAM,CAAC,QAAQ,CAAC,KAAK,iBAAiB;IACtC,MAAM,CAAC,QAAQ,CAAC,WAAW,gNACoL;IAC/M,MAAM,CAAC,QAAQ,CAAC,mBAAmB;QACjC,MAAM;MACN;IACF,MAAM,CAAC,QAAQ,CAAC,YAAY,UAAM;IAClC,MAAM,CAAC,QAAQ,CAAC,WAAW,WAAa;IAQhC,KAAK,EAAE,cAAc,CAAC;IAQtB,YAAY,EAAE,OAAO,CAAC;IAE9B,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CAExD;CACF;AAED,qBAAa,oBAAqB,SAAQ,gBAAgB;IACxD,MAAM,CAAC,QAAQ,CAAC,QAAQ,uCAAuC;IAC/D,MAAM,CAAC,QAAQ,CAAC,KAAK,wBAAwB;IAC7C,MAAM,CAAC,QAAQ,CAAC,WAAW,8iBACkhB;IAC7iB,MAAM,CAAC,QAAQ,CAAC,mBAAmB;QACjC,MAAM;MACN;IACF,MAAM,CAAC,QAAQ,CAAC,YAAY,UAAM;IAClC,MAAM,CAAC,QAAQ,CAAC,WAAW,WAAa;IAQhC,KAAK,EAAE,cAAc,CAAC;IAGtB,WAAW,EAAE,QAAQ,GAAG,UAAU,GAAG,MAAM,CAAC;IAG5C,WAAW,EAAE,MAAM,GAAG,QAAQ,GAAG,QAAQ,CAAC;IAG1C,aAAa,EAAE,OAAO,CAAC;IAGvB,WAAW,EAAE,MAAM,CAAC;IAGpB,eAAe,EAAE,OAAO,CAAC;IAGzB,WAAW,EAAE,GAAG,GAAG,GAAG,CAAC;IAE/B,SAAS,CAAC,SAAS,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,GAAG,IAAI,CASxD;CACF"}
@@ -0,0 +1,148 @@
1
+ var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
2
+ var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
3
+ if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
4
+ else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
5
+ return c > 3 && r && Object.defineProperty(target, key, r), r;
6
+ };
7
+ import { prop } from "@nodetool-ai/node-sdk";
8
+ import { GlbTransformNode } from "./base.js";
9
+ import { DEFAULT_MODEL_3D } from "./defaults.js";
10
+ import { centerGlb, normalizeGlb, transformGlb } from "./mesh-ops.js";
11
+ export class Transform3DNode extends GlbTransformNode {
12
+ static nodeType = "nodetool.model3d.Transform3D";
13
+ static title = "Transform 3D";
14
+ static description = "Apply translation, rotation, and scaling to a 3D model.\n 3d, mesh, model, transform, translate, rotate, scale, move\n\n Use cases:\n - Position models in 3D space\n - Scale models to specific dimensions\n - Rotate models for proper orientation";
15
+ static metadataOutputTypes = {
16
+ output: "model_3d"
17
+ };
18
+ static inlineFields = [];
19
+ static inputFields = ["model"];
20
+ transform(bytes) {
21
+ return transformGlb(bytes, {
22
+ translateX: this.translate_x,
23
+ translateY: this.translate_y,
24
+ translateZ: this.translate_z,
25
+ rotateXDeg: this.rotate_x,
26
+ rotateYDeg: this.rotate_y,
27
+ rotateZDeg: this.rotate_z,
28
+ scaleX: this.scale_x,
29
+ scaleY: this.scale_y,
30
+ scaleZ: this.scale_z,
31
+ uniformScale: this.uniform_scale
32
+ });
33
+ }
34
+ }
35
+ __decorate([
36
+ prop({
37
+ type: "model_3d",
38
+ default: DEFAULT_MODEL_3D,
39
+ title: "Model",
40
+ description: "The 3D model to transform"
41
+ })
42
+ ], Transform3DNode.prototype, "model", void 0);
43
+ __decorate([
44
+ prop({ type: "float", default: 0, title: "Translate X", description: "Translation along X axis" })
45
+ ], Transform3DNode.prototype, "translate_x", void 0);
46
+ __decorate([
47
+ prop({ type: "float", default: 0, title: "Translate Y", description: "Translation along Y axis" })
48
+ ], Transform3DNode.prototype, "translate_y", void 0);
49
+ __decorate([
50
+ prop({ type: "float", default: 0, title: "Translate Z", description: "Translation along Z axis" })
51
+ ], Transform3DNode.prototype, "translate_z", void 0);
52
+ __decorate([
53
+ prop({ type: "float", default: 0, title: "Rotate X", description: "Rotation around X axis in degrees", min: -360, max: 360 })
54
+ ], Transform3DNode.prototype, "rotate_x", void 0);
55
+ __decorate([
56
+ prop({ type: "float", default: 0, title: "Rotate Y", description: "Rotation around Y axis in degrees", min: -360, max: 360 })
57
+ ], Transform3DNode.prototype, "rotate_y", void 0);
58
+ __decorate([
59
+ prop({ type: "float", default: 0, title: "Rotate Z", description: "Rotation around Z axis in degrees", min: -360, max: 360 })
60
+ ], Transform3DNode.prototype, "rotate_z", void 0);
61
+ __decorate([
62
+ prop({ type: "float", default: 1, title: "Scale X", description: "Scale factor along X axis" })
63
+ ], Transform3DNode.prototype, "scale_x", void 0);
64
+ __decorate([
65
+ prop({ type: "float", default: 1, title: "Scale Y", description: "Scale factor along Y axis" })
66
+ ], Transform3DNode.prototype, "scale_y", void 0);
67
+ __decorate([
68
+ prop({ type: "float", default: 1, title: "Scale Z", description: "Scale factor along Z axis" })
69
+ ], Transform3DNode.prototype, "scale_z", void 0);
70
+ __decorate([
71
+ prop({ type: "float", default: 1, title: "Uniform Scale", description: "Uniform scale factor (applied after axis scales)" })
72
+ ], Transform3DNode.prototype, "uniform_scale", void 0);
73
+ export class CenterMeshNode extends GlbTransformNode {
74
+ static nodeType = "nodetool.model3d.CenterMesh";
75
+ static title = "Center Mesh";
76
+ static description = "Center a mesh at the origin.\n 3d, mesh, model, center, origin, align\n\n Use cases:\n - Center models for consistent positioning\n - Prepare models for rotation\n - Align multiple models";
77
+ static metadataOutputTypes = {
78
+ output: "model_3d"
79
+ };
80
+ static inlineFields = [];
81
+ static inputFields = ["model"];
82
+ transform(bytes) {
83
+ return centerGlb(bytes, { useCentroid: this.use_centroid });
84
+ }
85
+ }
86
+ __decorate([
87
+ prop({
88
+ type: "model_3d",
89
+ default: DEFAULT_MODEL_3D,
90
+ title: "Model",
91
+ description: "The 3D model to center"
92
+ })
93
+ ], CenterMeshNode.prototype, "model", void 0);
94
+ __decorate([
95
+ prop({
96
+ type: "bool",
97
+ default: true,
98
+ title: "Use Centroid",
99
+ description: "Use geometric centroid (True) or bounding box center (False)"
100
+ })
101
+ ], CenterMeshNode.prototype, "use_centroid", void 0);
102
+ export class NormalizeModel3DNode extends GlbTransformNode {
103
+ static nodeType = "nodetool.model3d.NormalizeModel3D";
104
+ static title = "Normalize Model 3D";
105
+ static description = "Normalize a 3D model with explicit axis cleanup, centering, optional uniform scaling, and optional ground placement.\n 3d, mesh, model, normalize, center, scale, orient, ground\n\n Current limits:\n - First honest pass supports GLB geometry cleanup only\n - Axis normalization is explicit (`keep`, `z_to_y`, `y_to_z`), not auto-detected\n\n Use cases:\n - Standardize imported GLB orientation\n - Fit meshes into a predictable size box\n - Center models before downstream processing\n - Place meshes onto a chosen ground axis";
106
+ static metadataOutputTypes = {
107
+ output: "model_3d"
108
+ };
109
+ static inlineFields = [];
110
+ static inputFields = ["model"];
111
+ transform(bytes) {
112
+ return normalizeGlb(bytes, {
113
+ centerMode: this.center_mode,
114
+ axisPreset: this.axis_preset,
115
+ scaleToSize: this.scale_to_size,
116
+ targetSize: this.target_size,
117
+ placeOnGround: this.place_on_ground,
118
+ groundAxis: this.ground_axis
119
+ });
120
+ }
121
+ }
122
+ __decorate([
123
+ prop({
124
+ type: "model_3d",
125
+ default: DEFAULT_MODEL_3D,
126
+ title: "Model",
127
+ description: "The 3D model to normalize"
128
+ })
129
+ ], NormalizeModel3DNode.prototype, "model", void 0);
130
+ __decorate([
131
+ prop({ type: "enum", default: "bounds", title: "Center Mode", description: "How to center the model before optional scaling", values: ["bounds", "centroid", "none"] })
132
+ ], NormalizeModel3DNode.prototype, "center_mode", void 0);
133
+ __decorate([
134
+ prop({ type: "enum", default: "keep", title: "Axis Preset", description: "Explicit orientation normalization preset", values: ["keep", "z_to_y", "y_to_z"] })
135
+ ], NormalizeModel3DNode.prototype, "axis_preset", void 0);
136
+ __decorate([
137
+ prop({ type: "bool", default: true, title: "Scale To Size", description: "Scale the model uniformly so its longest bounds dimension matches the target size" })
138
+ ], NormalizeModel3DNode.prototype, "scale_to_size", void 0);
139
+ __decorate([
140
+ prop({ type: "float", default: 1, title: "Target Size", description: "Longest bounds dimension after optional uniform scaling", min: 0.0001 })
141
+ ], NormalizeModel3DNode.prototype, "target_size", void 0);
142
+ __decorate([
143
+ prop({ type: "bool", default: true, title: "Place On Ground", description: "Translate the mesh so the chosen ground axis minimum becomes zero" })
144
+ ], NormalizeModel3DNode.prototype, "place_on_ground", void 0);
145
+ __decorate([
146
+ prop({ type: "enum", default: "y", title: "Ground Axis", description: "Axis treated as the up/ground direction for placement", values: ["y", "z"] })
147
+ ], NormalizeModel3DNode.prototype, "ground_axis", void 0);
148
+ //# sourceMappingURL=transforms.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"transforms.js","sourceRoot":"","sources":["../../../src/nodes/model3d/transforms.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,82 @@
1
+ export type Model3DRefLike = {
2
+ uri?: string;
3
+ data?: Uint8Array | string;
4
+ format?: string;
5
+ vertices?: number;
6
+ faces?: number;
7
+ };
8
+ export type ImageRefLike = {
9
+ data?: Uint8Array | string;
10
+ uri?: string;
11
+ };
12
+ export type JsonResources = Record<string, Uint8Array>;
13
+ export type JsonResourceRef = {
14
+ uri?: string;
15
+ };
16
+ export type Model3DMetadata = {
17
+ uri: string;
18
+ format: string;
19
+ size_bytes: number;
20
+ vertices: number;
21
+ faces: number;
22
+ vertex_count: number;
23
+ face_count: number;
24
+ mesh_count: number;
25
+ primitive_count: number;
26
+ bounds_min: number[];
27
+ bounds_max: number[];
28
+ is_watertight: boolean;
29
+ center_of_mass: number[] | null;
30
+ volume: number | null;
31
+ surface_area: number | null;
32
+ };
33
+ export type ManifoldMeshLike = {
34
+ numProp: number;
35
+ triVerts: Uint32Array;
36
+ vertProperties: Float32Array;
37
+ };
38
+ export type ManifoldInstance = {
39
+ add(other: ManifoldInstance): ManifoldInstance;
40
+ subtract(other: ManifoldInstance): ManifoldInstance;
41
+ intersect(other: ManifoldInstance): ManifoldInstance;
42
+ getMesh(): ManifoldMeshLike;
43
+ delete(): void;
44
+ };
45
+ export type ManifoldApi = {
46
+ setup(): void;
47
+ Manifold: {
48
+ ofMesh(mesh: ManifoldMeshLike): ManifoldInstance;
49
+ };
50
+ };
51
+ export interface GltfAccessor {
52
+ bufferView: number;
53
+ byteOffset?: number;
54
+ componentType: number;
55
+ count: number;
56
+ type: string;
57
+ min?: number[];
58
+ max?: number[];
59
+ }
60
+ export interface GltfBufferView {
61
+ buffer: number;
62
+ byteOffset?: number;
63
+ byteLength: number;
64
+ byteStride?: number;
65
+ }
66
+ interface GltfPrimitive {
67
+ attributes: Record<string, number>;
68
+ indices?: number;
69
+ mode?: number;
70
+ }
71
+ interface GltfMesh {
72
+ primitives: GltfPrimitive[];
73
+ [key: string]: unknown;
74
+ }
75
+ export interface GltfJson {
76
+ accessors?: GltfAccessor[];
77
+ bufferViews?: GltfBufferView[];
78
+ meshes?: GltfMesh[];
79
+ [key: string]: unknown;
80
+ }
81
+ export {};
82
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../../src/nodes/model3d/types.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ export {};
2
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../../src/nodes/model3d/types.ts"],"names":[],"mappings":""}
@@ -0,0 +1,46 @@
1
+ import type { JsonResourceRef, JsonResources, Model3DRefLike } from "./types.js";
2
+ export declare function toBytes(data: Uint8Array | string | undefined): Uint8Array;
3
+ export declare function modelBytes(model: unknown): Uint8Array;
4
+ export declare function modelRefToBytes(model: unknown, context?: {
5
+ storage?: {
6
+ retrieve(uri: string): Promise<Uint8Array | null>;
7
+ } | null;
8
+ }): Promise<Uint8Array>;
9
+ /**
10
+ * Resolve an image-ref-shaped value (`{uri, data, asset_id, ...}`) to raw
11
+ * image bytes. Accepts inline `data` (base64 string or Uint8Array), a
12
+ * `data:` URI, or — given a `ProcessingContext` — a storage URI / file://
13
+ * URI / http(s) URL.
14
+ *
15
+ * Throws when nothing resolvable is present so the caller can surface a
16
+ * clear "missing image" error rather than silently sending zero bytes.
17
+ */
18
+ export declare function imageRefToBytes(ref: unknown, context?: {
19
+ storage?: {
20
+ retrieve(uri: string): Promise<Uint8Array | null>;
21
+ } | null;
22
+ }): Promise<Uint8Array>;
23
+ export declare function modelRef(data: Uint8Array, extras?: Record<string, unknown>): {
24
+ type: string;
25
+ asset_id: null;
26
+ metadata: null;
27
+ data: string;
28
+ };
29
+ export declare function filePath(uriOrPath: string): string;
30
+ export declare function dateName(name: string): string;
31
+ export declare function extFormat(filename: string): string;
32
+ export declare function pad4(length: number): number;
33
+ export declare function replaceExtension(uriOrPath: string, format: string): string;
34
+ export declare function modelFormat(model: Model3DRefLike): string;
35
+ export declare function mimeTypeForResource(uri: string): string;
36
+ export declare function bytesToDataUri(bytes: Uint8Array, uri: string): string;
37
+ export declare function embedJsonResourceUris(refs: JsonResourceRef[] | undefined, resources: JsonResources): void;
38
+ export declare function passthroughModel(model: Model3DRefLike): {
39
+ output: {
40
+ type: string;
41
+ asset_id: null;
42
+ metadata: null;
43
+ data: string;
44
+ };
45
+ };
46
+ //# sourceMappingURL=utils.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"utils.d.ts","sourceRoot":"","sources":["../../../src/nodes/model3d/utils.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EACV,eAAe,EACf,aAAa,EACb,cAAc,EACf,MAAM,YAAY,CAAC;AAMpB,wBAAgB,OAAO,CAAC,IAAI,EAAE,UAAU,GAAG,MAAM,GAAG,SAAS,GAAG,UAAU,CAIzE;AAED,wBAAgB,UAAU,CAAC,KAAK,EAAE,OAAO,GAAG,UAAU,CAGrD;AAED,wBAAsB,eAAe,CACnC,KAAK,EAAE,OAAO,EACd,OAAO,CAAC,EAAE;IACR,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;KACnD,GAAG,IAAI,CAAC;CACV,GACA,OAAO,CAAC,UAAU,CAAC,CA8BrB;AAED;;;;;;;;GAQG;AACH,wBAAsB,eAAe,CACnC,GAAG,EAAE,OAAO,EACZ,OAAO,CAAC,EAAE;IACR,OAAO,CAAC,EAAE;QACR,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;KACnD,GAAG,IAAI,CAAC;CACV,GACA,OAAO,CAAC,UAAU,CAAC,CAgDrB;AAED,wBAAgB,QAAQ,CACtB,IAAI,EAAE,UAAU,EAChB,MAAM,GAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAM;;;;;EASrC;AAED,wBAAgB,QAAQ,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,wBAAgB,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,MAAM,CAU7C;AAED,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,GAAG,MAAM,CAGlD;AAED,wBAAgB,IAAI,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,CAE3C;AAED,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,EAAE,MAAM,EAAE,MAAM,GAAG,MAAM,CAS1E;AAED,wBAAgB,WAAW,CAAC,KAAK,EAAE,cAAc,GAAG,MAAM,CAKzD;AAED,wBAAgB,mBAAmB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAgBvD;AAED,wBAAgB,cAAc,CAAC,KAAK,EAAE,UAAU,EAAE,GAAG,EAAE,MAAM,GAAG,MAAM,CAGrE;AAED,wBAAgB,qBAAqB,CACnC,IAAI,EAAE,eAAe,EAAE,GAAG,SAAS,EACnC,SAAS,EAAE,aAAa,GACvB,IAAI,CAON;AAED,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,cAAc;IAGlD,MAAM;;;;;;EAKT"}