@selvajs/visualization 1.2.0 → 1.3.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.
@@ -1,2 +1,2 @@
1
- const e=require("./rolldown-runtime-BocRIvOZ.cjs");let t=require("three");t=e.t(t,1);const n={VALIDATION_ERROR:`VALIDATION_ERROR`,INVALID_STATE:`INVALID_STATE`,ENVIRONMENT_ERROR:`ENVIRONMENT_ERROR`,INVALID_CONFIG:`INVALID_CONFIG`,ENCODING_ERROR:`ENCODING_ERROR`,UNKNOWN_ERROR:`UNKNOWN_ERROR`};var r=class extends Error{code;context;originalError;constructor(e,t=n.UNKNOWN_ERROR,r){super(e),this.name=`VisualizationError`,this.code=t,this.context=r?.context,this.originalError=r?.originalError,r?.originalError&&(this.cause=r.originalError)}},i=class{debug(){}info(){}warn(){}error(){}},a=class{debug(e,...t){console.debug(e,...t)}info(e,...t){console.info(e,...t)}warn(e,...t){console.warn(e,...t)}error(e,...t){console.error(e,...t)}};let o=new i;function s(){return o}function c(e){if(e===null){o=new i;return}let t=[`debug`,`info`,`warn`,`error`].filter(t=>typeof e[t]!=`function`);if(t.length>0)throw new r(`Logger is missing required method(s): ${t.join(`, `)}. A logger must implement debug, info, warn and error.`,n.INVALID_CONFIG,{context:{missingMethods:t}});o=e}function l(){c(new a)}function u(e){if(!e||typeof e!=`string`)return s().warn(`Invalid color input: ${e}, using white`),new t.Color(16777215);let n=e.trim();if(/^#?[0-9A-Fa-f]{6}$/.test(n))try{let e=n.startsWith(`#`)?n:`#${n}`;return new t.Color(e)}catch{return s().warn(`Invalid hex color: ${e}, using white`),new t.Color(16777215)}if(n.includes(`,`)){let e=n.split(`,`).map(e=>parseInt(e.trim(),10));if(e.length===3&&e.every(e=>!isNaN(e)&&e>=0&&e<=255))return new t.Color(e[0]/255,e[1]/255,e[2]/255)}let r=n.toLowerCase();return r in t.Color.NAMES?new t.Color(t.Color.NAMES[r]):(s().warn(`Invalid color string: ${e}, using white`),new t.Color(16777215))}function d(e,t,n=`z`){e.forEach(e=>{e.position[n]-=t})}function f(e){let n=new t.Box3;return e.length===0||e.forEach(e=>{e.updateMatrixWorld(!0);let r=new t.Box3().setFromObject(e);n.union(r)}),n}const p=new Set;function m(e){return e?!p.has(e):!1}const h=new Set;let g=1;function _(e){let t=Math.max(1,e);if(t!==g){g=t;for(let e of h)e(t)}}function v(e){return h.add(e),e(g),()=>h.delete(e)}function y(e){if(m(e)){for(let n of Object.values(e))n instanceof t.Texture&&n.dispose();e.dispose()}}function b(e){e&&(Array.isArray(e)?e.forEach(y):y(e))}function x(e,t={}){let{materials:n=!0}=t;e.traverse(e=>{let t=e;!t.geometry&&!t.material||(t.geometry&&t.geometry?.dispose(),n&&b(t.material))})}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return n}});
2
- //# sourceMappingURL=gpu-dispose-DrN-ryj5.cjs.map
1
+ const e=require("./rolldown-runtime-BocRIvOZ.cjs");let t=require("three");t=e.t(t,1);const n={VALIDATION_ERROR:`VALIDATION_ERROR`,INVALID_STATE:`INVALID_STATE`,ENVIRONMENT_ERROR:`ENVIRONMENT_ERROR`,INVALID_CONFIG:`INVALID_CONFIG`,ENCODING_ERROR:`ENCODING_ERROR`,UNKNOWN_ERROR:`UNKNOWN_ERROR`};var r=class extends Error{code;context;originalError;constructor(e,t=n.UNKNOWN_ERROR,r){super(e),this.name=`VisualizationError`,this.code=t,this.context=r?.context,this.originalError=r?.originalError,r?.originalError&&(this.cause=r.originalError)}},i=class{debug(){}info(){}warn(){}error(){}},a=class{debug(e,...t){console.debug(e,...t)}info(e,...t){console.info(e,...t)}warn(e,...t){console.warn(e,...t)}error(e,...t){console.error(e,...t)}};let o=new i;function s(){return o}function c(e){if(e===null){o=new i;return}let t=[`debug`,`info`,`warn`,`error`].filter(t=>typeof e[t]!=`function`);if(t.length>0)throw new r(`Logger is missing required method(s): ${t.join(`, `)}. A logger must implement debug, info, warn and error.`,n.INVALID_CONFIG,{context:{missingMethods:t}});o=e}function l(){c(new a)}function u(e){if(!e||typeof e!=`string`)return s().warn(`Invalid color input: ${e}, using white`),new t.Color(16777215);let n=e.trim();if(/^#?[0-9A-Fa-f]{6}$/.test(n))try{let e=n.startsWith(`#`)?n:`#${n}`;return new t.Color(e)}catch{return s().warn(`Invalid hex color: ${e}, using white`),new t.Color(16777215)}if(n.includes(`,`)){let e=n.split(`,`).map(e=>parseInt(e.trim(),10));if(e.length===3&&e.every(e=>!isNaN(e)&&e>=0&&e<=255))return new t.Color(e[0]/255,e[1]/255,e[2]/255)}let r=n.toLowerCase();return r in t.Color.NAMES?new t.Color(t.Color.NAMES[r]):(s().warn(`Invalid color string: ${e}, using white`),new t.Color(16777215))}function d(e,t,n=`z`){e.forEach(e=>{e.position[n]-=t})}function f(e){let n=new t.Box3;return e.length===0||e.forEach(e=>{e.updateMatrixWorld(!0);let r=new t.Box3().setFromObject(e);n.union(r)}),n}const p=new Set;function m(e){return e?!p.has(e):!1}const h=new Set;let g=1;function _(e){let t=Math.max(1,e);if(t!==g){g=t;for(let e of h)e(t)}}function v(e){return h.add(e),e(g),()=>h.delete(e)}function y(e){if(m(e)){for(let n of Object.values(e))n instanceof t.Texture&&n.dispose();e.dispose()}}function b(e){e&&(Array.isArray(e)?e.forEach(y):y(e))}function x(e,t={}){let{materials:n=!0}=t;e.traverse(e=>{let t=e;(t.geometry||t.material)&&(t.geometry&&t.geometry?.dispose(),n&&b(t.material))})}Object.defineProperty(exports,"a",{enumerable:!0,get:function(){return f}}),Object.defineProperty(exports,"c",{enumerable:!0,get:function(){return s}}),Object.defineProperty(exports,"d",{enumerable:!0,get:function(){return r}}),Object.defineProperty(exports,"i",{enumerable:!0,get:function(){return d}}),Object.defineProperty(exports,"l",{enumerable:!0,get:function(){return c}}),Object.defineProperty(exports,"n",{enumerable:!0,get:function(){return v}}),Object.defineProperty(exports,"o",{enumerable:!0,get:function(){return u}}),Object.defineProperty(exports,"r",{enumerable:!0,get:function(){return _}}),Object.defineProperty(exports,"s",{enumerable:!0,get:function(){return l}}),Object.defineProperty(exports,"t",{enumerable:!0,get:function(){return x}}),Object.defineProperty(exports,"u",{enumerable:!0,get:function(){return n}});
2
+ //# sourceMappingURL=gpu-dispose-08qVHlV6.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"gpu-dispose-DrN-ryj5.cjs","names":["THREE","THREE"],"sources":["../src/shared/errors.ts","../src/shared/logger.ts","../src/shared/geometry.ts","../src/shared/gpu-ownership.ts","../src/shared/gpu-capabilities.ts","../src/shared/gpu-dispose.ts"],"sourcesContent":["/**\n * Errors for the visualization package. Replaces `@selvajs/compute`'s `RhinoComputeError`, which\n * mis-named failures on paths (e.g. the plugin WebSocket) that never touch Rhino.Compute. `code`\n * values match compute's so existing catch-sites keep working.\n */\n\nexport const ErrorCodes = {\n\t/** Structural check failed: bad magic bytes, out-of-window index, malformed metadata. */\n\tVALIDATION_ERROR: 'VALIDATION_ERROR',\n\tINVALID_STATE: 'INVALID_STATE',\n\t/** No `DecompressionStream`, no WebGL context, etc. */\n\tENVIRONMENT_ERROR: 'ENVIRONMENT_ERROR',\n\tINVALID_CONFIG: 'INVALID_CONFIG',\n\t/** Base64 input could not be decoded. */\n\tENCODING_ERROR: 'ENCODING_ERROR',\n\tUNKNOWN_ERROR: 'UNKNOWN_ERROR'\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\nexport class VisualizationError extends Error {\n\tpublic readonly code: ErrorCode;\n\tpublic readonly context?: Record<string, unknown>;\n\tpublic readonly originalError?: Error;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tcode: ErrorCode = ErrorCodes.UNKNOWN_ERROR,\n\t\toptions?: { context?: Record<string, unknown>; originalError?: Error }\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'VisualizationError';\n\t\tthis.code = code;\n\t\tthis.context = options?.context;\n\t\tthis.originalError = options?.originalError;\n\t\tif (options?.originalError) {\n\t\t\t(this as { cause?: unknown }).cause = options.originalError;\n\t\t}\n\t}\n}\n","/**\n * Logging facility for the visualization package. Deliberately local rather than imported from\n * `@selvajs/compute` (logging isn't a compute concern). Mirrors compute's logger shape so a host\n * wanting one sink for both can call `setLogger(computeLogger.getLogger())`.\n */\n\nimport { VisualizationError, ErrorCodes } from './errors.js';\n\nexport interface Logger {\n\tdebug(message: string, ...args: unknown[]): void;\n\tinfo(message: string, ...args: unknown[]): void;\n\twarn(message: string, ...args: unknown[]): void;\n\terror(message: string, ...args: unknown[]): void;\n}\n\nclass NoOpLogger implements Logger {\n\tdebug(): void {}\n\tinfo(): void {}\n\twarn(): void {}\n\terror(): void {}\n}\n\nclass ConsoleLogger implements Logger {\n\tdebug(message: string, ...args: unknown[]): void {\n\t\t// eslint-disable-next-line no-console -- this class exists to be the console sink\n\t\tconsole.debug(message, ...args);\n\t}\n\n\tinfo(message: string, ...args: unknown[]): void {\n\t\tconsole.info(message, ...args);\n\t}\n\n\twarn(message: string, ...args: unknown[]): void {\n\t\tconsole.warn(message, ...args);\n\t}\n\n\terror(message: string, ...args: unknown[]): void {\n\t\tconsole.error(message, ...args);\n\t}\n}\n\n// Defaults to no-op: a library that writes to the console uninvited is a nuisance in a host with\n// its own logging. Opt in with setLogger or enableDebugLogging.\nlet internalLogger: Logger = new NoOpLogger();\n\n// Call per-use rather than caching — the sink is settable at any time.\nexport function getLogger(): Logger {\n\treturn internalLogger;\n}\n\n// Validates logger shape up front: failing here beats a confusing \"getLogger().debug is not a\n// function\" at some later, unrelated call site.\nexport function setLogger(logger: Logger | Console | null): void {\n\tif (logger === null) {\n\t\tinternalLogger = new NoOpLogger();\n\t\treturn;\n\t}\n\n\tconst missing = (['debug', 'info', 'warn', 'error'] as const).filter(\n\t\t(method) => typeof (logger as unknown as Record<string, unknown>)[method] !== 'function'\n\t);\n\tif (missing.length > 0) {\n\t\tthrow new VisualizationError(\n\t\t\t`Logger is missing required method(s): ${missing.join(', ')}. A logger must implement debug, info, warn and error.`,\n\t\t\tErrorCodes.INVALID_CONFIG,\n\t\t\t{ context: { missingMethods: missing } }\n\t\t);\n\t}\n\n\tinternalLogger = logger as Logger;\n}\n\nexport function enableDebugLogging(): void {\n\tsetLogger(new ConsoleLogger());\n}\n","import * as THREE from 'three';\n\nimport { getLogger } from './logger.js';\n\n// parse/ needs these and must never import upward from render/, so they live in shared/ instead\n// of render's three-helpers.\n\nexport function parseColor(colorString: string): THREE.Color {\n\tif (!colorString || typeof colorString !== 'string') {\n\t\tgetLogger().warn(`Invalid color input: ${colorString}, using white`);\n\t\treturn new THREE.Color(0xffffff);\n\t}\n\n\tconst trimmed = colorString.trim();\n\n\tif (/^#?[0-9A-Fa-f]{6}$/.test(trimmed)) {\n\t\ttry {\n\t\t\tconst hex = trimmed.startsWith('#') ? trimmed : `#${trimmed}`;\n\t\t\treturn new THREE.Color(hex);\n\t\t} catch {\n\t\t\tgetLogger().warn(`Invalid hex color: ${colorString}, using white`);\n\t\t\treturn new THREE.Color(0xffffff);\n\t\t}\n\t}\n\n\tif (trimmed.includes(',')) {\n\t\tconst rgb = trimmed.split(',').map((c) => parseInt(c.trim(), 10));\n\t\tif (rgb.length === 3 && rgb.every((n) => !isNaN(n) && n >= 0 && n <= 255)) {\n\t\t\treturn new THREE.Color(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255);\n\t\t}\n\t}\n\n\t// `new THREE.Color(name)` never throws on unknown names (it logs its own warning and leaves the\n\t// color white), so validate against three's CSS name table instead.\n\tconst named = trimmed.toLowerCase();\n\tif (named in THREE.Color.NAMES) {\n\t\treturn new THREE.Color(THREE.Color.NAMES[named as keyof typeof THREE.Color.NAMES]);\n\t}\n\n\tgetLogger().warn(`Invalid color string: ${colorString}, using white`);\n\treturn new THREE.Color(0xffffff);\n}\n\n/** Defaults to `z` (Rhino's up axis); pass an explicit axis when the scene uses a different `sceneUp`. */\nexport function applyOffset(\n\tmeshes: THREE.Object3D[],\n\toffset: number,\n\taxis: 'x' | 'y' | 'z' = 'z'\n): void {\n\tmeshes.forEach((mesh) => {\n\t\tmesh.position[axis] -= offset;\n\t});\n}\n\nexport function computeCombinedBoundingBox(meshes: THREE.Object3D[]): THREE.Box3 {\n\tconst combinedBoundingBox = new THREE.Box3();\n\tif (meshes.length === 0) return combinedBoundingBox;\n\tmeshes.forEach((mesh) => {\n\t\tmesh.updateMatrixWorld(true);\n\t\tconst bbox = new THREE.Box3().setFromObject(mesh);\n\t\tcombinedBoundingBox.union(bbox);\n\t});\n\treturn combinedBoundingBox;\n}\n","import type * as THREE from 'three';\n\n// ============================================================================\n// GPU resource ownership — the single rule every disposal path obeys\n// ============================================================================\n\n/**\n * A GPU resource has exactly one owner: a **module singleton** (nobody ever frees it) or the\n * **scene** (freed on teardown). Every disposal path asks {@link canDisposeMaterial} and disposes\n * only if true. Geometries and textures are always scene-owned, so they have no claim to check.\n */\n\n// Module-scope singletons from `render/three-materials.ts`, shared across meshes and solves —\n// disposing one would free textures still in use and force a recompile. Held here (not imported\n// there) to avoid an import cycle.\nconst protectedMaterials = new Set<THREE.Material>();\n\n/** Register materials as never-disposable. Called once by `render/three-materials.ts`. */\nexport function protectMaterials(materials: Iterable<THREE.Material>): void {\n\tfor (const material of materials) protectedMaterials.add(material);\n}\n\n/** True when `material` is scene-owned (not one of the protected singletons). */\nexport function canDisposeMaterial(material: THREE.Material | undefined): boolean {\n\tif (!material) return false;\n\treturn !protectedMaterials.has(material);\n}\n","// ============================================================================\n// GPU capabilities — published by the renderer, read by whoever needs them\n// ============================================================================\n\n// Lets a renderer publish GPU capabilities (max anisotropy) without `render/` and `parse/` importing\n// each other: the renderer publishes on init, interested parties subscribe.\n\ntype AnisotropyObserver = (value: number) => void;\n\nconst observers = new Set<AnisotropyObserver>();\n\n// Module load order between layers isn't guaranteed, so a subscriber arriving after init still\n// needs the current value rather than waiting for a second renderer to publish.\nlet maxAnisotropy = 1;\n\nexport function publishMaxAnisotropy(value: number): void {\n\tconst next = Math.max(1, value);\n\tif (next === maxAnisotropy) return;\n\tmaxAnisotropy = next;\n\tfor (const observe of observers) observe(next);\n}\n\n/** Fires immediately with the current value (1 until a renderer has reported), then on every change. */\nexport function observeMaxAnisotropy(observe: AnisotropyObserver): () => void {\n\tobservers.add(observe);\n\tobserve(maxAnisotropy);\n\treturn () => observers.delete(observe);\n}\n","import * as THREE from 'three';\n\nimport { canDisposeMaterial } from './gpu-ownership.js';\n\n// ============================================================================\n// The disposal walkers — every teardown path in the package goes through these\n// ============================================================================\n\n/** Frees a material and its textures, respecting ownership (`./gpu-ownership.ts`). */\nexport function disposeMaterial(material: THREE.Material): void {\n\tif (!canDisposeMaterial(material)) return;\n\n\tfor (const value of Object.values(material)) {\n\t\tif (value instanceof THREE.Texture) {\n\t\t\tvalue.dispose();\n\t\t}\n\t}\n\tmaterial.dispose();\n}\n\nfunction disposeMaterials(material: THREE.Material | THREE.Material[] | undefined): void {\n\tif (!material) return;\n\tif (Array.isArray(material)) material.forEach(disposeMaterial);\n\telse disposeMaterial(material);\n}\n\nexport interface DisposeOptions {\n\t/** Free materials and their textures too. Default true; the solve memo passes false. */\n\tmaterials?: boolean;\n\t/** Called for each geometry before disposal, so a subsystem can free derived resources keyed on it (e.g. edge caches). */\n\tonGeometry?: (geometry: THREE.BufferGeometry) => void;\n}\n\n/**\n * Frees the GPU resources of an object subtree, respecting ownership. **The only traversal that\n * should dispose scene content** — a second disposing `traverse` risks missing an ownership guard.\n */\nexport function disposeObjectTree(root: THREE.Object3D, options: DisposeOptions = {}): void {\n\tconst { materials = true } = options;\n\n\troot.traverse((object) => {\n\t\tconst renderable = object as Partial<THREE.Mesh> & THREE.Object3D;\n\t\tif (!renderable.geometry && !renderable.material) return;\n\n\t\tif (renderable.geometry) {\n\t\t\trenderable.geometry?.dispose();\n\t\t}\n\n\t\tif (materials) disposeMaterials(renderable.material);\n\t});\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"gpu-dispose-08qVHlV6.cjs","names":["THREE","THREE"],"sources":["../src/shared/errors.ts","../src/shared/logger.ts","../src/shared/geometry.ts","../src/shared/gpu-ownership.ts","../src/shared/gpu-capabilities.ts","../src/shared/gpu-dispose.ts"],"sourcesContent":["/**\n * Errors for the visualization package. Replaces `@selvajs/compute`'s `RhinoComputeError`, which\n * mis-named failures on paths (e.g. the plugin WebSocket) that never touch Rhino.Compute. `code`\n * values match compute's so existing catch-sites keep working.\n */\n\nexport const ErrorCodes = {\n\t/** Structural check failed: bad magic bytes, out-of-window index, malformed metadata. */\n\tVALIDATION_ERROR: 'VALIDATION_ERROR',\n\tINVALID_STATE: 'INVALID_STATE',\n\t/** No `DecompressionStream`, no WebGL context, etc. */\n\tENVIRONMENT_ERROR: 'ENVIRONMENT_ERROR',\n\tINVALID_CONFIG: 'INVALID_CONFIG',\n\t/** Base64 input could not be decoded. */\n\tENCODING_ERROR: 'ENCODING_ERROR',\n\tUNKNOWN_ERROR: 'UNKNOWN_ERROR'\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\nexport class VisualizationError extends Error {\n\tpublic readonly code: ErrorCode;\n\tpublic readonly context?: Record<string, unknown>;\n\tpublic readonly originalError?: Error;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tcode: ErrorCode = ErrorCodes.UNKNOWN_ERROR,\n\t\toptions?: { context?: Record<string, unknown>; originalError?: Error }\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'VisualizationError';\n\t\tthis.code = code;\n\t\tthis.context = options?.context;\n\t\tthis.originalError = options?.originalError;\n\t\tif (options?.originalError) {\n\t\t\t(this as { cause?: unknown }).cause = options.originalError;\n\t\t}\n\t}\n}\n","/**\n * Logging facility for the visualization package. Deliberately local rather than imported from\n * `@selvajs/compute` (logging isn't a compute concern). Mirrors compute's logger shape so a host\n * wanting one sink for both can call `setLogger(computeLogger.getLogger())`.\n */\n\nimport { VisualizationError, ErrorCodes } from './errors.js';\n\nexport interface Logger {\n\tdebug(message: string, ...args: unknown[]): void;\n\tinfo(message: string, ...args: unknown[]): void;\n\twarn(message: string, ...args: unknown[]): void;\n\terror(message: string, ...args: unknown[]): void;\n}\n\nclass NoOpLogger implements Logger {\n\tdebug(): void {}\n\tinfo(): void {}\n\twarn(): void {}\n\terror(): void {}\n}\n\nclass ConsoleLogger implements Logger {\n\tdebug(message: string, ...args: unknown[]): void {\n\t\t// eslint-disable-next-line no-console -- this class exists to be the console sink\n\t\tconsole.debug(message, ...args);\n\t}\n\n\tinfo(message: string, ...args: unknown[]): void {\n\t\tconsole.info(message, ...args);\n\t}\n\n\twarn(message: string, ...args: unknown[]): void {\n\t\tconsole.warn(message, ...args);\n\t}\n\n\terror(message: string, ...args: unknown[]): void {\n\t\tconsole.error(message, ...args);\n\t}\n}\n\n// Defaults to no-op: a library that writes to the console uninvited is a nuisance in a host with\n// its own logging. Opt in with setLogger or enableDebugLogging.\nlet internalLogger: Logger = new NoOpLogger();\n\n// Call per-use rather than caching — the sink is settable at any time.\nexport function getLogger(): Logger {\n\treturn internalLogger;\n}\n\n// Validates logger shape up front: failing here beats a confusing \"getLogger().debug is not a\n// function\" at some later, unrelated call site.\nexport function setLogger(logger: Logger | Console | null): void {\n\tif (logger === null) {\n\t\tinternalLogger = new NoOpLogger();\n\t\treturn;\n\t}\n\n\tconst missing = (['debug', 'info', 'warn', 'error'] as const).filter(\n\t\t(method) => typeof (logger as unknown as Record<string, unknown>)[method] !== 'function'\n\t);\n\tif (missing.length > 0) {\n\t\tthrow new VisualizationError(\n\t\t\t`Logger is missing required method(s): ${missing.join(', ')}. A logger must implement debug, info, warn and error.`,\n\t\t\tErrorCodes.INVALID_CONFIG,\n\t\t\t{ context: { missingMethods: missing } }\n\t\t);\n\t}\n\n\tinternalLogger = logger as Logger;\n}\n\nexport function enableDebugLogging(): void {\n\tsetLogger(new ConsoleLogger());\n}\n","import * as THREE from 'three';\n\nimport { getLogger } from './logger.js';\n\n// parse/ needs these and must never import upward from render/, so they live in shared/ instead\n// of render's three-helpers.\n\nexport function parseColor(colorString: string): THREE.Color {\n\tif (!colorString || typeof colorString !== 'string') {\n\t\tgetLogger().warn(`Invalid color input: ${colorString}, using white`);\n\t\treturn new THREE.Color(0xffffff);\n\t}\n\n\tconst trimmed = colorString.trim();\n\n\tif (/^#?[0-9A-Fa-f]{6}$/.test(trimmed)) {\n\t\ttry {\n\t\t\tconst hex = trimmed.startsWith('#') ? trimmed : `#${trimmed}`;\n\t\t\treturn new THREE.Color(hex);\n\t\t} catch {\n\t\t\tgetLogger().warn(`Invalid hex color: ${colorString}, using white`);\n\t\t\treturn new THREE.Color(0xffffff);\n\t\t}\n\t}\n\n\tif (trimmed.includes(',')) {\n\t\tconst rgb = trimmed.split(',').map((c) => parseInt(c.trim(), 10));\n\t\tif (rgb.length === 3 && rgb.every((n) => !isNaN(n) && n >= 0 && n <= 255)) {\n\t\t\treturn new THREE.Color(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255);\n\t\t}\n\t}\n\n\t// `new THREE.Color(name)` never throws on unknown names (it logs its own warning and leaves the\n\t// color white), so validate against three's CSS name table instead.\n\tconst named = trimmed.toLowerCase();\n\tif (named in THREE.Color.NAMES) {\n\t\treturn new THREE.Color(THREE.Color.NAMES[named as keyof typeof THREE.Color.NAMES]);\n\t}\n\n\tgetLogger().warn(`Invalid color string: ${colorString}, using white`);\n\treturn new THREE.Color(0xffffff);\n}\n\n/** Defaults to `z` (Rhino's up axis); pass an explicit axis when the scene uses a different `sceneUp`. */\nexport function applyOffset(\n\tmeshes: THREE.Object3D[],\n\toffset: number,\n\taxis: 'x' | 'y' | 'z' = 'z'\n): void {\n\tmeshes.forEach((mesh) => {\n\t\tmesh.position[axis] -= offset;\n\t});\n}\n\nexport function computeCombinedBoundingBox(meshes: THREE.Object3D[]): THREE.Box3 {\n\tconst combinedBoundingBox = new THREE.Box3();\n\tif (meshes.length === 0) return combinedBoundingBox;\n\tmeshes.forEach((mesh) => {\n\t\tmesh.updateMatrixWorld(true);\n\t\tconst bbox = new THREE.Box3().setFromObject(mesh);\n\t\tcombinedBoundingBox.union(bbox);\n\t});\n\treturn combinedBoundingBox;\n}\n","import type * as THREE from 'three';\n\n// ============================================================================\n// GPU resource ownership — the single rule every disposal path obeys\n// ============================================================================\n\n/**\n * A GPU resource has exactly one owner: a **module singleton** (nobody ever frees it) or the\n * **scene** (freed on teardown). Every disposal path asks {@link canDisposeMaterial} and disposes\n * only if true. Geometries and textures are always scene-owned, so they have no claim to check.\n */\n\n// Module-scope singletons from `render/three-materials.ts`, shared across meshes and solves —\n// disposing one would free textures still in use and force a recompile. Held here (not imported\n// there) to avoid an import cycle.\nconst protectedMaterials = new Set<THREE.Material>();\n\n/** Register materials as never-disposable. Called once by `render/three-materials.ts`. */\nexport function protectMaterials(materials: Iterable<THREE.Material>): void {\n\tfor (const material of materials) protectedMaterials.add(material);\n}\n\n/** True when `material` is scene-owned (not one of the protected singletons). */\nexport function canDisposeMaterial(material: THREE.Material | undefined): boolean {\n\tif (!material) return false;\n\treturn !protectedMaterials.has(material);\n}\n","// ============================================================================\n// GPU capabilities — published by the renderer, read by whoever needs them\n// ============================================================================\n\n// Lets a renderer publish GPU capabilities (max anisotropy) without `render/` and `parse/` importing\n// each other: the renderer publishes on init, interested parties subscribe.\n\ntype AnisotropyObserver = (value: number) => void;\n\nconst observers = new Set<AnisotropyObserver>();\n\n// Module load order between layers isn't guaranteed, so a subscriber arriving after init still\n// needs the current value rather than waiting for a second renderer to publish.\nlet maxAnisotropy = 1;\n\nexport function publishMaxAnisotropy(value: number): void {\n\tconst next = Math.max(1, value);\n\tif (next === maxAnisotropy) return;\n\tmaxAnisotropy = next;\n\tfor (const observe of observers) observe(next);\n}\n\n/** Fires immediately with the current value (1 until a renderer has reported), then on every change. */\nexport function observeMaxAnisotropy(observe: AnisotropyObserver): () => void {\n\tobservers.add(observe);\n\tobserve(maxAnisotropy);\n\treturn () => observers.delete(observe);\n}\n","import * as THREE from 'three';\n\nimport { canDisposeMaterial } from './gpu-ownership.js';\n\n// ============================================================================\n// The disposal walkers — every teardown path in the package goes through these\n// ============================================================================\n\n/** Frees a material and its textures, respecting ownership (`./gpu-ownership.ts`). */\nexport function disposeMaterial(material: THREE.Material): void {\n\tif (!canDisposeMaterial(material)) return;\n\n\tfor (const value of Object.values(material)) {\n\t\tif (value instanceof THREE.Texture) {\n\t\t\tvalue.dispose();\n\t\t}\n\t}\n\tmaterial.dispose();\n}\n\nfunction disposeMaterials(material: THREE.Material | THREE.Material[] | undefined): void {\n\tif (!material) return;\n\tif (Array.isArray(material)) material.forEach(disposeMaterial);\n\telse disposeMaterial(material);\n}\n\nexport interface DisposeOptions {\n\t/** Free materials and their textures too. Default true; the solve memo passes false. */\n\tmaterials?: boolean;\n\t/** Called for each geometry before disposal, so a subsystem can free derived resources keyed on it (e.g. edge caches). */\n\tonGeometry?: (geometry: THREE.BufferGeometry) => void;\n}\n\n/**\n * Frees the GPU resources of an object subtree, respecting ownership. **The only traversal that\n * should dispose scene content** — a second disposing `traverse` risks missing an ownership guard.\n */\nexport function disposeObjectTree(root: THREE.Object3D, options: DisposeOptions = {}): void {\n\tconst { materials = true } = options;\n\n\troot.traverse((object) => {\n\t\tconst renderable = object as Partial<THREE.Mesh> & THREE.Object3D;\n\t\tif (!renderable.geometry && !renderable.material) return;\n\n\t\tif (renderable.geometry) {\n\t\t\trenderable.geometry?.dispose();\n\t\t}\n\n\t\tif (materials) disposeMaterials(renderable.material);\n\t});\n}\n"],"mappings":"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"}
@@ -1,2 +1,2 @@
1
- import*as e from"three";const t={VALIDATION_ERROR:`VALIDATION_ERROR`,INVALID_STATE:`INVALID_STATE`,ENVIRONMENT_ERROR:`ENVIRONMENT_ERROR`,INVALID_CONFIG:`INVALID_CONFIG`,ENCODING_ERROR:`ENCODING_ERROR`,UNKNOWN_ERROR:`UNKNOWN_ERROR`};var n=class extends Error{code;context;originalError;constructor(e,n=t.UNKNOWN_ERROR,r){super(e),this.name=`VisualizationError`,this.code=n,this.context=r?.context,this.originalError=r?.originalError,r?.originalError&&(this.cause=r.originalError)}},r=class{debug(){}info(){}warn(){}error(){}},i=class{debug(e,...t){console.debug(e,...t)}info(e,...t){console.info(e,...t)}warn(e,...t){console.warn(e,...t)}error(e,...t){console.error(e,...t)}};let a=new r;function o(){return a}function s(e){if(e===null){a=new r;return}let i=[`debug`,`info`,`warn`,`error`].filter(t=>typeof e[t]!=`function`);if(i.length>0)throw new n(`Logger is missing required method(s): ${i.join(`, `)}. A logger must implement debug, info, warn and error.`,t.INVALID_CONFIG,{context:{missingMethods:i}});a=e}function c(){s(new i)}function l(t){if(!t||typeof t!=`string`)return o().warn(`Invalid color input: ${t}, using white`),new e.Color(16777215);let n=t.trim();if(/^#?[0-9A-Fa-f]{6}$/.test(n))try{let t=n.startsWith(`#`)?n:`#${n}`;return new e.Color(t)}catch{return o().warn(`Invalid hex color: ${t}, using white`),new e.Color(16777215)}if(n.includes(`,`)){let t=n.split(`,`).map(e=>parseInt(e.trim(),10));if(t.length===3&&t.every(e=>!isNaN(e)&&e>=0&&e<=255))return new e.Color(t[0]/255,t[1]/255,t[2]/255)}let r=n.toLowerCase();return r in e.Color.NAMES?new e.Color(e.Color.NAMES[r]):(o().warn(`Invalid color string: ${t}, using white`),new e.Color(16777215))}function u(e,t,n=`z`){e.forEach(e=>{e.position[n]-=t})}function d(t){let n=new e.Box3;return t.length===0||t.forEach(t=>{t.updateMatrixWorld(!0);let r=new e.Box3().setFromObject(t);n.union(r)}),n}const f=new Set;function p(e){return e?!f.has(e):!1}const m=new Set;let h=1;function g(e){let t=Math.max(1,e);if(t!==h){h=t;for(let e of m)e(t)}}function _(e){return m.add(e),e(h),()=>m.delete(e)}function v(t){if(p(t)){for(let n of Object.values(t))n instanceof e.Texture&&n.dispose();t.dispose()}}function y(e){e&&(Array.isArray(e)?e.forEach(v):v(e))}function b(e,t={}){let{materials:n=!0}=t;e.traverse(e=>{let t=e;!t.geometry&&!t.material||(t.geometry&&t.geometry?.dispose(),n&&y(t.material))})}export{d as a,o as c,n as d,u as i,s as l,_ as n,l as o,g as r,c as s,b as t,t as u};
2
- //# sourceMappingURL=gpu-dispose-Dkj-BKt4.js.map
1
+ import*as e from"three";const t={VALIDATION_ERROR:`VALIDATION_ERROR`,INVALID_STATE:`INVALID_STATE`,ENVIRONMENT_ERROR:`ENVIRONMENT_ERROR`,INVALID_CONFIG:`INVALID_CONFIG`,ENCODING_ERROR:`ENCODING_ERROR`,UNKNOWN_ERROR:`UNKNOWN_ERROR`};var n=class extends Error{code;context;originalError;constructor(e,n=t.UNKNOWN_ERROR,r){super(e),this.name=`VisualizationError`,this.code=n,this.context=r?.context,this.originalError=r?.originalError,r?.originalError&&(this.cause=r.originalError)}},r=class{debug(){}info(){}warn(){}error(){}},i=class{debug(e,...t){console.debug(e,...t)}info(e,...t){console.info(e,...t)}warn(e,...t){console.warn(e,...t)}error(e,...t){console.error(e,...t)}};let a=new r;function o(){return a}function s(e){if(e===null){a=new r;return}let i=[`debug`,`info`,`warn`,`error`].filter(t=>typeof e[t]!=`function`);if(i.length>0)throw new n(`Logger is missing required method(s): ${i.join(`, `)}. A logger must implement debug, info, warn and error.`,t.INVALID_CONFIG,{context:{missingMethods:i}});a=e}function c(){s(new i)}function l(t){if(!t||typeof t!=`string`)return o().warn(`Invalid color input: ${t}, using white`),new e.Color(16777215);let n=t.trim();if(/^#?[0-9A-Fa-f]{6}$/.test(n))try{let t=n.startsWith(`#`)?n:`#${n}`;return new e.Color(t)}catch{return o().warn(`Invalid hex color: ${t}, using white`),new e.Color(16777215)}if(n.includes(`,`)){let t=n.split(`,`).map(e=>parseInt(e.trim(),10));if(t.length===3&&t.every(e=>!isNaN(e)&&e>=0&&e<=255))return new e.Color(t[0]/255,t[1]/255,t[2]/255)}let r=n.toLowerCase();return r in e.Color.NAMES?new e.Color(e.Color.NAMES[r]):(o().warn(`Invalid color string: ${t}, using white`),new e.Color(16777215))}function u(e,t,n=`z`){e.forEach(e=>{e.position[n]-=t})}function d(t){let n=new e.Box3;return t.length===0||t.forEach(t=>{t.updateMatrixWorld(!0);let r=new e.Box3().setFromObject(t);n.union(r)}),n}const f=new Set;function p(e){return e?!f.has(e):!1}const m=new Set;let h=1;function g(e){let t=Math.max(1,e);if(t!==h){h=t;for(let e of m)e(t)}}function _(e){return m.add(e),e(h),()=>m.delete(e)}function v(t){if(p(t)){for(let n of Object.values(t))n instanceof e.Texture&&n.dispose();t.dispose()}}function y(e){e&&(Array.isArray(e)?e.forEach(v):v(e))}function b(e,t={}){let{materials:n=!0}=t;e.traverse(e=>{let t=e;(t.geometry||t.material)&&(t.geometry&&t.geometry?.dispose(),n&&y(t.material))})}export{d as a,o as c,n as d,u as i,s as l,_ as n,l as o,g as r,c as s,b as t,t as u};
2
+ //# sourceMappingURL=gpu-dispose-Cm4qCZiL.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"gpu-dispose-Dkj-BKt4.js","names":[],"sources":["../src/shared/errors.ts","../src/shared/logger.ts","../src/shared/geometry.ts","../src/shared/gpu-ownership.ts","../src/shared/gpu-capabilities.ts","../src/shared/gpu-dispose.ts"],"sourcesContent":["/**\n * Errors for the visualization package. Replaces `@selvajs/compute`'s `RhinoComputeError`, which\n * mis-named failures on paths (e.g. the plugin WebSocket) that never touch Rhino.Compute. `code`\n * values match compute's so existing catch-sites keep working.\n */\n\nexport const ErrorCodes = {\n\t/** Structural check failed: bad magic bytes, out-of-window index, malformed metadata. */\n\tVALIDATION_ERROR: 'VALIDATION_ERROR',\n\tINVALID_STATE: 'INVALID_STATE',\n\t/** No `DecompressionStream`, no WebGL context, etc. */\n\tENVIRONMENT_ERROR: 'ENVIRONMENT_ERROR',\n\tINVALID_CONFIG: 'INVALID_CONFIG',\n\t/** Base64 input could not be decoded. */\n\tENCODING_ERROR: 'ENCODING_ERROR',\n\tUNKNOWN_ERROR: 'UNKNOWN_ERROR'\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\nexport class VisualizationError extends Error {\n\tpublic readonly code: ErrorCode;\n\tpublic readonly context?: Record<string, unknown>;\n\tpublic readonly originalError?: Error;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tcode: ErrorCode = ErrorCodes.UNKNOWN_ERROR,\n\t\toptions?: { context?: Record<string, unknown>; originalError?: Error }\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'VisualizationError';\n\t\tthis.code = code;\n\t\tthis.context = options?.context;\n\t\tthis.originalError = options?.originalError;\n\t\tif (options?.originalError) {\n\t\t\t(this as { cause?: unknown }).cause = options.originalError;\n\t\t}\n\t}\n}\n","/**\n * Logging facility for the visualization package. Deliberately local rather than imported from\n * `@selvajs/compute` (logging isn't a compute concern). Mirrors compute's logger shape so a host\n * wanting one sink for both can call `setLogger(computeLogger.getLogger())`.\n */\n\nimport { VisualizationError, ErrorCodes } from './errors.js';\n\nexport interface Logger {\n\tdebug(message: string, ...args: unknown[]): void;\n\tinfo(message: string, ...args: unknown[]): void;\n\twarn(message: string, ...args: unknown[]): void;\n\terror(message: string, ...args: unknown[]): void;\n}\n\nclass NoOpLogger implements Logger {\n\tdebug(): void {}\n\tinfo(): void {}\n\twarn(): void {}\n\terror(): void {}\n}\n\nclass ConsoleLogger implements Logger {\n\tdebug(message: string, ...args: unknown[]): void {\n\t\t// eslint-disable-next-line no-console -- this class exists to be the console sink\n\t\tconsole.debug(message, ...args);\n\t}\n\n\tinfo(message: string, ...args: unknown[]): void {\n\t\tconsole.info(message, ...args);\n\t}\n\n\twarn(message: string, ...args: unknown[]): void {\n\t\tconsole.warn(message, ...args);\n\t}\n\n\terror(message: string, ...args: unknown[]): void {\n\t\tconsole.error(message, ...args);\n\t}\n}\n\n// Defaults to no-op: a library that writes to the console uninvited is a nuisance in a host with\n// its own logging. Opt in with setLogger or enableDebugLogging.\nlet internalLogger: Logger = new NoOpLogger();\n\n// Call per-use rather than caching — the sink is settable at any time.\nexport function getLogger(): Logger {\n\treturn internalLogger;\n}\n\n// Validates logger shape up front: failing here beats a confusing \"getLogger().debug is not a\n// function\" at some later, unrelated call site.\nexport function setLogger(logger: Logger | Console | null): void {\n\tif (logger === null) {\n\t\tinternalLogger = new NoOpLogger();\n\t\treturn;\n\t}\n\n\tconst missing = (['debug', 'info', 'warn', 'error'] as const).filter(\n\t\t(method) => typeof (logger as unknown as Record<string, unknown>)[method] !== 'function'\n\t);\n\tif (missing.length > 0) {\n\t\tthrow new VisualizationError(\n\t\t\t`Logger is missing required method(s): ${missing.join(', ')}. A logger must implement debug, info, warn and error.`,\n\t\t\tErrorCodes.INVALID_CONFIG,\n\t\t\t{ context: { missingMethods: missing } }\n\t\t);\n\t}\n\n\tinternalLogger = logger as Logger;\n}\n\nexport function enableDebugLogging(): void {\n\tsetLogger(new ConsoleLogger());\n}\n","import * as THREE from 'three';\n\nimport { getLogger } from './logger.js';\n\n// parse/ needs these and must never import upward from render/, so they live in shared/ instead\n// of render's three-helpers.\n\nexport function parseColor(colorString: string): THREE.Color {\n\tif (!colorString || typeof colorString !== 'string') {\n\t\tgetLogger().warn(`Invalid color input: ${colorString}, using white`);\n\t\treturn new THREE.Color(0xffffff);\n\t}\n\n\tconst trimmed = colorString.trim();\n\n\tif (/^#?[0-9A-Fa-f]{6}$/.test(trimmed)) {\n\t\ttry {\n\t\t\tconst hex = trimmed.startsWith('#') ? trimmed : `#${trimmed}`;\n\t\t\treturn new THREE.Color(hex);\n\t\t} catch {\n\t\t\tgetLogger().warn(`Invalid hex color: ${colorString}, using white`);\n\t\t\treturn new THREE.Color(0xffffff);\n\t\t}\n\t}\n\n\tif (trimmed.includes(',')) {\n\t\tconst rgb = trimmed.split(',').map((c) => parseInt(c.trim(), 10));\n\t\tif (rgb.length === 3 && rgb.every((n) => !isNaN(n) && n >= 0 && n <= 255)) {\n\t\t\treturn new THREE.Color(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255);\n\t\t}\n\t}\n\n\t// `new THREE.Color(name)` never throws on unknown names (it logs its own warning and leaves the\n\t// color white), so validate against three's CSS name table instead.\n\tconst named = trimmed.toLowerCase();\n\tif (named in THREE.Color.NAMES) {\n\t\treturn new THREE.Color(THREE.Color.NAMES[named as keyof typeof THREE.Color.NAMES]);\n\t}\n\n\tgetLogger().warn(`Invalid color string: ${colorString}, using white`);\n\treturn new THREE.Color(0xffffff);\n}\n\n/** Defaults to `z` (Rhino's up axis); pass an explicit axis when the scene uses a different `sceneUp`. */\nexport function applyOffset(\n\tmeshes: THREE.Object3D[],\n\toffset: number,\n\taxis: 'x' | 'y' | 'z' = 'z'\n): void {\n\tmeshes.forEach((mesh) => {\n\t\tmesh.position[axis] -= offset;\n\t});\n}\n\nexport function computeCombinedBoundingBox(meshes: THREE.Object3D[]): THREE.Box3 {\n\tconst combinedBoundingBox = new THREE.Box3();\n\tif (meshes.length === 0) return combinedBoundingBox;\n\tmeshes.forEach((mesh) => {\n\t\tmesh.updateMatrixWorld(true);\n\t\tconst bbox = new THREE.Box3().setFromObject(mesh);\n\t\tcombinedBoundingBox.union(bbox);\n\t});\n\treturn combinedBoundingBox;\n}\n","import type * as THREE from 'three';\n\n// ============================================================================\n// GPU resource ownership — the single rule every disposal path obeys\n// ============================================================================\n\n/**\n * A GPU resource has exactly one owner: a **module singleton** (nobody ever frees it) or the\n * **scene** (freed on teardown). Every disposal path asks {@link canDisposeMaterial} and disposes\n * only if true. Geometries and textures are always scene-owned, so they have no claim to check.\n */\n\n// Module-scope singletons from `render/three-materials.ts`, shared across meshes and solves —\n// disposing one would free textures still in use and force a recompile. Held here (not imported\n// there) to avoid an import cycle.\nconst protectedMaterials = new Set<THREE.Material>();\n\n/** Register materials as never-disposable. Called once by `render/three-materials.ts`. */\nexport function protectMaterials(materials: Iterable<THREE.Material>): void {\n\tfor (const material of materials) protectedMaterials.add(material);\n}\n\n/** True when `material` is scene-owned (not one of the protected singletons). */\nexport function canDisposeMaterial(material: THREE.Material | undefined): boolean {\n\tif (!material) return false;\n\treturn !protectedMaterials.has(material);\n}\n","// ============================================================================\n// GPU capabilities — published by the renderer, read by whoever needs them\n// ============================================================================\n\n// Lets a renderer publish GPU capabilities (max anisotropy) without `render/` and `parse/` importing\n// each other: the renderer publishes on init, interested parties subscribe.\n\ntype AnisotropyObserver = (value: number) => void;\n\nconst observers = new Set<AnisotropyObserver>();\n\n// Module load order between layers isn't guaranteed, so a subscriber arriving after init still\n// needs the current value rather than waiting for a second renderer to publish.\nlet maxAnisotropy = 1;\n\nexport function publishMaxAnisotropy(value: number): void {\n\tconst next = Math.max(1, value);\n\tif (next === maxAnisotropy) return;\n\tmaxAnisotropy = next;\n\tfor (const observe of observers) observe(next);\n}\n\n/** Fires immediately with the current value (1 until a renderer has reported), then on every change. */\nexport function observeMaxAnisotropy(observe: AnisotropyObserver): () => void {\n\tobservers.add(observe);\n\tobserve(maxAnisotropy);\n\treturn () => observers.delete(observe);\n}\n","import * as THREE from 'three';\n\nimport { canDisposeMaterial } from './gpu-ownership.js';\n\n// ============================================================================\n// The disposal walkers — every teardown path in the package goes through these\n// ============================================================================\n\n/** Frees a material and its textures, respecting ownership (`./gpu-ownership.ts`). */\nexport function disposeMaterial(material: THREE.Material): void {\n\tif (!canDisposeMaterial(material)) return;\n\n\tfor (const value of Object.values(material)) {\n\t\tif (value instanceof THREE.Texture) {\n\t\t\tvalue.dispose();\n\t\t}\n\t}\n\tmaterial.dispose();\n}\n\nfunction disposeMaterials(material: THREE.Material | THREE.Material[] | undefined): void {\n\tif (!material) return;\n\tif (Array.isArray(material)) material.forEach(disposeMaterial);\n\telse disposeMaterial(material);\n}\n\nexport interface DisposeOptions {\n\t/** Free materials and their textures too. Default true; the solve memo passes false. */\n\tmaterials?: boolean;\n\t/** Called for each geometry before disposal, so a subsystem can free derived resources keyed on it (e.g. edge caches). */\n\tonGeometry?: (geometry: THREE.BufferGeometry) => void;\n}\n\n/**\n * Frees the GPU resources of an object subtree, respecting ownership. **The only traversal that\n * should dispose scene content** — a second disposing `traverse` risks missing an ownership guard.\n */\nexport function disposeObjectTree(root: THREE.Object3D, options: DisposeOptions = {}): void {\n\tconst { materials = true } = options;\n\n\troot.traverse((object) => {\n\t\tconst renderable = object as Partial<THREE.Mesh> & THREE.Object3D;\n\t\tif (!renderable.geometry && !renderable.material) return;\n\n\t\tif (renderable.geometry) {\n\t\t\trenderable.geometry?.dispose();\n\t\t}\n\n\t\tif (materials) disposeMaterials(renderable.material);\n\t});\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"gpu-dispose-Cm4qCZiL.js","names":[],"sources":["../src/shared/errors.ts","../src/shared/logger.ts","../src/shared/geometry.ts","../src/shared/gpu-ownership.ts","../src/shared/gpu-capabilities.ts","../src/shared/gpu-dispose.ts"],"sourcesContent":["/**\n * Errors for the visualization package. Replaces `@selvajs/compute`'s `RhinoComputeError`, which\n * mis-named failures on paths (e.g. the plugin WebSocket) that never touch Rhino.Compute. `code`\n * values match compute's so existing catch-sites keep working.\n */\n\nexport const ErrorCodes = {\n\t/** Structural check failed: bad magic bytes, out-of-window index, malformed metadata. */\n\tVALIDATION_ERROR: 'VALIDATION_ERROR',\n\tINVALID_STATE: 'INVALID_STATE',\n\t/** No `DecompressionStream`, no WebGL context, etc. */\n\tENVIRONMENT_ERROR: 'ENVIRONMENT_ERROR',\n\tINVALID_CONFIG: 'INVALID_CONFIG',\n\t/** Base64 input could not be decoded. */\n\tENCODING_ERROR: 'ENCODING_ERROR',\n\tUNKNOWN_ERROR: 'UNKNOWN_ERROR'\n} as const;\n\nexport type ErrorCode = (typeof ErrorCodes)[keyof typeof ErrorCodes];\n\nexport class VisualizationError extends Error {\n\tpublic readonly code: ErrorCode;\n\tpublic readonly context?: Record<string, unknown>;\n\tpublic readonly originalError?: Error;\n\n\tconstructor(\n\t\tmessage: string,\n\t\tcode: ErrorCode = ErrorCodes.UNKNOWN_ERROR,\n\t\toptions?: { context?: Record<string, unknown>; originalError?: Error }\n\t) {\n\t\tsuper(message);\n\t\tthis.name = 'VisualizationError';\n\t\tthis.code = code;\n\t\tthis.context = options?.context;\n\t\tthis.originalError = options?.originalError;\n\t\tif (options?.originalError) {\n\t\t\t(this as { cause?: unknown }).cause = options.originalError;\n\t\t}\n\t}\n}\n","/**\n * Logging facility for the visualization package. Deliberately local rather than imported from\n * `@selvajs/compute` (logging isn't a compute concern). Mirrors compute's logger shape so a host\n * wanting one sink for both can call `setLogger(computeLogger.getLogger())`.\n */\n\nimport { VisualizationError, ErrorCodes } from './errors.js';\n\nexport interface Logger {\n\tdebug(message: string, ...args: unknown[]): void;\n\tinfo(message: string, ...args: unknown[]): void;\n\twarn(message: string, ...args: unknown[]): void;\n\terror(message: string, ...args: unknown[]): void;\n}\n\nclass NoOpLogger implements Logger {\n\tdebug(): void {}\n\tinfo(): void {}\n\twarn(): void {}\n\terror(): void {}\n}\n\nclass ConsoleLogger implements Logger {\n\tdebug(message: string, ...args: unknown[]): void {\n\t\t// eslint-disable-next-line no-console -- this class exists to be the console sink\n\t\tconsole.debug(message, ...args);\n\t}\n\n\tinfo(message: string, ...args: unknown[]): void {\n\t\tconsole.info(message, ...args);\n\t}\n\n\twarn(message: string, ...args: unknown[]): void {\n\t\tconsole.warn(message, ...args);\n\t}\n\n\terror(message: string, ...args: unknown[]): void {\n\t\tconsole.error(message, ...args);\n\t}\n}\n\n// Defaults to no-op: a library that writes to the console uninvited is a nuisance in a host with\n// its own logging. Opt in with setLogger or enableDebugLogging.\nlet internalLogger: Logger = new NoOpLogger();\n\n// Call per-use rather than caching — the sink is settable at any time.\nexport function getLogger(): Logger {\n\treturn internalLogger;\n}\n\n// Validates logger shape up front: failing here beats a confusing \"getLogger().debug is not a\n// function\" at some later, unrelated call site.\nexport function setLogger(logger: Logger | Console | null): void {\n\tif (logger === null) {\n\t\tinternalLogger = new NoOpLogger();\n\t\treturn;\n\t}\n\n\tconst missing = (['debug', 'info', 'warn', 'error'] as const).filter(\n\t\t(method) => typeof (logger as unknown as Record<string, unknown>)[method] !== 'function'\n\t);\n\tif (missing.length > 0) {\n\t\tthrow new VisualizationError(\n\t\t\t`Logger is missing required method(s): ${missing.join(', ')}. A logger must implement debug, info, warn and error.`,\n\t\t\tErrorCodes.INVALID_CONFIG,\n\t\t\t{ context: { missingMethods: missing } }\n\t\t);\n\t}\n\n\tinternalLogger = logger as Logger;\n}\n\nexport function enableDebugLogging(): void {\n\tsetLogger(new ConsoleLogger());\n}\n","import * as THREE from 'three';\n\nimport { getLogger } from './logger.js';\n\n// parse/ needs these and must never import upward from render/, so they live in shared/ instead\n// of render's three-helpers.\n\nexport function parseColor(colorString: string): THREE.Color {\n\tif (!colorString || typeof colorString !== 'string') {\n\t\tgetLogger().warn(`Invalid color input: ${colorString}, using white`);\n\t\treturn new THREE.Color(0xffffff);\n\t}\n\n\tconst trimmed = colorString.trim();\n\n\tif (/^#?[0-9A-Fa-f]{6}$/.test(trimmed)) {\n\t\ttry {\n\t\t\tconst hex = trimmed.startsWith('#') ? trimmed : `#${trimmed}`;\n\t\t\treturn new THREE.Color(hex);\n\t\t} catch {\n\t\t\tgetLogger().warn(`Invalid hex color: ${colorString}, using white`);\n\t\t\treturn new THREE.Color(0xffffff);\n\t\t}\n\t}\n\n\tif (trimmed.includes(',')) {\n\t\tconst rgb = trimmed.split(',').map((c) => parseInt(c.trim(), 10));\n\t\tif (rgb.length === 3 && rgb.every((n) => !isNaN(n) && n >= 0 && n <= 255)) {\n\t\t\treturn new THREE.Color(rgb[0] / 255, rgb[1] / 255, rgb[2] / 255);\n\t\t}\n\t}\n\n\t// `new THREE.Color(name)` never throws on unknown names (it logs its own warning and leaves the\n\t// color white), so validate against three's CSS name table instead.\n\tconst named = trimmed.toLowerCase();\n\tif (named in THREE.Color.NAMES) {\n\t\treturn new THREE.Color(THREE.Color.NAMES[named as keyof typeof THREE.Color.NAMES]);\n\t}\n\n\tgetLogger().warn(`Invalid color string: ${colorString}, using white`);\n\treturn new THREE.Color(0xffffff);\n}\n\n/** Defaults to `z` (Rhino's up axis); pass an explicit axis when the scene uses a different `sceneUp`. */\nexport function applyOffset(\n\tmeshes: THREE.Object3D[],\n\toffset: number,\n\taxis: 'x' | 'y' | 'z' = 'z'\n): void {\n\tmeshes.forEach((mesh) => {\n\t\tmesh.position[axis] -= offset;\n\t});\n}\n\nexport function computeCombinedBoundingBox(meshes: THREE.Object3D[]): THREE.Box3 {\n\tconst combinedBoundingBox = new THREE.Box3();\n\tif (meshes.length === 0) return combinedBoundingBox;\n\tmeshes.forEach((mesh) => {\n\t\tmesh.updateMatrixWorld(true);\n\t\tconst bbox = new THREE.Box3().setFromObject(mesh);\n\t\tcombinedBoundingBox.union(bbox);\n\t});\n\treturn combinedBoundingBox;\n}\n","import type * as THREE from 'three';\n\n// ============================================================================\n// GPU resource ownership — the single rule every disposal path obeys\n// ============================================================================\n\n/**\n * A GPU resource has exactly one owner: a **module singleton** (nobody ever frees it) or the\n * **scene** (freed on teardown). Every disposal path asks {@link canDisposeMaterial} and disposes\n * only if true. Geometries and textures are always scene-owned, so they have no claim to check.\n */\n\n// Module-scope singletons from `render/three-materials.ts`, shared across meshes and solves —\n// disposing one would free textures still in use and force a recompile. Held here (not imported\n// there) to avoid an import cycle.\nconst protectedMaterials = new Set<THREE.Material>();\n\n/** Register materials as never-disposable. Called once by `render/three-materials.ts`. */\nexport function protectMaterials(materials: Iterable<THREE.Material>): void {\n\tfor (const material of materials) protectedMaterials.add(material);\n}\n\n/** True when `material` is scene-owned (not one of the protected singletons). */\nexport function canDisposeMaterial(material: THREE.Material | undefined): boolean {\n\tif (!material) return false;\n\treturn !protectedMaterials.has(material);\n}\n","// ============================================================================\n// GPU capabilities — published by the renderer, read by whoever needs them\n// ============================================================================\n\n// Lets a renderer publish GPU capabilities (max anisotropy) without `render/` and `parse/` importing\n// each other: the renderer publishes on init, interested parties subscribe.\n\ntype AnisotropyObserver = (value: number) => void;\n\nconst observers = new Set<AnisotropyObserver>();\n\n// Module load order between layers isn't guaranteed, so a subscriber arriving after init still\n// needs the current value rather than waiting for a second renderer to publish.\nlet maxAnisotropy = 1;\n\nexport function publishMaxAnisotropy(value: number): void {\n\tconst next = Math.max(1, value);\n\tif (next === maxAnisotropy) return;\n\tmaxAnisotropy = next;\n\tfor (const observe of observers) observe(next);\n}\n\n/** Fires immediately with the current value (1 until a renderer has reported), then on every change. */\nexport function observeMaxAnisotropy(observe: AnisotropyObserver): () => void {\n\tobservers.add(observe);\n\tobserve(maxAnisotropy);\n\treturn () => observers.delete(observe);\n}\n","import * as THREE from 'three';\n\nimport { canDisposeMaterial } from './gpu-ownership.js';\n\n// ============================================================================\n// The disposal walkers — every teardown path in the package goes through these\n// ============================================================================\n\n/** Frees a material and its textures, respecting ownership (`./gpu-ownership.ts`). */\nexport function disposeMaterial(material: THREE.Material): void {\n\tif (!canDisposeMaterial(material)) return;\n\n\tfor (const value of Object.values(material)) {\n\t\tif (value instanceof THREE.Texture) {\n\t\t\tvalue.dispose();\n\t\t}\n\t}\n\tmaterial.dispose();\n}\n\nfunction disposeMaterials(material: THREE.Material | THREE.Material[] | undefined): void {\n\tif (!material) return;\n\tif (Array.isArray(material)) material.forEach(disposeMaterial);\n\telse disposeMaterial(material);\n}\n\nexport interface DisposeOptions {\n\t/** Free materials and their textures too. Default true; the solve memo passes false. */\n\tmaterials?: boolean;\n\t/** Called for each geometry before disposal, so a subsystem can free derived resources keyed on it (e.g. edge caches). */\n\tonGeometry?: (geometry: THREE.BufferGeometry) => void;\n}\n\n/**\n * Frees the GPU resources of an object subtree, respecting ownership. **The only traversal that\n * should dispose scene content** — a second disposing `traverse` risks missing an ownership guard.\n */\nexport function disposeObjectTree(root: THREE.Object3D, options: DisposeOptions = {}): void {\n\tconst { materials = true } = options;\n\n\troot.traverse((object) => {\n\t\tconst renderable = object as Partial<THREE.Mesh> & THREE.Object3D;\n\t\tif (!renderable.geometry && !renderable.material) return;\n\n\t\tif (renderable.geometry) {\n\t\t\trenderable.geometry?.dispose();\n\t\t}\n\n\t\tif (materials) disposeMaterials(renderable.material);\n\t});\n}\n"],"mappings":"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"}
package/dist/parse.cjs CHANGED
@@ -1,4 +1,4 @@
1
- Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./rolldown-runtime-BocRIvOZ.cjs"),t=require("./gpu-dispose-DrN-ryj5.cjs");let n=require("three");n=e.t(n,1);let r=require("three/addons/lines/Line2.js"),i=require("three/addons/lines/LineGeometry.js"),a=require("three/addons/lines/LineMaterial.js"),o=require("fflate");function s(){let e=globalThis.Buffer;return typeof e==`function`?e:void 0}function c(e){let n=e.replace(/[\t\n\f\r ]/g,``);if(n.length%4==0&&(n=n.replace(/={1,2}$/,``)),n.length%4==1||!/^[A-Za-z0-9+/]*$/.test(n))throw new t.d(`Invalid base64 input.`,t.u.ENCODING_ERROR,{context:{inputLength:e.length}});let r=s();if(r)return new Uint8Array(r.from(n,`base64`));if(typeof globalThis.atob==`function`){let e=globalThis.atob(n),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n)&255;return t}throw new t.d(`Base64 decoding not supported in this environment.`,t.u.INVALID_STATE,{context:{environmentInfo:`atob or Buffer not available`}})}function l(e){return e.map(e=>{let t=e.clone(!0),n=[];e.traverse(e=>n.push(e));let r=0;return t.traverse(e=>{let t=n[r++],i=e;t.geometry&&(i.geometry=t.geometry.clone())}),t})}function u(e){e.forEach(e=>t.t(e,{materials:!1}))}const d={clone:l,release:u};function f(e,t){let r=t??1;return{color:new n.Color(e??`#ffffff`),transparent:r<1,opacity:r}}function p(e){let t=m(e);if(!t)return null;let n=new i.LineGeometry;n.setPositions(t);let o=f(e.color,e.opacity),s=new a.LineMaterial({color:o.color}),c=s;c.linewidth=e.width??2,c.transparent=o.transparent,c.opacity=o.opacity;let l=new r.Line2(n,s);return l.computeLineDistances(),l.name=e.name,l.userData={source:`compute`,id:e.id,layer:e.layer,kind:`curve`,metadata:e.metadata},l}function m(e){if(!e.points)throw new t.d(`Curve display item '${e.id}' has no tessellated points. It was produced by an outdated Display component — upgrade it in Grasshopper (Solution → Upgrade obsolete components) and re-save the definition.`,t.u.INVALID_CONFIG,{context:{itemId:e.id,kind:e.kind}});return e.points.length>=6?e.points:null}function h(e){let{position:r}=e;if(!r||typeof r.X!=`number`||!Number.isFinite(r.X)||typeof r.Y!=`number`||!Number.isFinite(r.Y)||typeof r.Z!=`number`||!Number.isFinite(r.Z))return t.c().warn(`Skipping point display item with missing or non-finite position (id: ${String(e.id)}).`),null;let i=new n.BufferGeometry;i.setAttribute(`position`,new n.Float32BufferAttribute([r.X,r.Y,r.Z],3));let a=new n.PointsMaterial({...f(e.color,e.opacity),size:6,sizeAttenuation:!1}),o=new n.Points(i,a);return o.name=e.name,o.userData={source:`compute`,id:e.id,layer:e.layer,kind:`point`,metadata:e.metadata},o}function g(e){if(!e||e.length===0)return[];let n=[];for(let r of e)switch(r.kind){case`curve`:{let e=p(r);e&&n.push(e);break}case`point`:{let e=h(r);e&&n.push(e);break}default:{let e=r;t.c().warn(`Skipping unknown display item kind: ${String(e.kind)}`);break}}return n}const _=new Uint16Array(new Uint8Array([1,0]).buffer)[0]===1;function v(e){return typeof e==`string`?c(e):e instanceof Uint8Array?e:new Uint8Array(e)}function y(e){if(e.byteLength<8)return e;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(t.getUint32(0,!0)!==1515605075)return e;let n=t.getUint32(4,!0),r=e.subarray(8),i=Math.max(r.byteLength*1032+1024,1<<20);if(n>i)throw M(`SLVZ header declares an implausible uncompressed length`,{uncompressedLen:n,deflatedBytes:r.byteLength,maxPlausibleLen:i});let a;try{a=(0,o.inflateSync)(r,{out:new Uint8Array(n+1)})}catch(e){throw M(`Failed to inflate SLVZ blob: ${e instanceof Error?e.message:String(e)}`,{uncompressedLen:n,deflatedBytes:r.byteLength})}if(a.byteLength!==n)throw M(`SLVZ payload inflated to a different size than the header declares.`,{declaredLen:n,actualLen:a.byteLength,deflatedBytes:r.byteLength});return a}function b(e){if(typeof TextDecoder<`u`)return new TextDecoder(`utf-8`).decode(e);if(globalThis.Buffer!==void 0)return globalThis.Buffer.from(e).toString(`utf-8`);throw new t.d(`No UTF-8 decoder available in this environment.`,t.u.INVALID_STATE)}function x(e,t,n){if(n===0)return new Int16Array;if(t%2==0)return new Int16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Int16Array(r.buffer)}function S(e,t,n){if(n===0)return new Float32Array;if(t%4==0)return new Float32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Float32Array(r.buffer)}function C(e,t,n){if(n===0)return new Uint16Array;if(t%2==0)return new Uint16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Uint16Array(r.buffer)}function ee(e,t,n){if(n===0)return new Uint32Array;if(t%4==0)return new Uint32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Uint32Array(r.buffer)}function w(e,t){if(e.length!==0&&!(e instanceof Uint16Array&&t>65535)){for(let n=0;n<e.length;n++)if(e[n]>=t)throw M(`Index out of range of vertexCount.`,{indexPosition:n,indexValue:e[n],vertexCount:t})}}function T(e){return e>>>1^-(e&1)}function E(e){let t=new Int16Array(e.length),n=0,r=0,i=0;for(let a=0;a<e.length;a+=3)n=n+T(e[a])<<16>>16,r=r+T(e[a+1])<<16>>16,i=i+T(e[a+2])<<16>>16,t[a]=n,t[a+1]=r,t[a+2]=i;return t}function D(e,t){let n=new Int16Array(t*3),r=t,i=0,a=0,o=0;for(let t=0;t<r;t++)i=i+T(e[t]|e[r*3+t]<<8)<<16>>16,a=a+T(e[r+t]|e[r*4+t]<<8)<<16>>16,o=o+T(e[r*2+t]|e[r*5+t]<<8)<<16>>16,n[t*3]=i,n[t*3+1]=a,n[t*3+2]=o;return n}function O(e,t){let n=new Uint16Array(t),r=0;for(let i=0;i<t;i++)r=r+T(e[i]|e[t+i]<<8)&65535,n[i]=r;return n}function k(e,t){let n=new Uint32Array(t),r=0;for(let i=0;i<t;i++){let a=(e[i]|e[t+i]<<8|e[t*2+i]<<16|e[t*3+i]<<24)>>>0;r=r+T(a)>>>0,n[i]=r}return n}function A(e){let t=new Uint16Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+T(e[r])&65535,t[r]=n;return t}function j(e){let t=new Uint32Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+T(e[r])>>>0,t[r]=n;return t}function M(e,n){return new t.d(e,t.u.VALIDATION_ERROR,{context:n})}function te(e,t,n,r,i,a=!1){if(n+36>e.byteLength)throw M(`Insufficient data to read UV chunk header.`,{expectedBytes:36,availableBytes:e.byteLength-n,offset:n});let o=t.getUint32(n,!0);n+=4;let s=t.getFloat64(n,!0);n+=8;let c=t.getFloat64(n,!0);n+=8;let l=t.getFloat64(n,!0);n+=8;let u=t.getFloat64(n,!0);n+=8;let d=r*2,f=o===1,p=d*(f?4:2);if(n+p>e.byteLength)throw M(`Insufficient data to read UV chunk.`,{expectedBytes:p,availableBytes:e.byteLength-n,offset:n,uvFormat:o,vertexCount:r});let m=e.byteOffset+n,h;if(f)h=S(e.buffer,m,d).slice();else if(a){let t=e.subarray(n,n+p),i=r;h=new Float32Array(d);let a=0,o=0;for(let e=0;e<i;e++)a=a+T(t[e]|t[i*2+e]<<8)&65535,o=o+T(t[i+e]|t[i*3+e]<<8)&65535,h[e*2]=s+a*l,h[e*2+1]=c+o*u}else{let t=C(e.buffer,m,d);h=new Float32Array(d);let n=0,r=0;for(let e=0;e<d;e+=2)i?(n=n+T(t[e])&65535,r=r+T(t[e+1])&65535):(n=t[e],r=t[e+1]),h[e]=s+n*l,h[e+1]=c+r*u}return{uvs:h,offset:n+p}}function ne(e,t,n,r){let i=n*3;if(t+i>e.byteLength)throw M(`Insufficient data to read vertex-color chunk.`,{expectedBytes:i,availableBytes:e.byteLength-t,offset:t,vertexCount:n});let a=e.subarray(t,t+i);if(!r)return a.slice();let o=new Uint8Array(i),s=0,c=0,l=0;for(let e=0;e<i;e+=3)s=s+T(a[e])&255,c=c+T(a[e+1])&255,l=l+T(a[e+2])&255,o[e]=s,o[e+1]=c,o[e+2]=l;return o}function re(e){return e.byteLength>=4&&new DataView(e.buffer,e.byteOffset,4).getUint32(0,!0)===1297501267}function ie(e){let t=N(e),n=null,r=null,i=null,a=[];for(let{type:e,payload:o}of t)switch(e){case 1297040711:n=o;break;case 1279410516:r=y(o);break;case 1280590157:i=b(o);break;case 1381516628:a.push(o)}if(n===null)throw M(`SLVM container has no GEOM chunk.`,{chunkCount:t.length});if(r===null)throw M(`SLVM container has no TABL chunk.`,{chunkCount:t.length});let{groups:o}=I(r),s=L(i,a);return{geometryBlob:n,metadata:{materials:s,groups:o}}}function N(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(e.byteLength<12||t.getUint32(0,!0)!==1297501267)throw M(`Not an SLVM container (bad magic).`,{byteLength:e.byteLength});let n=t.getUint32(4,!0);if(n!==3)throw M(`Unsupported SLVM version: ${n}`,{expectedVersion:3});let r=t.getUint32(8,!0),i=[],a=12;for(let n=0;n<r;n++){if(a+8>e.byteLength)throw M(`Truncated SLVM chunk header.`,{offset:a,chunkIndex:n});let r=t.getUint32(a,!0),o=t.getUint32(a+4,!0);if(a+=8,a+o>e.byteLength)throw M(`Truncated SLVM chunk payload.`,{offset:a,chunkIndex:n,byteLen:o});i.push({type:r,payload:e.subarray(a,a+o)}),a+=o+(4-o%4)%4}return i}function P(e){let t=0,n=0;for(;;){if(e.pos>=e.bytes.byteLength||n>28)throw M(`Malformed varint in SLVM table.`,{pos:e.pos});let r=e.bytes[e.pos++];if(t|=(r&127)<<n,!(r&128))return t>>>0;n+=7}}function F(e,t,n){let r=e.bytes[e.pos++],i=Array(t);switch(r){case 0:i.fill(``);break;case 1:for(let e=0;e<t;e++)i[e]=String(e+1);break;case 2:for(let r=0;r<t;r++)i[r]=n[P(e)]??``;break;default:throw M(`Unknown SLVM string column mode: ${r}`,{pos:e.pos})}return i}function I(e){let t={bytes:e,pos:0},n=P(t),r=P(t),i=P(t),a=n+r+i,o=P(t),s=Array(o);for(let n=0;n<o;n++){let r=P(t);s[n]=b(e.subarray(t.pos,t.pos+r)),t.pos+=r}let c=Array(n),l=Array(n);for(let e=0;e<n;e++)c[e]=P(t),l[e]=P(t);for(let e=0;e<r;e++)P(t);let u=P(t),d=[];for(let e=0;e<u;e++)d.push({materialId:P(t),meshCount:P(t)});let f=F(t,a,s),p=F(t,a,s),m=Array(a),h=P(t);for(let e=0;e<h;e++){let e=s[P(t)]??``,n=P(t),r=Array(n),i=0;for(let e=0;e<n;e++)i+=P(t),r[e]=i;for(let i=0;i<n;i++){let n=s[P(t)]??``,a=r[i];(m[a]??={})[e]=n}}let g=d.length>0||n===0?d:[{materialId:0,meshCount:n}],_=[],v=0,y=0,x=0;for(let e of g){let t=[];for(let r=0;r<e.meshCount&&v<n;r++,v++){let e=m[v],n=e?.id;e!==void 0&&delete e.id,t.push({id:n,name:f[v],layer:p[v],vertexCount:c[v],indexCount:l[v]*3,vertexStart:y,indexStart:x,metadata:e??{}}),y+=c[v],x+=l[v]*3}_.push({materialId:e.materialId,meshes:t})}return{groups:_}}function L(e,t){if(e===null)return[];let n;try{n=JSON.parse(e).materials??[]}catch(t){throw M(`Failed to parse SLVM materials JSON: ${t instanceof Error?t.message:String(t)}`,{byteLength:e.length})}for(let e of n)if(e.map?.startsWith(`slvm:tex:`)){let n=t[Number(e.map.slice(9))];n!==void 0&&(e.map=R(n))}return n}function R(e){let t={bytes:e,pos:0},n=P(t),r=b(e.subarray(t.pos,t.pos+n)),i=e.subarray(t.pos+n),a=``,o=32768;for(let e=0;e<i.byteLength;e+=o)a+=String.fromCharCode(...i.subarray(e,e+o));return`data:${r};base64,${btoa(a)}`}function z(e){let t=B(e),n;n=t.isFloat32?t.vertexData:t.planarByteSplit?D(t.vertexData,t.vertexCount):t.deltaEncoded?E(t.vertexData):t.vertexData;let r;if(t.planarByteSplit){let e=t.indexData;r=t.uint16Indices?O(e,e.length/2):k(e,e.length/4)}else r=t.deltaEncoded?t.indexData instanceof Uint16Array?A(t.indexData):j(t.indexData):t.indexData;return w(r,t.vertexCount),{metadata:t.metadata,flags:t.flags,vertices:n,indices:r,origin:t.origin,scale:t.scale,uvs:t.uvs,colors:t.colors}}function B(e){if(!_)throw new t.d(`SLVA parsing requires a little-endian host: the zero-copy geometry readers view the wire bytes in host byte order.`,t.u.ENVIRONMENT_ERROR);let n=v(e);if(re(n)){let e=ie(n),t=B(e.geometryBlob);return t.metadata=e.metadata,t}let r=y(n),i=new DataView(r.buffer,r.byteOffset,r.byteLength);if(r.byteLength<12)throw M(`Blob too small to contain SLVA header.`,{expectedBytes:12,availableBytes:r.byteLength});let a=0,o=i.getUint32(a,!0);if(a+=4,o!==1096174675)throw M(`Invalid SLVA magic: 0x${o.toString(16)}`,{expectedMagic:`0x41564c53`,actualMagic:`0x${o.toString(16)}`});let s=i.getUint32(a,!0);if(a+=4,s<1||s>4)throw M(`Unsupported SLVA version: ${s}`,{minSupportedVersion:1,maxSupportedVersion:4,actualVersion:s});let c=i.getUint32(a,!0);if(a+=4,a+c>r.byteLength)throw M(`Insufficient data to read metadata JSON.`,{expectedBytes:c,availableBytes:r.byteLength-a,offset:a});let l=r.subarray(a,a+c);a+=c;let u;try{u=c===0?{}:JSON.parse(b(l))}catch(e){throw M(`Failed to parse metadata JSON: ${e instanceof Error?e.message:String(e)}`,{metadataLen:c})}if(a+56>r.byteLength)throw M(`Insufficient data to read geometry header.`,{expectedBytes:56,availableBytes:r.byteLength-a,offset:a});let d=i.getUint32(a,!0);a+=4;let f=i.getFloat64(a,!0);a+=8;let p=i.getFloat64(a,!0);a+=8;let m=i.getFloat64(a,!0);a+=8;let h=i.getFloat64(a,!0);a+=8;let g=i.getFloat64(a,!0);a+=8;let w=i.getFloat64(a,!0);a+=8;let T=i.getUint32(a,!0);a+=4;let E=!!(d&1),D=!!(d&4),O=!!(d&32),k=T*3,A=k*(E?4:2);if(a+A>r.byteLength)throw M(`Insufficient data to read vertices.`,{expectedBytes:A,availableBytes:r.byteLength-a,offset:a,useFloat32:E,vertexCount:T});let j=r.byteOffset+a,N;if(N=E?S(r.buffer,j,k):O?r.subarray(a,a+A):D?C(r.buffer,j,k):x(r.buffer,j,k),a+=A,a+4>r.byteLength)throw M(`Insufficient data to read index count.`,{expectedBytes:4,availableBytes:r.byteLength-a,offset:a});let P=i.getUint32(a,!0);a+=4;let F=!!(d&2),I=P*(F?2:4);if(a+I>r.byteLength)throw M(`Insufficient data to read indices.`,{expectedBytes:I,availableBytes:r.byteLength-a,offset:a,indexCount:P,useUint16Indices:F});let L=O?r.subarray(a,a+I):F?C(r.buffer,r.byteOffset+a,P):ee(r.buffer,r.byteOffset+a,P);a+=I;let R=null;if(d&8){let e=te(r,i,a,T,D,O);R=e.uvs,a=e.offset}let z=null;return d&16&&(z=ne(r,a,T,D)),{metadata:u,flags:d,vertexData:N,indexData:L,isFloat32:E,deltaEncoded:D,planarByteSplit:O,uint16Indices:F,vertexCount:T,origin:[f,p,m],scale:[h,g,w],uvs:R,colors:z}}function ae(e){let{isFloat32:t,deltaEncoded:n,planarByteSplit:r,uint16Indices:i,origin:a,scale:o,uvs:s,colors:c,jobs:l}=e,u=e=>e>>>1^-(e&1),d;if(t)d=e.vertexData;else{let t;if(r){let n=e.vertexData,r=n.length/6;t=new Int16Array(r*3);let i=0,a=0,o=0;for(let e=0;e<r;e++)i=i+u(n[e]|n[r*3+e]<<8)<<16>>16,a=a+u(n[r+e]|n[r*4+e]<<8)<<16>>16,o=o+u(n[r*2+e]|n[r*5+e]<<8)<<16>>16,t[e*3]=i,t[e*3+1]=a,t[e*3+2]=o}else if(n){let n=e.vertexData;t=new Int16Array(n.length);let r=0,i=0,a=0;for(let e=0;e<n.length;e+=3)r=r+u(n[e])<<16>>16,i=i+u(n[e+1])<<16>>16,a=a+u(n[e+2])<<16>>16,t[e]=r,t[e+1]=i,t[e+2]=a}else t=e.vertexData;d=new Float32Array(t.length);let i=a[0],s=a[1],c=a[2],l=o[0],f=o[1],p=o[2];for(let e=0;e<t.length;e+=3)d[e]=i+(t[e]+32767)*l,d[e+1]=s+(t[e+1]+32767)*f,d[e+2]=c+(t[e+2]+32767)*p}let f;if(r){let t=e.indexData;if(i){let e=t.length/2,n=new Uint16Array(e),r=0;for(let i=0;i<e;i++)r=r+u(t[i]|t[e+i]<<8)&65535,n[i]=r;f=n}else{let e=t.length/4,n=new Uint32Array(e),r=0;for(let i=0;i<e;i++){let a=(t[i]|t[e+i]<<8|t[e*2+i]<<16|t[e*3+i]<<24)>>>0;r=r+u(a)>>>0,n[i]=r}f=n}}else if(n){let t=e.indexData;if(t instanceof Uint16Array){let e=new Uint16Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+u(t[r])&65535,e[r]=n;f=e}else{let e=new Uint32Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+u(t[r])>>>0,e[r]=n;f=e}}else f=e.indexData;let p=d.length/3;for(let e=0;e<f.length;e++)if(f[e]>=p)throw Error(`Index ${f[e]} out of range of vertexCount ${p}`);let m=[];for(let e of l){let t=0,n=0;for(let r of e.windows)t+=r.vertexCount,n+=r.indexCount;let r=new Float32Array(t*3),i=new Uint32Array(n),a=s?new Float32Array(t*2):null,o=c?new Uint8Array(t*3):null,l=0,u=0;for(let t of e.windows){let e=t.vertexStart*3;r.set(d.subarray(e,e+t.vertexCount*3),l*3),a&&s&&a.set(s.subarray(t.vertexStart*2,(t.vertexStart+t.vertexCount)*2),l*2),o&&c&&o.set(c.subarray(e,e+t.vertexCount*3),l*3);let n=t.vertexStart,p=t.vertexStart+t.vertexCount,m=l-t.vertexStart;for(let e=0;e<t.indexCount;e++){let r=f[t.indexStart+e];if(r<n||r>=p)throw Error(`Index ${r} outside vertex window [${n}, ${p})`);i[u+e]=r+m}l+=t.vertexCount,u+=t.indexCount}let p=new Float32Array(t*3);for(let e=0;e<i.length;e+=3){let t=i[e]*3,n=i[e+1]*3,a=i[e+2]*3,o=r[a]-r[n],s=r[a+1]-r[n+1],c=r[a+2]-r[n+2],l=r[t]-r[n],u=r[t+1]-r[n+1],d=r[t+2]-r[n+2],f=s*d-c*u,m=c*l-o*d,h=o*u-s*l;p[t]+=f,p[t+1]+=m,p[t+2]+=h,p[n]+=f,p[n+1]+=m,p[n+2]+=h,p[a]+=f,p[a+1]+=m,p[a+2]+=h}for(let e=0;e<p.length;e+=3){let t=p[e],n=p[e+1],r=p[e+2],i=Math.sqrt(t*t+n*n+r*r)||1;p[e]=t/i,p[e+1]=n/i,p[e+2]=r/i}m.push({positions:r,normals:p,indices:i,uvs:a,colors:o})}return m}function oe(){return[`const assemble = ${ae.toString()};`,`self.onmessage = (event) => {`,` const { id, input } = event.data;`,` try {`,` const geometries = assemble(input);`,` const transfer = [];`,` for (const g of geometries) {`,` transfer.push(g.positions.buffer, g.normals.buffer, g.indices.buffer);`,` if (g.uvs) transfer.push(g.uvs.buffer);`,` if (g.colors) transfer.push(g.colors.buffer);`,` }`,` self.postMessage({ id, geometries }, transfer);`,` } catch (error) {`,` self.postMessage({ id, error: String((error && error.message) || error) });`,` }`,`};`].join(`
1
+ Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});const e=require("./rolldown-runtime-BocRIvOZ.cjs"),t=require("./gpu-dispose-08qVHlV6.cjs");let n=require("three");n=e.t(n,1);let r=require("three/addons/lines/Line2.js"),i=require("three/addons/lines/LineGeometry.js"),a=require("three/addons/lines/LineMaterial.js"),o=require("fflate");function s(){let e=globalThis.Buffer;return typeof e==`function`?e:void 0}function c(e){let n=e.replace(/[\t\n\f\r ]/g,``);if(n.length%4==0&&(n=n.replace(/={1,2}$/,``)),n.length%4==1||!/^[A-Za-z0-9+/]*$/.test(n))throw new t.d(`Invalid base64 input.`,t.u.ENCODING_ERROR,{context:{inputLength:e.length}});let r=s();if(r)return new Uint8Array(r.from(n,`base64`));if(typeof globalThis.atob==`function`){let e=globalThis.atob(n),t=new Uint8Array(e.length);for(let n=0;n<e.length;n++)t[n]=e.charCodeAt(n)&255;return t}throw new t.d(`Base64 decoding not supported in this environment.`,t.u.INVALID_STATE,{context:{environmentInfo:`atob or Buffer not available`}})}function l(e){return e.map(e=>{let t=e.clone(!0),n=[];e.traverse(e=>n.push(e));let r=0;return t.traverse(e=>{let t=n[r++],i=e;t.geometry&&(i.geometry=t.geometry.clone())}),t})}function u(e){e.forEach(e=>t.t(e,{materials:!1}))}const d={clone:l,release:u};function f(e,t){let r=t??1;return{color:new n.Color(e??`#ffffff`),transparent:r<1,opacity:r}}function p(e){let t=m(e);if(!t)return null;let n=new i.LineGeometry;n.setPositions(t);let o=f(e.color,e.opacity),s=new a.LineMaterial({color:o.color}),c=s;c.linewidth=e.width??2,c.transparent=o.transparent,c.opacity=o.opacity;let l=new r.Line2(n,s);return l.computeLineDistances(),l.name=e.name,l.userData={source:`compute`,id:e.id,layer:e.layer,kind:`curve`,metadata:e.metadata},l}function m(e){if(!e.points)throw new t.d(`Curve display item '${e.id}' has no tessellated points. It was produced by an outdated Display component — upgrade it in Grasshopper (Solution → Upgrade obsolete components) and re-save the definition.`,t.u.INVALID_CONFIG,{context:{itemId:e.id,kind:e.kind}});return e.points.length>=6?e.points:null}function h(e){let{position:r}=e;if(!r||typeof r.X!=`number`||!Number.isFinite(r.X)||typeof r.Y!=`number`||!Number.isFinite(r.Y)||typeof r.Z!=`number`||!Number.isFinite(r.Z))return t.c().warn(`Skipping point display item with missing or non-finite position (id: ${String(e.id)}).`),null;let i=new n.BufferGeometry;i.setAttribute(`position`,new n.Float32BufferAttribute([r.X,r.Y,r.Z],3));let a=new n.PointsMaterial({...f(e.color,e.opacity),size:6,sizeAttenuation:!1}),o=new n.Points(i,a);return o.name=e.name,o.userData={source:`compute`,id:e.id,layer:e.layer,kind:`point`,metadata:e.metadata},o}function g(e){if(!e||e.length===0)return[];let n=[];for(let r of e)switch(r.kind){case`curve`:{let e=p(r);e&&n.push(e);break}case`point`:{let e=h(r);e&&n.push(e);break}default:{let e=r;t.c().warn(`Skipping unknown display item kind: ${String(e.kind)}`);break}}return n}const _=new Uint16Array(new Uint8Array([1,0]).buffer)[0]===1;function v(e){return typeof e==`string`?c(e):e instanceof Uint8Array?e:new Uint8Array(e)}function y(e){if(e.byteLength<8)return e;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(t.getUint32(0,!0)!==1515605075)return e;let n=t.getUint32(4,!0),r=e.subarray(8),i=Math.max(r.byteLength*1032+1024,1<<20);if(n>i)throw M(`SLVZ header declares an implausible uncompressed length`,{uncompressedLen:n,deflatedBytes:r.byteLength,maxPlausibleLen:i});let a;try{a=(0,o.inflateSync)(r,{out:new Uint8Array(n+1)})}catch(e){throw M(`Failed to inflate SLVZ blob: ${e instanceof Error?e.message:String(e)}`,{uncompressedLen:n,deflatedBytes:r.byteLength})}if(a.byteLength!==n)throw M(`SLVZ payload inflated to a different size than the header declares.`,{declaredLen:n,actualLen:a.byteLength,deflatedBytes:r.byteLength});return a}function b(e){if(typeof TextDecoder<`u`)return new TextDecoder(`utf-8`).decode(e);if(globalThis.Buffer!==void 0)return globalThis.Buffer.from(e).toString(`utf-8`);throw new t.d(`No UTF-8 decoder available in this environment.`,t.u.INVALID_STATE)}function x(e,t,n){if(n===0)return new Int16Array;if(t%2==0)return new Int16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Int16Array(r.buffer)}function S(e,t,n){if(n===0)return new Float32Array;if(t%4==0)return new Float32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Float32Array(r.buffer)}function C(e,t,n){if(n===0)return new Uint16Array;if(t%2==0)return new Uint16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Uint16Array(r.buffer)}function ee(e,t,n){if(n===0)return new Uint32Array;if(t%4==0)return new Uint32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Uint32Array(r.buffer)}function w(e,t){if(e.length!==0&&!(e instanceof Uint16Array&&t>65535)){for(let n=0;n<e.length;n++)if(e[n]>=t)throw M(`Index out of range of vertexCount.`,{indexPosition:n,indexValue:e[n],vertexCount:t})}}function T(e){return e>>>1^-(e&1)}function E(e){let t=new Int16Array(e.length),n=0,r=0,i=0;for(let a=0;a<e.length;a+=3)n=n+T(e[a])<<16>>16,r=r+T(e[a+1])<<16>>16,i=i+T(e[a+2])<<16>>16,t[a]=n,t[a+1]=r,t[a+2]=i;return t}function D(e,t){let n=new Int16Array(t*3),r=t,i=0,a=0,o=0;for(let t=0;t<r;t++)i=i+T(e[t]|e[r*3+t]<<8)<<16>>16,a=a+T(e[r+t]|e[r*4+t]<<8)<<16>>16,o=o+T(e[r*2+t]|e[r*5+t]<<8)<<16>>16,n[t*3]=i,n[t*3+1]=a,n[t*3+2]=o;return n}function O(e,t){let n=new Uint16Array(t),r=0;for(let i=0;i<t;i++)r=r+T(e[i]|e[t+i]<<8)&65535,n[i]=r;return n}function k(e,t){let n=new Uint32Array(t),r=0;for(let i=0;i<t;i++){let a=(e[i]|e[t+i]<<8|e[t*2+i]<<16|e[t*3+i]<<24)>>>0;r=r+T(a)>>>0,n[i]=r}return n}function A(e){let t=new Uint16Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+T(e[r])&65535,t[r]=n;return t}function j(e){let t=new Uint32Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+T(e[r])>>>0,t[r]=n;return t}function M(e,n){return new t.d(e,t.u.VALIDATION_ERROR,{context:n})}function te(e,t,n,r,i,a=!1){if(n+36>e.byteLength)throw M(`Insufficient data to read UV chunk header.`,{expectedBytes:36,availableBytes:e.byteLength-n,offset:n});let o=t.getUint32(n,!0);n+=4;let s=t.getFloat64(n,!0);n+=8;let c=t.getFloat64(n,!0);n+=8;let l=t.getFloat64(n,!0);n+=8;let u=t.getFloat64(n,!0);n+=8;let d=r*2,f=o===1,p=d*(f?4:2);if(n+p>e.byteLength)throw M(`Insufficient data to read UV chunk.`,{expectedBytes:p,availableBytes:e.byteLength-n,offset:n,uvFormat:o,vertexCount:r});let m=e.byteOffset+n,h;if(f)h=S(e.buffer,m,d).slice();else if(a){let t=e.subarray(n,n+p),i=r;h=new Float32Array(d);let a=0,o=0;for(let e=0;e<i;e++)a=a+T(t[e]|t[i*2+e]<<8)&65535,o=o+T(t[i+e]|t[i*3+e]<<8)&65535,h[e*2]=s+a*l,h[e*2+1]=c+o*u}else{let t=C(e.buffer,m,d);h=new Float32Array(d);let n=0,r=0;for(let e=0;e<d;e+=2)i?(n=n+T(t[e])&65535,r=r+T(t[e+1])&65535):(n=t[e],r=t[e+1]),h[e]=s+n*l,h[e+1]=c+r*u}return{uvs:h,offset:n+p}}function ne(e,t,n,r){let i=n*3;if(t+i>e.byteLength)throw M(`Insufficient data to read vertex-color chunk.`,{expectedBytes:i,availableBytes:e.byteLength-t,offset:t,vertexCount:n});let a=e.subarray(t,t+i);if(!r)return a.slice();let o=new Uint8Array(i),s=0,c=0,l=0;for(let e=0;e<i;e+=3)s=s+T(a[e])&255,c=c+T(a[e+1])&255,l=l+T(a[e+2])&255,o[e]=s,o[e+1]=c,o[e+2]=l;return o}function re(e){return e.byteLength>=4&&new DataView(e.buffer,e.byteOffset,4).getUint32(0,!0)===1297501267}function ie(e){let t=N(e),n=null,r=null,i=null,a=[];for(let{type:e,payload:o}of t)switch(e){case 1297040711:n=o;break;case 1279410516:r=y(o);break;case 1280590157:i=b(o);break;case 1381516628:a.push(o)}if(n===null)throw M(`SLVM container has no GEOM chunk.`,{chunkCount:t.length});if(r===null)throw M(`SLVM container has no TABL chunk.`,{chunkCount:t.length});let{groups:o}=I(r),s=L(i,a);return{geometryBlob:n,metadata:{materials:s,groups:o}}}function N(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(e.byteLength<12||t.getUint32(0,!0)!==1297501267)throw M(`Not an SLVM container (bad magic).`,{byteLength:e.byteLength});let n=t.getUint32(4,!0);if(n!==3)throw M(`Unsupported SLVM version: ${n}`,{expectedVersion:3});let r=t.getUint32(8,!0),i=[],a=12;for(let n=0;n<r;n++){if(a+8>e.byteLength)throw M(`Truncated SLVM chunk header.`,{offset:a,chunkIndex:n});let r=t.getUint32(a,!0),o=t.getUint32(a+4,!0);if(a+=8,a+o>e.byteLength)throw M(`Truncated SLVM chunk payload.`,{offset:a,chunkIndex:n,byteLen:o});i.push({type:r,payload:e.subarray(a,a+o)}),a+=o+(4-o%4)%4}return i}function P(e){let t=0,n=0;for(;;){if(e.pos>=e.bytes.byteLength||n>28)throw M(`Malformed varint in SLVM table.`,{pos:e.pos});let r=e.bytes[e.pos++];if(t|=(r&127)<<n,!(r&128))return t>>>0;n+=7}}function F(e,t,n){let r=e.bytes[e.pos++],i=Array(t);switch(r){case 0:i.fill(``);break;case 1:for(let e=0;e<t;e++)i[e]=String(e+1);break;case 2:for(let r=0;r<t;r++)i[r]=n[P(e)]??``;break;default:throw M(`Unknown SLVM string column mode: ${r}`,{pos:e.pos})}return i}function I(e){let t={bytes:e,pos:0},n=P(t),r=P(t),i=P(t),a=n+r+i,o=P(t),s=Array(o);for(let n=0;n<o;n++){let r=P(t);s[n]=b(e.subarray(t.pos,t.pos+r)),t.pos+=r}let c=Array(n),l=Array(n);for(let e=0;e<n;e++)c[e]=P(t),l[e]=P(t);for(let e=0;e<r;e++)P(t);let u=P(t),d=[];for(let e=0;e<u;e++)d.push({materialId:P(t),meshCount:P(t)});let f=F(t,a,s),p=F(t,a,s),m=Array(a),h=P(t);for(let e=0;e<h;e++){let e=s[P(t)]??``,n=P(t),r=Array(n),i=0;for(let e=0;e<n;e++)i+=P(t),r[e]=i;for(let i=0;i<n;i++){let n=s[P(t)]??``,a=r[i];(m[a]??={})[e]=n}}let g=d.length>0||n===0?d:[{materialId:0,meshCount:n}],_=[],v=0,y=0,x=0;for(let e of g){let t=[];for(let r=0;r<e.meshCount&&v<n;r++,v++){let e=m[v],n=e?.id;e!==void 0&&delete e.id,t.push({id:n,name:f[v],layer:p[v],vertexCount:c[v],indexCount:l[v]*3,vertexStart:y,indexStart:x,metadata:e??{}}),y+=c[v],x+=l[v]*3}_.push({materialId:e.materialId,meshes:t})}return{groups:_}}function L(e,t){if(e===null)return[];let n;try{n=JSON.parse(e).materials??[]}catch(t){throw M(`Failed to parse SLVM materials JSON: ${t instanceof Error?t.message:String(t)}`,{byteLength:e.length})}for(let e of n)if(e.map?.startsWith(`slvm:tex:`)){let n=t[Number(e.map.slice(9))];n!==void 0&&(e.map=R(n))}return n}function R(e){let t={bytes:e,pos:0},n=P(t),r=b(e.subarray(t.pos,t.pos+n)),i=e.subarray(t.pos+n),a=``,o=32768;for(let e=0;e<i.byteLength;e+=o)a+=String.fromCharCode(...i.subarray(e,e+o));return`data:${r};base64,${btoa(a)}`}function z(e){let t=B(e),n;n=t.isFloat32?t.vertexData:t.planarByteSplit?D(t.vertexData,t.vertexCount):t.deltaEncoded?E(t.vertexData):t.vertexData;let r;if(t.planarByteSplit){let e=t.indexData;r=t.uint16Indices?O(e,e.length/2):k(e,e.length/4)}else r=t.deltaEncoded?t.indexData instanceof Uint16Array?A(t.indexData):j(t.indexData):t.indexData;return w(r,t.vertexCount),{metadata:t.metadata,flags:t.flags,vertices:n,indices:r,origin:t.origin,scale:t.scale,uvs:t.uvs,colors:t.colors}}function B(e){if(!_)throw new t.d(`SLVA parsing requires a little-endian host: the zero-copy geometry readers view the wire bytes in host byte order.`,t.u.ENVIRONMENT_ERROR);let n=v(e);if(re(n)){let e=ie(n),t=B(e.geometryBlob);return t.metadata=e.metadata,t}let r=y(n),i=new DataView(r.buffer,r.byteOffset,r.byteLength);if(r.byteLength<12)throw M(`Blob too small to contain SLVA header.`,{expectedBytes:12,availableBytes:r.byteLength});let a=0,o=i.getUint32(a,!0);if(a+=4,o!==1096174675)throw M(`Invalid SLVA magic: 0x${o.toString(16)}`,{expectedMagic:`0x41564c53`,actualMagic:`0x${o.toString(16)}`});let s=i.getUint32(a,!0);if(a+=4,s<1||s>4)throw M(`Unsupported SLVA version: ${s}`,{minSupportedVersion:1,maxSupportedVersion:4,actualVersion:s});let c=i.getUint32(a,!0);if(a+=4,a+c>r.byteLength)throw M(`Insufficient data to read metadata JSON.`,{expectedBytes:c,availableBytes:r.byteLength-a,offset:a});let l=r.subarray(a,a+c);a+=c;let u;try{u=c===0?{}:JSON.parse(b(l))}catch(e){throw M(`Failed to parse metadata JSON: ${e instanceof Error?e.message:String(e)}`,{metadataLen:c})}if(a+56>r.byteLength)throw M(`Insufficient data to read geometry header.`,{expectedBytes:56,availableBytes:r.byteLength-a,offset:a});let d=i.getUint32(a,!0);a+=4;let f=i.getFloat64(a,!0);a+=8;let p=i.getFloat64(a,!0);a+=8;let m=i.getFloat64(a,!0);a+=8;let h=i.getFloat64(a,!0);a+=8;let g=i.getFloat64(a,!0);a+=8;let w=i.getFloat64(a,!0);a+=8;let T=i.getUint32(a,!0);a+=4;let E=!!(d&1),D=!!(d&4),O=!!(d&32),k=T*3,A=k*(E?4:2);if(a+A>r.byteLength)throw M(`Insufficient data to read vertices.`,{expectedBytes:A,availableBytes:r.byteLength-a,offset:a,useFloat32:E,vertexCount:T});let j=r.byteOffset+a,N;if(N=E?S(r.buffer,j,k):O?r.subarray(a,a+A):D?C(r.buffer,j,k):x(r.buffer,j,k),a+=A,a+4>r.byteLength)throw M(`Insufficient data to read index count.`,{expectedBytes:4,availableBytes:r.byteLength-a,offset:a});let P=i.getUint32(a,!0);a+=4;let F=!!(d&2),I=P*(F?2:4);if(a+I>r.byteLength)throw M(`Insufficient data to read indices.`,{expectedBytes:I,availableBytes:r.byteLength-a,offset:a,indexCount:P,useUint16Indices:F});let L=O?r.subarray(a,a+I):F?C(r.buffer,r.byteOffset+a,P):ee(r.buffer,r.byteOffset+a,P);a+=I;let R=null;if(d&8){let e=te(r,i,a,T,D,O);R=e.uvs,a=e.offset}let z=null;return d&16&&(z=ne(r,a,T,D)),{metadata:u,flags:d,vertexData:N,indexData:L,isFloat32:E,deltaEncoded:D,planarByteSplit:O,uint16Indices:F,vertexCount:T,origin:[f,p,m],scale:[h,g,w],uvs:R,colors:z}}function ae(e){let{isFloat32:t,deltaEncoded:n,planarByteSplit:r,uint16Indices:i,origin:a,scale:o,uvs:s,colors:c,jobs:l}=e,u=e=>e>>>1^-(e&1),d;if(t)d=e.vertexData;else{let t;if(r){let n=e.vertexData,r=n.length/6;t=new Int16Array(r*3);let i=0,a=0,o=0;for(let e=0;e<r;e++)i=i+u(n[e]|n[r*3+e]<<8)<<16>>16,a=a+u(n[r+e]|n[r*4+e]<<8)<<16>>16,o=o+u(n[r*2+e]|n[r*5+e]<<8)<<16>>16,t[e*3]=i,t[e*3+1]=a,t[e*3+2]=o}else if(n){let n=e.vertexData;t=new Int16Array(n.length);let r=0,i=0,a=0;for(let e=0;e<n.length;e+=3)r=r+u(n[e])<<16>>16,i=i+u(n[e+1])<<16>>16,a=a+u(n[e+2])<<16>>16,t[e]=r,t[e+1]=i,t[e+2]=a}else t=e.vertexData;d=new Float32Array(t.length);let i=a[0],s=a[1],c=a[2],l=o[0],f=o[1],p=o[2];for(let e=0;e<t.length;e+=3)d[e]=i+(t[e]+32767)*l,d[e+1]=s+(t[e+1]+32767)*f,d[e+2]=c+(t[e+2]+32767)*p}let f;if(r){let t=e.indexData;if(i){let e=t.length/2,n=new Uint16Array(e),r=0;for(let i=0;i<e;i++)r=r+u(t[i]|t[e+i]<<8)&65535,n[i]=r;f=n}else{let e=t.length/4,n=new Uint32Array(e),r=0;for(let i=0;i<e;i++){let a=(t[i]|t[e+i]<<8|t[e*2+i]<<16|t[e*3+i]<<24)>>>0;r=r+u(a)>>>0,n[i]=r}f=n}}else if(n){let t=e.indexData;if(t instanceof Uint16Array){let e=new Uint16Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+u(t[r])&65535,e[r]=n;f=e}else{let e=new Uint32Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+u(t[r])>>>0,e[r]=n;f=e}}else f=e.indexData;let p=d.length/3;for(let e=0;e<f.length;e++)if(f[e]>=p)throw Error(`Index ${f[e]} out of range of vertexCount ${p}`);let m=[];for(let e of l){let t=0,n=0;for(let r of e.windows)t+=r.vertexCount,n+=r.indexCount;let r=new Float32Array(t*3),i=new Uint32Array(n),a=s?new Float32Array(t*2):null,o=c?new Uint8Array(t*3):null,l=0,u=0;for(let t of e.windows){let e=t.vertexStart*3;r.set(d.subarray(e,e+t.vertexCount*3),l*3),a&&s&&a.set(s.subarray(t.vertexStart*2,(t.vertexStart+t.vertexCount)*2),l*2),o&&c&&o.set(c.subarray(e,e+t.vertexCount*3),l*3);let n=t.vertexStart,p=t.vertexStart+t.vertexCount,m=l-t.vertexStart;for(let e=0;e<t.indexCount;e++){let r=f[t.indexStart+e];if(r<n||r>=p)throw Error(`Index ${r} outside vertex window [${n}, ${p})`);i[u+e]=r+m}l+=t.vertexCount,u+=t.indexCount}let p=new Float32Array(t*3);for(let e=0;e<i.length;e+=3){let t=i[e]*3,n=i[e+1]*3,a=i[e+2]*3,o=r[a]-r[n],s=r[a+1]-r[n+1],c=r[a+2]-r[n+2],l=r[t]-r[n],u=r[t+1]-r[n+1],d=r[t+2]-r[n+2],f=s*d-c*u,m=c*l-o*d,h=o*u-s*l;p[t]+=f,p[t+1]+=m,p[t+2]+=h,p[n]+=f,p[n+1]+=m,p[n+2]+=h,p[a]+=f,p[a+1]+=m,p[a+2]+=h}for(let e=0;e<p.length;e+=3){let t=p[e],n=p[e+1],r=p[e+2],i=Math.sqrt(t*t+n*n+r*r)||1;p[e]=t/i,p[e+1]=n/i,p[e+2]=r/i}m.push({positions:r,normals:p,indices:i,uvs:a,colors:o})}return m}function oe(){return[`const assemble = ${ae.toString()};`,`self.onmessage = (event) => {`,` const { id, input } = event.data;`,` try {`,` const geometries = assemble(input);`,` const transfer = [];`,` for (const g of geometries) {`,` transfer.push(g.positions.buffer, g.normals.buffer, g.indices.buffer);`,` if (g.uvs) transfer.push(g.uvs.buffer);`,` if (g.colors) transfer.push(g.colors.buffer);`,` }`,` self.postMessage({ id, geometries }, transfer);`,` } catch (error) {`,` self.postMessage({ id, error: String((error && error.message) || error) });`,` }`,`};`].join(`
2
2
  `)}let V;const H=new Map;let se=1;function ce(){if(V!==void 0)return V;if(typeof Worker>`u`||typeof Blob>`u`||typeof URL>`u`||typeof URL.createObjectURL!=`function`)return V=null,null;try{let e=URL.createObjectURL(new Blob([oe()],{type:`text/javascript`})),t=new Worker(e);t.onmessage=e=>{let{id:t,geometries:n,error:r}=e.data,i=H.get(t);i&&(H.delete(t),n?i.resolve(n):i.reject(Error(r??`mesh assembly failed in worker`)))},t.onerror=()=>{for(let e of H.values())e.reject(Error(`mesh assembly worker crashed`));H.clear(),t.terminate(),V=null},V=t}catch{V=null}return V}function le(e,t,n){return new Promise((r,i)=>{let a=se++;H.set(a,{resolve:r,reject:i}),e.postMessage({id:a,input:t},n)})}let U=1;function W(e){U=Math.max(1,e)}t.n(W);function ue(e,r){typeof document>`u`||new n.TextureLoader().load(r,t=>{t.colorSpace=n.SRGBColorSpace,t.anisotropy=U,e.map=t,e.needsUpdate=!0},void 0,e=>{t.c().warn(`Failed to load material texture ${r}:`,e)})}function G(e,r){let i=t.o(e.color),a=r?.vertexColors??!1,o=r?.appearance,s=new n.MeshPhysicalMaterial({color:i,metalness:e.metalness,roughness:e.roughness,opacity:e.opacity,transparent:e.transparent,vertexColors:a,side:o?.cullBackfaces?n.FrontSide:n.DoubleSide,polygonOffset:!0,polygonOffsetFactor:.5,polygonOffsetUnits:.5,depthWrite:!0,depthTest:!0});return o?.envMapIntensity!=null&&(s.envMapIntensity=o.envMapIntensity),e.metalness>.5&&(s.clearcoat=.5,s.clearcoatRoughness=.3),a&&de(s),e.map&&ue(s,e.map),s}function de(e){e.onBeforeCompile=e=>{e.vertexShader=e.vertexShader.replace(`#include <color_vertex>`,`#include <color_vertex>
3
3
  #if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )
4
4
  vColor.rgb = mix(
package/dist/parse.d.cts CHANGED
@@ -2,7 +2,7 @@ import { a as MaterialAppearanceOptions } from "./types-C0V-dIU-.cjs";
2
2
  import * as THREE from "three";
3
3
  //#region src/parse/mesh-policy.d.ts
4
4
  /** Structurally, not nominally, typed as `@selvajs/solve/client`'s `MeshPolicy<THREE.Object3D>` — avoids a dependency on solve. */
5
- declare const meshPolicy: {
5
+ export declare const meshPolicy: {
6
6
  clone(meshes: THREE.Object3D[]): THREE.Object3D[];
7
7
  release(meshes: THREE.Object3D[]): void;
8
8
  };
@@ -165,7 +165,7 @@ interface MeshExtractionOptions {
165
165
  * response). Imperial factors are the exact international definitions. Units missing from this
166
166
  * table scale by 1 and log a one-time warning — see {@link getScaleFactor}.
167
167
  */
168
- declare const SCALE_FACTORS: Record<string, number>;
168
+ export declare const SCALE_FACTORS: Record<string, number>;
169
169
  /**
170
170
  * Extracts display meshes and items from a Grasshopper WebDisplay compute response: decompresses,
171
171
  * scales to meters, and optionally grounds them. Requires the VektorNode Rhino.Compute fork.
@@ -175,7 +175,7 @@ declare const SCALE_FACTORS: Record<string, number>;
175
175
  *
176
176
  * @throws Rethrows unexpected errors after attempting to dispose any created meshes.
177
177
  */
178
- declare function getThreeObjectsFromComputeResponse(data: GrasshopperComputeResponse, options?: MeshExtractionOptions): Promise<THREE.Object3D[]>;
178
+ export declare function getThreeObjectsFromComputeResponse(data: GrasshopperComputeResponse, options?: MeshExtractionOptions): Promise<THREE.Object3D[]>;
179
179
  //#endregion
180
180
  //#region src/parse/webdisplay/batch-parser.d.ts
181
181
  interface ParseTelemetry {
@@ -190,7 +190,7 @@ interface ParseTelemetry {
190
190
  *
191
191
  * @throws {VisualizationError} On a corrupt/truncated/unsupported mesh blob or malformed group metadata.
192
192
  */
193
- declare function parseMeshBatchObject(batch: DisplayBatch, options?: MeshBatchParsingOptions,
193
+ export declare function parseMeshBatchObject(batch: DisplayBatch, options?: MeshBatchParsingOptions,
194
194
  /** @internal Timings threaded from an outer entry point — not a caller option. */
195
195
  telemetry?: ParseTelemetry): Promise<THREE.Mesh[]>;
196
196
  /**
@@ -202,7 +202,7 @@ telemetry?: ParseTelemetry): Promise<THREE.Mesh[]>;
202
202
  *
203
203
  * @throws {VisualizationError} On a corrupt/truncated/unsupported mesh blob or malformed group metadata.
204
204
  */
205
- declare function parseMeshBatchBlob(blob: ArrayBuffer | Uint8Array, options?: MeshBatchParsingOptions): Promise<THREE.Mesh[]>;
205
+ export declare function parseMeshBatchBlob(blob: ArrayBuffer | Uint8Array, options?: MeshBatchParsingOptions): Promise<THREE.Mesh[]>;
206
206
  //#endregion
207
207
  //#region src/parse/webdisplay/apply-texture.d.ts
208
208
  /**
@@ -210,7 +210,7 @@ declare function parseMeshBatchBlob(blob: ArrayBuffer | Uint8Array, options?: Me
210
210
  * host embedding a foreign renderer that wants to set it directly. Applies to textures loaded from
211
211
  * here on — textures already decoded keep the value they were given.
212
212
  */
213
- declare function setTextureAnisotropy(value: number): void;
213
+ export declare function setTextureAnisotropy(value: number): void;
214
214
  //#endregion
215
215
  //#region src/parse/display-items/display-items-parser.d.ts
216
216
  /**
@@ -220,7 +220,7 @@ declare function setTextureAnisotropy(value: number): void;
220
220
  * surfaces as an actionable error instead of a scene quietly missing its curves. Every other
221
221
  * unrenderable item is logged and skipped.
222
222
  */
223
- declare function parseDisplayItems(items: DisplayItem[] | undefined): THREE.Object3D[];
223
+ export declare function parseDisplayItems(items: DisplayItem[] | undefined): THREE.Object3D[];
224
224
  //#endregion
225
- export { type DisplayBatch, type DisplayCurve, type DisplayIdentity, type DisplayItem, type DisplayItemBase, type DisplayPoint, type DisplayPosition, type MaterialGroup, type MeshBatchParsingOptions, type MeshExtractionOptions, type MeshMetadata, SCALE_FACTORS, type SerializableMaterial, getThreeObjectsFromComputeResponse, meshPolicy, parseDisplayItems, parseMeshBatchBlob, parseMeshBatchObject, setTextureAnisotropy };
225
+ export type { DisplayBatch, DisplayCurve, DisplayIdentity, DisplayItem, DisplayItemBase, DisplayPoint, DisplayPosition, MaterialGroup, MeshBatchParsingOptions, MeshExtractionOptions, MeshMetadata, SerializableMaterial };
226
226
  //# sourceMappingURL=parse.d.cts.map
package/dist/parse.d.ts CHANGED
@@ -2,7 +2,7 @@ import { a as MaterialAppearanceOptions } from "./types-C0V-dIU-.js";
2
2
  import * as THREE from "three";
3
3
  //#region src/parse/mesh-policy.d.ts
4
4
  /** Structurally, not nominally, typed as `@selvajs/solve/client`'s `MeshPolicy<THREE.Object3D>` — avoids a dependency on solve. */
5
- declare const meshPolicy: {
5
+ export declare const meshPolicy: {
6
6
  clone(meshes: THREE.Object3D[]): THREE.Object3D[];
7
7
  release(meshes: THREE.Object3D[]): void;
8
8
  };
@@ -165,7 +165,7 @@ interface MeshExtractionOptions {
165
165
  * response). Imperial factors are the exact international definitions. Units missing from this
166
166
  * table scale by 1 and log a one-time warning — see {@link getScaleFactor}.
167
167
  */
168
- declare const SCALE_FACTORS: Record<string, number>;
168
+ export declare const SCALE_FACTORS: Record<string, number>;
169
169
  /**
170
170
  * Extracts display meshes and items from a Grasshopper WebDisplay compute response: decompresses,
171
171
  * scales to meters, and optionally grounds them. Requires the VektorNode Rhino.Compute fork.
@@ -175,7 +175,7 @@ declare const SCALE_FACTORS: Record<string, number>;
175
175
  *
176
176
  * @throws Rethrows unexpected errors after attempting to dispose any created meshes.
177
177
  */
178
- declare function getThreeObjectsFromComputeResponse(data: GrasshopperComputeResponse, options?: MeshExtractionOptions): Promise<THREE.Object3D[]>;
178
+ export declare function getThreeObjectsFromComputeResponse(data: GrasshopperComputeResponse, options?: MeshExtractionOptions): Promise<THREE.Object3D[]>;
179
179
  //#endregion
180
180
  //#region src/parse/webdisplay/batch-parser.d.ts
181
181
  interface ParseTelemetry {
@@ -190,7 +190,7 @@ interface ParseTelemetry {
190
190
  *
191
191
  * @throws {VisualizationError} On a corrupt/truncated/unsupported mesh blob or malformed group metadata.
192
192
  */
193
- declare function parseMeshBatchObject(batch: DisplayBatch, options?: MeshBatchParsingOptions,
193
+ export declare function parseMeshBatchObject(batch: DisplayBatch, options?: MeshBatchParsingOptions,
194
194
  /** @internal Timings threaded from an outer entry point — not a caller option. */
195
195
  telemetry?: ParseTelemetry): Promise<THREE.Mesh[]>;
196
196
  /**
@@ -202,7 +202,7 @@ telemetry?: ParseTelemetry): Promise<THREE.Mesh[]>;
202
202
  *
203
203
  * @throws {VisualizationError} On a corrupt/truncated/unsupported mesh blob or malformed group metadata.
204
204
  */
205
- declare function parseMeshBatchBlob(blob: ArrayBuffer | Uint8Array, options?: MeshBatchParsingOptions): Promise<THREE.Mesh[]>;
205
+ export declare function parseMeshBatchBlob(blob: ArrayBuffer | Uint8Array, options?: MeshBatchParsingOptions): Promise<THREE.Mesh[]>;
206
206
  //#endregion
207
207
  //#region src/parse/webdisplay/apply-texture.d.ts
208
208
  /**
@@ -210,7 +210,7 @@ declare function parseMeshBatchBlob(blob: ArrayBuffer | Uint8Array, options?: Me
210
210
  * host embedding a foreign renderer that wants to set it directly. Applies to textures loaded from
211
211
  * here on — textures already decoded keep the value they were given.
212
212
  */
213
- declare function setTextureAnisotropy(value: number): void;
213
+ export declare function setTextureAnisotropy(value: number): void;
214
214
  //#endregion
215
215
  //#region src/parse/display-items/display-items-parser.d.ts
216
216
  /**
@@ -220,7 +220,7 @@ declare function setTextureAnisotropy(value: number): void;
220
220
  * surfaces as an actionable error instead of a scene quietly missing its curves. Every other
221
221
  * unrenderable item is logged and skipped.
222
222
  */
223
- declare function parseDisplayItems(items: DisplayItem[] | undefined): THREE.Object3D[];
223
+ export declare function parseDisplayItems(items: DisplayItem[] | undefined): THREE.Object3D[];
224
224
  //#endregion
225
- export { type DisplayBatch, type DisplayCurve, type DisplayIdentity, type DisplayItem, type DisplayItemBase, type DisplayPoint, type DisplayPosition, type MaterialGroup, type MeshBatchParsingOptions, type MeshExtractionOptions, type MeshMetadata, SCALE_FACTORS, type SerializableMaterial, getThreeObjectsFromComputeResponse, meshPolicy, parseDisplayItems, parseMeshBatchBlob, parseMeshBatchObject, setTextureAnisotropy };
225
+ export type { DisplayBatch, DisplayCurve, DisplayIdentity, DisplayItem, DisplayItemBase, DisplayPoint, DisplayPosition, MaterialGroup, MeshBatchParsingOptions, MeshExtractionOptions, MeshMetadata, SerializableMaterial };
226
226
  //# sourceMappingURL=parse.d.ts.map
package/dist/parse.js CHANGED
@@ -1,4 +1,4 @@
1
- import{a as e,c as t,d as n,i as r,n as i,o as a,t as o,u as s}from"./gpu-dispose-Dkj-BKt4.js";import*as c from"three";import{Line2 as l}from"three/addons/lines/Line2.js";import{LineGeometry as u}from"three/addons/lines/LineGeometry.js";import{LineMaterial as d}from"three/addons/lines/LineMaterial.js";import{inflateSync as f}from"fflate";function p(){let e=globalThis.Buffer;return typeof e==`function`?e:void 0}function m(e){let t=e.replace(/[\t\n\f\r ]/g,``);if(t.length%4==0&&(t=t.replace(/={1,2}$/,``)),t.length%4==1||!/^[A-Za-z0-9+/]*$/.test(t))throw new n(`Invalid base64 input.`,s.ENCODING_ERROR,{context:{inputLength:e.length}});let r=p();if(r)return new Uint8Array(r.from(t,`base64`));if(typeof globalThis.atob==`function`){let e=globalThis.atob(t),n=new Uint8Array(e.length);for(let t=0;t<e.length;t++)n[t]=e.charCodeAt(t)&255;return n}throw new n(`Base64 decoding not supported in this environment.`,s.INVALID_STATE,{context:{environmentInfo:`atob or Buffer not available`}})}function h(e){return e.map(e=>{let t=e.clone(!0),n=[];e.traverse(e=>n.push(e));let r=0;return t.traverse(e=>{let t=n[r++],i=e;t.geometry&&(i.geometry=t.geometry.clone())}),t})}function g(e){e.forEach(e=>o(e,{materials:!1}))}const _={clone:h,release:g};function v(e,t){let n=t??1;return{color:new c.Color(e??`#ffffff`),transparent:n<1,opacity:n}}function y(e){let t=b(e);if(!t)return null;let n=new u;n.setPositions(t);let r=v(e.color,e.opacity),i=new d({color:r.color}),a=i;a.linewidth=e.width??2,a.transparent=r.transparent,a.opacity=r.opacity;let o=new l(n,i);return o.computeLineDistances(),o.name=e.name,o.userData={source:`compute`,id:e.id,layer:e.layer,kind:`curve`,metadata:e.metadata},o}function b(e){if(!e.points)throw new n(`Curve display item '${e.id}' has no tessellated points. It was produced by an outdated Display component — upgrade it in Grasshopper (Solution → Upgrade obsolete components) and re-save the definition.`,s.INVALID_CONFIG,{context:{itemId:e.id,kind:e.kind}});return e.points.length>=6?e.points:null}function x(e){let{position:n}=e;if(!n||typeof n.X!=`number`||!Number.isFinite(n.X)||typeof n.Y!=`number`||!Number.isFinite(n.Y)||typeof n.Z!=`number`||!Number.isFinite(n.Z))return t().warn(`Skipping point display item with missing or non-finite position (id: ${String(e.id)}).`),null;let r=new c.BufferGeometry;r.setAttribute(`position`,new c.Float32BufferAttribute([n.X,n.Y,n.Z],3));let i=new c.PointsMaterial({...v(e.color,e.opacity),size:6,sizeAttenuation:!1}),a=new c.Points(r,i);return a.name=e.name,a.userData={source:`compute`,id:e.id,layer:e.layer,kind:`point`,metadata:e.metadata},a}function S(e){if(!e||e.length===0)return[];let n=[];for(let r of e)switch(r.kind){case`curve`:{let e=y(r);e&&n.push(e);break}case`point`:{let e=x(r);e&&n.push(e);break}default:{let e=r;t().warn(`Skipping unknown display item kind: ${String(e.kind)}`);break}}return n}const ee=new Uint16Array(new Uint8Array([1,0]).buffer)[0]===1;function te(e){return typeof e==`string`?m(e):e instanceof Uint8Array?e:new Uint8Array(e)}function C(e){if(e.byteLength<8)return e;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(t.getUint32(0,!0)!==1515605075)return e;let n=t.getUint32(4,!0),r=e.subarray(8),i=Math.max(r.byteLength*1032+1024,1<<20);if(n>i)throw P(`SLVZ header declares an implausible uncompressed length`,{uncompressedLen:n,deflatedBytes:r.byteLength,maxPlausibleLen:i});let a;try{a=f(r,{out:new Uint8Array(n+1)})}catch(e){throw P(`Failed to inflate SLVZ blob: ${e instanceof Error?e.message:String(e)}`,{uncompressedLen:n,deflatedBytes:r.byteLength})}if(a.byteLength!==n)throw P(`SLVZ payload inflated to a different size than the header declares.`,{declaredLen:n,actualLen:a.byteLength,deflatedBytes:r.byteLength});return a}function w(e){if(typeof TextDecoder<`u`)return new TextDecoder(`utf-8`).decode(e);if(globalThis.Buffer!==void 0)return globalThis.Buffer.from(e).toString(`utf-8`);throw new n(`No UTF-8 decoder available in this environment.`,s.INVALID_STATE)}function ne(e,t,n){if(n===0)return new Int16Array;if(t%2==0)return new Int16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Int16Array(r.buffer)}function re(e,t,n){if(n===0)return new Float32Array;if(t%4==0)return new Float32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Float32Array(r.buffer)}function T(e,t,n){if(n===0)return new Uint16Array;if(t%2==0)return new Uint16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Uint16Array(r.buffer)}function ie(e,t,n){if(n===0)return new Uint32Array;if(t%4==0)return new Uint32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Uint32Array(r.buffer)}function E(e,t){if(e.length!==0&&!(e instanceof Uint16Array&&t>65535)){for(let n=0;n<e.length;n++)if(e[n]>=t)throw P(`Index out of range of vertexCount.`,{indexPosition:n,indexValue:e[n],vertexCount:t})}}function D(e){return e>>>1^-(e&1)}function O(e){let t=new Int16Array(e.length),n=0,r=0,i=0;for(let a=0;a<e.length;a+=3)n=n+D(e[a])<<16>>16,r=r+D(e[a+1])<<16>>16,i=i+D(e[a+2])<<16>>16,t[a]=n,t[a+1]=r,t[a+2]=i;return t}function k(e,t){let n=new Int16Array(t*3),r=t,i=0,a=0,o=0;for(let t=0;t<r;t++)i=i+D(e[t]|e[r*3+t]<<8)<<16>>16,a=a+D(e[r+t]|e[r*4+t]<<8)<<16>>16,o=o+D(e[r*2+t]|e[r*5+t]<<8)<<16>>16,n[t*3]=i,n[t*3+1]=a,n[t*3+2]=o;return n}function A(e,t){let n=new Uint16Array(t),r=0;for(let i=0;i<t;i++)r=r+D(e[i]|e[t+i]<<8)&65535,n[i]=r;return n}function j(e,t){let n=new Uint32Array(t),r=0;for(let i=0;i<t;i++){let a=(e[i]|e[t+i]<<8|e[t*2+i]<<16|e[t*3+i]<<24)>>>0;r=r+D(a)>>>0,n[i]=r}return n}function M(e){let t=new Uint16Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+D(e[r])&65535,t[r]=n;return t}function N(e){let t=new Uint32Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+D(e[r])>>>0,t[r]=n;return t}function P(e,t){return new n(e,s.VALIDATION_ERROR,{context:t})}function ae(e,t,n,r,i,a=!1){if(n+36>e.byteLength)throw P(`Insufficient data to read UV chunk header.`,{expectedBytes:36,availableBytes:e.byteLength-n,offset:n});let o=t.getUint32(n,!0);n+=4;let s=t.getFloat64(n,!0);n+=8;let c=t.getFloat64(n,!0);n+=8;let l=t.getFloat64(n,!0);n+=8;let u=t.getFloat64(n,!0);n+=8;let d=r*2,f=o===1,p=d*(f?4:2);if(n+p>e.byteLength)throw P(`Insufficient data to read UV chunk.`,{expectedBytes:p,availableBytes:e.byteLength-n,offset:n,uvFormat:o,vertexCount:r});let m=e.byteOffset+n,h;if(f)h=re(e.buffer,m,d).slice();else if(a){let t=e.subarray(n,n+p),i=r;h=new Float32Array(d);let a=0,o=0;for(let e=0;e<i;e++)a=a+D(t[e]|t[i*2+e]<<8)&65535,o=o+D(t[i+e]|t[i*3+e]<<8)&65535,h[e*2]=s+a*l,h[e*2+1]=c+o*u}else{let t=T(e.buffer,m,d);h=new Float32Array(d);let n=0,r=0;for(let e=0;e<d;e+=2)i?(n=n+D(t[e])&65535,r=r+D(t[e+1])&65535):(n=t[e],r=t[e+1]),h[e]=s+n*l,h[e+1]=c+r*u}return{uvs:h,offset:n+p}}function oe(e,t,n,r){let i=n*3;if(t+i>e.byteLength)throw P(`Insufficient data to read vertex-color chunk.`,{expectedBytes:i,availableBytes:e.byteLength-t,offset:t,vertexCount:n});let a=e.subarray(t,t+i);if(!r)return a.slice();let o=new Uint8Array(i),s=0,c=0,l=0;for(let e=0;e<i;e+=3)s=s+D(a[e])&255,c=c+D(a[e+1])&255,l=l+D(a[e+2])&255,o[e]=s,o[e+1]=c,o[e+2]=l;return o}function se(e){return e.byteLength>=4&&new DataView(e.buffer,e.byteOffset,4).getUint32(0,!0)===1297501267}function ce(e){let t=F(e),n=null,r=null,i=null,a=[];for(let{type:e,payload:o}of t)switch(e){case 1297040711:n=o;break;case 1279410516:r=C(o);break;case 1280590157:i=w(o);break;case 1381516628:a.push(o)}if(n===null)throw P(`SLVM container has no GEOM chunk.`,{chunkCount:t.length});if(r===null)throw P(`SLVM container has no TABL chunk.`,{chunkCount:t.length});let{groups:o}=le(r),s=ue(i,a);return{geometryBlob:n,metadata:{materials:s,groups:o}}}function F(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(e.byteLength<12||t.getUint32(0,!0)!==1297501267)throw P(`Not an SLVM container (bad magic).`,{byteLength:e.byteLength});let n=t.getUint32(4,!0);if(n!==3)throw P(`Unsupported SLVM version: ${n}`,{expectedVersion:3});let r=t.getUint32(8,!0),i=[],a=12;for(let n=0;n<r;n++){if(a+8>e.byteLength)throw P(`Truncated SLVM chunk header.`,{offset:a,chunkIndex:n});let r=t.getUint32(a,!0),o=t.getUint32(a+4,!0);if(a+=8,a+o>e.byteLength)throw P(`Truncated SLVM chunk payload.`,{offset:a,chunkIndex:n,byteLen:o});i.push({type:r,payload:e.subarray(a,a+o)}),a+=o+(4-o%4)%4}return i}function I(e){let t=0,n=0;for(;;){if(e.pos>=e.bytes.byteLength||n>28)throw P(`Malformed varint in SLVM table.`,{pos:e.pos});let r=e.bytes[e.pos++];if(t|=(r&127)<<n,!(r&128))return t>>>0;n+=7}}function L(e,t,n){let r=e.bytes[e.pos++],i=Array(t);switch(r){case 0:i.fill(``);break;case 1:for(let e=0;e<t;e++)i[e]=String(e+1);break;case 2:for(let r=0;r<t;r++)i[r]=n[I(e)]??``;break;default:throw P(`Unknown SLVM string column mode: ${r}`,{pos:e.pos})}return i}function le(e){let t={bytes:e,pos:0},n=I(t),r=I(t),i=I(t),a=n+r+i,o=I(t),s=Array(o);for(let n=0;n<o;n++){let r=I(t);s[n]=w(e.subarray(t.pos,t.pos+r)),t.pos+=r}let c=Array(n),l=Array(n);for(let e=0;e<n;e++)c[e]=I(t),l[e]=I(t);for(let e=0;e<r;e++)I(t);let u=I(t),d=[];for(let e=0;e<u;e++)d.push({materialId:I(t),meshCount:I(t)});let f=L(t,a,s),p=L(t,a,s),m=Array(a),h=I(t);for(let e=0;e<h;e++){let e=s[I(t)]??``,n=I(t),r=Array(n),i=0;for(let e=0;e<n;e++)i+=I(t),r[e]=i;for(let i=0;i<n;i++){let n=s[I(t)]??``,a=r[i];(m[a]??={})[e]=n}}let g=d.length>0||n===0?d:[{materialId:0,meshCount:n}],_=[],v=0,y=0,b=0;for(let e of g){let t=[];for(let r=0;r<e.meshCount&&v<n;r++,v++){let e=m[v],n=e?.id;e!==void 0&&delete e.id,t.push({id:n,name:f[v],layer:p[v],vertexCount:c[v],indexCount:l[v]*3,vertexStart:y,indexStart:b,metadata:e??{}}),y+=c[v],b+=l[v]*3}_.push({materialId:e.materialId,meshes:t})}return{groups:_}}function ue(e,t){if(e===null)return[];let n;try{n=JSON.parse(e).materials??[]}catch(t){throw P(`Failed to parse SLVM materials JSON: ${t instanceof Error?t.message:String(t)}`,{byteLength:e.length})}for(let e of n)if(e.map?.startsWith(`slvm:tex:`)){let n=t[Number(e.map.slice(9))];n!==void 0&&(e.map=de(n))}return n}function de(e){let t={bytes:e,pos:0},n=I(t),r=w(e.subarray(t.pos,t.pos+n)),i=e.subarray(t.pos+n),a=``,o=32768;for(let e=0;e<i.byteLength;e+=o)a+=String.fromCharCode(...i.subarray(e,e+o));return`data:${r};base64,${btoa(a)}`}function R(e){let t=z(e),n;n=t.isFloat32?t.vertexData:t.planarByteSplit?k(t.vertexData,t.vertexCount):t.deltaEncoded?O(t.vertexData):t.vertexData;let r;if(t.planarByteSplit){let e=t.indexData;r=t.uint16Indices?A(e,e.length/2):j(e,e.length/4)}else r=t.deltaEncoded?t.indexData instanceof Uint16Array?M(t.indexData):N(t.indexData):t.indexData;return E(r,t.vertexCount),{metadata:t.metadata,flags:t.flags,vertices:n,indices:r,origin:t.origin,scale:t.scale,uvs:t.uvs,colors:t.colors}}function z(e){if(!ee)throw new n(`SLVA parsing requires a little-endian host: the zero-copy geometry readers view the wire bytes in host byte order.`,s.ENVIRONMENT_ERROR);let t=te(e);if(se(t)){let e=ce(t),n=z(e.geometryBlob);return n.metadata=e.metadata,n}let r=C(t),i=new DataView(r.buffer,r.byteOffset,r.byteLength);if(r.byteLength<12)throw P(`Blob too small to contain SLVA header.`,{expectedBytes:12,availableBytes:r.byteLength});let a=0,o=i.getUint32(a,!0);if(a+=4,o!==1096174675)throw P(`Invalid SLVA magic: 0x${o.toString(16)}`,{expectedMagic:`0x41564c53`,actualMagic:`0x${o.toString(16)}`});let c=i.getUint32(a,!0);if(a+=4,c<1||c>4)throw P(`Unsupported SLVA version: ${c}`,{minSupportedVersion:1,maxSupportedVersion:4,actualVersion:c});let l=i.getUint32(a,!0);if(a+=4,a+l>r.byteLength)throw P(`Insufficient data to read metadata JSON.`,{expectedBytes:l,availableBytes:r.byteLength-a,offset:a});let u=r.subarray(a,a+l);a+=l;let d;try{d=l===0?{}:JSON.parse(w(u))}catch(e){throw P(`Failed to parse metadata JSON: ${e instanceof Error?e.message:String(e)}`,{metadataLen:l})}if(a+56>r.byteLength)throw P(`Insufficient data to read geometry header.`,{expectedBytes:56,availableBytes:r.byteLength-a,offset:a});let f=i.getUint32(a,!0);a+=4;let p=i.getFloat64(a,!0);a+=8;let m=i.getFloat64(a,!0);a+=8;let h=i.getFloat64(a,!0);a+=8;let g=i.getFloat64(a,!0);a+=8;let _=i.getFloat64(a,!0);a+=8;let v=i.getFloat64(a,!0);a+=8;let y=i.getUint32(a,!0);a+=4;let b=!!(f&1),x=!!(f&4),S=!!(f&32),E=y*3,D=E*(b?4:2);if(a+D>r.byteLength)throw P(`Insufficient data to read vertices.`,{expectedBytes:D,availableBytes:r.byteLength-a,offset:a,useFloat32:b,vertexCount:y});let O=r.byteOffset+a,k;if(k=b?re(r.buffer,O,E):S?r.subarray(a,a+D):x?T(r.buffer,O,E):ne(r.buffer,O,E),a+=D,a+4>r.byteLength)throw P(`Insufficient data to read index count.`,{expectedBytes:4,availableBytes:r.byteLength-a,offset:a});let A=i.getUint32(a,!0);a+=4;let j=!!(f&2),M=A*(j?2:4);if(a+M>r.byteLength)throw P(`Insufficient data to read indices.`,{expectedBytes:M,availableBytes:r.byteLength-a,offset:a,indexCount:A,useUint16Indices:j});let N=S?r.subarray(a,a+M):j?T(r.buffer,r.byteOffset+a,A):ie(r.buffer,r.byteOffset+a,A);a+=M;let F=null;if(f&8){let e=ae(r,i,a,y,x,S);F=e.uvs,a=e.offset}let I=null;return f&16&&(I=oe(r,a,y,x)),{metadata:d,flags:f,vertexData:k,indexData:N,isFloat32:b,deltaEncoded:x,planarByteSplit:S,uint16Indices:j,vertexCount:y,origin:[p,m,h],scale:[g,_,v],uvs:F,colors:I}}function fe(e){let{isFloat32:t,deltaEncoded:n,planarByteSplit:r,uint16Indices:i,origin:a,scale:o,uvs:s,colors:c,jobs:l}=e,u=e=>e>>>1^-(e&1),d;if(t)d=e.vertexData;else{let t;if(r){let n=e.vertexData,r=n.length/6;t=new Int16Array(r*3);let i=0,a=0,o=0;for(let e=0;e<r;e++)i=i+u(n[e]|n[r*3+e]<<8)<<16>>16,a=a+u(n[r+e]|n[r*4+e]<<8)<<16>>16,o=o+u(n[r*2+e]|n[r*5+e]<<8)<<16>>16,t[e*3]=i,t[e*3+1]=a,t[e*3+2]=o}else if(n){let n=e.vertexData;t=new Int16Array(n.length);let r=0,i=0,a=0;for(let e=0;e<n.length;e+=3)r=r+u(n[e])<<16>>16,i=i+u(n[e+1])<<16>>16,a=a+u(n[e+2])<<16>>16,t[e]=r,t[e+1]=i,t[e+2]=a}else t=e.vertexData;d=new Float32Array(t.length);let i=a[0],s=a[1],c=a[2],l=o[0],f=o[1],p=o[2];for(let e=0;e<t.length;e+=3)d[e]=i+(t[e]+32767)*l,d[e+1]=s+(t[e+1]+32767)*f,d[e+2]=c+(t[e+2]+32767)*p}let f;if(r){let t=e.indexData;if(i){let e=t.length/2,n=new Uint16Array(e),r=0;for(let i=0;i<e;i++)r=r+u(t[i]|t[e+i]<<8)&65535,n[i]=r;f=n}else{let e=t.length/4,n=new Uint32Array(e),r=0;for(let i=0;i<e;i++){let a=(t[i]|t[e+i]<<8|t[e*2+i]<<16|t[e*3+i]<<24)>>>0;r=r+u(a)>>>0,n[i]=r}f=n}}else if(n){let t=e.indexData;if(t instanceof Uint16Array){let e=new Uint16Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+u(t[r])&65535,e[r]=n;f=e}else{let e=new Uint32Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+u(t[r])>>>0,e[r]=n;f=e}}else f=e.indexData;let p=d.length/3;for(let e=0;e<f.length;e++)if(f[e]>=p)throw Error(`Index ${f[e]} out of range of vertexCount ${p}`);let m=[];for(let e of l){let t=0,n=0;for(let r of e.windows)t+=r.vertexCount,n+=r.indexCount;let r=new Float32Array(t*3),i=new Uint32Array(n),a=s?new Float32Array(t*2):null,o=c?new Uint8Array(t*3):null,l=0,u=0;for(let t of e.windows){let e=t.vertexStart*3;r.set(d.subarray(e,e+t.vertexCount*3),l*3),a&&s&&a.set(s.subarray(t.vertexStart*2,(t.vertexStart+t.vertexCount)*2),l*2),o&&c&&o.set(c.subarray(e,e+t.vertexCount*3),l*3);let n=t.vertexStart,p=t.vertexStart+t.vertexCount,m=l-t.vertexStart;for(let e=0;e<t.indexCount;e++){let r=f[t.indexStart+e];if(r<n||r>=p)throw Error(`Index ${r} outside vertex window [${n}, ${p})`);i[u+e]=r+m}l+=t.vertexCount,u+=t.indexCount}let p=new Float32Array(t*3);for(let e=0;e<i.length;e+=3){let t=i[e]*3,n=i[e+1]*3,a=i[e+2]*3,o=r[a]-r[n],s=r[a+1]-r[n+1],c=r[a+2]-r[n+2],l=r[t]-r[n],u=r[t+1]-r[n+1],d=r[t+2]-r[n+2],f=s*d-c*u,m=c*l-o*d,h=o*u-s*l;p[t]+=f,p[t+1]+=m,p[t+2]+=h,p[n]+=f,p[n+1]+=m,p[n+2]+=h,p[a]+=f,p[a+1]+=m,p[a+2]+=h}for(let e=0;e<p.length;e+=3){let t=p[e],n=p[e+1],r=p[e+2],i=Math.sqrt(t*t+n*n+r*r)||1;p[e]=t/i,p[e+1]=n/i,p[e+2]=r/i}m.push({positions:r,normals:p,indices:i,uvs:a,colors:o})}return m}function pe(){return[`const assemble = ${fe.toString()};`,`self.onmessage = (event) => {`,` const { id, input } = event.data;`,` try {`,` const geometries = assemble(input);`,` const transfer = [];`,` for (const g of geometries) {`,` transfer.push(g.positions.buffer, g.normals.buffer, g.indices.buffer);`,` if (g.uvs) transfer.push(g.uvs.buffer);`,` if (g.colors) transfer.push(g.colors.buffer);`,` }`,` self.postMessage({ id, geometries }, transfer);`,` } catch (error) {`,` self.postMessage({ id, error: String((error && error.message) || error) });`,` }`,`};`].join(`
1
+ import{a as e,c as t,d as n,i as r,n as i,o as a,t as o,u as s}from"./gpu-dispose-Cm4qCZiL.js";import*as c from"three";import{Line2 as l}from"three/addons/lines/Line2.js";import{LineGeometry as u}from"three/addons/lines/LineGeometry.js";import{LineMaterial as d}from"three/addons/lines/LineMaterial.js";import{inflateSync as f}from"fflate";function p(){let e=globalThis.Buffer;return typeof e==`function`?e:void 0}function m(e){let t=e.replace(/[\t\n\f\r ]/g,``);if(t.length%4==0&&(t=t.replace(/={1,2}$/,``)),t.length%4==1||!/^[A-Za-z0-9+/]*$/.test(t))throw new n(`Invalid base64 input.`,s.ENCODING_ERROR,{context:{inputLength:e.length}});let r=p();if(r)return new Uint8Array(r.from(t,`base64`));if(typeof globalThis.atob==`function`){let e=globalThis.atob(t),n=new Uint8Array(e.length);for(let t=0;t<e.length;t++)n[t]=e.charCodeAt(t)&255;return n}throw new n(`Base64 decoding not supported in this environment.`,s.INVALID_STATE,{context:{environmentInfo:`atob or Buffer not available`}})}function h(e){return e.map(e=>{let t=e.clone(!0),n=[];e.traverse(e=>n.push(e));let r=0;return t.traverse(e=>{let t=n[r++],i=e;t.geometry&&(i.geometry=t.geometry.clone())}),t})}function g(e){e.forEach(e=>o(e,{materials:!1}))}const _={clone:h,release:g};function v(e,t){let n=t??1;return{color:new c.Color(e??`#ffffff`),transparent:n<1,opacity:n}}function y(e){let t=b(e);if(!t)return null;let n=new u;n.setPositions(t);let r=v(e.color,e.opacity),i=new d({color:r.color}),a=i;a.linewidth=e.width??2,a.transparent=r.transparent,a.opacity=r.opacity;let o=new l(n,i);return o.computeLineDistances(),o.name=e.name,o.userData={source:`compute`,id:e.id,layer:e.layer,kind:`curve`,metadata:e.metadata},o}function b(e){if(!e.points)throw new n(`Curve display item '${e.id}' has no tessellated points. It was produced by an outdated Display component — upgrade it in Grasshopper (Solution → Upgrade obsolete components) and re-save the definition.`,s.INVALID_CONFIG,{context:{itemId:e.id,kind:e.kind}});return e.points.length>=6?e.points:null}function x(e){let{position:n}=e;if(!n||typeof n.X!=`number`||!Number.isFinite(n.X)||typeof n.Y!=`number`||!Number.isFinite(n.Y)||typeof n.Z!=`number`||!Number.isFinite(n.Z))return t().warn(`Skipping point display item with missing or non-finite position (id: ${String(e.id)}).`),null;let r=new c.BufferGeometry;r.setAttribute(`position`,new c.Float32BufferAttribute([n.X,n.Y,n.Z],3));let i=new c.PointsMaterial({...v(e.color,e.opacity),size:6,sizeAttenuation:!1}),a=new c.Points(r,i);return a.name=e.name,a.userData={source:`compute`,id:e.id,layer:e.layer,kind:`point`,metadata:e.metadata},a}function S(e){if(!e||e.length===0)return[];let n=[];for(let r of e)switch(r.kind){case`curve`:{let e=y(r);e&&n.push(e);break}case`point`:{let e=x(r);e&&n.push(e);break}default:{let e=r;t().warn(`Skipping unknown display item kind: ${String(e.kind)}`);break}}return n}const ee=new Uint16Array(new Uint8Array([1,0]).buffer)[0]===1;function te(e){return typeof e==`string`?m(e):e instanceof Uint8Array?e:new Uint8Array(e)}function C(e){if(e.byteLength<8)return e;let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(t.getUint32(0,!0)!==1515605075)return e;let n=t.getUint32(4,!0),r=e.subarray(8),i=Math.max(r.byteLength*1032+1024,1<<20);if(n>i)throw P(`SLVZ header declares an implausible uncompressed length`,{uncompressedLen:n,deflatedBytes:r.byteLength,maxPlausibleLen:i});let a;try{a=f(r,{out:new Uint8Array(n+1)})}catch(e){throw P(`Failed to inflate SLVZ blob: ${e instanceof Error?e.message:String(e)}`,{uncompressedLen:n,deflatedBytes:r.byteLength})}if(a.byteLength!==n)throw P(`SLVZ payload inflated to a different size than the header declares.`,{declaredLen:n,actualLen:a.byteLength,deflatedBytes:r.byteLength});return a}function w(e){if(typeof TextDecoder<`u`)return new TextDecoder(`utf-8`).decode(e);if(globalThis.Buffer!==void 0)return globalThis.Buffer.from(e).toString(`utf-8`);throw new n(`No UTF-8 decoder available in this environment.`,s.INVALID_STATE)}function ne(e,t,n){if(n===0)return new Int16Array;if(t%2==0)return new Int16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Int16Array(r.buffer)}function re(e,t,n){if(n===0)return new Float32Array;if(t%4==0)return new Float32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Float32Array(r.buffer)}function T(e,t,n){if(n===0)return new Uint16Array;if(t%2==0)return new Uint16Array(e,t,n);let r=new Uint8Array(n*2);return r.set(new Uint8Array(e,t,n*2)),new Uint16Array(r.buffer)}function ie(e,t,n){if(n===0)return new Uint32Array;if(t%4==0)return new Uint32Array(e,t,n);let r=new Uint8Array(n*4);return r.set(new Uint8Array(e,t,n*4)),new Uint32Array(r.buffer)}function E(e,t){if(e.length!==0&&!(e instanceof Uint16Array&&t>65535)){for(let n=0;n<e.length;n++)if(e[n]>=t)throw P(`Index out of range of vertexCount.`,{indexPosition:n,indexValue:e[n],vertexCount:t})}}function D(e){return e>>>1^-(e&1)}function O(e){let t=new Int16Array(e.length),n=0,r=0,i=0;for(let a=0;a<e.length;a+=3)n=n+D(e[a])<<16>>16,r=r+D(e[a+1])<<16>>16,i=i+D(e[a+2])<<16>>16,t[a]=n,t[a+1]=r,t[a+2]=i;return t}function k(e,t){let n=new Int16Array(t*3),r=t,i=0,a=0,o=0;for(let t=0;t<r;t++)i=i+D(e[t]|e[r*3+t]<<8)<<16>>16,a=a+D(e[r+t]|e[r*4+t]<<8)<<16>>16,o=o+D(e[r*2+t]|e[r*5+t]<<8)<<16>>16,n[t*3]=i,n[t*3+1]=a,n[t*3+2]=o;return n}function A(e,t){let n=new Uint16Array(t),r=0;for(let i=0;i<t;i++)r=r+D(e[i]|e[t+i]<<8)&65535,n[i]=r;return n}function j(e,t){let n=new Uint32Array(t),r=0;for(let i=0;i<t;i++){let a=(e[i]|e[t+i]<<8|e[t*2+i]<<16|e[t*3+i]<<24)>>>0;r=r+D(a)>>>0,n[i]=r}return n}function M(e){let t=new Uint16Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+D(e[r])&65535,t[r]=n;return t}function N(e){let t=new Uint32Array(e.length),n=0;for(let r=0;r<e.length;r++)n=n+D(e[r])>>>0,t[r]=n;return t}function P(e,t){return new n(e,s.VALIDATION_ERROR,{context:t})}function ae(e,t,n,r,i,a=!1){if(n+36>e.byteLength)throw P(`Insufficient data to read UV chunk header.`,{expectedBytes:36,availableBytes:e.byteLength-n,offset:n});let o=t.getUint32(n,!0);n+=4;let s=t.getFloat64(n,!0);n+=8;let c=t.getFloat64(n,!0);n+=8;let l=t.getFloat64(n,!0);n+=8;let u=t.getFloat64(n,!0);n+=8;let d=r*2,f=o===1,p=d*(f?4:2);if(n+p>e.byteLength)throw P(`Insufficient data to read UV chunk.`,{expectedBytes:p,availableBytes:e.byteLength-n,offset:n,uvFormat:o,vertexCount:r});let m=e.byteOffset+n,h;if(f)h=re(e.buffer,m,d).slice();else if(a){let t=e.subarray(n,n+p),i=r;h=new Float32Array(d);let a=0,o=0;for(let e=0;e<i;e++)a=a+D(t[e]|t[i*2+e]<<8)&65535,o=o+D(t[i+e]|t[i*3+e]<<8)&65535,h[e*2]=s+a*l,h[e*2+1]=c+o*u}else{let t=T(e.buffer,m,d);h=new Float32Array(d);let n=0,r=0;for(let e=0;e<d;e+=2)i?(n=n+D(t[e])&65535,r=r+D(t[e+1])&65535):(n=t[e],r=t[e+1]),h[e]=s+n*l,h[e+1]=c+r*u}return{uvs:h,offset:n+p}}function oe(e,t,n,r){let i=n*3;if(t+i>e.byteLength)throw P(`Insufficient data to read vertex-color chunk.`,{expectedBytes:i,availableBytes:e.byteLength-t,offset:t,vertexCount:n});let a=e.subarray(t,t+i);if(!r)return a.slice();let o=new Uint8Array(i),s=0,c=0,l=0;for(let e=0;e<i;e+=3)s=s+D(a[e])&255,c=c+D(a[e+1])&255,l=l+D(a[e+2])&255,o[e]=s,o[e+1]=c,o[e+2]=l;return o}function se(e){return e.byteLength>=4&&new DataView(e.buffer,e.byteOffset,4).getUint32(0,!0)===1297501267}function ce(e){let t=F(e),n=null,r=null,i=null,a=[];for(let{type:e,payload:o}of t)switch(e){case 1297040711:n=o;break;case 1279410516:r=C(o);break;case 1280590157:i=w(o);break;case 1381516628:a.push(o)}if(n===null)throw P(`SLVM container has no GEOM chunk.`,{chunkCount:t.length});if(r===null)throw P(`SLVM container has no TABL chunk.`,{chunkCount:t.length});let{groups:o}=le(r),s=ue(i,a);return{geometryBlob:n,metadata:{materials:s,groups:o}}}function F(e){let t=new DataView(e.buffer,e.byteOffset,e.byteLength);if(e.byteLength<12||t.getUint32(0,!0)!==1297501267)throw P(`Not an SLVM container (bad magic).`,{byteLength:e.byteLength});let n=t.getUint32(4,!0);if(n!==3)throw P(`Unsupported SLVM version: ${n}`,{expectedVersion:3});let r=t.getUint32(8,!0),i=[],a=12;for(let n=0;n<r;n++){if(a+8>e.byteLength)throw P(`Truncated SLVM chunk header.`,{offset:a,chunkIndex:n});let r=t.getUint32(a,!0),o=t.getUint32(a+4,!0);if(a+=8,a+o>e.byteLength)throw P(`Truncated SLVM chunk payload.`,{offset:a,chunkIndex:n,byteLen:o});i.push({type:r,payload:e.subarray(a,a+o)}),a+=o+(4-o%4)%4}return i}function I(e){let t=0,n=0;for(;;){if(e.pos>=e.bytes.byteLength||n>28)throw P(`Malformed varint in SLVM table.`,{pos:e.pos});let r=e.bytes[e.pos++];if(t|=(r&127)<<n,!(r&128))return t>>>0;n+=7}}function L(e,t,n){let r=e.bytes[e.pos++],i=Array(t);switch(r){case 0:i.fill(``);break;case 1:for(let e=0;e<t;e++)i[e]=String(e+1);break;case 2:for(let r=0;r<t;r++)i[r]=n[I(e)]??``;break;default:throw P(`Unknown SLVM string column mode: ${r}`,{pos:e.pos})}return i}function le(e){let t={bytes:e,pos:0},n=I(t),r=I(t),i=I(t),a=n+r+i,o=I(t),s=Array(o);for(let n=0;n<o;n++){let r=I(t);s[n]=w(e.subarray(t.pos,t.pos+r)),t.pos+=r}let c=Array(n),l=Array(n);for(let e=0;e<n;e++)c[e]=I(t),l[e]=I(t);for(let e=0;e<r;e++)I(t);let u=I(t),d=[];for(let e=0;e<u;e++)d.push({materialId:I(t),meshCount:I(t)});let f=L(t,a,s),p=L(t,a,s),m=Array(a),h=I(t);for(let e=0;e<h;e++){let e=s[I(t)]??``,n=I(t),r=Array(n),i=0;for(let e=0;e<n;e++)i+=I(t),r[e]=i;for(let i=0;i<n;i++){let n=s[I(t)]??``,a=r[i];(m[a]??={})[e]=n}}let g=d.length>0||n===0?d:[{materialId:0,meshCount:n}],_=[],v=0,y=0,b=0;for(let e of g){let t=[];for(let r=0;r<e.meshCount&&v<n;r++,v++){let e=m[v],n=e?.id;e!==void 0&&delete e.id,t.push({id:n,name:f[v],layer:p[v],vertexCount:c[v],indexCount:l[v]*3,vertexStart:y,indexStart:b,metadata:e??{}}),y+=c[v],b+=l[v]*3}_.push({materialId:e.materialId,meshes:t})}return{groups:_}}function ue(e,t){if(e===null)return[];let n;try{n=JSON.parse(e).materials??[]}catch(t){throw P(`Failed to parse SLVM materials JSON: ${t instanceof Error?t.message:String(t)}`,{byteLength:e.length})}for(let e of n)if(e.map?.startsWith(`slvm:tex:`)){let n=t[Number(e.map.slice(9))];n!==void 0&&(e.map=de(n))}return n}function de(e){let t={bytes:e,pos:0},n=I(t),r=w(e.subarray(t.pos,t.pos+n)),i=e.subarray(t.pos+n),a=``,o=32768;for(let e=0;e<i.byteLength;e+=o)a+=String.fromCharCode(...i.subarray(e,e+o));return`data:${r};base64,${btoa(a)}`}function R(e){let t=z(e),n;n=t.isFloat32?t.vertexData:t.planarByteSplit?k(t.vertexData,t.vertexCount):t.deltaEncoded?O(t.vertexData):t.vertexData;let r;if(t.planarByteSplit){let e=t.indexData;r=t.uint16Indices?A(e,e.length/2):j(e,e.length/4)}else r=t.deltaEncoded?t.indexData instanceof Uint16Array?M(t.indexData):N(t.indexData):t.indexData;return E(r,t.vertexCount),{metadata:t.metadata,flags:t.flags,vertices:n,indices:r,origin:t.origin,scale:t.scale,uvs:t.uvs,colors:t.colors}}function z(e){if(!ee)throw new n(`SLVA parsing requires a little-endian host: the zero-copy geometry readers view the wire bytes in host byte order.`,s.ENVIRONMENT_ERROR);let t=te(e);if(se(t)){let e=ce(t),n=z(e.geometryBlob);return n.metadata=e.metadata,n}let r=C(t),i=new DataView(r.buffer,r.byteOffset,r.byteLength);if(r.byteLength<12)throw P(`Blob too small to contain SLVA header.`,{expectedBytes:12,availableBytes:r.byteLength});let a=0,o=i.getUint32(a,!0);if(a+=4,o!==1096174675)throw P(`Invalid SLVA magic: 0x${o.toString(16)}`,{expectedMagic:`0x41564c53`,actualMagic:`0x${o.toString(16)}`});let c=i.getUint32(a,!0);if(a+=4,c<1||c>4)throw P(`Unsupported SLVA version: ${c}`,{minSupportedVersion:1,maxSupportedVersion:4,actualVersion:c});let l=i.getUint32(a,!0);if(a+=4,a+l>r.byteLength)throw P(`Insufficient data to read metadata JSON.`,{expectedBytes:l,availableBytes:r.byteLength-a,offset:a});let u=r.subarray(a,a+l);a+=l;let d;try{d=l===0?{}:JSON.parse(w(u))}catch(e){throw P(`Failed to parse metadata JSON: ${e instanceof Error?e.message:String(e)}`,{metadataLen:l})}if(a+56>r.byteLength)throw P(`Insufficient data to read geometry header.`,{expectedBytes:56,availableBytes:r.byteLength-a,offset:a});let f=i.getUint32(a,!0);a+=4;let p=i.getFloat64(a,!0);a+=8;let m=i.getFloat64(a,!0);a+=8;let h=i.getFloat64(a,!0);a+=8;let g=i.getFloat64(a,!0);a+=8;let _=i.getFloat64(a,!0);a+=8;let v=i.getFloat64(a,!0);a+=8;let y=i.getUint32(a,!0);a+=4;let b=!!(f&1),x=!!(f&4),S=!!(f&32),E=y*3,D=E*(b?4:2);if(a+D>r.byteLength)throw P(`Insufficient data to read vertices.`,{expectedBytes:D,availableBytes:r.byteLength-a,offset:a,useFloat32:b,vertexCount:y});let O=r.byteOffset+a,k;if(k=b?re(r.buffer,O,E):S?r.subarray(a,a+D):x?T(r.buffer,O,E):ne(r.buffer,O,E),a+=D,a+4>r.byteLength)throw P(`Insufficient data to read index count.`,{expectedBytes:4,availableBytes:r.byteLength-a,offset:a});let A=i.getUint32(a,!0);a+=4;let j=!!(f&2),M=A*(j?2:4);if(a+M>r.byteLength)throw P(`Insufficient data to read indices.`,{expectedBytes:M,availableBytes:r.byteLength-a,offset:a,indexCount:A,useUint16Indices:j});let N=S?r.subarray(a,a+M):j?T(r.buffer,r.byteOffset+a,A):ie(r.buffer,r.byteOffset+a,A);a+=M;let F=null;if(f&8){let e=ae(r,i,a,y,x,S);F=e.uvs,a=e.offset}let I=null;return f&16&&(I=oe(r,a,y,x)),{metadata:d,flags:f,vertexData:k,indexData:N,isFloat32:b,deltaEncoded:x,planarByteSplit:S,uint16Indices:j,vertexCount:y,origin:[p,m,h],scale:[g,_,v],uvs:F,colors:I}}function fe(e){let{isFloat32:t,deltaEncoded:n,planarByteSplit:r,uint16Indices:i,origin:a,scale:o,uvs:s,colors:c,jobs:l}=e,u=e=>e>>>1^-(e&1),d;if(t)d=e.vertexData;else{let t;if(r){let n=e.vertexData,r=n.length/6;t=new Int16Array(r*3);let i=0,a=0,o=0;for(let e=0;e<r;e++)i=i+u(n[e]|n[r*3+e]<<8)<<16>>16,a=a+u(n[r+e]|n[r*4+e]<<8)<<16>>16,o=o+u(n[r*2+e]|n[r*5+e]<<8)<<16>>16,t[e*3]=i,t[e*3+1]=a,t[e*3+2]=o}else if(n){let n=e.vertexData;t=new Int16Array(n.length);let r=0,i=0,a=0;for(let e=0;e<n.length;e+=3)r=r+u(n[e])<<16>>16,i=i+u(n[e+1])<<16>>16,a=a+u(n[e+2])<<16>>16,t[e]=r,t[e+1]=i,t[e+2]=a}else t=e.vertexData;d=new Float32Array(t.length);let i=a[0],s=a[1],c=a[2],l=o[0],f=o[1],p=o[2];for(let e=0;e<t.length;e+=3)d[e]=i+(t[e]+32767)*l,d[e+1]=s+(t[e+1]+32767)*f,d[e+2]=c+(t[e+2]+32767)*p}let f;if(r){let t=e.indexData;if(i){let e=t.length/2,n=new Uint16Array(e),r=0;for(let i=0;i<e;i++)r=r+u(t[i]|t[e+i]<<8)&65535,n[i]=r;f=n}else{let e=t.length/4,n=new Uint32Array(e),r=0;for(let i=0;i<e;i++){let a=(t[i]|t[e+i]<<8|t[e*2+i]<<16|t[e*3+i]<<24)>>>0;r=r+u(a)>>>0,n[i]=r}f=n}}else if(n){let t=e.indexData;if(t instanceof Uint16Array){let e=new Uint16Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+u(t[r])&65535,e[r]=n;f=e}else{let e=new Uint32Array(t.length),n=0;for(let r=0;r<t.length;r++)n=n+u(t[r])>>>0,e[r]=n;f=e}}else f=e.indexData;let p=d.length/3;for(let e=0;e<f.length;e++)if(f[e]>=p)throw Error(`Index ${f[e]} out of range of vertexCount ${p}`);let m=[];for(let e of l){let t=0,n=0;for(let r of e.windows)t+=r.vertexCount,n+=r.indexCount;let r=new Float32Array(t*3),i=new Uint32Array(n),a=s?new Float32Array(t*2):null,o=c?new Uint8Array(t*3):null,l=0,u=0;for(let t of e.windows){let e=t.vertexStart*3;r.set(d.subarray(e,e+t.vertexCount*3),l*3),a&&s&&a.set(s.subarray(t.vertexStart*2,(t.vertexStart+t.vertexCount)*2),l*2),o&&c&&o.set(c.subarray(e,e+t.vertexCount*3),l*3);let n=t.vertexStart,p=t.vertexStart+t.vertexCount,m=l-t.vertexStart;for(let e=0;e<t.indexCount;e++){let r=f[t.indexStart+e];if(r<n||r>=p)throw Error(`Index ${r} outside vertex window [${n}, ${p})`);i[u+e]=r+m}l+=t.vertexCount,u+=t.indexCount}let p=new Float32Array(t*3);for(let e=0;e<i.length;e+=3){let t=i[e]*3,n=i[e+1]*3,a=i[e+2]*3,o=r[a]-r[n],s=r[a+1]-r[n+1],c=r[a+2]-r[n+2],l=r[t]-r[n],u=r[t+1]-r[n+1],d=r[t+2]-r[n+2],f=s*d-c*u,m=c*l-o*d,h=o*u-s*l;p[t]+=f,p[t+1]+=m,p[t+2]+=h,p[n]+=f,p[n+1]+=m,p[n+2]+=h,p[a]+=f,p[a+1]+=m,p[a+2]+=h}for(let e=0;e<p.length;e+=3){let t=p[e],n=p[e+1],r=p[e+2],i=Math.sqrt(t*t+n*n+r*r)||1;p[e]=t/i,p[e+1]=n/i,p[e+2]=r/i}m.push({positions:r,normals:p,indices:i,uvs:a,colors:o})}return m}function pe(){return[`const assemble = ${fe.toString()};`,`self.onmessage = (event) => {`,` const { id, input } = event.data;`,` try {`,` const geometries = assemble(input);`,` const transfer = [];`,` for (const g of geometries) {`,` transfer.push(g.positions.buffer, g.normals.buffer, g.indices.buffer);`,` if (g.uvs) transfer.push(g.uvs.buffer);`,` if (g.colors) transfer.push(g.colors.buffer);`,` }`,` self.postMessage({ id, geometries }, transfer);`,` } catch (error) {`,` self.postMessage({ id, error: String((error && error.message) || error) });`,` }`,`};`].join(`
2
2
  `)}let B;const V=new Map;let me=1;function he(){if(B!==void 0)return B;if(typeof Worker>`u`||typeof Blob>`u`||typeof URL>`u`||typeof URL.createObjectURL!=`function`)return B=null,null;try{let e=URL.createObjectURL(new Blob([pe()],{type:`text/javascript`})),t=new Worker(e);t.onmessage=e=>{let{id:t,geometries:n,error:r}=e.data,i=V.get(t);i&&(V.delete(t),n?i.resolve(n):i.reject(Error(r??`mesh assembly failed in worker`)))},t.onerror=()=>{for(let e of V.values())e.reject(Error(`mesh assembly worker crashed`));V.clear(),t.terminate(),B=null},B=t}catch{B=null}return B}function ge(e,t,n){return new Promise((r,i)=>{let a=me++;V.set(a,{resolve:r,reject:i}),e.postMessage({id:a,input:t},n)})}let H=1;function U(e){H=Math.max(1,e)}i(U);function _e(e,n){typeof document>`u`||new c.TextureLoader().load(n,t=>{t.colorSpace=c.SRGBColorSpace,t.anisotropy=H,e.map=t,e.needsUpdate=!0},void 0,e=>{t().warn(`Failed to load material texture ${n}:`,e)})}function W(e,t){let n=a(e.color),r=t?.vertexColors??!1,i=t?.appearance,o=new c.MeshPhysicalMaterial({color:n,metalness:e.metalness,roughness:e.roughness,opacity:e.opacity,transparent:e.transparent,vertexColors:r,side:i?.cullBackfaces?c.FrontSide:c.DoubleSide,polygonOffset:!0,polygonOffsetFactor:.5,polygonOffsetUnits:.5,depthWrite:!0,depthTest:!0});return i?.envMapIntensity!=null&&(o.envMapIntensity=i.envMapIntensity),e.metalness>.5&&(o.clearcoat=.5,o.clearcoatRoughness=.3),r&&ve(o),e.map&&_e(o,e.map),o}function ve(e){e.onBeforeCompile=e=>{e.vertexShader=e.vertexShader.replace(`#include <color_vertex>`,`#include <color_vertex>
3
3
  #if defined( USE_COLOR ) || defined( USE_COLOR_ALPHA )
4
4
  vColor.rgb = mix(