@polarfront-lab/ionian 1.5.0 → 1.7.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- {"version":3,"file":"ionian.js","sources":["../src/lib/easing.ts","../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/dist/mitt.mjs","../src/lib/events/defaultEventEmitter.ts","../src/lib/utils.ts","../src/lib/services/assets/assetService.ts","../node_modules/.pnpm/three@0.173.0/node_modules/three/examples/jsm/math/MeshSurfaceSampler.js","../src/lib/services/dataTexture/dataTextureService.ts","../src/lib/services/instancedmesh/shaders/instanceFragmentShader.ts","../src/lib/services/instancedmesh/shaders/instanceVertexShader.ts","../src/lib/services/instancedmesh/instancedMeshManager.ts","../src/lib/services/intersection/intersectionService.ts","../node_modules/.pnpm/three@0.173.0/node_modules/three/examples/jsm/postprocessing/Pass.js","../node_modules/.pnpm/three@0.173.0/node_modules/three/examples/jsm/misc/GPUComputationRenderer.js","../src/lib/services/simulation/shaders/simulationMixShader.ts","../src/lib/services/simulation/shaders/simulationPositionShader.ts","../src/lib/services/simulation/shaders/simulationVelocityShader.ts","../src/lib/services/simulation/simulationRenderer.ts","../src/lib/services/simulation/simulationRendererService.ts","../src/lib/services/transition/transitionService.ts","../src/lib/particlesEngine.ts"],"sourcesContent":["import { EasingFunction } from '@/lib/types';\n\n/**\n * Linear easing function.\n */\nexport const linear: EasingFunction = (n: number) => n;\n","export default function(n){return{all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e])},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]))},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e)}),(i=n.get(\"*\"))&&i.slice().map(function(n){n(t,e)})}}}\n//# sourceMappingURL=mitt.mjs.map\n","import { Events } from '@/lib/events/topics';\nimport mitt from 'mitt';\nimport { EngineEventEmitter } from './engineEventEmitter';\n\nexport class DefaultEventEmitter implements EngineEventEmitter<Events> {\n private readonly emitter = mitt<Events>();\n\n emit<Key extends keyof Events>(type: Key, payload: Events[Key]): void {\n this.emitter.emit(type, payload);\n }\n\n off<Key extends keyof Events>(type: Key, handler?: (payload: Events[Key]) => void): void {\n this.emitter.off(type, handler);\n }\n\n on<Key extends keyof Events>(type: Key, handler: (payload: Events[Key]) => void): void {\n this.emitter.on(type, handler);\n }\n\n once<Key extends keyof Events>(type: Key, handler: (payload: Events[Key]) => void): void {\n this.emitter.on(type, (payload: Events[Key]) => {\n this.emitter.off(type, handler);\n handler(payload);\n });\n }\n\n dispose(): void {\n this.emitter.all.clear();\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Creates a new DataTexture from the given data and size.\n * @param data - The data for the texture.\n * @param size - The size of the texture.\n * @returns The created DataTexture.\n */\nexport function createDataTexture(data: Float32Array, size: number) {\n const texture = new THREE.DataTexture(data, size, size, THREE.RGBAFormat, THREE.FloatType);\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * Creates a blank DataTexture with the given size.\n * @param size - The size of the texture.\n * @returns The created blank DataTexture.\n */\nexport function createBlankDataTexture(size: number) {\n return createDataTexture(new Float32Array(4 * size * size), size);\n}\n\n/**\n * Creates a DataTexture representing a sphere.\n * @param size - The size of the texture.\n * @returns The created DataTexture.\n */\nexport function createSpherePoints(size: number) {\n const data = new Float32Array(size * size * 4);\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n\n let theta = Math.random() * Math.PI * 2;\n let phi = Math.acos(Math.random() * 2 - 1);\n let x = Math.sin(phi) * Math.cos(theta);\n let y = Math.sin(phi) * Math.sin(theta);\n let z = Math.cos(phi);\n\n data[4 * index] = x;\n data[4 * index + 1] = y;\n data[4 * index + 2] = z;\n data[4 * index + 3] = (Math.random() - 0.5) * 0.01;\n }\n }\n\n return createDataTexture(data, size);\n}\n\nexport function disposeMesh(mesh: THREE.Mesh) {\n mesh.geometry.dispose();\n if (mesh.material instanceof THREE.Material) {\n mesh.material.dispose();\n } else {\n mesh.material.forEach((material) => material.dispose());\n }\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n value = Math.min(value, max);\n value = Math.max(value, min);\n return value;\n}\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { ServiceState } from '@/lib/types';\nimport { disposeMesh } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { DRACOLoader, GLTFLoader } from 'three-stdlib';\n\nexport class AssetService {\n private serviceState: ServiceState = 'created';\n\n private readonly eventEmitter;\n private readonly meshes = new Map<string, THREE.Mesh>();\n private readonly textures = new Map<string, THREE.Texture>();\n\n private readonly gltfLoader = new GLTFLoader();\n private readonly textureLoader = new THREE.TextureLoader();\n private readonly dracoLoader = new DRACOLoader();\n\n private solidColorTexture = new THREE.DataTexture(new Uint8Array([127, 127, 127, 255]), 1, 1, THREE.RGBAFormat);\n\n constructor(eventEmitter: DefaultEventEmitter) {\n this.eventEmitter = eventEmitter;\n this.dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.7/');\n this.gltfLoader.setDRACOLoader(this.dracoLoader);\n this.updateServiceState('ready');\n }\n\n /**\n * Registers an asset.\n * @param id - The ID of the asset.\n * @param item - The asset to set.\n */\n register(id: string, item: THREE.Mesh | THREE.Texture) {\n item.name = id;\n\n if (item instanceof THREE.Mesh) {\n const prev = this.meshes.get(id);\n if (prev) disposeMesh(prev);\n this.meshes.set(id, item);\n } else {\n const prev = this.textures.get(id);\n if (prev) prev.dispose();\n this.textures.set(id, item);\n }\n\n this.eventEmitter.emit('assetRegistered', { id });\n }\n\n setSolidColor(color: THREE.ColorRepresentation) {\n this.changeColor(color);\n }\n\n getSolidColorTexture() {\n return this.solidColorTexture;\n }\n\n getMesh(id: string): THREE.Mesh | null {\n return this.meshes.get(id) ?? null;\n }\n\n getMatcap(id: string): THREE.Texture {\n const texture = this.textures.get(id);\n if (!texture) this.eventEmitter.emit('invalidRequest', { message: `texture with id \"${id}\" not found. using solid color texture instead...` });\n return texture ?? this.solidColorTexture;\n }\n\n getMeshIDs(): string[] {\n return Array.from(this.meshes.keys());\n }\n\n getTextureIDs(): string[] {\n return Array.from(this.textures.keys());\n }\n\n getMeshes(): THREE.Mesh[] {\n return Array.from(this.meshes.values());\n }\n\n getTextures(): THREE.Texture[] {\n return Array.from(this.textures.values());\n }\n\n hasMatcap(id: string) {\n return this.textures.has(id);\n }\n\n /**\n * Loads a mesh asynchronously.\n * @param id - The ID of the mesh.\n * @param url - The URL of the mesh.\n * @param options - Optional parameters.\n * @returns The loaded mesh or null.\n */\n async loadMeshAsync(id: string, url: string, options: { meshName?: string } = {}): Promise<THREE.Mesh | null> {\n const gltf = await this.gltfLoader.loadAsync(url);\n try {\n if (options.meshName) {\n const mesh = gltf.scene.getObjectByName(options.meshName) as THREE.Mesh;\n this.register(id, mesh);\n return mesh;\n } else {\n const mesh = gltf.scene.children[0] as THREE.Mesh;\n this.register(id, mesh);\n return mesh;\n }\n } catch (error) {\n this.eventEmitter.emit('invalidRequest', { message: `failed to load mesh: ${id}. ${error}` });\n return null;\n }\n }\n\n /**\n * Loads a texture asynchronously.\n * @param id - The ID of the texture.\n * @param url - The URL of the texture.\n * @returns The loaded texture or null.\n */\n async loadTextureAsync(id: string, url: string): Promise<THREE.Texture | null> {\n try {\n const texture = await this.textureLoader.loadAsync(url);\n this.register(id, texture);\n return texture;\n } catch (error) {\n this.eventEmitter.emit('invalidRequest', { message: `failed to load texture: ${id}. ${error}` });\n return null;\n }\n }\n\n dispose() {\n this.updateServiceState('disposed');\n this.meshes.forEach((mesh) => disposeMesh(mesh));\n this.meshes.clear();\n this.textures.forEach((texture) => texture.dispose());\n this.textures.clear();\n }\n\n private changeColor(color: THREE.ColorRepresentation) {\n const actual = new THREE.Color(color);\n this.solidColorTexture = new THREE.DataTexture(new Uint8Array([actual.r, actual.g, actual.b, 255]), 1, 1, THREE.RGBAFormat);\n this.solidColorTexture.needsUpdate = true;\n }\n\n private updateServiceState(serviceState: ServiceState) {\n this.serviceState = serviceState;\n this.eventEmitter.emit('serviceStateUpdated', { type: 'asset', state: serviceState });\n }\n}\n","import {\n\tTriangle,\n\tVector2,\n\tVector3\n} from 'three';\n\n/**\n * Utility class for sampling weighted random points on the surface of a mesh.\n *\n * Building the sampler is a one-time O(n) operation. Once built, any number of\n * random samples may be selected in O(logn) time. Memory usage is O(n).\n *\n * References:\n * - http://www.joesfer.com/?p=84\n * - https://stackoverflow.com/a/4322940/1314762\n */\n\nconst _face = new Triangle();\nconst _color = new Vector3();\nconst _uva = new Vector2(), _uvb = new Vector2(), _uvc = new Vector2();\n\nclass MeshSurfaceSampler {\n\n\tconstructor( mesh ) {\n\n\t\tthis.geometry = mesh.geometry;\n\t\tthis.randomFunction = Math.random;\n\n\t\tthis.indexAttribute = this.geometry.index;\n\t\tthis.positionAttribute = this.geometry.getAttribute( 'position' );\n\t\tthis.normalAttribute = this.geometry.getAttribute( 'normal' );\n\t\tthis.colorAttribute = this.geometry.getAttribute( 'color' );\n\t\tthis.uvAttribute = this.geometry.getAttribute( 'uv' );\n\t\tthis.weightAttribute = null;\n\n\t\tthis.distribution = null;\n\n\t}\n\n\tsetWeightAttribute( name ) {\n\n\t\tthis.weightAttribute = name ? this.geometry.getAttribute( name ) : null;\n\n\t\treturn this;\n\n\t}\n\n\tbuild() {\n\n\t\tconst indexAttribute = this.indexAttribute;\n\t\tconst positionAttribute = this.positionAttribute;\n\t\tconst weightAttribute = this.weightAttribute;\n\n\t\tconst totalFaces = indexAttribute ? ( indexAttribute.count / 3 ) : ( positionAttribute.count / 3 );\n\t\tconst faceWeights = new Float32Array( totalFaces );\n\n\t\t// Accumulate weights for each mesh face.\n\n\t\tfor ( let i = 0; i < totalFaces; i ++ ) {\n\n\t\t\tlet faceWeight = 1;\n\n\t\t\tlet i0 = 3 * i;\n\t\t\tlet i1 = 3 * i + 1;\n\t\t\tlet i2 = 3 * i + 2;\n\n\t\t\tif ( indexAttribute ) {\n\n\t\t\t\ti0 = indexAttribute.getX( i0 );\n\t\t\t\ti1 = indexAttribute.getX( i1 );\n\t\t\t\ti2 = indexAttribute.getX( i2 );\n\n\t\t\t}\n\n\t\t\tif ( weightAttribute ) {\n\n\t\t\t\tfaceWeight = weightAttribute.getX( i0 )\n\t\t\t\t\t+ weightAttribute.getX( i1 )\n\t\t\t\t\t+ weightAttribute.getX( i2 );\n\n\t\t\t}\n\n\t\t\t_face.a.fromBufferAttribute( positionAttribute, i0 );\n\t\t\t_face.b.fromBufferAttribute( positionAttribute, i1 );\n\t\t\t_face.c.fromBufferAttribute( positionAttribute, i2 );\n\t\t\tfaceWeight *= _face.getArea();\n\n\t\t\tfaceWeights[ i ] = faceWeight;\n\n\t\t}\n\n\t\t// Store cumulative total face weights in an array, where weight index\n\t\t// corresponds to face index.\n\n\t\tconst distribution = new Float32Array( totalFaces );\n\t\tlet cumulativeTotal = 0;\n\n\t\tfor ( let i = 0; i < totalFaces; i ++ ) {\n\n\t\t\tcumulativeTotal += faceWeights[ i ];\n\t\t\tdistribution[ i ] = cumulativeTotal;\n\n\t\t}\n\n\t\tthis.distribution = distribution;\n\t\treturn this;\n\n\t}\n\n\tsetRandomGenerator( randomFunction ) {\n\n\t\tthis.randomFunction = randomFunction;\n\t\treturn this;\n\n\t}\n\n\tsample( targetPosition, targetNormal, targetColor, targetUV ) {\n\n\t\tconst faceIndex = this.sampleFaceIndex();\n\t\treturn this.sampleFace( faceIndex, targetPosition, targetNormal, targetColor, targetUV );\n\n\t}\n\n\tsampleFaceIndex() {\n\n\t\tconst cumulativeTotal = this.distribution[ this.distribution.length - 1 ];\n\t\treturn this.binarySearch( this.randomFunction() * cumulativeTotal );\n\n\t}\n\n\tbinarySearch( x ) {\n\n\t\tconst dist = this.distribution;\n\t\tlet start = 0;\n\t\tlet end = dist.length - 1;\n\n\t\tlet index = - 1;\n\n\t\twhile ( start <= end ) {\n\n\t\t\tconst mid = Math.ceil( ( start + end ) / 2 );\n\n\t\t\tif ( mid === 0 || dist[ mid - 1 ] <= x && dist[ mid ] > x ) {\n\n\t\t\t\tindex = mid;\n\n\t\t\t\tbreak;\n\n\t\t\t} else if ( x < dist[ mid ] ) {\n\n\t\t\t\tend = mid - 1;\n\n\t\t\t} else {\n\n\t\t\t\tstart = mid + 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn index;\n\n\t}\n\n\tsampleFace( faceIndex, targetPosition, targetNormal, targetColor, targetUV ) {\n\n\t\tlet u = this.randomFunction();\n\t\tlet v = this.randomFunction();\n\n\t\tif ( u + v > 1 ) {\n\n\t\t\tu = 1 - u;\n\t\t\tv = 1 - v;\n\n\t\t}\n\n\t\t// get the vertex attribute indices\n\t\tconst indexAttribute = this.indexAttribute;\n\t\tlet i0 = faceIndex * 3;\n\t\tlet i1 = faceIndex * 3 + 1;\n\t\tlet i2 = faceIndex * 3 + 2;\n\t\tif ( indexAttribute ) {\n\n\t\t\ti0 = indexAttribute.getX( i0 );\n\t\t\ti1 = indexAttribute.getX( i1 );\n\t\t\ti2 = indexAttribute.getX( i2 );\n\n\t\t}\n\n\t\t_face.a.fromBufferAttribute( this.positionAttribute, i0 );\n\t\t_face.b.fromBufferAttribute( this.positionAttribute, i1 );\n\t\t_face.c.fromBufferAttribute( this.positionAttribute, i2 );\n\n\t\ttargetPosition\n\t\t\t.set( 0, 0, 0 )\n\t\t\t.addScaledVector( _face.a, u )\n\t\t\t.addScaledVector( _face.b, v )\n\t\t\t.addScaledVector( _face.c, 1 - ( u + v ) );\n\n\t\tif ( targetNormal !== undefined ) {\n\n\t\t\tif ( this.normalAttribute !== undefined ) {\n\n\t\t\t\t_face.a.fromBufferAttribute( this.normalAttribute, i0 );\n\t\t\t\t_face.b.fromBufferAttribute( this.normalAttribute, i1 );\n\t\t\t\t_face.c.fromBufferAttribute( this.normalAttribute, i2 );\n\t\t\t\ttargetNormal.set( 0, 0, 0 ).addScaledVector( _face.a, u ).addScaledVector( _face.b, v ).addScaledVector( _face.c, 1 - ( u + v ) ).normalize();\n\n\t\t\t} else {\n\n\t\t\t\t_face.getNormal( targetNormal );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( targetColor !== undefined && this.colorAttribute !== undefined ) {\n\n\t\t\t_face.a.fromBufferAttribute( this.colorAttribute, i0 );\n\t\t\t_face.b.fromBufferAttribute( this.colorAttribute, i1 );\n\t\t\t_face.c.fromBufferAttribute( this.colorAttribute, i2 );\n\n\t\t\t_color\n\t\t\t\t.set( 0, 0, 0 )\n\t\t\t\t.addScaledVector( _face.a, u )\n\t\t\t\t.addScaledVector( _face.b, v )\n\t\t\t\t.addScaledVector( _face.c, 1 - ( u + v ) );\n\n\t\t\ttargetColor.r = _color.x;\n\t\t\ttargetColor.g = _color.y;\n\t\t\ttargetColor.b = _color.z;\n\n\t\t}\n\n\t\tif ( targetUV !== undefined && this.uvAttribute !== undefined ) {\n\n\t\t\t_uva.fromBufferAttribute( this.uvAttribute, i0 );\n\t\t\t_uvb.fromBufferAttribute( this.uvAttribute, i1 );\n\t\t\t_uvc.fromBufferAttribute( this.uvAttribute, i2 );\n\t\t\ttargetUV.set( 0, 0 ).addScaledVector( _uva, u ).addScaledVector( _uvb, v ).addScaledVector( _uvc, 1 - ( u + v ) );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nexport { MeshSurfaceSampler };\n","import { DefaultEventEmitter } from '@/lib/events/defaultEventEmitter';\nimport { MeshData, ServiceState } from '@/lib/types';\nimport { createDataTexture } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { MeshSurfaceSampler } from 'three/examples/jsm/math/MeshSurfaceSampler.js';\n\n/**\n * DataTextureManager is responsible for managing data textures used for mesh sampling.\n */\nexport class DataTextureService {\n private textureSize: number;\n private dataTextures: Map<string, THREE.DataTexture>;\n private eventEmitter;\n\n /**\n * Creates a new DataTextureManager instance.\n * @param eventEmitter\n * @param textureSize\n */\n constructor(eventEmitter: DefaultEventEmitter, textureSize: number) {\n this.eventEmitter = eventEmitter;\n this.textureSize = textureSize;\n this.dataTextures = new Map<string, THREE.DataTexture>();\n this.updateServiceState('ready');\n }\n\n setTextureSize(textureSize: number) {\n if (this.textureSize === textureSize) return;\n this.textureSize = textureSize;\n this.dataTextures.forEach((texture) => texture.dispose());\n this.dataTextures.clear();\n }\n\n /**\n * Prepares a mesh for sampling.\n * @returns The prepared data texture.\n * @param asset The asset to prepare.\n */\n async getDataTexture(asset: THREE.Mesh) {\n const texture = this.dataTextures.get(asset.name);\n if (texture) {\n return texture; // already prepared\n }\n\n const meshData = parseMeshData(asset);\n const array = sampleMesh(meshData, this.textureSize);\n const dataTexture = createDataTexture(array, this.textureSize);\n dataTexture.name = asset.name;\n return dataTexture;\n }\n\n async dispose() {\n this.dataTextures.clear();\n this.updateServiceState('disposed');\n }\n\n private updateServiceState(serviceState: ServiceState) {\n this.eventEmitter.emit('serviceStateUpdated', { type: 'data-texture', state: serviceState });\n }\n}\n\n/**\n * Parses mesh data into a simplified format.\n * @param mesh The mesh to parse.\n * @returns The parsed mesh data.\n */\nfunction parseMeshData(mesh: THREE.Mesh): MeshData {\n return {\n position: mesh.geometry.attributes.position.array,\n normal: (mesh.geometry.attributes.normal as THREE.BufferAttribute)?.array,\n scale: { x: mesh.scale.x, y: mesh.scale.y, z: mesh.scale.z },\n };\n}\n\nfunction sampleMesh(meshData: MeshData, size: number): Float32Array {\n const geometry = new THREE.BufferGeometry();\n geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(meshData.position), 3));\n if (meshData.normal) {\n geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(meshData.normal), 3));\n }\n const material = new THREE.MeshBasicMaterial();\n const mesh = new THREE.Mesh(geometry, material);\n mesh.scale.set(meshData.scale.x, meshData.scale.y, meshData.scale.z);\n\n const sampler = new MeshSurfaceSampler(mesh).build();\n const data = new Float32Array(size * size * 4);\n const position = new THREE.Vector3();\n\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n sampler.sample(position);\n data[4 * index] = position.x * meshData.scale.x;\n data[4 * index + 1] = position.y * meshData.scale.y;\n data[4 * index + 2] = position.z * meshData.scale.z;\n data[4 * index + 3] = (Math.random() - 0.5) * 0.01;\n }\n }\n\n return data;\n}\n","export default `\nvarying vec2 vUv;\nuniform sampler2D uTexture;\n\nuniform sampler2D uOriginTexture;\nuniform sampler2D uDestinationTexture;\n\nuniform float uProgress;\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvoid main() {\n vec3 viewDir = normalize( vViewPosition );\n vec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n vec3 y = cross( viewDir, x );\n vec2 uv = vec2( dot( x, vNormal ), dot( y, vNormal ) ) * 0.495 + 0.5; // 0.495 to remove artifacts caused by undersized matcap disks\n\n vec4 sourceMatcap = texture2D( uOriginTexture, uv );\n vec4 targetMatcap = texture2D( uDestinationTexture, uv );\n\n vec4 matcap = mix(sourceMatcap, targetMatcap, uProgress);\n gl_FragColor = matcap;\n}\n`;\n","export default `\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform sampler2D uVelocity;\nuniform float uTime;\nvarying vec3 vNormal;\nattribute vec2 uvRef;\nvarying vec3 vViewPosition;\n\nvec3 rotate3D(vec3 v, vec3 vel) {\n vec3 pos = v;\n vec3 up = vec3(0, 1, 0);\n vec3 axis = normalize(cross(up, vel));\n float angle = acos(dot(up, normalize(vel)));\n pos = pos * cos(angle) + cross(axis, pos) * sin(angle) + axis * dot(axis, pos) * (1. - cos(angle));\n return pos;\n}\n\nvoid main() {\n vUv = uv;\n vNormal = normal;\n\n vec4 color = texture2D(uTexture, uvRef);\n vec4 velocity = texture2D(uVelocity, uvRef);\n vec3 pos = color.xyz;// apply the texture to the vertex distribution.\n\n vec3 localPosition = position.xyz;\n if (length (velocity.xyz) < 0.0001) {\n velocity.xyz = vec3(0.0, 0.0001, 0.0001);\n }\n localPosition.y *= max(1.0, length(velocity.xyz) * 1000.0);\n localPosition = rotate3D(localPosition, velocity.xyz);\n vNormal = rotate3D(normal, velocity.xyz);\n\n mat4 instanceMat = instanceMatrix;\n instanceMat[3].xyz = pos.xyz;\n\n // unlike the traditional mvMatrix * position, we need to additional multiplication with the instance matrix.\n vec4 modelViewPosition = modelViewMatrix * instanceMat * vec4(localPosition, 1.0);\n\n vViewPosition = - modelViewPosition.xyz;\n\n gl_Position = projectionMatrix * modelViewPosition;\n}\n`;\n","import * as THREE from 'three';\nimport { Vector3Like } from 'three';\nimport instanceFragmentShader from './shaders/instanceFragmentShader';\nimport instanceVertexShader from './shaders/instanceVertexShader';\n\ntype MaterialUniforms = {\n uTime: { value: number };\n uProgress: { value: number };\n uTexture: { value: THREE.DataTexture | null };\n uVelocity: { value: THREE.DataTexture | null };\n uOriginTexture: { value: THREE.Texture | null };\n uDestinationTexture: { value: THREE.Texture | null };\n};\n\n/**\n * InstancedMeshManager is responsible for managing instanced meshes.\n */\nexport class InstancedMeshManager {\n private size: number;\n private mesh: THREE.InstancedMesh;\n\n private readonly matcapMaterial: THREE.ShaderMaterial;\n private readonly fallbackGeometry: THREE.BufferGeometry;\n\n private readonly uniforms: MaterialUniforms;\n\n private originColor: THREE.ColorRepresentation | null;\n private destinationColor: THREE.ColorRepresentation | null;\n\n private geometries: Map<string, THREE.BufferGeometry>;\n private uvRefsCache: Map<number, THREE.InstancedBufferAttribute>;\n\n private previousScale: Vector3Like;\n\n /**\n * Creates a new InstancedMeshManager instance.\n * @param initialSize The initial size of the instanced mesh.\n */\n constructor(initialSize: number) {\n this.size = initialSize;\n this.geometries = new Map();\n this.uvRefsCache = new Map();\n\n this.previousScale = { x: 1, y: 1, z: 1 };\n this.originColor = 'grey';\n this.destinationColor = 'grey';\n\n this.uniforms = {\n uTime: { value: 0 },\n uProgress: { value: 0 },\n uTexture: { value: null },\n uVelocity: { value: null },\n uOriginTexture: { value: null },\n uDestinationTexture: { value: null },\n };\n\n this.matcapMaterial = new THREE.ShaderMaterial({\n uniforms: this.uniforms,\n vertexShader: instanceVertexShader,\n fragmentShader: instanceFragmentShader,\n });\n\n this.setOriginColor(this.originColor);\n this.setDestinationColor(this.destinationColor);\n\n this.fallbackGeometry = new THREE.BoxGeometry(0.001, 0.001, 0.001);\n this.mesh = this.createInstancedMesh(initialSize, this.fallbackGeometry, this.matcapMaterial);\n }\n\n /**\n * Gets the instanced mesh.\n * @returns The instanced mesh.\n */\n getMesh() {\n return this.mesh;\n }\n\n /**\n * Updates the instanced mesh.\n * @param elapsedTime The elapsed time.\n */\n update(elapsedTime: number) {\n const material = this.mesh.material;\n if (material instanceof THREE.ShaderMaterial || material instanceof THREE.RawShaderMaterial) {\n material.uniforms.uTime.value = elapsedTime;\n }\n }\n\n /**\n * Sets the matcap texture.\n * @param matcap The matcap texture to set.\n */\n setOriginMatcap(matcap: THREE.Texture) {\n this.disposeSolidColorOriginTexture();\n this.matcapMaterial.uniforms.uOriginTexture.value = matcap;\n }\n\n setDestinationMatcap(matcap: THREE.Texture) {\n this.disposeSolidColorDestinationTexture();\n this.matcapMaterial.uniforms.uDestinationTexture.value = matcap;\n }\n\n setProgress(float: number) {\n float = Math.max(0, float);\n float = Math.min(1, float);\n this.matcapMaterial.uniforms.uProgress.value = float;\n }\n\n setGeometrySize(size: THREE.Vector3Like) {\n this.mesh.geometry.scale(1 / this.previousScale.x, 1 / this.previousScale.y, 1 / this.previousScale.z);\n this.mesh.geometry.scale(size.x, size.y, size.z);\n this.previousScale = size;\n }\n\n /**\n * Use the matcap material for the instanced mesh.\n */\n useMatcapMaterial() {\n this.mesh.material = this.matcapMaterial;\n }\n\n /**\n * Use the specified geometry for the instanced mesh.\n * @param id The ID of the geometry to use.\n */\n useGeometry(id: string) {\n const geometry = this.geometries.get(id);\n if (geometry) {\n this.mesh.geometry = geometry;\n }\n }\n\n /**\n * Updates the velocity texture.\n * @param texture The velocity texture to update with.\n */\n updateVelocityTexture(texture: THREE.Texture) {\n this.matcapMaterial.uniforms.uVelocity.value = texture;\n }\n\n /**\n * Updates the position texture.\n * @param texture The position texture to update with.\n */\n updatePositionTexture(texture: THREE.Texture) {\n this.matcapMaterial.uniforms.uTexture.value = texture;\n }\n\n /**\n * Resizes or replaces the instanced mesh.\n * @param size The new size of the instanced mesh.\n * @returns An object containing the updated mesh, the previous mesh, and a boolean indicating whether the mesh was updated.\n */\n resize(size: number): { current: THREE.InstancedMesh; previous: THREE.InstancedMesh } {\n if (this.size === size) return { current: this.mesh, previous: this.mesh };\n\n this.size = size;\n\n // create new instances since it is greater than the last known value\n const prev = this.mesh;\n\n this.mesh = this.createInstancedMesh(size, prev.geometry, prev.material);\n\n return { current: this.mesh, previous: prev };\n }\n\n /**\n * Disposes the resources used by the InstancedMeshManager.\n */\n dispose() {\n this.mesh.dispose();\n\n this.geometries.forEach((geometry) => geometry.dispose());\n this.disposeSolidColorOriginTexture();\n this.disposeSolidColorDestinationTexture();\n this.matcapMaterial.dispose();\n\n this.uvRefsCache.clear();\n this.geometries.clear();\n }\n\n /**\n * Registers a geometry.\n * @param id The ID of the geometry to register.\n * @param geometry The geometry to register.\n */\n registerGeometry(id: string, geometry: THREE.BufferGeometry) {\n const previous = this.geometries.get(id);\n\n if (previous) {\n if (previous === geometry) {\n return;\n }\n }\n\n // finally, we are attaching uvRefs.\n const uvRefs = this.createUVRefs(this.size);\n geometry.setAttribute('uvRef', uvRefs);\n\n this.geometries.set(id, geometry);\n\n if (this.mesh.geometry === previous) {\n this.mesh.geometry = geometry;\n }\n\n previous?.dispose();\n }\n\n setOriginColor(color: THREE.ColorRepresentation) {\n this.disposeSolidColorOriginTexture();\n this.originColor = color;\n this.uniforms.uOriginTexture.value = this.createSolidColorDataTexture(color);\n }\n\n setDestinationColor(color: THREE.ColorRepresentation) {\n this.disposeSolidColorDestinationTexture();\n this.destinationColor = color;\n this.uniforms.uDestinationTexture.value = this.createSolidColorDataTexture(color);\n }\n\n /**\n * Gets the UV references for the specified size.\n * @param size The size for which to generate UV references.\n * @returns The UV references.\n */\n private createUVRefs(size: number) {\n const cached = this.uvRefsCache.get(size);\n\n if (cached) {\n return cached;\n }\n\n const uvRefs = new Float32Array(size * size * 2);\n\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n uvRefs[2 * index] = j / (size - 1);\n uvRefs[2 * index + 1] = i / (size - 1);\n }\n }\n\n const attr = new THREE.InstancedBufferAttribute(uvRefs, 2);\n\n this.uvRefsCache.set(size, attr);\n return attr;\n }\n\n /**\n * Creates a new instanced mesh.\n * @param size The size of the instanced mesh.\n * @param geometry The geometry to use for the instanced mesh.\n * @param material The material to use for the instanced mesh.\n * @returns The created instanced mesh.\n */\n private createInstancedMesh(size: number, geometry: THREE.BufferGeometry, material: THREE.Material | THREE.Material[]) {\n geometry = geometry || this.fallbackGeometry;\n geometry.setAttribute('uvRef', this.createUVRefs(size));\n const count = size * size;\n return new THREE.InstancedMesh(geometry, material, count);\n }\n\n private createSolidColorDataTexture(color: THREE.ColorRepresentation, size: number = 16): THREE.DataTexture {\n const col = new THREE.Color(color);\n const width = size;\n const height = size;\n const data = new Uint8Array(width * height * 4); // RGBA\n\n const r = Math.floor(col.r * 255);\n const g = Math.floor(col.g * 255);\n const b = Math.floor(col.b * 255);\n\n for (let i = 0; i < width * height; i++) {\n const index = i * 4;\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = 255; // Alpha\n }\n\n const texture = new THREE.DataTexture(data, width, height, THREE.RGBAFormat);\n texture.type = THREE.UnsignedByteType;\n texture.wrapS = THREE.RepeatWrapping; // Or ClampToEdgeWrapping\n texture.wrapT = THREE.RepeatWrapping; // Or ClampToEdgeWrapping\n texture.minFilter = THREE.NearestFilter; // Ensure sharp color\n texture.magFilter = THREE.NearestFilter;\n texture.needsUpdate = true;\n return texture;\n }\n\n private disposeSolidColorOriginTexture() {\n if (this.originColor) {\n this.originColor = null;\n if (this.uniforms.uOriginTexture.value) {\n this.uniforms.uOriginTexture.value.dispose();\n }\n }\n }\n\n private disposeSolidColorDestinationTexture() {\n if (this.destinationColor) {\n this.destinationColor = null;\n if (this.uniforms.uDestinationTexture.value) {\n this.uniforms.uDestinationTexture.value.dispose();\n }\n }\n }\n}\n","import { DefaultEventEmitter, EngineEventEmitter, Events } from '@/lib/events';\nimport * as THREE from 'three';\n\n/**\n * Service for calculating intersections between a ray and a morphed geometry.\n */\nexport class IntersectionService {\n private active: boolean = true;\n\n private raycaster = new THREE.Raycaster();\n private mousePosition = new THREE.Vector2();\n\n private camera?: THREE.Camera;\n private originGeometry?: THREE.BufferGeometry;\n private destinationGeometry?: THREE.BufferGeometry;\n\n private progress: number = 0;\n private intersectionMesh = new THREE.Mesh();\n\n private geometryNeedsUpdate: boolean;\n private eventEmitter: EngineEventEmitter<Events>;\n\n private blendedGeometry?: THREE.BufferGeometry;\n private intersection?: THREE.Vector4;\n\n private lastKnownOriginMeshID?: string;\n private lastKnownDestinationMeshID?: string;\n /**\n * Creates a new IntersectionService instance.\n * @param eventEmitter The event emitter used for emitting events.\n * @param camera The camera used for raycasting.\n * @param originGeometry The origin geometry.\n * @param destinationGeometry The destination geometry.\n */\n constructor(eventEmitter: DefaultEventEmitter, camera?: THREE.Camera, originGeometry?: THREE.BufferGeometry, destinationGeometry?: THREE.BufferGeometry) {\n this.camera = camera;\n this.originGeometry = originGeometry;\n this.eventEmitter = eventEmitter;\n this.destinationGeometry = destinationGeometry;\n this.geometryNeedsUpdate = true;\n }\n\n setActive(active: boolean) {\n this.active = active;\n }\n\n getIntersectionMesh(): THREE.Mesh {\n return this.intersectionMesh;\n }\n\n /**\n * Set the camera used for raycasting.\n * @param camera\n */\n setCamera(camera: THREE.Camera) {\n this.camera = camera;\n }\n\n /**\n * Set the origin geometry.\n * @param source\n */\n setOriginGeometry(source: THREE.Mesh) {\n if (this.lastKnownOriginMeshID === source.uuid) return;\n // dispose the previous geometry\n if (this.originGeometry) this.originGeometry.dispose();\n\n this.lastKnownOriginMeshID = source.uuid;\n // we need to clone the geometry because we are going to modify it.\n this.originGeometry = source.geometry.clone();\n this.originGeometry.applyMatrix4(source.matrixWorld);\n this.geometryNeedsUpdate = true;\n }\n\n /**\n * Set the destination geometry.\n * @param source\n */\n setDestinationGeometry(source: THREE.Mesh) {\n if (this.lastKnownDestinationMeshID === source.uuid) return;\n // dispose the previous geometry\n if (this.destinationGeometry) this.destinationGeometry.dispose();\n\n this.lastKnownDestinationMeshID = source.uuid;\n // we need to clone the geometry because we are going to modify it.\n this.destinationGeometry = source.geometry.clone();\n this.destinationGeometry.applyMatrix4(source.matrixWorld);\n\n this.geometryNeedsUpdate = true;\n }\n\n /**\n * Set the progress of the morphing animation.\n * @param progress\n */\n setProgress(progress: number) {\n this.progress = progress;\n this.geometryNeedsUpdate = true;\n }\n\n /**\n * Set the mouse position.\n * @param mousePosition\n */\n setPointerPosition(mousePosition?: THREE.Vector2Like) {\n if (mousePosition) this.mousePosition.copy(mousePosition);\n }\n\n /**\n * Calculate the intersection.\n * @returns The intersection point or undefined if no intersection was found.\n */\n calculate(instancedMesh: THREE.Mesh): THREE.Vector4 | undefined {\n if (!this.active) return;\n this.updateIntersectionMesh(instancedMesh);\n\n if (!this.camera) return;\n if (this.geometryNeedsUpdate) {\n this.geometryNeedsUpdate = false;\n this.blendedGeometry = this.getBlendedGeometry();\n }\n\n if (this.blendedGeometry) {\n this.intersection = this.getFirstIntersection(this.camera, instancedMesh);\n } else {\n this.intersection = undefined;\n }\n\n if (this.intersection) {\n this.eventEmitter.emit('interactionPositionUpdated', { position: this.intersection });\n } else {\n this.eventEmitter.emit('interactionPositionUpdated', { position: { x: 0, y: 0, z: 0, w: 0 } });\n }\n\n return this.intersection;\n }\n\n /**\n * Dispose the resources used by the IntersectionService.\n */\n dispose() {\n this.blendedGeometry?.dispose();\n this.intersectionMesh.geometry.dispose();\n }\n\n private updateIntersectionMesh(instancedMesh: THREE.Mesh) {\n if (this.blendedGeometry) {\n if (this.blendedGeometry.uuid !== this.intersectionMesh.geometry.uuid) {\n this.intersectionMesh.geometry.dispose();\n this.intersectionMesh.geometry = this.blendedGeometry;\n }\n }\n this.intersectionMesh.matrix.copy(instancedMesh.matrixWorld);\n this.intersectionMesh.matrixWorld.copy(instancedMesh.matrixWorld);\n this.intersectionMesh.matrixAutoUpdate = false;\n this.intersectionMesh.updateMatrixWorld(true);\n }\n\n private getFirstIntersection(camera: THREE.Camera, instancedMesh: THREE.Mesh) {\n this.raycaster.setFromCamera(this.mousePosition, camera);\n\n const intersection = this.raycaster.intersectObject(this.intersectionMesh, false)[0];\n if (intersection) {\n const worldPoint = intersection.point.clone();\n const localPoint = instancedMesh.worldToLocal(worldPoint);\n return new THREE.Vector4(localPoint.x, localPoint.y, localPoint.z, 1);\n }\n }\n\n private getBlendedGeometry() {\n if (this.progress === 0) {\n return this.originGeometry;\n }\n if (this.progress === 1) {\n return this.destinationGeometry;\n }\n\n if (!this.originGeometry || !this.destinationGeometry) {\n return;\n }\n\n if (this.originGeometry === this.destinationGeometry) {\n // if same, just return one of them\n return this.originGeometry;\n }\n\n return this.blendGeometry(this.originGeometry, this.destinationGeometry, this.progress);\n }\n\n private blendGeometry(from: THREE.BufferGeometry, to: THREE.BufferGeometry, progress: number): THREE.BufferGeometry {\n const blended = new THREE.BufferGeometry();\n const originPositions = from.attributes.position.array;\n const destinationPositions = to.attributes.position.array;\n const blendedPositions = new Float32Array(originPositions.length);\n\n for (let i = 0; i < originPositions.length; i += 3) {\n const originVert = new THREE.Vector3(originPositions[i], originPositions[i + 1], originPositions[i + 2]);\n const destinationVert = new THREE.Vector3(destinationPositions[i], destinationPositions[i + 1], destinationPositions[i + 2]);\n const blendedVert = new THREE.Vector3().lerpVectors(originVert, destinationVert, progress);\n\n blendedPositions[i] = blendedVert.x;\n blendedPositions[i + 1] = blendedVert.y;\n blendedPositions[i + 2] = blendedVert.z;\n }\n\n blended.setAttribute('position', new THREE.BufferAttribute(blendedPositions, 3));\n\n if (from.attributes.normal) blended.setAttribute('normal', from.attributes.normal.clone());\n if (from.attributes.uv) blended.setAttribute('uv', from.attributes.uv.clone());\n if (from.index) blended.setIndex(from.index.clone());\n\n return blended;\n }\n}\n","import {\n\tBufferGeometry,\n\tFloat32BufferAttribute,\n\tOrthographicCamera,\n\tMesh\n} from 'three';\n\nclass Pass {\n\n\tconstructor() {\n\n\t\tthis.isPass = true;\n\n\t\t// if set to true, the pass is processed by the composer\n\t\tthis.enabled = true;\n\n\t\t// if set to true, the pass indicates to swap read and write buffer after rendering\n\t\tthis.needsSwap = true;\n\n\t\t// if set to true, the pass clears its buffer before rendering\n\t\tthis.clear = false;\n\n\t\t// if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.\n\t\tthis.renderToScreen = false;\n\n\t}\n\n\tsetSize( /* width, height */ ) {}\n\n\trender( /* renderer, writeBuffer, readBuffer, deltaTime, maskActive */ ) {\n\n\t\tconsole.error( 'THREE.Pass: .render() must be implemented in derived pass.' );\n\n\t}\n\n\tdispose() {}\n\n}\n\n// Helper for passes that need to fill the viewport with a single quad.\n\nconst _camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n// https://github.com/mrdoob/three.js/pull/21358\n\nclass FullscreenTriangleGeometry extends BufferGeometry {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );\n\n\t}\n\n}\n\nconst _geometry = new FullscreenTriangleGeometry();\n\nclass FullScreenQuad {\n\n\tconstructor( material ) {\n\n\t\tthis._mesh = new Mesh( _geometry, material );\n\n\t}\n\n\tdispose() {\n\n\t\tthis._mesh.geometry.dispose();\n\n\t}\n\n\trender( renderer ) {\n\n\t\trenderer.render( this._mesh, _camera );\n\n\t}\n\n\tget material() {\n\n\t\treturn this._mesh.material;\n\n\t}\n\n\tset material( value ) {\n\n\t\tthis._mesh.material = value;\n\n\t}\n\n}\n\nexport { Pass, FullScreenQuad };\n","import {\n\tClampToEdgeWrapping,\n\tDataTexture,\n\tFloatType,\n\tNearestFilter,\n\tRGBAFormat,\n\tShaderMaterial,\n\tWebGLRenderTarget\n} from 'three';\n\nimport { FullScreenQuad } from '../postprocessing/Pass.js';\n\n/**\n * GPUComputationRenderer, based on SimulationRenderer by zz85\n *\n * The GPUComputationRenderer uses the concept of variables. These variables are RGBA float textures that hold 4 floats\n * for each compute element (texel)\n *\n * Each variable has a fragment shader that defines the computation made to obtain the variable in question.\n * You can use as many variables you need, and make dependencies so you can use textures of other variables in the shader\n * (the sampler uniforms are added automatically) Most of the variables will need themselves as dependency.\n *\n * The renderer has actually two render targets per variable, to make ping-pong. Textures from the current frame are used\n * as inputs to render the textures of the next frame.\n *\n * The render targets of the variables can be used as input textures for your visualization shaders.\n *\n * Variable names should be valid identifiers and should not collide with THREE GLSL used identifiers.\n * a common approach could be to use 'texture' prefixing the variable name; i.e texturePosition, textureVelocity...\n *\n * The size of the computation (sizeX * sizeY) is defined as 'resolution' automatically in the shader. For example:\n * #DEFINE resolution vec2( 1024.0, 1024.0 )\n *\n * -------------\n *\n * Basic use:\n *\n * // Initialization...\n *\n * // Create computation renderer\n * const gpuCompute = new GPUComputationRenderer( 1024, 1024, renderer );\n *\n * // Create initial state float textures\n * const pos0 = gpuCompute.createTexture();\n * const vel0 = gpuCompute.createTexture();\n * // and fill in here the texture data...\n *\n * // Add texture variables\n * const velVar = gpuCompute.addVariable( \"textureVelocity\", fragmentShaderVel, vel0 );\n * const posVar = gpuCompute.addVariable( \"texturePosition\", fragmentShaderPos, pos0 );\n *\n * // Add variable dependencies\n * gpuCompute.setVariableDependencies( velVar, [ velVar, posVar ] );\n * gpuCompute.setVariableDependencies( posVar, [ velVar, posVar ] );\n *\n * // Add custom uniforms\n * velVar.material.uniforms.time = { value: 0.0 };\n *\n * // Check for completeness\n * const error = gpuCompute.init();\n * if ( error !== null ) {\n *\t\tconsole.error( error );\n * }\n *\n *\n * // In each frame...\n *\n * // Compute!\n * gpuCompute.compute();\n *\n * // Update texture uniforms in your visualization materials with the gpu renderer output\n * myMaterial.uniforms.myTexture.value = gpuCompute.getCurrentRenderTarget( posVar ).texture;\n *\n * // Do your rendering\n * renderer.render( myScene, myCamera );\n *\n * -------------\n *\n * Also, you can use utility functions to create ShaderMaterial and perform computations (rendering between textures)\n * Note that the shaders can have multiple input textures.\n *\n * const myFilter1 = gpuCompute.createShaderMaterial( myFilterFragmentShader1, { theTexture: { value: null } } );\n * const myFilter2 = gpuCompute.createShaderMaterial( myFilterFragmentShader2, { theTexture: { value: null } } );\n *\n * const inputTexture = gpuCompute.createTexture();\n *\n * // Fill in here inputTexture...\n *\n * myFilter1.uniforms.theTexture.value = inputTexture;\n *\n * const myRenderTarget = gpuCompute.createRenderTarget();\n * myFilter2.uniforms.theTexture.value = myRenderTarget.texture;\n *\n * const outputRenderTarget = gpuCompute.createRenderTarget();\n *\n * // Now use the output texture where you want:\n * myMaterial.uniforms.map.value = outputRenderTarget.texture;\n *\n * // And compute each frame, before rendering to screen:\n * gpuCompute.doRenderTarget( myFilter1, myRenderTarget );\n * gpuCompute.doRenderTarget( myFilter2, outputRenderTarget );\n */\n\nclass GPUComputationRenderer {\n\n\t/**\n\t * @param {Number} sizeX Computation problem size is always 2d: sizeX * sizeY elements.\n \t * @param {Number} sizeY Computation problem size is always 2d: sizeX * sizeY elements.\n \t * @param {WebGLRenderer} renderer The renderer\n\t */\n\tconstructor( sizeX, sizeY, renderer ) {\n\n\t\tthis.variables = [];\n\n\t\tthis.currentTextureIndex = 0;\n\n\t\tlet dataType = FloatType;\n\n\t\tconst passThruUniforms = {\n\t\t\tpassThruTexture: { value: null }\n\t\t};\n\n\t\tconst passThruShader = createShaderMaterial( getPassThroughFragmentShader(), passThruUniforms );\n\n\t\tconst quad = new FullScreenQuad( passThruShader );\n\n\t\tthis.setDataType = function ( type ) {\n\n\t\t\tdataType = type;\n\t\t\treturn this;\n\n\t\t};\n\n\t\tthis.addVariable = function ( variableName, computeFragmentShader, initialValueTexture ) {\n\n\t\t\tconst material = this.createShaderMaterial( computeFragmentShader );\n\n\t\t\tconst variable = {\n\t\t\t\tname: variableName,\n\t\t\t\tinitialValueTexture: initialValueTexture,\n\t\t\t\tmaterial: material,\n\t\t\t\tdependencies: null,\n\t\t\t\trenderTargets: [],\n\t\t\t\twrapS: null,\n\t\t\t\twrapT: null,\n\t\t\t\tminFilter: NearestFilter,\n\t\t\t\tmagFilter: NearestFilter\n\t\t\t};\n\n\t\t\tthis.variables.push( variable );\n\n\t\t\treturn variable;\n\n\t\t};\n\n\t\tthis.setVariableDependencies = function ( variable, dependencies ) {\n\n\t\t\tvariable.dependencies = dependencies;\n\n\t\t};\n\n\t\tthis.init = function () {\n\n\t\t\tif ( renderer.capabilities.maxVertexTextures === 0 ) {\n\n\t\t\t\treturn 'No support for vertex shader textures.';\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0; i < this.variables.length; i ++ ) {\n\n\t\t\t\tconst variable = this.variables[ i ];\n\n\t\t\t\t// Creates rendertargets and initialize them with input texture\n\t\t\t\tvariable.renderTargets[ 0 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter );\n\t\t\t\tvariable.renderTargets[ 1 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter );\n\t\t\t\tthis.renderTexture( variable.initialValueTexture, variable.renderTargets[ 0 ] );\n\t\t\t\tthis.renderTexture( variable.initialValueTexture, variable.renderTargets[ 1 ] );\n\n\t\t\t\t// Adds dependencies uniforms to the ShaderMaterial\n\t\t\t\tconst material = variable.material;\n\t\t\t\tconst uniforms = material.uniforms;\n\n\t\t\t\tif ( variable.dependencies !== null ) {\n\n\t\t\t\t\tfor ( let d = 0; d < variable.dependencies.length; d ++ ) {\n\n\t\t\t\t\t\tconst depVar = variable.dependencies[ d ];\n\n\t\t\t\t\t\tif ( depVar.name !== variable.name ) {\n\n\t\t\t\t\t\t\t// Checks if variable exists\n\t\t\t\t\t\t\tlet found = false;\n\n\t\t\t\t\t\t\tfor ( let j = 0; j < this.variables.length; j ++ ) {\n\n\t\t\t\t\t\t\t\tif ( depVar.name === this.variables[ j ].name ) {\n\n\t\t\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( ! found ) {\n\n\t\t\t\t\t\t\t\treturn 'Variable dependency not found. Variable=' + variable.name + ', dependency=' + depVar.name;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tuniforms[ depVar.name ] = { value: null };\n\n\t\t\t\t\t\tmaterial.fragmentShader = '\\nuniform sampler2D ' + depVar.name + ';\\n' + material.fragmentShader;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.currentTextureIndex = 0;\n\n\t\t\treturn null;\n\n\t\t};\n\n\t\tthis.compute = function () {\n\n\t\t\tconst currentTextureIndex = this.currentTextureIndex;\n\t\t\tconst nextTextureIndex = this.currentTextureIndex === 0 ? 1 : 0;\n\n\t\t\tfor ( let i = 0, il = this.variables.length; i < il; i ++ ) {\n\n\t\t\t\tconst variable = this.variables[ i ];\n\n\t\t\t\t// Sets texture dependencies uniforms\n\t\t\t\tif ( variable.dependencies !== null ) {\n\n\t\t\t\t\tconst uniforms = variable.material.uniforms;\n\n\t\t\t\t\tfor ( let d = 0, dl = variable.dependencies.length; d < dl; d ++ ) {\n\n\t\t\t\t\t\tconst depVar = variable.dependencies[ d ];\n\n\t\t\t\t\t\tuniforms[ depVar.name ].value = depVar.renderTargets[ currentTextureIndex ].texture;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Performs the computation for this variable\n\t\t\t\tthis.doRenderTarget( variable.material, variable.renderTargets[ nextTextureIndex ] );\n\n\t\t\t}\n\n\t\t\tthis.currentTextureIndex = nextTextureIndex;\n\n\t\t};\n\n\t\tthis.getCurrentRenderTarget = function ( variable ) {\n\n\t\t\treturn variable.renderTargets[ this.currentTextureIndex ];\n\n\t\t};\n\n\t\tthis.getAlternateRenderTarget = function ( variable ) {\n\n\t\t\treturn variable.renderTargets[ this.currentTextureIndex === 0 ? 1 : 0 ];\n\n\t\t};\n\n\t\tthis.dispose = function () {\n\n\t\t\tquad.dispose();\n\n\t\t\tconst variables = this.variables;\n\n\t\t\tfor ( let i = 0; i < variables.length; i ++ ) {\n\n\t\t\t\tconst variable = variables[ i ];\n\n\t\t\t\tif ( variable.initialValueTexture ) variable.initialValueTexture.dispose();\n\n\t\t\t\tconst renderTargets = variable.renderTargets;\n\n\t\t\t\tfor ( let j = 0; j < renderTargets.length; j ++ ) {\n\n\t\t\t\t\tconst renderTarget = renderTargets[ j ];\n\t\t\t\t\trenderTarget.dispose();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction addResolutionDefine( materialShader ) {\n\n\t\t\tmaterialShader.defines.resolution = 'vec2( ' + sizeX.toFixed( 1 ) + ', ' + sizeY.toFixed( 1 ) + ' )';\n\n\t\t}\n\n\t\tthis.addResolutionDefine = addResolutionDefine;\n\n\n\t\t// The following functions can be used to compute things manually\n\n\t\tfunction createShaderMaterial( computeFragmentShader, uniforms ) {\n\n\t\t\tuniforms = uniforms || {};\n\n\t\t\tconst material = new ShaderMaterial( {\n\t\t\t\tname: 'GPUComputationShader',\n\t\t\t\tuniforms: uniforms,\n\t\t\t\tvertexShader: getPassThroughVertexShader(),\n\t\t\t\tfragmentShader: computeFragmentShader\n\t\t\t} );\n\n\t\t\taddResolutionDefine( material );\n\n\t\t\treturn material;\n\n\t\t}\n\n\t\tthis.createShaderMaterial = createShaderMaterial;\n\n\t\tthis.createRenderTarget = function ( sizeXTexture, sizeYTexture, wrapS, wrapT, minFilter, magFilter ) {\n\n\t\t\tsizeXTexture = sizeXTexture || sizeX;\n\t\t\tsizeYTexture = sizeYTexture || sizeY;\n\n\t\t\twrapS = wrapS || ClampToEdgeWrapping;\n\t\t\twrapT = wrapT || ClampToEdgeWrapping;\n\n\t\t\tminFilter = minFilter || NearestFilter;\n\t\t\tmagFilter = magFilter || NearestFilter;\n\n\t\t\tconst renderTarget = new WebGLRenderTarget( sizeXTexture, sizeYTexture, {\n\t\t\t\twrapS: wrapS,\n\t\t\t\twrapT: wrapT,\n\t\t\t\tminFilter: minFilter,\n\t\t\t\tmagFilter: magFilter,\n\t\t\t\tformat: RGBAFormat,\n\t\t\t\ttype: dataType,\n\t\t\t\tdepthBuffer: false\n\t\t\t} );\n\n\t\t\treturn renderTarget;\n\n\t\t};\n\n\t\tthis.createTexture = function () {\n\n\t\t\tconst data = new Float32Array( sizeX * sizeY * 4 );\n\t\t\tconst texture = new DataTexture( data, sizeX, sizeY, RGBAFormat, FloatType );\n\t\t\ttexture.needsUpdate = true;\n\t\t\treturn texture;\n\n\t\t};\n\n\t\tthis.renderTexture = function ( input, output ) {\n\n\t\t\t// Takes a texture, and render out in rendertarget\n\t\t\t// input = Texture\n\t\t\t// output = RenderTarget\n\n\t\t\tpassThruUniforms.passThruTexture.value = input;\n\n\t\t\tthis.doRenderTarget( passThruShader, output );\n\n\t\t\tpassThruUniforms.passThruTexture.value = null;\n\n\t\t};\n\n\t\tthis.doRenderTarget = function ( material, output ) {\n\n\t\t\tconst currentRenderTarget = renderer.getRenderTarget();\n\n\t\t\tconst currentXrEnabled = renderer.xr.enabled;\n\t\t\tconst currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;\n\n\t\t\trenderer.xr.enabled = false; // Avoid camera modification\n\t\t\trenderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows\n\t\t\tquad.material = material;\n\t\t\trenderer.setRenderTarget( output );\n\t\t\tquad.render( renderer );\n\t\t\tquad.material = passThruShader;\n\n\t\t\trenderer.xr.enabled = currentXrEnabled;\n\t\t\trenderer.shadowMap.autoUpdate = currentShadowAutoUpdate;\n\n\t\t\trenderer.setRenderTarget( currentRenderTarget );\n\n\t\t};\n\n\t\t// Shaders\n\n\t\tfunction getPassThroughVertexShader() {\n\n\t\t\treturn\t'void main()\t{\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tgl_Position = vec4( position, 1.0 );\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'}\\n';\n\n\t\t}\n\n\t\tfunction getPassThroughFragmentShader() {\n\n\t\t\treturn\t'uniform sampler2D passThruTexture;\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'void main() {\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tvec2 uv = gl_FragCoord.xy / resolution.xy;\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tgl_FragColor = texture2D( passThruTexture, uv );\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'}\\n';\n\n\t\t}\n\n\t}\n\n}\n\nexport { GPUComputationRenderer };\n","export default `\nuniform sampler2D uPositionA;\nuniform sampler2D uPositionB;\nuniform float uProgress;\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n vec3 positionA = texture2D(uPositionA, uv).xyz;\n vec3 positionB = texture2D(uPositionB, uv).xyz;\n vec3 mixedPosition = mix(positionA, positionB, uProgress);\n gl_FragColor = vec4(mixedPosition, 1.0);\n}\n`;\n","export default `\nuniform float uProgress;\nuniform vec4 uInteractionPosition;\nuniform float uTime;\nuniform float uTractionForce;\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main() {\n\n // in GPGPU, we calculate the uv on each fragment shader, not using the static varying passed over from the v shader.\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n float offset = rand(uv);\n\n vec3 position = texture2D(uCurrentPosition, uv).xyz;\n vec3 velocity = texture2D(uCurrentVelocity, uv).xyz;\n vec3 mixedPosition = texture2D(uMixedPosition, uv).xyz;\n\n // particle attraction to original position.\n vec3 direction = normalize(mixedPosition - position); // direction vector\n float dist = length ( mixedPosition - position ); // distance from where it was supposed to be, and currently are.\n\n if (dist > 0.01) {\n position = mix(position, mixedPosition, 0.1 * uTractionForce); // 0.1 ~ 0.001 (faster, slower)\n }\n\n position += velocity;\n gl_FragColor = vec4(position, 1.0);\n}\n`;\n","export default `\nuniform float uProgress;\nuniform vec4 uInteractionPosition;\nuniform float uTime;\nuniform float uTractionForce;\nuniform float uMaxRepelDistance;\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n float offset = rand(uv);\n\n vec3 position = texture2D(uCurrentPosition, uv).xyz;\n vec3 velocity = texture2D(uCurrentVelocity, uv).xyz;\n vec3 mixedPosition = texture2D(uMixedPosition, uv).xyz;\n\n velocity *= 0.9;\n\n // particle traction\n vec3 direction = normalize(mixedPosition - position); // direction vector\n float dist = length ( mixedPosition - position ); // distance from where it was supposed to be, and currently are.\n if (dist > 0.01) {\n position += direction * 0.1 * uTractionForce; // uTractionForce defaults to 0.1\n }\n\n // mouse repel force\n float pointerDistance = distance(position, uInteractionPosition.xyz);\n float mouseRepelModifier = clamp(uMaxRepelDistance - pointerDistance, 0.0, 1.0);\n float normalizedDistance = pointerDistance / uMaxRepelDistance;\n float repulsionStrength = (1.0 - normalizedDistance) * uInteractionPosition.w;\n direction = normalize(position - uInteractionPosition.xyz);\n velocity += (direction * 0.01 * repulsionStrength) * mouseRepelModifier;\n\n float lifespan = 20.0;\n float age = mod(uTime + lifespan * offset, lifespan);\n\n if (age < 0.1) {\n position.xyz = mixedPosition;\n }\n\n gl_FragColor = vec4(velocity, 1.0);\n}\n`;\n","import { clamp, createBlankDataTexture, createSpherePoints } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { GPUComputationRenderer, Variable } from 'three/examples/jsm/misc/GPUComputationRenderer.js';\nimport mixShader from './shaders/simulationMixShader';\nimport positionShader from './shaders/simulationPositionShader';\nimport velocityShader from './shaders/simulationVelocityShader';\n\n/**\n * SimulationRenderer is responsible for running the particle simulation using the GPU.\n */\nexport class SimulationRenderer {\n gpuComputationRenderer: GPUComputationRenderer;\n webGLRenderer: THREE.WebGLRenderer;\n\n // calculations\n private readonly positionDataTexture: THREE.DataTexture;\n private readonly velocityDataTexture: THREE.DataTexture;\n\n // GPUComputationRenderer variables\n private readonly mixPositionsVar: Variable;\n private readonly velocityVar: Variable;\n private readonly positionVar: Variable;\n\n readonly interactionPosition: THREE.Vector4;\n\n private lastKnownPositionDataTexture: THREE.Texture;\n private lastKnownVelocityDataTexture: THREE.Texture;\n private lastKnownMixProgress: number;\n\n private readonly initialDataTexture: THREE.DataTexture;\n\n /**\n * Creates a new SimulationRenderer instance.\n * @param size The size of the simulation textures.\n * @param webGLRenderer The WebGL renderer.\n * @param initialPosition The initial position data texture. If not provided, a default sphere will be used.\n */\n constructor(size: number, webGLRenderer: THREE.WebGLRenderer, initialPosition?: THREE.DataTexture) {\n this.initialDataTexture = initialPosition ?? createSpherePoints(size);\n this.positionDataTexture = this.initialDataTexture;\n\n this.webGLRenderer = webGLRenderer;\n this.gpuComputationRenderer = new GPUComputationRenderer(size, size, this.webGLRenderer);\n this.lastKnownMixProgress = 0;\n\n if (!webGLRenderer.capabilities.isWebGL2) {\n this.gpuComputationRenderer.setDataType(THREE.HalfFloatType);\n }\n\n this.velocityDataTexture = createBlankDataTexture(size);\n this.interactionPosition = new THREE.Vector4(0, 0, 0, 0);\n\n // init gpgpu render target textures.\n this.mixPositionsVar = this.gpuComputationRenderer.addVariable('uMixedPosition', mixShader, this.positionDataTexture);\n this.velocityVar = this.gpuComputationRenderer.addVariable('uCurrentVelocity', velocityShader, this.velocityDataTexture);\n this.positionVar = this.gpuComputationRenderer.addVariable('uCurrentPosition', positionShader, this.positionDataTexture);\n\n // attach uniforms\n this.mixPositionsVar.material.uniforms.uProgress = { value: 0 };\n this.mixPositionsVar.material.uniforms.uPositionA = { value: this.initialDataTexture };\n this.mixPositionsVar.material.uniforms.uPositionB = { value: this.initialDataTexture };\n\n this.velocityVar.material.uniforms.uTime = { value: 0 };\n this.velocityVar.material.uniforms.uInteractionPosition = { value: this.interactionPosition };\n this.velocityVar.material.uniforms.uCurrentPosition = { value: this.positionDataTexture };\n this.velocityVar.material.uniforms.uTractionForce = { value: 0.1 };\n this.velocityVar.material.uniforms.uMaxRepelDistance = { value: 0.3 };\n\n this.positionVar.material.uniforms.uTime = { value: 0 };\n this.positionVar.material.uniforms.uProgress = { value: 0 };\n this.positionVar.material.uniforms.uTractionForce = { value: 0.1 };\n this.positionVar.material.uniforms.uInteractionPosition = { value: this.interactionPosition };\n this.positionVar.material.uniforms.uCurrentPosition = { value: this.positionDataTexture };\n\n this.gpuComputationRenderer.setVariableDependencies(this.positionVar, [this.velocityVar, this.positionVar, this.mixPositionsVar]);\n this.gpuComputationRenderer.setVariableDependencies(this.velocityVar, [this.velocityVar, this.positionVar, this.mixPositionsVar]);\n\n const err = this.gpuComputationRenderer.init();\n if (err) {\n throw new Error('failed to initialize SimulationRenderer: ' + err);\n }\n\n this.lastKnownVelocityDataTexture = this.getVelocityTexture();\n this.lastKnownPositionDataTexture = this.getPositionTexture();\n }\n\n /**\n * Sets the source data texture for morphing.\n * @param texture The source data texture.\n */\n setMorphSourceDataTexture(texture: THREE.DataTexture) {\n this.mixPositionsVar.material.uniforms.uPositionA.value = texture;\n }\n\n /**\n * Sets the destination data texture for morphing.\n * @param texture The destination data texture.\n */\n setMorphDestinationDataTexture(texture: THREE.DataTexture) {\n this.mixPositionsVar.material.uniforms.uPositionB.value = texture;\n }\n\n setMaxRepelDistance(distance: number) {\n this.velocityVar.material.uniforms.uMaxRepelDistance.value = distance;\n }\n\n /**\n * Sets the progress of the morphing animation.\n * @param progress The progress value, between 0 and 1.\n */\n setProgress(progress: number) {\n this.lastKnownMixProgress = clamp(progress, 0, 1);\n this.mixPositionsVar.material.uniforms.uProgress.value = this.lastKnownMixProgress;\n }\n\n setVelocityTractionForce(force: number) {\n this.velocityVar.material.uniforms.uTractionForce.value = force;\n }\n\n setPositionalTractionForce(force: number) {\n this.positionVar.material.uniforms.uTractionForce.value = force;\n }\n\n setInteractionPosition(position: THREE.Vector4Like) {\n this.interactionPosition.copy(position);\n }\n\n /**\n * Disposes the resources used by the simulation renderer.\n */\n dispose() {\n this.mixPositionsVar.renderTargets.forEach((rtt) => rtt.dispose());\n this.positionVar.renderTargets.forEach((rtt) => rtt.dispose());\n this.velocityVar.renderTargets.forEach((rtt) => rtt.dispose());\n\n this.positionDataTexture.dispose();\n this.velocityDataTexture.dispose();\n\n this.gpuComputationRenderer.dispose();\n }\n\n /**\n * Computes the next step of the simulation.\n * @param elapsedTime The elapsed time since the simulation started.\n */\n compute(elapsedTime: number) {\n this.velocityVar.material.uniforms.uTime.value = elapsedTime;\n this.positionVar.material.uniforms.uTime.value = elapsedTime;\n this.gpuComputationRenderer.compute();\n }\n\n /**\n * Gets the current velocity texture.\n * @returns The current velocity texture.\n */\n getVelocityTexture(): THREE.Texture {\n this.lastKnownVelocityDataTexture = this.gpuComputationRenderer.getCurrentRenderTarget(this.velocityVar).texture;\n return this.lastKnownVelocityDataTexture;\n }\n\n /**\n * Gets the current position texture.\n * @returns The current position texture.\n */\n getPositionTexture(): THREE.Texture {\n this.lastKnownPositionDataTexture = this.gpuComputationRenderer.getCurrentRenderTarget(this.positionVar).texture;\n return this.lastKnownPositionDataTexture;\n }\n}\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { DataTextureEntry, ServiceState } from '@/lib/types';\nimport * as THREE from 'three';\nimport { SimulationRenderer } from './simulationRenderer';\n\nexport class SimulationRendererService {\n private state!: ServiceState;\n private textureSize: number;\n private dataTextureTransitionProgress: number;\n private velocityTractionForce: number;\n private positionalTractionForce: number;\n\n private simulationRenderer;\n private webGLRenderer;\n private eventEmitter;\n\n private lastKnownVelocityDataTexture: THREE.Texture;\n private lastKnownPositionDataTexture: THREE.Texture;\n\n constructor(eventEmitter: DefaultEventEmitter, size: number, webGLRenderer: THREE.WebGLRenderer) {\n this.eventEmitter = eventEmitter;\n this.webGLRenderer = webGLRenderer;\n this.textureSize = size;\n this.dataTextureTransitionProgress = 0;\n this.velocityTractionForce = 0.1;\n this.positionalTractionForce = 0.1;\n\n this.updateServiceState('initializing');\n\n this.simulationRenderer = new SimulationRenderer(this.textureSize, this.webGLRenderer);\n this.lastKnownVelocityDataTexture = this.simulationRenderer.getVelocityTexture();\n this.lastKnownPositionDataTexture = this.simulationRenderer.getPositionTexture();\n\n this.updateServiceState('ready');\n }\n\n setTextureSize(size: number) {\n this.updateServiceState('initializing');\n this.simulationRenderer.dispose();\n this.textureSize = size;\n this.simulationRenderer = new SimulationRenderer(size, this.webGLRenderer);\n this.updateServiceState('ready');\n }\n\n setOriginDataTexture(entry: DataTextureEntry) {\n if (this.textureSize !== entry.textureSize) {\n this.eventEmitter.emit('invalidRequest', { message: `Texture size mismatch: ${entry.textureSize} vs ${this.textureSize}` });\n } else {\n this.simulationRenderer.setMorphSourceDataTexture(entry.dataTexture);\n }\n }\n\n setDestinationDataTexture(entry: DataTextureEntry) {\n if (this.textureSize !== entry.textureSize) {\n this.eventEmitter.emit('invalidRequest', { message: `Texture size mismatch: ${entry.textureSize} vs ${this.textureSize}` });\n } else {\n this.simulationRenderer.setMorphDestinationDataTexture(entry.dataTexture);\n }\n }\n\n setDataTextureTransitionProgress(progress: number) {\n this.dataTextureTransitionProgress = progress;\n this.simulationRenderer.setProgress(this.dataTextureTransitionProgress);\n }\n\n setVelocityTractionForce(force: number) {\n this.velocityTractionForce = force;\n this.simulationRenderer.setVelocityTractionForce(this.velocityTractionForce);\n }\n\n setPositionalTractionForce(force: number) {\n this.positionalTractionForce = force;\n this.simulationRenderer.setPositionalTractionForce(this.positionalTractionForce);\n }\n\n compute(elapsedTime: number) {\n this.simulationRenderer.compute(elapsedTime);\n }\n\n getVelocityTexture(): THREE.Texture {\n if (this.state === 'ready') this.lastKnownVelocityDataTexture = this.simulationRenderer.getVelocityTexture();\n return this.lastKnownVelocityDataTexture;\n }\n\n getPositionTexture(): THREE.Texture {\n if (this.state === 'ready') this.lastKnownPositionDataTexture = this.simulationRenderer.getPositionTexture();\n return this.lastKnownPositionDataTexture;\n }\n\n dispose() {\n this.updateServiceState('disposed');\n this.simulationRenderer.dispose();\n this.lastKnownVelocityDataTexture.dispose();\n this.lastKnownPositionDataTexture.dispose();\n }\n\n private updateServiceState(serviceState: ServiceState) {\n this.state = serviceState;\n this.eventEmitter.emit('serviceStateUpdated', { type: 'simulation', state: serviceState });\n }\n\n setInteractionPosition(position: THREE.Vector4Like) {\n this.simulationRenderer.setInteractionPosition(position);\n }\n\n setMaxRepelDistance(distance: number) {\n this.simulationRenderer.setMaxRepelDistance(distance);\n }\n}\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { TransitionDetail, TransitionOptions, TransitionType } from '@/lib/types';\nimport { clamp } from '@/lib/utils';\n\ntype ExecStatus = 'idle' | 'running';\n\ntype TransitionQueueItem = { cancelled: boolean; startTime?: number } & TransitionDetail & TransitionOptions;\ntype OngoingTransition = { startTime: number } & TransitionQueueItem;\n\nclass ExecutionStatusMap {\n private readonly execStatus = new Map<TransitionType, ExecStatus>();\n\n get(type: TransitionType): ExecStatus {\n const status = this.execStatus.get(type);\n if (!status) {\n this.execStatus.set(type, 'idle');\n return 'idle';\n }\n return status;\n }\n\n set(type: TransitionType, status: ExecStatus) {\n this.execStatus.set(type, status);\n }\n}\n\nexport class TransitionService {\n private readonly eventEmitter;\n private readonly transitions: Map<TransitionType, Array<TransitionQueueItem>> = new Map();\n private readonly execStatus: ExecutionStatusMap;\n private readonly ongoingTransitions: Map<TransitionType, OngoingTransition> = new Map();\n\n constructor(eventEmitter: DefaultEventEmitter) {\n this.eventEmitter = eventEmitter;\n this.execStatus = new ExecutionStatusMap();\n this.eventEmitter.on('transitionCancelled', this.handleTransitionCancelledEvent.bind(this));\n }\n\n /**\n * Enqueues a transition.\n * @param type - The type of transition.\n * @param transition - The transition details.\n * @param options - Optional transition options.\n */\n enqueue<T extends TransitionType>(type: T, transition: TransitionDetail, options: TransitionOptions = {}) {\n const transitionQueueItem: TransitionQueueItem = {\n ...transition,\n ...options,\n cancelled: false,\n duration: transition.duration * 0.001, // convert to seconds\n };\n this.getQueue(type).push(transitionQueueItem);\n }\n\n compute(elapsedTime: number) {\n this.transitions.forEach((queue, type) => {\n if (queue.length && !this.ongoingTransitions.has(type)) {\n const transition = queue.shift();\n if (transition) {\n this.ongoingTransitions.set(type, { ...transition, startTime: elapsedTime });\n transition.onTransitionBegin?.();\n }\n }\n });\n\n this.ongoingTransitions.forEach((transition, type) => {\n if (transition.cancelled) {\n transition.onTransitionCancelled?.();\n this.ongoingTransitions.delete(type);\n return;\n }\n\n const { startTime, duration, easing } = transition;\n\n const timeDistance = elapsedTime - startTime;\n const progress = clamp(easing(Math.min(1.0, timeDistance / duration)), 0.0, 1.0);\n\n this.emitTransitionProgress(type, progress);\n transition.onTransitionProgress?.(progress);\n\n if (progress >= 1) {\n this.emitTransitionFinished(type);\n transition.onTransitionFinished?.();\n this.ongoingTransitions.delete(type);\n }\n });\n }\n\n private getQueue(type: TransitionType): Array<TransitionQueueItem> {\n const queue = this.transitions.get(type);\n if (!queue) {\n this.transitions.set(type, []);\n return this.transitions.get(type) ?? [];\n }\n return queue;\n }\n\n private handleTransitionCancelledEvent({ type }: { type: TransitionType }) {\n const transitions = this.getQueue(type);\n while (transitions.length) transitions.pop();\n\n const ongoingTransition = this.ongoingTransitions.get(type);\n if (ongoingTransition) {\n ongoingTransition.cancelled = true;\n ongoingTransition.onTransitionCancelled?.();\n }\n }\n\n private emitTransitionProgress(type: TransitionType, progress: number) {\n this.eventEmitter.emit('transitionProgressed', { type, progress });\n }\n\n private emitTransitionFinished(type: TransitionType) {\n this.eventEmitter.emit('transitionFinished', { type });\n }\n}\n","import { linear } from '@/lib/easing';\nimport { DefaultEventEmitter } from '@/lib/events/defaultEventEmitter';\nimport { AssetService } from '@/lib/services/assets/assetService';\nimport { DataTextureService } from '@/lib/services/dataTexture/dataTextureService';\nimport { InstancedMeshManager } from '@/lib/services/instancedmesh/instancedMeshManager';\nimport { IntersectionService } from '@/lib/services/intersection/intersectionService';\nimport { SimulationRendererService } from '@/lib/services/simulation/simulationRendererService';\nimport { TransitionService } from '@/lib/services/transition/transitionService';\nimport { EasingFunction, ServiceState, ServiceType, TransitionType } from '@/lib/types';\nimport { EngineState } from '@/lib/types/state';\nimport * as THREE from 'three';\n\n/**\n * Parameters for creating a ParticlesEngine instance.\n */\ntype ParticlesEngineParameters = {\n textureSize: number;\n scene: THREE.Scene;\n renderer: THREE.WebGLRenderer;\n camera?: THREE.Camera;\n useIntersection?: boolean;\n};\n\ntype ServiceStates = Record<ServiceType, ServiceState>;\n\n/**\n * The main class for the particle engine.\n */\nexport class ParticlesEngine {\n private simulationRendererService: SimulationRendererService;\n private eventEmitter: DefaultEventEmitter;\n private renderer: THREE.WebGLRenderer;\n\n private scene: THREE.Scene;\n private serviceStates: ServiceStates;\n\n // assets\n private assetService: AssetService;\n private dataTextureManager: DataTextureService;\n private instancedMeshManager: InstancedMeshManager;\n\n private transitionService: TransitionService;\n private engineState: EngineState;\n\n private intersectionService: IntersectionService;\n\n /**\n * Creates a new ParticlesEngine instance.\n * @param params The parameters for creating the instance.\n */\n constructor(params: ParticlesEngineParameters) {\n const { scene, renderer, camera, textureSize, useIntersection = true } = params;\n\n this.eventEmitter = new DefaultEventEmitter();\n this.serviceStates = this.getInitialServiceStates();\n this.eventEmitter.on('serviceStateUpdated', this.handleServiceStateUpdated.bind(this));\n\n this.scene = scene;\n this.renderer = renderer;\n this.engineState = this.initialEngineState(params);\n\n this.assetService = new AssetService(this.eventEmitter);\n this.transitionService = new TransitionService(this.eventEmitter);\n this.dataTextureManager = new DataTextureService(this.eventEmitter, textureSize);\n this.simulationRendererService = new SimulationRendererService(this.eventEmitter, textureSize, this.renderer);\n this.instancedMeshManager = new InstancedMeshManager(textureSize);\n this.instancedMeshManager.useMatcapMaterial();\n this.scene.add(this.instancedMeshManager.getMesh());\n\n this.intersectionService = new IntersectionService(this.eventEmitter, camera);\n if (!useIntersection) this.intersectionService.setActive(false);\n\n this.eventEmitter.on('transitionProgressed', this.handleTransitionProgress.bind(this));\n this.eventEmitter.on('interactionPositionUpdated', this.handleInteractionPositionUpdated.bind(this));\n }\n\n /**\n * Renders the scene.\n * @param elapsedTime The elapsed time since the last frame.\n */\n\n render(elapsedTime: number) {\n this.intersectionService.calculate(this.instancedMeshManager.getMesh());\n this.transitionService.compute(elapsedTime);\n this.simulationRendererService.compute(elapsedTime);\n this.instancedMeshManager.update(elapsedTime);\n this.instancedMeshManager.updateVelocityTexture(this.simulationRendererService.getVelocityTexture());\n this.instancedMeshManager.updatePositionTexture(this.simulationRendererService.getPositionTexture());\n }\n\n setOriginDataTexture(meshID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'data-texture' });\n\n const mesh = this.assetService.getMesh(meshID);\n\n if (!mesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${meshID}\" does not exist` });\n return;\n }\n\n this.dataTextureManager.getDataTexture(mesh).then((dataTexture) => {\n this.engineState.originMeshID = meshID;\n this.simulationRendererService.setOriginDataTexture({ dataTexture, textureSize: this.engineState.textureSize });\n this.intersectionService.setOriginGeometry(mesh);\n });\n }\n\n setDestinationDataTexture(meshID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'data-texture' });\n\n const mesh = this.assetService.getMesh(meshID);\n\n if (!mesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${meshID}\" does not exist` });\n return;\n }\n\n this.dataTextureManager.getDataTexture(mesh).then((texture) => {\n this.engineState.destinationMeshID = meshID;\n this.simulationRendererService.setDestinationDataTexture({\n dataTexture: texture,\n textureSize: this.engineState.textureSize\n });\n this.intersectionService.setDestinationGeometry(mesh);\n });\n }\n\n setDataTextureTransitionProgress(progress: number, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'data-texture' });\n this.engineState.dataTextureTransitionProgress = progress;\n this.simulationRendererService.setDataTextureTransitionProgress(progress);\n this.intersectionService.setProgress(progress);\n }\n\n setOriginMatcap(matcapID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.originMatcapID = matcapID;\n this.instancedMeshManager.setOriginMatcap(this.assetService.getMatcap(matcapID));\n }\n\n setDestinationMatcap(matcapID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.destinationMatcapID = matcapID;\n this.instancedMeshManager.setDestinationMatcap(this.assetService.getMatcap(matcapID));\n }\n\n setOriginColor(color: THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.instancedMeshManager.setOriginColor(color);\n }\n\n setDestinationColor(color: THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.instancedMeshManager.setDestinationColor(color);\n }\n\n setOriginTexture(id: string | THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n\n if (typeof id === 'string' && this.assetService.hasMatcap(id)) {\n this.setOriginMatcap(id);\n } else {\n this.setOriginColor(id);\n }\n }\n\n setDestinationTexture(id: string | THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n\n if (typeof id === 'string' && this.assetService.hasMatcap(id)) {\n this.setDestinationMatcap(id);\n } else {\n this.setDestinationColor(id);\n }\n }\n\n setMatcapProgress(progress: number, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.matcapTransitionProgress = progress;\n this.instancedMeshManager.setProgress(progress);\n }\n\n async setTextureSize(size: number) {\n this.engineState.textureSize = size;\n this.dataTextureManager.setTextureSize(size);\n this.simulationRendererService.setTextureSize(size);\n this.instancedMeshManager.resize(size);\n\n const originMesh = this.assetService.getMesh(this.engineState.originMeshID);\n if (!originMesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${this.engineState.originMeshID}\" does not exist` });\n return;\n }\n\n const destinationMesh = this.assetService.getMesh(this.engineState.destinationMeshID);\n if (!destinationMesh) {\n this.eventEmitter.emit('invalidRequest', { message: `Mesh with id \"${this.engineState.destinationMeshID}\" does not exist` });\n return;\n }\n\n this.dataTextureManager.getDataTexture(originMesh).then((texture) =>\n this.simulationRendererService.setOriginDataTexture({\n dataTexture: texture,\n textureSize: size\n })\n );\n\n this.dataTextureManager.getDataTexture(destinationMesh).then((texture) =>\n this.simulationRendererService.setDestinationDataTexture({\n dataTexture: texture,\n textureSize: size\n })\n );\n\n this.simulationRendererService.setDataTextureTransitionProgress(this.engineState.dataTextureTransitionProgress);\n this.simulationRendererService.setVelocityTractionForce(this.engineState.velocityTractionForce);\n this.simulationRendererService.setPositionalTractionForce(this.engineState.positionalTractionForce);\n\n this.instancedMeshManager.setOriginMatcap(this.assetService.getMatcap(this.engineState.originMatcapID));\n this.instancedMeshManager.setDestinationMatcap(this.assetService.getMatcap(this.engineState.destinationMatcapID));\n this.instancedMeshManager.setProgress(this.engineState.matcapTransitionProgress);\n this.instancedMeshManager.setGeometrySize(this.engineState.instanceGeometryScale);\n }\n\n registerMesh(id: string, mesh: THREE.Mesh) {\n this.assetService.register(id, mesh);\n }\n\n registerMatcap(id: string, matcap: THREE.Texture) {\n this.assetService.register(id, matcap);\n }\n\n async fetchAndRegisterMesh(id: string, url: string) {\n return await this.assetService.loadMeshAsync(id, url);\n }\n\n async fetchAndRegisterMatcap(id: string, url: string) {\n return await this.assetService.loadTextureAsync(id, url);\n }\n\n useIntersect(use: boolean) {\n this.intersectionService.setActive(use);\n this.engineState.useIntersect = use;\n\n if (!use) {\n this.engineState.pointerPosition = { x: -99999999, y: -99999999 };\n this.intersectionService.setPointerPosition(this.engineState.pointerPosition);\n }\n }\n\n setPointerPosition(position: THREE.Vector2Like) {\n if (!this.engineState.useIntersect) return;\n this.engineState.pointerPosition = position;\n this.intersectionService.setPointerPosition(position);\n }\n\n setGeometrySize(geometrySize: THREE.Vector3Like) {\n this.engineState.instanceGeometryScale = geometrySize;\n this.instancedMeshManager.setGeometrySize(geometrySize);\n }\n\n setVelocityTractionForce(force: number) {\n this.engineState.velocityTractionForce = force;\n this.simulationRendererService.setVelocityTractionForce(force);\n }\n\n setPositionalTractionForce(force: number) {\n this.engineState.positionalTractionForce = force;\n this.simulationRendererService.setPositionalTractionForce(force);\n }\n\n setMaxRepelDistance(distance: number) {\n this.engineState.maxRepelDistance = distance;\n this.simulationRendererService.setMaxRepelDistance(distance);\n }\n\n scheduleMeshTransition(originMeshID: string, destinationMeshID: string, easing: EasingFunction = linear, duration: number = 1000, override: boolean = false) {\n this.transitionService.enqueue(\n 'data-texture',\n { easing, duration },\n {\n onTransitionBegin: () => {\n this.setOriginDataTexture(originMeshID, override);\n this.setDestinationDataTexture(destinationMeshID, override);\n this.setDataTextureTransitionProgress(0);\n }\n }\n );\n }\n\n scheduleMatcapTransition(\n originMatcapID: string,\n destinationMatcapID: string,\n easing: EasingFunction = linear,\n duration: number = 1000,\n override: boolean = false\n ) {\n this.transitionService.enqueue(\n 'matcap',\n { easing, duration },\n {\n onTransitionBegin: () => {\n this.setOriginMatcap(originMatcapID, override);\n this.setDestinationMatcap(destinationMatcapID, override);\n this.setMatcapProgress(0);\n }\n }\n );\n }\n\n scheduleTextureTransition(\n origin: string,\n destination: string,\n options?: {\n easing?: EasingFunction;\n duration?: number;\n override?: boolean;\n }\n ) {\n const easing = options?.easing ?? linear;\n const duration = options?.duration ?? 1000;\n\n if (options?.override) {\n this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n }\n\n this.transitionService.enqueue(\n 'matcap',\n { easing, duration },\n {\n onTransitionBegin: () => {\n this.setOriginTexture(origin);\n this.setDestinationTexture(destination);\n this.setMatcapProgress(0);\n }\n }\n );\n }\n\n handleServiceStateUpdated({ type, state }: { type: ServiceType; state: ServiceState }) {\n this.serviceStates[type] = state;\n }\n\n getObject(): THREE.Mesh {\n return this.instancedMeshManager.getMesh();\n }\n\n getMeshIDs() {\n return this.assetService.getMeshIDs();\n }\n\n getMatcapIDs() {\n return this.assetService.getTextureIDs();\n }\n\n /**\n * Disposes the resources used by the engine.\n */\n dispose() {\n this.scene.remove(this.instancedMeshManager.getMesh());\n this.simulationRendererService.dispose();\n this.instancedMeshManager.dispose();\n this.intersectionService.dispose();\n this.assetService.dispose();\n this.dataTextureManager.dispose();\n }\n\n private initialEngineState(params: ParticlesEngineParameters): EngineState {\n return {\n textureSize: params.textureSize,\n originMeshID: '',\n destinationMeshID: '',\n dataTextureTransitionProgress: 0,\n originMatcapID: '',\n destinationMatcapID: '',\n matcapTransitionProgress: 0,\n velocityTractionForce: 0.1,\n positionalTractionForce: 0.1,\n maxRepelDistance: 0.3,\n pointerPosition: { x: 0, y: 0 },\n instanceGeometryScale: { x: 1, y: 1, z: 1 },\n useIntersect: params.useIntersection ?? true\n };\n }\n\n private getInitialServiceStates(): ServiceStates {\n return {\n 'data-texture': 'created',\n 'instanced-mesh': 'created',\n matcap: 'created',\n simulation: 'created',\n asset: 'created'\n };\n }\n\n private handleTransitionProgress({ type, progress }: { type: TransitionType; progress: number }) {\n switch (type) {\n case 'data-texture':\n this.setDataTextureTransitionProgress(progress);\n break;\n case 'matcap':\n this.setMatcapProgress(progress);\n break;\n }\n }\n\n private handleInteractionPositionUpdated({ position }: { position: THREE.Vector4Like }) {\n this.simulationRendererService.setInteractionPosition(position);\n }\n}\n"],"names":["n"],"mappings":";;;;;;AAKa,MAAA,SAAyB,CAAC,MAAc;ACLtC,SAAA,KAAS,GAAE;AAAC,SAAM,EAAC,KAAI,IAAE,KAAG,oBAAI,OAAI,IAAG,SAAS,GAAE,GAAE;AAAC,QAAI,IAAE,EAAE,IAAI,CAAC;AAAE,QAAE,EAAE,KAAK,CAAC,IAAE,EAAE,IAAI,GAAE,CAAC,CAAC,CAAC;AAAA,EAAC,GAAE,KAAI,SAAS,GAAE,GAAE;AAAC,QAAI,IAAE,EAAE,IAAI,CAAC;AAAE,UAAI,IAAE,EAAE,OAAO,EAAE,QAAQ,CAAC,MAAI,GAAE,CAAC,IAAE,EAAE,IAAI,GAAE,EAAE;AAAA,EAAE,GAAE,MAAK,SAAS,GAAE,GAAE;AAAC,QAAI,IAAE,EAAE,IAAI,CAAC;AAAE,SAAG,EAAE,QAAQ,IAAI,SAASA,IAAE;AAAC,MAAAA,GAAE,CAAC;AAAA,IAAC,CAAC,IAAG,IAAE,EAAE,IAAI,GAAG,MAAI,EAAE,MAAO,EAAC,IAAI,SAASA,IAAE;AAAC,MAAAA,GAAE,GAAE,CAAC;AAAA,IAAC,CAAC;AAAA,EAAC,EAAC;AAAC;ACIlT,MAAM,oBAA0D;AAAA,EAAhE;AACY,mCAAU,KAAa;AAAA;AAAA,EAExC,KAA+B,MAAW,SAA4B;AAC/D,SAAA,QAAQ,KAAK,MAAM,OAAO;AAAA,EAAA;AAAA,EAGjC,IAA8B,MAAW,SAAgD;AAClF,SAAA,QAAQ,IAAI,MAAM,OAAO;AAAA,EAAA;AAAA,EAGhC,GAA6B,MAAW,SAA+C;AAChF,SAAA,QAAQ,GAAG,MAAM,OAAO;AAAA,EAAA;AAAA,EAG/B,KAA+B,MAAW,SAA+C;AACvF,SAAK,QAAQ,GAAG,MAAM,CAAC,YAAyB;AACzC,WAAA,QAAQ,IAAI,MAAM,OAAO;AAC9B,cAAQ,OAAO;AAAA,IAAA,CAChB;AAAA,EAAA;AAAA,EAGH,UAAgB;AACT,SAAA,QAAQ,IAAI,MAAM;AAAA,EAAA;AAE3B;ACrBgB,SAAA,kBAAkB,MAAoB,MAAc;AAC5D,QAAA,UAAU,IAAI,MAAM,YAAY,MAAM,MAAM,MAAM,MAAM,YAAY,MAAM,SAAS;AACzF,UAAQ,cAAc;AACf,SAAA;AACT;AAOO,SAAS,uBAAuB,MAAc;AACnD,SAAO,kBAAkB,IAAI,aAAa,IAAI,OAAO,IAAI,GAAG,IAAI;AAClE;AAOO,SAAS,mBAAmB,MAAc;AAC/C,QAAM,OAAO,IAAI,aAAa,OAAO,OAAO,CAAC;AAC7C,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AACvB,YAAA,QAAQ,IAAI,OAAO;AAEzB,UAAI,QAAQ,KAAK,OAAO,IAAI,KAAK,KAAK;AACtC,UAAI,MAAM,KAAK,KAAK,KAAK,OAAO,IAAI,IAAI,CAAC;AACzC,UAAI,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,KAAK;AACtC,UAAI,IAAI,KAAK,IAAI,GAAG,IAAI,KAAK,IAAI,KAAK;AAClC,UAAA,IAAI,KAAK,IAAI,GAAG;AAEf,WAAA,IAAI,KAAK,IAAI;AACb,WAAA,IAAI,QAAQ,CAAC,IAAI;AACjB,WAAA,IAAI,QAAQ,CAAC,IAAI;AACtB,WAAK,IAAI,QAAQ,CAAC,KAAK,KAAK,WAAW,OAAO;AAAA,IAAA;AAAA,EAChD;AAGK,SAAA,kBAAkB,MAAM,IAAI;AACrC;AAEO,SAAS,YAAY,MAAkB;AAC5C,OAAK,SAAS,QAAQ;AAClB,MAAA,KAAK,oBAAoB,MAAM,UAAU;AAC3C,SAAK,SAAS,QAAQ;AAAA,EAAA,OACjB;AACL,SAAK,SAAS,QAAQ,CAAC,aAAa,SAAS,SAAS;AAAA,EAAA;AAE1D;AAEgB,SAAA,MAAM,OAAe,KAAa,KAAqB;AAC7D,UAAA,KAAK,IAAI,OAAO,GAAG;AACnB,UAAA,KAAK,IAAI,OAAO,GAAG;AACpB,SAAA;AACT;ACzDO,MAAM,aAAa;AAAA,EAaxB,YAAY,cAAmC;AAZvC,wCAA6B;AAEpB;AACA,sDAAa,IAAwB;AACrC,wDAAe,IAA2B;AAE1C,sCAAa,IAAI,WAAW;AAC5B,yCAAgB,IAAI,MAAM,cAAc;AACxC,uCAAc,IAAI,YAAY;AAEvC,6CAAoB,IAAI,MAAM,YAAY,IAAI,WAAW,CAAC,KAAK,KAAK,KAAK,GAAG,CAAC,GAAG,GAAG,GAAG,MAAM,UAAU;AAG5G,SAAK,eAAe;AACf,SAAA,YAAY,eAAe,yDAAyD;AACpF,SAAA,WAAW,eAAe,KAAK,WAAW;AAC/C,SAAK,mBAAmB,OAAO;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQjC,SAAS,IAAY,MAAkC;AACrD,SAAK,OAAO;AAER,QAAA,gBAAgB,MAAM,MAAM;AAC9B,YAAM,OAAO,KAAK,OAAO,IAAI,EAAE;AAC3B,UAAA,kBAAkB,IAAI;AACrB,WAAA,OAAO,IAAI,IAAI,IAAI;AAAA,IAAA,OACnB;AACL,YAAM,OAAO,KAAK,SAAS,IAAI,EAAE;AAC7B,UAAA,WAAW,QAAQ;AAClB,WAAA,SAAS,IAAI,IAAI,IAAI;AAAA,IAAA;AAG5B,SAAK,aAAa,KAAK,mBAAmB,EAAE,IAAI;AAAA,EAAA;AAAA,EAGlD,cAAc,OAAkC;AAC9C,SAAK,YAAY,KAAK;AAAA,EAAA;AAAA,EAGxB,uBAAuB;AACrB,WAAO,KAAK;AAAA,EAAA;AAAA,EAGd,QAAQ,IAA+B;AACrC,WAAO,KAAK,OAAO,IAAI,EAAE,KAAK;AAAA,EAAA;AAAA,EAGhC,UAAU,IAA2B;AACnC,UAAM,UAAU,KAAK,SAAS,IAAI,EAAE;AAChC,QAAA,CAAC,QAAS,MAAK,aAAa,KAAK,kBAAkB,EAAE,SAAS,oBAAoB,EAAE,oDAAA,CAAqD;AAC7I,WAAO,WAAW,KAAK;AAAA,EAAA;AAAA,EAGzB,aAAuB;AACrB,WAAO,MAAM,KAAK,KAAK,OAAO,MAAM;AAAA,EAAA;AAAA,EAGtC,gBAA0B;AACxB,WAAO,MAAM,KAAK,KAAK,SAAS,MAAM;AAAA,EAAA;AAAA,EAGxC,YAA0B;AACxB,WAAO,MAAM,KAAK,KAAK,OAAO,QAAQ;AAAA,EAAA;AAAA,EAGxC,cAA+B;AAC7B,WAAO,MAAM,KAAK,KAAK,SAAS,QAAQ;AAAA,EAAA;AAAA,EAG1C,UAAU,IAAY;AACb,WAAA,KAAK,SAAS,IAAI,EAAE;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU7B,MAAM,cAAc,IAAY,KAAa,UAAiC,CAAA,GAAgC;AAC5G,UAAM,OAAO,MAAM,KAAK,WAAW,UAAU,GAAG;AAC5C,QAAA;AACF,UAAI,QAAQ,UAAU;AACpB,cAAM,OAAO,KAAK,MAAM,gBAAgB,QAAQ,QAAQ;AACnD,aAAA,SAAS,IAAI,IAAI;AACf,eAAA;AAAA,MAAA,OACF;AACL,cAAM,OAAO,KAAK,MAAM,SAAS,CAAC;AAC7B,aAAA,SAAS,IAAI,IAAI;AACf,eAAA;AAAA,MAAA;AAAA,aAEF,OAAO;AACT,WAAA,aAAa,KAAK,kBAAkB,EAAE,SAAS,wBAAwB,EAAE,KAAK,KAAK,GAAA,CAAI;AACrF,aAAA;AAAA,IAAA;AAAA,EACT;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EASF,MAAM,iBAAiB,IAAY,KAA4C;AACzE,QAAA;AACF,YAAM,UAAU,MAAM,KAAK,cAAc,UAAU,GAAG;AACjD,WAAA,SAAS,IAAI,OAAO;AAClB,aAAA;AAAA,aACA,OAAO;AACT,WAAA,aAAa,KAAK,kBAAkB,EAAE,SAAS,2BAA2B,EAAE,KAAK,KAAK,GAAA,CAAI;AACxF,aAAA;AAAA,IAAA;AAAA,EACT;AAAA,EAGF,UAAU;AACR,SAAK,mBAAmB,UAAU;AAClC,SAAK,OAAO,QAAQ,CAAC,SAAS,YAAY,IAAI,CAAC;AAC/C,SAAK,OAAO,MAAM;AAClB,SAAK,SAAS,QAAQ,CAAC,YAAY,QAAQ,SAAS;AACpD,SAAK,SAAS,MAAM;AAAA,EAAA;AAAA,EAGd,YAAY,OAAkC;AACpD,UAAM,SAAS,IAAI,MAAM,MAAM,KAAK;AACpC,SAAK,oBAAoB,IAAI,MAAM,YAAY,IAAI,WAAW,CAAC,OAAO,GAAG,OAAO,GAAG,OAAO,GAAG,GAAG,CAAC,GAAG,GAAG,GAAG,MAAM,UAAU;AAC1H,SAAK,kBAAkB,cAAc;AAAA,EAAA;AAAA,EAG/B,mBAAmB,cAA4B;AACrD,SAAK,eAAe;AACf,SAAA,aAAa,KAAK,uBAAuB,EAAE,MAAM,SAAS,OAAO,cAAc;AAAA,EAAA;AAExF;AChIA,MAAM,QAAQ,IAAI,SAAU;AAC5B,MAAM,SAAS,IAAI,QAAS;AAC5B,MAAM,OAAO,IAAI,QAAO,GAAI,OAAO,IAAI,WAAW,OAAO,IAAI,QAAS;AAEtE,MAAM,mBAAmB;AAAA,EAExB,YAAa,MAAO;AAEnB,SAAK,WAAW,KAAK;AACrB,SAAK,iBAAiB,KAAK;AAE3B,SAAK,iBAAiB,KAAK,SAAS;AACpC,SAAK,oBAAoB,KAAK,SAAS,aAAc,UAAY;AACjE,SAAK,kBAAkB,KAAK,SAAS,aAAc,QAAU;AAC7D,SAAK,iBAAiB,KAAK,SAAS,aAAc,OAAS;AAC3D,SAAK,cAAc,KAAK,SAAS,aAAc,IAAM;AACrD,SAAK,kBAAkB;AAEvB,SAAK,eAAe;AAAA,EAEtB;AAAA,EAEC,mBAAoB,MAAO;AAE1B,SAAK,kBAAkB,OAAO,KAAK,SAAS,aAAc,IAAI,IAAK;AAEnE,WAAO;AAAA,EAET;AAAA,EAEC,QAAQ;AAEP,UAAM,iBAAiB,KAAK;AAC5B,UAAM,oBAAoB,KAAK;AAC/B,UAAM,kBAAkB,KAAK;AAE7B,UAAM,aAAa,iBAAmB,eAAe,QAAQ,IAAQ,kBAAkB,QAAQ;AAC/F,UAAM,cAAc,IAAI,aAAc,UAAY;AAIlD,aAAU,IAAI,GAAG,IAAI,YAAY,KAAO;AAEvC,UAAI,aAAa;AAEjB,UAAI,KAAK,IAAI;AACb,UAAI,KAAK,IAAI,IAAI;AACjB,UAAI,KAAK,IAAI,IAAI;AAEjB,UAAK,gBAAiB;AAErB,aAAK,eAAe,KAAM,EAAI;AAC9B,aAAK,eAAe,KAAM,EAAI;AAC9B,aAAK,eAAe,KAAM,EAAI;AAAA,MAElC;AAEG,UAAK,iBAAkB;AAEtB,qBAAa,gBAAgB,KAAM,EAAE,IAClC,gBAAgB,KAAM,EAAE,IACxB,gBAAgB,KAAM,EAAI;AAAA,MAEjC;AAEG,YAAM,EAAE,oBAAqB,mBAAmB,EAAI;AACpD,YAAM,EAAE,oBAAqB,mBAAmB,EAAI;AACpD,YAAM,EAAE,oBAAqB,mBAAmB,EAAI;AACpD,oBAAc,MAAM,QAAS;AAE7B,kBAAa,CAAC,IAAK;AAAA,IAEtB;AAKE,UAAM,eAAe,IAAI,aAAc,UAAY;AACnD,QAAI,kBAAkB;AAEtB,aAAU,IAAI,GAAG,IAAI,YAAY,KAAO;AAEvC,yBAAmB,YAAa,CAAG;AACnC,mBAAc,CAAC,IAAK;AAAA,IAEvB;AAEE,SAAK,eAAe;AACpB,WAAO;AAAA,EAET;AAAA,EAEC,mBAAoB,gBAAiB;AAEpC,SAAK,iBAAiB;AACtB,WAAO;AAAA,EAET;AAAA,EAEC,OAAQ,gBAAgB,cAAc,aAAa,UAAW;AAE7D,UAAM,YAAY,KAAK,gBAAiB;AACxC,WAAO,KAAK,WAAY,WAAW,gBAAgB,cAAc,aAAa,QAAU;AAAA,EAE1F;AAAA,EAEC,kBAAkB;AAEjB,UAAM,kBAAkB,KAAK,aAAc,KAAK,aAAa,SAAS,CAAG;AACzE,WAAO,KAAK,aAAc,KAAK,eAAc,IAAK,eAAiB;AAAA,EAErE;AAAA,EAEC,aAAc,GAAI;AAEjB,UAAM,OAAO,KAAK;AAClB,QAAI,QAAQ;AACZ,QAAI,MAAM,KAAK,SAAS;AAExB,QAAI,QAAQ;AAEZ,WAAQ,SAAS,KAAM;AAEtB,YAAM,MAAM,KAAK,MAAQ,QAAQ,OAAQ,CAAG;AAE5C,UAAK,QAAQ,KAAK,KAAM,MAAM,MAAO,KAAK,KAAM,GAAK,IAAG,GAAI;AAE3D,gBAAQ;AAER;AAAA,MAEA,WAAW,IAAI,KAAM,MAAQ;AAE7B,cAAM,MAAM;AAAA,MAEhB,OAAU;AAEN,gBAAQ,MAAM;AAAA,MAElB;AAAA,IAEA;AAEE,WAAO;AAAA,EAET;AAAA,EAEC,WAAY,WAAW,gBAAgB,cAAc,aAAa,UAAW;AAE5E,QAAI,IAAI,KAAK,eAAgB;AAC7B,QAAI,IAAI,KAAK,eAAgB;AAE7B,QAAK,IAAI,IAAI,GAAI;AAEhB,UAAI,IAAI;AACR,UAAI,IAAI;AAAA,IAEX;AAGE,UAAM,iBAAiB,KAAK;AAC5B,QAAI,KAAK,YAAY;AACrB,QAAI,KAAK,YAAY,IAAI;AACzB,QAAI,KAAK,YAAY,IAAI;AACzB,QAAK,gBAAiB;AAErB,WAAK,eAAe,KAAM,EAAI;AAC9B,WAAK,eAAe,KAAM,EAAI;AAC9B,WAAK,eAAe,KAAM,EAAI;AAAA,IAEjC;AAEE,UAAM,EAAE,oBAAqB,KAAK,mBAAmB,EAAI;AACzD,UAAM,EAAE,oBAAqB,KAAK,mBAAmB,EAAI;AACzD,UAAM,EAAE,oBAAqB,KAAK,mBAAmB,EAAI;AAEzD,mBACE,IAAK,GAAG,GAAG,CAAC,EACZ,gBAAiB,MAAM,GAAG,CAAC,EAC3B,gBAAiB,MAAM,GAAG,CAAC,EAC3B,gBAAiB,MAAM,GAAG,KAAM,IAAI,EAAK;AAE3C,QAAK,iBAAiB,QAAY;AAEjC,UAAK,KAAK,oBAAoB,QAAY;AAEzC,cAAM,EAAE,oBAAqB,KAAK,iBAAiB,EAAI;AACvD,cAAM,EAAE,oBAAqB,KAAK,iBAAiB,EAAI;AACvD,cAAM,EAAE,oBAAqB,KAAK,iBAAiB,EAAI;AACvD,qBAAa,IAAK,GAAG,GAAG,CAAC,EAAG,gBAAiB,MAAM,GAAG,CAAC,EAAG,gBAAiB,MAAM,GAAG,CAAC,EAAG,gBAAiB,MAAM,GAAG,KAAM,IAAI,EAAK,EAAC,UAAW;AAAA,MAEjJ,OAAU;AAEN,cAAM,UAAW,YAAc;AAAA,MAEnC;AAAA,IAEA;AAEE,QAAK,gBAAgB,UAAa,KAAK,mBAAmB,QAAY;AAErE,YAAM,EAAE,oBAAqB,KAAK,gBAAgB,EAAI;AACtD,YAAM,EAAE,oBAAqB,KAAK,gBAAgB,EAAI;AACtD,YAAM,EAAE,oBAAqB,KAAK,gBAAgB,EAAI;AAEtD,aACE,IAAK,GAAG,GAAG,CAAC,EACZ,gBAAiB,MAAM,GAAG,CAAC,EAC3B,gBAAiB,MAAM,GAAG,CAAC,EAC3B,gBAAiB,MAAM,GAAG,KAAM,IAAI,EAAK;AAE3C,kBAAY,IAAI,OAAO;AACvB,kBAAY,IAAI,OAAO;AACvB,kBAAY,IAAI,OAAO;AAAA,IAE1B;AAEE,QAAK,aAAa,UAAa,KAAK,gBAAgB,QAAY;AAE/D,WAAK,oBAAqB,KAAK,aAAa,EAAI;AAChD,WAAK,oBAAqB,KAAK,aAAa,EAAI;AAChD,WAAK,oBAAqB,KAAK,aAAa,EAAI;AAChD,eAAS,IAAK,GAAG,CAAG,EAAC,gBAAiB,MAAM,CAAG,EAAC,gBAAiB,MAAM,CAAC,EAAG,gBAAiB,MAAM,KAAM,IAAI,EAAK;AAAA,IAEpH;AAEE,WAAO;AAAA,EAET;AAEA;AC9OO,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAU9B,YAAY,cAAmC,aAAqB;AAT5D;AACA;AACA;AAQN,SAAK,eAAe;AACpB,SAAK,cAAc;AACd,SAAA,mCAAmB,IAA+B;AACvD,SAAK,mBAAmB,OAAO;AAAA,EAAA;AAAA,EAGjC,eAAe,aAAqB;AAC9B,QAAA,KAAK,gBAAgB,YAAa;AACtC,SAAK,cAAc;AACnB,SAAK,aAAa,QAAQ,CAAC,YAAY,QAAQ,SAAS;AACxD,SAAK,aAAa,MAAM;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ1B,MAAM,eAAe,OAAmB;AACtC,UAAM,UAAU,KAAK,aAAa,IAAI,MAAM,IAAI;AAChD,QAAI,SAAS;AACJ,aAAA;AAAA,IAAA;AAGH,UAAA,WAAW,cAAc,KAAK;AACpC,UAAM,QAAQ,WAAW,UAAU,KAAK,WAAW;AACnD,UAAM,cAAc,kBAAkB,OAAO,KAAK,WAAW;AAC7D,gBAAY,OAAO,MAAM;AAClB,WAAA;AAAA,EAAA;AAAA,EAGT,MAAM,UAAU;AACd,SAAK,aAAa,MAAM;AACxB,SAAK,mBAAmB,UAAU;AAAA,EAAA;AAAA,EAG5B,mBAAmB,cAA4B;AAChD,SAAA,aAAa,KAAK,uBAAuB,EAAE,MAAM,gBAAgB,OAAO,cAAc;AAAA,EAAA;AAE/F;AAOA,SAAS,cAAc,MAA4B;;AAC1C,SAAA;AAAA,IACL,UAAU,KAAK,SAAS,WAAW,SAAS;AAAA,IAC5C,SAAS,UAAK,SAAS,WAAW,WAAzB,mBAA2D;AAAA,IACpE,OAAO,EAAE,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,MAAM,GAAG,GAAG,KAAK,MAAM,EAAE;AAAA,EAC7D;AACF;AAEA,SAAS,WAAW,UAAoB,MAA4B;AAC5D,QAAA,WAAW,IAAI,MAAM,eAAe;AACjC,WAAA,aAAa,YAAY,IAAI,MAAM,gBAAgB,IAAI,aAAa,SAAS,QAAQ,GAAG,CAAC,CAAC;AACnG,MAAI,SAAS,QAAQ;AACV,aAAA,aAAa,UAAU,IAAI,MAAM,gBAAgB,IAAI,aAAa,SAAS,MAAM,GAAG,CAAC,CAAC;AAAA,EAAA;AAE3F,QAAA,WAAW,IAAI,MAAM,kBAAkB;AAC7C,QAAM,OAAO,IAAI,MAAM,KAAK,UAAU,QAAQ;AACzC,OAAA,MAAM,IAAI,SAAS,MAAM,GAAG,SAAS,MAAM,GAAG,SAAS,MAAM,CAAC;AAEnE,QAAM,UAAU,IAAI,mBAAmB,IAAI,EAAE,MAAM;AACnD,QAAM,OAAO,IAAI,aAAa,OAAO,OAAO,CAAC;AACvC,QAAA,WAAW,IAAI,MAAM,QAAQ;AAEnC,WAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AACvB,YAAA,QAAQ,IAAI,OAAO;AACzB,cAAQ,OAAO,QAAQ;AACvB,WAAK,IAAI,KAAK,IAAI,SAAS,IAAI,SAAS,MAAM;AAC9C,WAAK,IAAI,QAAQ,CAAC,IAAI,SAAS,IAAI,SAAS,MAAM;AAClD,WAAK,IAAI,QAAQ,CAAC,IAAI,SAAS,IAAI,SAAS,MAAM;AAClD,WAAK,IAAI,QAAQ,CAAC,KAAK,KAAK,WAAW,OAAO;AAAA,IAAA;AAAA,EAChD;AAGK,SAAA;AACT;ACpGA,MAAe,yBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAf,MAAe,uBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACiBR,MAAM,qBAAqB;AAAA;AAAA;AAAA;AAAA;AAAA,EAqBhC,YAAY,aAAqB;AApBzB;AACA;AAES;AACA;AAEA;AAET;AACA;AAEA;AACA;AAEA;AAON,SAAK,OAAO;AACP,SAAA,iCAAiB,IAAI;AACrB,SAAA,kCAAkB,IAAI;AAE3B,SAAK,gBAAgB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AACxC,SAAK,cAAc;AACnB,SAAK,mBAAmB;AAExB,SAAK,WAAW;AAAA,MACd,OAAO,EAAE,OAAO,EAAE;AAAA,MAClB,WAAW,EAAE,OAAO,EAAE;AAAA,MACtB,UAAU,EAAE,OAAO,KAAK;AAAA,MACxB,WAAW,EAAE,OAAO,KAAK;AAAA,MACzB,gBAAgB,EAAE,OAAO,KAAK;AAAA,MAC9B,qBAAqB,EAAE,OAAO,KAAK;AAAA,IACrC;AAEK,SAAA,iBAAiB,IAAI,MAAM,eAAe;AAAA,MAC7C,UAAU,KAAK;AAAA,MACf,cAAc;AAAA,MACd,gBAAgB;AAAA,IAAA,CACjB;AAEI,SAAA,eAAe,KAAK,WAAW;AAC/B,SAAA,oBAAoB,KAAK,gBAAgB;AAE9C,SAAK,mBAAmB,IAAI,MAAM,YAAY,MAAO,MAAO,IAAK;AACjE,SAAK,OAAO,KAAK,oBAAoB,aAAa,KAAK,kBAAkB,KAAK,cAAc;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO9F,UAAU;AACR,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOd,OAAO,aAAqB;AACpB,UAAA,WAAW,KAAK,KAAK;AAC3B,QAAI,oBAAoB,MAAM,kBAAkB,oBAAoB,MAAM,mBAAmB;AAClF,eAAA,SAAS,MAAM,QAAQ;AAAA,IAAA;AAAA,EAClC;AAAA;AAAA;AAAA;AAAA;AAAA,EAOF,gBAAgB,QAAuB;AACrC,SAAK,+BAA+B;AAC/B,SAAA,eAAe,SAAS,eAAe,QAAQ;AAAA,EAAA;AAAA,EAGtD,qBAAqB,QAAuB;AAC1C,SAAK,oCAAoC;AACpC,SAAA,eAAe,SAAS,oBAAoB,QAAQ;AAAA,EAAA;AAAA,EAG3D,YAAY,OAAe;AACjB,YAAA,KAAK,IAAI,GAAG,KAAK;AACjB,YAAA,KAAK,IAAI,GAAG,KAAK;AACpB,SAAA,eAAe,SAAS,UAAU,QAAQ;AAAA,EAAA;AAAA,EAGjD,gBAAgB,MAAyB;AACvC,SAAK,KAAK,SAAS,MAAM,IAAI,KAAK,cAAc,GAAG,IAAI,KAAK,cAAc,GAAG,IAAI,KAAK,cAAc,CAAC;AAChG,SAAA,KAAK,SAAS,MAAM,KAAK,GAAG,KAAK,GAAG,KAAK,CAAC;AAC/C,SAAK,gBAAgB;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMvB,oBAAoB;AACb,SAAA,KAAK,WAAW,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO5B,YAAY,IAAY;AACtB,UAAM,WAAW,KAAK,WAAW,IAAI,EAAE;AACvC,QAAI,UAAU;AACZ,WAAK,KAAK,WAAW;AAAA,IAAA;AAAA,EACvB;AAAA;AAAA;AAAA;AAAA;AAAA,EAOF,sBAAsB,SAAwB;AACvC,SAAA,eAAe,SAAS,UAAU,QAAQ;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOjD,sBAAsB,SAAwB;AACvC,SAAA,eAAe,SAAS,SAAS,QAAQ;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQhD,OAAO,MAA+E;AAChF,QAAA,KAAK,SAAS,KAAa,QAAA,EAAE,SAAS,KAAK,MAAM,UAAU,KAAK,KAAK;AAEzE,SAAK,OAAO;AAGZ,UAAM,OAAO,KAAK;AAElB,SAAK,OAAO,KAAK,oBAAoB,MAAM,KAAK,UAAU,KAAK,QAAQ;AAEvE,WAAO,EAAE,SAAS,KAAK,MAAM,UAAU,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAM9C,UAAU;AACR,SAAK,KAAK,QAAQ;AAElB,SAAK,WAAW,QAAQ,CAAC,aAAa,SAAS,SAAS;AACxD,SAAK,+BAA+B;AACpC,SAAK,oCAAoC;AACzC,SAAK,eAAe,QAAQ;AAE5B,SAAK,YAAY,MAAM;AACvB,SAAK,WAAW,MAAM;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQxB,iBAAiB,IAAY,UAAgC;AAC3D,UAAM,WAAW,KAAK,WAAW,IAAI,EAAE;AAEvC,QAAI,UAAU;AACZ,UAAI,aAAa,UAAU;AACzB;AAAA,MAAA;AAAA,IACF;AAIF,UAAM,SAAS,KAAK,aAAa,KAAK,IAAI;AACjC,aAAA,aAAa,SAAS,MAAM;AAEhC,SAAA,WAAW,IAAI,IAAI,QAAQ;AAE5B,QAAA,KAAK,KAAK,aAAa,UAAU;AACnC,WAAK,KAAK,WAAW;AAAA,IAAA;AAGvB,yCAAU;AAAA,EAAQ;AAAA,EAGpB,eAAe,OAAkC;AAC/C,SAAK,+BAA+B;AACpC,SAAK,cAAc;AACnB,SAAK,SAAS,eAAe,QAAQ,KAAK,4BAA4B,KAAK;AAAA,EAAA;AAAA,EAG7E,oBAAoB,OAAkC;AACpD,SAAK,oCAAoC;AACzC,SAAK,mBAAmB;AACxB,SAAK,SAAS,oBAAoB,QAAQ,KAAK,4BAA4B,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQ1E,aAAa,MAAc;AACjC,UAAM,SAAS,KAAK,YAAY,IAAI,IAAI;AAExC,QAAI,QAAQ;AACH,aAAA;AAAA,IAAA;AAGT,UAAM,SAAS,IAAI,aAAa,OAAO,OAAO,CAAC;AAE/C,aAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AAC7B,eAAS,IAAI,GAAG,IAAI,MAAM,KAAK;AACvB,cAAA,QAAQ,IAAI,OAAO;AACzB,eAAO,IAAI,KAAK,IAAI,KAAK,OAAO;AAChC,eAAO,IAAI,QAAQ,CAAC,IAAI,KAAK,OAAO;AAAA,MAAA;AAAA,IACtC;AAGF,UAAM,OAAO,IAAI,MAAM,yBAAyB,QAAQ,CAAC;AAEpD,SAAA,YAAY,IAAI,MAAM,IAAI;AACxB,WAAA;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAUD,oBAAoB,MAAc,UAAgC,UAA6C;AACrH,eAAW,YAAY,KAAK;AAC5B,aAAS,aAAa,SAAS,KAAK,aAAa,IAAI,CAAC;AACtD,UAAM,QAAQ,OAAO;AACrB,WAAO,IAAI,MAAM,cAAc,UAAU,UAAU,KAAK;AAAA,EAAA;AAAA,EAGlD,4BAA4B,OAAkC,OAAe,IAAuB;AAC1G,UAAM,MAAM,IAAI,MAAM,MAAM,KAAK;AACjC,UAAM,QAAQ;AACd,UAAM,SAAS;AACf,UAAM,OAAO,IAAI,WAAW,QAAQ,SAAS,CAAC;AAE9C,UAAM,IAAI,KAAK,MAAM,IAAI,IAAI,GAAG;AAChC,UAAM,IAAI,KAAK,MAAM,IAAI,IAAI,GAAG;AAChC,UAAM,IAAI,KAAK,MAAM,IAAI,IAAI,GAAG;AAEhC,aAAS,IAAI,GAAG,IAAI,QAAQ,QAAQ,KAAK;AACvC,YAAM,QAAQ,IAAI;AAClB,WAAK,KAAK,IAAI;AACT,WAAA,QAAQ,CAAC,IAAI;AACb,WAAA,QAAQ,CAAC,IAAI;AACb,WAAA,QAAQ,CAAC,IAAI;AAAA,IAAA;AAGd,UAAA,UAAU,IAAI,MAAM,YAAY,MAAM,OAAO,QAAQ,MAAM,UAAU;AAC3E,YAAQ,OAAO,MAAM;AACrB,YAAQ,QAAQ,MAAM;AACtB,YAAQ,QAAQ,MAAM;AACtB,YAAQ,YAAY,MAAM;AAC1B,YAAQ,YAAY,MAAM;AAC1B,YAAQ,cAAc;AACf,WAAA;AAAA,EAAA;AAAA,EAGD,iCAAiC;AACvC,QAAI,KAAK,aAAa;AACpB,WAAK,cAAc;AACf,UAAA,KAAK,SAAS,eAAe,OAAO;AACjC,aAAA,SAAS,eAAe,MAAM,QAAQ;AAAA,MAAA;AAAA,IAC7C;AAAA,EACF;AAAA,EAGM,sCAAsC;AAC5C,QAAI,KAAK,kBAAkB;AACzB,WAAK,mBAAmB;AACpB,UAAA,KAAK,SAAS,oBAAoB,OAAO;AACtC,aAAA,SAAS,oBAAoB,MAAM,QAAQ;AAAA,MAAA;AAAA,IAClD;AAAA,EACF;AAEJ;AC7SO,MAAM,oBAAoB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA4B/B,YAAY,cAAmC,QAAuB,gBAAuC,qBAA4C;AA3BjJ,kCAAkB;AAElB,qCAAY,IAAI,MAAM,UAAU;AAChC,yCAAgB,IAAI,MAAM,QAAQ;AAElC;AACA;AACA;AAEA,oCAAmB;AACnB,4CAAmB,IAAI,MAAM,KAAK;AAElC;AACA;AAEA;AACA;AAEA;AACA;AASN,SAAK,SAAS;AACd,SAAK,iBAAiB;AACtB,SAAK,eAAe;AACpB,SAAK,sBAAsB;AAC3B,SAAK,sBAAsB;AAAA,EAAA;AAAA,EAG7B,UAAU,QAAiB;AACzB,SAAK,SAAS;AAAA,EAAA;AAAA,EAGhB,sBAAkC;AAChC,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOd,UAAU,QAAsB;AAC9B,SAAK,SAAS;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOhB,kBAAkB,QAAoB;AAChC,QAAA,KAAK,0BAA0B,OAAO,KAAM;AAEhD,QAAI,KAAK,eAAqB,MAAA,eAAe,QAAQ;AAErD,SAAK,wBAAwB,OAAO;AAE/B,SAAA,iBAAiB,OAAO,SAAS,MAAM;AACvC,SAAA,eAAe,aAAa,OAAO,WAAW;AACnD,SAAK,sBAAsB;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO7B,uBAAuB,QAAoB;AACrC,QAAA,KAAK,+BAA+B,OAAO,KAAM;AAErD,QAAI,KAAK,oBAA0B,MAAA,oBAAoB,QAAQ;AAE/D,SAAK,6BAA6B,OAAO;AAEpC,SAAA,sBAAsB,OAAO,SAAS,MAAM;AAC5C,SAAA,oBAAoB,aAAa,OAAO,WAAW;AAExD,SAAK,sBAAsB;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO7B,YAAY,UAAkB;AAC5B,SAAK,WAAW;AAChB,SAAK,sBAAsB;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO7B,mBAAmB,eAAmC;AACpD,QAAI,cAAe,MAAK,cAAc,KAAK,aAAa;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO1D,UAAU,eAAsD;AAC1D,QAAA,CAAC,KAAK,OAAQ;AAClB,SAAK,uBAAuB,aAAa;AAErC,QAAA,CAAC,KAAK,OAAQ;AAClB,QAAI,KAAK,qBAAqB;AAC5B,WAAK,sBAAsB;AACtB,WAAA,kBAAkB,KAAK,mBAAmB;AAAA,IAAA;AAGjD,QAAI,KAAK,iBAAiB;AACxB,WAAK,eAAe,KAAK,qBAAqB,KAAK,QAAQ,aAAa;AAAA,IAAA,OACnE;AACL,WAAK,eAAe;AAAA,IAAA;AAGtB,QAAI,KAAK,cAAc;AACrB,WAAK,aAAa,KAAK,8BAA8B,EAAE,UAAU,KAAK,cAAc;AAAA,IAAA,OAC/E;AACL,WAAK,aAAa,KAAK,8BAA8B,EAAE,UAAU,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,GAAG,EAAA,GAAK;AAAA,IAAA;AAG/F,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMd,UAAU;;AACR,eAAK,oBAAL,mBAAsB;AACjB,SAAA,iBAAiB,SAAS,QAAQ;AAAA,EAAA;AAAA,EAGjC,uBAAuB,eAA2B;AACxD,QAAI,KAAK,iBAAiB;AACxB,UAAI,KAAK,gBAAgB,SAAS,KAAK,iBAAiB,SAAS,MAAM;AAChE,aAAA,iBAAiB,SAAS,QAAQ;AAClC,aAAA,iBAAiB,WAAW,KAAK;AAAA,MAAA;AAAA,IACxC;AAEF,SAAK,iBAAiB,OAAO,KAAK,cAAc,WAAW;AAC3D,SAAK,iBAAiB,YAAY,KAAK,cAAc,WAAW;AAChE,SAAK,iBAAiB,mBAAmB;AACpC,SAAA,iBAAiB,kBAAkB,IAAI;AAAA,EAAA;AAAA,EAGtC,qBAAqB,QAAsB,eAA2B;AAC5E,SAAK,UAAU,cAAc,KAAK,eAAe,MAAM;AAEjD,UAAA,eAAe,KAAK,UAAU,gBAAgB,KAAK,kBAAkB,KAAK,EAAE,CAAC;AACnF,QAAI,cAAc;AACV,YAAA,aAAa,aAAa,MAAM,MAAM;AACtC,YAAA,aAAa,cAAc,aAAa,UAAU;AACjD,aAAA,IAAI,MAAM,QAAQ,WAAW,GAAG,WAAW,GAAG,WAAW,GAAG,CAAC;AAAA,IAAA;AAAA,EACtE;AAAA,EAGM,qBAAqB;AACvB,QAAA,KAAK,aAAa,GAAG;AACvB,aAAO,KAAK;AAAA,IAAA;AAEV,QAAA,KAAK,aAAa,GAAG;AACvB,aAAO,KAAK;AAAA,IAAA;AAGd,QAAI,CAAC,KAAK,kBAAkB,CAAC,KAAK,qBAAqB;AACrD;AAAA,IAAA;AAGE,QAAA,KAAK,mBAAmB,KAAK,qBAAqB;AAEpD,aAAO,KAAK;AAAA,IAAA;AAGd,WAAO,KAAK,cAAc,KAAK,gBAAgB,KAAK,qBAAqB,KAAK,QAAQ;AAAA,EAAA;AAAA,EAGhF,cAAc,MAA4B,IAA0B,UAAwC;AAC5G,UAAA,UAAU,IAAI,MAAM,eAAe;AACnC,UAAA,kBAAkB,KAAK,WAAW,SAAS;AAC3C,UAAA,uBAAuB,GAAG,WAAW,SAAS;AACpD,UAAM,mBAAmB,IAAI,aAAa,gBAAgB,MAAM;AAEhE,aAAS,IAAI,GAAG,IAAI,gBAAgB,QAAQ,KAAK,GAAG;AAClD,YAAM,aAAa,IAAI,MAAM,QAAQ,gBAAgB,CAAC,GAAG,gBAAgB,IAAI,CAAC,GAAG,gBAAgB,IAAI,CAAC,CAAC;AACvG,YAAM,kBAAkB,IAAI,MAAM,QAAQ,qBAAqB,CAAC,GAAG,qBAAqB,IAAI,CAAC,GAAG,qBAAqB,IAAI,CAAC,CAAC;AACrH,YAAA,cAAc,IAAI,MAAM,QAAA,EAAU,YAAY,YAAY,iBAAiB,QAAQ;AAExE,uBAAA,CAAC,IAAI,YAAY;AACjB,uBAAA,IAAI,CAAC,IAAI,YAAY;AACrB,uBAAA,IAAI,CAAC,IAAI,YAAY;AAAA,IAAA;AAGxC,YAAQ,aAAa,YAAY,IAAI,MAAM,gBAAgB,kBAAkB,CAAC,CAAC;AAE3E,QAAA,KAAK,WAAW,OAAgB,SAAA,aAAa,UAAU,KAAK,WAAW,OAAO,MAAA,CAAO;AACrF,QAAA,KAAK,WAAW,GAAY,SAAA,aAAa,MAAM,KAAK,WAAW,GAAG,MAAA,CAAO;AAC7E,QAAI,KAAK,MAAO,SAAQ,SAAS,KAAK,MAAM,OAAO;AAE5C,WAAA;AAAA,EAAA;AAEX;AC5KA,MAAM,UAAU,IAAI,mBAAoB,IAAK,GAAG,GAAG,IAAK,GAAG,CAAG;AAI9D,MAAM,mCAAmC,eAAe;AAAA,EAEvD,cAAc;AAEb,UAAO;AAEP,SAAK,aAAc,YAAY,IAAI,uBAAwB,CAAE,IAAK,GAAG,GAAG,IAAK,IAAK,GAAG,GAAG,IAAK,CAAC,GAAI,EAAK;AACvG,SAAK,aAAc,MAAM,IAAI,uBAAwB,CAAE,GAAG,GAAG,GAAG,GAAG,GAAG,CAAG,GAAE,CAAC,CAAI;AAAA,EAElF;AAEA;AAEA,MAAM,YAAY,IAAI,2BAA4B;AAElD,MAAM,eAAe;AAAA,EAEpB,YAAa,UAAW;AAEvB,SAAK,QAAQ,IAAI,KAAM,WAAW,QAAU;AAAA,EAE9C;AAAA,EAEC,UAAU;AAET,SAAK,MAAM,SAAS,QAAS;AAAA,EAE/B;AAAA,EAEC,OAAQ,UAAW;AAElB,aAAS,OAAQ,KAAK,OAAO,OAAS;AAAA,EAExC;AAAA,EAEC,IAAI,WAAW;AAEd,WAAO,KAAK,MAAM;AAAA,EAEpB;AAAA,EAEC,IAAI,SAAU,OAAQ;AAErB,SAAK,MAAM,WAAW;AAAA,EAExB;AAEA;ACWA,MAAM,uBAAuB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO5B,YAAa,OAAO,OAAO,UAAW;AAErC,SAAK,YAAY,CAAE;AAEnB,SAAK,sBAAsB;AAE3B,QAAI,WAAW;AAEf,UAAM,mBAAmB;AAAA,MACxB,iBAAiB,EAAE,OAAO,KAAI;AAAA,IAC9B;AAED,UAAM,iBAAiB,qBAAsB,6BAA4B,GAAI,gBAAkB;AAE/F,UAAM,OAAO,IAAI,eAAgB,cAAgB;AAEjD,SAAK,cAAc,SAAW,MAAO;AAEpC,iBAAW;AACX,aAAO;AAAA,IAEP;AAED,SAAK,cAAc,SAAW,cAAc,uBAAuB,qBAAsB;AAExF,YAAM,WAAW,KAAK,qBAAsB,qBAAuB;AAEnE,YAAM,WAAW;AAAA,QAChB,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,cAAc;AAAA,QACd,eAAe,CAAE;AAAA,QACjB,OAAO;AAAA,QACP,OAAO;AAAA,QACP,WAAW;AAAA,QACX,WAAW;AAAA,MACX;AAED,WAAK,UAAU,KAAM,QAAU;AAE/B,aAAO;AAAA,IAEP;AAED,SAAK,0BAA0B,SAAW,UAAU,cAAe;AAElE,eAAS,eAAe;AAAA,IAExB;AAED,SAAK,OAAO,WAAY;AAEvB,UAAK,SAAS,aAAa,sBAAsB,GAAI;AAEpD,eAAO;AAAA,MAEX;AAEG,eAAU,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAO;AAElD,cAAM,WAAW,KAAK,UAAW,CAAG;AAGpC,iBAAS,cAAe,CAAC,IAAK,KAAK,mBAAoB,OAAO,OAAO,SAAS,OAAO,SAAS,OAAO,SAAS,WAAW,SAAS,SAAW;AAC7I,iBAAS,cAAe,CAAC,IAAK,KAAK,mBAAoB,OAAO,OAAO,SAAS,OAAO,SAAS,OAAO,SAAS,WAAW,SAAS,SAAW;AAC7I,aAAK,cAAe,SAAS,qBAAqB,SAAS,cAAe,EAAK;AAC/E,aAAK,cAAe,SAAS,qBAAqB,SAAS,cAAe,EAAK;AAG/E,cAAM,WAAW,SAAS;AAC1B,cAAM,WAAW,SAAS;AAE1B,YAAK,SAAS,iBAAiB,MAAO;AAErC,mBAAU,IAAI,GAAG,IAAI,SAAS,aAAa,QAAQ,KAAO;AAEzD,kBAAM,SAAS,SAAS,aAAc,CAAG;AAEzC,gBAAK,OAAO,SAAS,SAAS,MAAO;AAGpC,kBAAI,QAAQ;AAEZ,uBAAU,IAAI,GAAG,IAAI,KAAK,UAAU,QAAQ,KAAO;AAElD,oBAAK,OAAO,SAAS,KAAK,UAAW,CAAG,EAAC,MAAO;AAE/C,0BAAQ;AACR;AAAA,gBAET;AAAA,cAEA;AAEO,kBAAK,CAAE,OAAQ;AAEd,uBAAO,6CAA6C,SAAS,OAAO,kBAAkB,OAAO;AAAA,cAErG;AAAA,YAEA;AAEM,qBAAU,OAAO,IAAM,IAAG,EAAE,OAAO,KAAM;AAEzC,qBAAS,iBAAiB,yBAAyB,OAAO,OAAO,QAAQ,SAAS;AAAA,UAExF;AAAA,QAEA;AAAA,MAEA;AAEG,WAAK,sBAAsB;AAE3B,aAAO;AAAA,IAEP;AAED,SAAK,UAAU,WAAY;AAE1B,YAAM,sBAAsB,KAAK;AACjC,YAAM,mBAAmB,KAAK,wBAAwB,IAAI,IAAI;AAE9D,eAAU,IAAI,GAAG,KAAK,KAAK,UAAU,QAAQ,IAAI,IAAI,KAAO;AAE3D,cAAM,WAAW,KAAK,UAAW,CAAG;AAGpC,YAAK,SAAS,iBAAiB,MAAO;AAErC,gBAAM,WAAW,SAAS,SAAS;AAEnC,mBAAU,IAAI,GAAG,KAAK,SAAS,aAAa,QAAQ,IAAI,IAAI,KAAO;AAElE,kBAAM,SAAS,SAAS,aAAc,CAAG;AAEzC,qBAAU,OAAO,MAAO,QAAQ,OAAO,cAAe,mBAAmB,EAAG;AAAA,UAElF;AAAA,QAEA;AAGI,aAAK,eAAgB,SAAS,UAAU,SAAS,cAAe,iBAAoB;AAAA,MAExF;AAEG,WAAK,sBAAsB;AAAA,IAE3B;AAED,SAAK,yBAAyB,SAAW,UAAW;AAEnD,aAAO,SAAS,cAAe,KAAK,mBAAqB;AAAA,IAEzD;AAED,SAAK,2BAA2B,SAAW,UAAW;AAErD,aAAO,SAAS,cAAe,KAAK,wBAAwB,IAAI,IAAI,CAAG;AAAA,IAEvE;AAED,SAAK,UAAU,WAAY;AAE1B,WAAK,QAAS;AAEd,YAAM,YAAY,KAAK;AAEvB,eAAU,IAAI,GAAG,IAAI,UAAU,QAAQ,KAAO;AAE7C,cAAM,WAAW,UAAW,CAAG;AAE/B,YAAK,SAAS,oBAAsB,UAAS,oBAAoB,QAAS;AAE1E,cAAM,gBAAgB,SAAS;AAE/B,iBAAU,IAAI,GAAG,IAAI,cAAc,QAAQ,KAAO;AAEjD,gBAAM,eAAe,cAAe,CAAG;AACvC,uBAAa,QAAS;AAAA,QAE3B;AAAA,MAEA;AAAA,IAEG;AAED,aAAS,oBAAqB,gBAAiB;AAE9C,qBAAe,QAAQ,aAAa,WAAW,MAAM,QAAS,CAAG,IAAG,OAAO,MAAM,QAAS,CAAG,IAAG;AAAA,IAEnG;AAEE,SAAK,sBAAsB;AAK3B,aAAS,qBAAsB,uBAAuB,UAAW;AAEhE,iBAAW,YAAY,CAAE;AAEzB,YAAM,WAAW,IAAI,eAAgB;AAAA,QACpC,MAAM;AAAA,QACN;AAAA,QACA,cAAc,2BAA4B;AAAA,QAC1C,gBAAgB;AAAA,MACpB,CAAM;AAEH,0BAAqB,QAAU;AAE/B,aAAO;AAAA,IAEV;AAEE,SAAK,uBAAuB;AAE5B,SAAK,qBAAqB,SAAW,cAAc,cAAc,OAAO,OAAO,WAAW,WAAY;AAErG,qBAAe,gBAAgB;AAC/B,qBAAe,gBAAgB;AAE/B,cAAQ,SAAS;AACjB,cAAQ,SAAS;AAEjB,kBAAY,aAAa;AACzB,kBAAY,aAAa;AAEzB,YAAM,eAAe,IAAI,kBAAmB,cAAc,cAAc;AAAA,QACvE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,QAAQ;AAAA,QACR,MAAM;AAAA,QACN,aAAa;AAAA,MACjB,CAAM;AAEH,aAAO;AAAA,IAEP;AAED,SAAK,gBAAgB,WAAY;AAEhC,YAAM,OAAO,IAAI,aAAc,QAAQ,QAAQ,CAAG;AAClD,YAAM,UAAU,IAAI,YAAa,MAAM,OAAO,OAAO,YAAY,SAAW;AAC5E,cAAQ,cAAc;AACtB,aAAO;AAAA,IAEP;AAED,SAAK,gBAAgB,SAAW,OAAO,QAAS;AAM/C,uBAAiB,gBAAgB,QAAQ;AAEzC,WAAK,eAAgB,gBAAgB,MAAQ;AAE7C,uBAAiB,gBAAgB,QAAQ;AAAA,IAEzC;AAED,SAAK,iBAAiB,SAAW,UAAU,QAAS;AAEnD,YAAM,sBAAsB,SAAS,gBAAiB;AAEtD,YAAM,mBAAmB,SAAS,GAAG;AACrC,YAAM,0BAA0B,SAAS,UAAU;AAEnD,eAAS,GAAG,UAAU;AACtB,eAAS,UAAU,aAAa;AAChC,WAAK,WAAW;AAChB,eAAS,gBAAiB,MAAQ;AAClC,WAAK,OAAQ,QAAU;AACvB,WAAK,WAAW;AAEhB,eAAS,GAAG,UAAU;AACtB,eAAS,UAAU,aAAa;AAEhC,eAAS,gBAAiB,mBAAqB;AAAA,IAE/C;AAID,aAAS,6BAA6B;AAErC,aAAO;AAAA,IAMV;AAEE,aAAS,+BAA+B;AAEvC,aAAO;AAAA,IAUV;AAAA,EAEA;AAEA;AC1aA,MAAe,YAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAf,MAAe,iBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACAf,MAAe,iBAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;ACUR,MAAM,mBAAmB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EA2B9B,YAAY,MAAc,eAAoC,iBAAqC;AA1BnG;AACA;AAGiB;AAAA;AACA;AAGA;AAAA;AACA;AACA;AAER;AAED;AACA;AACA;AAES;AASV,SAAA,qBAAqB,mBAAmB,mBAAmB,IAAI;AACpE,SAAK,sBAAsB,KAAK;AAEhC,SAAK,gBAAgB;AACrB,SAAK,yBAAyB,IAAI,uBAAuB,MAAM,MAAM,KAAK,aAAa;AACvF,SAAK,uBAAuB;AAExB,QAAA,CAAC,cAAc,aAAa,UAAU;AACnC,WAAA,uBAAuB,YAAY,MAAM,aAAa;AAAA,IAAA;AAGxD,SAAA,sBAAsB,uBAAuB,IAAI;AACtD,SAAK,sBAAsB,IAAI,MAAM,QAAQ,GAAG,GAAG,GAAG,CAAC;AAGvD,SAAK,kBAAkB,KAAK,uBAAuB,YAAY,kBAAkB,WAAW,KAAK,mBAAmB;AACpH,SAAK,cAAc,KAAK,uBAAuB,YAAY,oBAAoB,gBAAgB,KAAK,mBAAmB;AACvH,SAAK,cAAc,KAAK,uBAAuB,YAAY,oBAAoB,gBAAgB,KAAK,mBAAmB;AAGvH,SAAK,gBAAgB,SAAS,SAAS,YAAY,EAAE,OAAO,EAAE;AAC9D,SAAK,gBAAgB,SAAS,SAAS,aAAa,EAAE,OAAO,KAAK,mBAAmB;AACrF,SAAK,gBAAgB,SAAS,SAAS,aAAa,EAAE,OAAO,KAAK,mBAAmB;AAErF,SAAK,YAAY,SAAS,SAAS,QAAQ,EAAE,OAAO,EAAE;AACtD,SAAK,YAAY,SAAS,SAAS,uBAAuB,EAAE,OAAO,KAAK,oBAAoB;AAC5F,SAAK,YAAY,SAAS,SAAS,mBAAmB,EAAE,OAAO,KAAK,oBAAoB;AACxF,SAAK,YAAY,SAAS,SAAS,iBAAiB,EAAE,OAAO,IAAI;AACjE,SAAK,YAAY,SAAS,SAAS,oBAAoB,EAAE,OAAO,IAAI;AAEpE,SAAK,YAAY,SAAS,SAAS,QAAQ,EAAE,OAAO,EAAE;AACtD,SAAK,YAAY,SAAS,SAAS,YAAY,EAAE,OAAO,EAAE;AAC1D,SAAK,YAAY,SAAS,SAAS,iBAAiB,EAAE,OAAO,IAAI;AACjE,SAAK,YAAY,SAAS,SAAS,uBAAuB,EAAE,OAAO,KAAK,oBAAoB;AAC5F,SAAK,YAAY,SAAS,SAAS,mBAAmB,EAAE,OAAO,KAAK,oBAAoB;AAEnF,SAAA,uBAAuB,wBAAwB,KAAK,aAAa,CAAC,KAAK,aAAa,KAAK,aAAa,KAAK,eAAe,CAAC;AAC3H,SAAA,uBAAuB,wBAAwB,KAAK,aAAa,CAAC,KAAK,aAAa,KAAK,aAAa,KAAK,eAAe,CAAC;AAE1H,UAAA,MAAM,KAAK,uBAAuB,KAAK;AAC7C,QAAI,KAAK;AACD,YAAA,IAAI,MAAM,8CAA8C,GAAG;AAAA,IAAA;AAG9D,SAAA,+BAA+B,KAAK,mBAAmB;AACvD,SAAA,+BAA+B,KAAK,mBAAmB;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO9D,0BAA0B,SAA4B;AACpD,SAAK,gBAAgB,SAAS,SAAS,WAAW,QAAQ;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO5D,+BAA+B,SAA4B;AACzD,SAAK,gBAAgB,SAAS,SAAS,WAAW,QAAQ;AAAA,EAAA;AAAA,EAG5D,oBAAoB,UAAkB;AACpC,SAAK,YAAY,SAAS,SAAS,kBAAkB,QAAQ;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAO/D,YAAY,UAAkB;AAC5B,SAAK,uBAAuB,MAAM,UAAU,GAAG,CAAC;AAChD,SAAK,gBAAgB,SAAS,SAAS,UAAU,QAAQ,KAAK;AAAA,EAAA;AAAA,EAGhE,yBAAyB,OAAe;AACtC,SAAK,YAAY,SAAS,SAAS,eAAe,QAAQ;AAAA,EAAA;AAAA,EAG5D,2BAA2B,OAAe;AACxC,SAAK,YAAY,SAAS,SAAS,eAAe,QAAQ;AAAA,EAAA;AAAA,EAG5D,uBAAuB,UAA6B;AAC7C,SAAA,oBAAoB,KAAK,QAAQ;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMxC,UAAU;AACR,SAAK,gBAAgB,cAAc,QAAQ,CAAC,QAAQ,IAAI,SAAS;AACjE,SAAK,YAAY,cAAc,QAAQ,CAAC,QAAQ,IAAI,SAAS;AAC7D,SAAK,YAAY,cAAc,QAAQ,CAAC,QAAQ,IAAI,SAAS;AAE7D,SAAK,oBAAoB,QAAQ;AACjC,SAAK,oBAAoB,QAAQ;AAEjC,SAAK,uBAAuB,QAAQ;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOtC,QAAQ,aAAqB;AAC3B,SAAK,YAAY,SAAS,SAAS,MAAM,QAAQ;AACjD,SAAK,YAAY,SAAS,SAAS,MAAM,QAAQ;AACjD,SAAK,uBAAuB,QAAQ;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOtC,qBAAoC;AAClC,SAAK,+BAA+B,KAAK,uBAAuB,uBAAuB,KAAK,WAAW,EAAE;AACzG,WAAO,KAAK;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAOd,qBAAoC;AAClC,SAAK,+BAA+B,KAAK,uBAAuB,uBAAuB,KAAK,WAAW,EAAE;AACzG,WAAO,KAAK;AAAA,EAAA;AAEhB;ACnKO,MAAM,0BAA0B;AAAA,EAcrC,YAAY,cAAmC,MAAc,eAAoC;AAbzF;AACA;AACA;AACA;AACA;AAEA;AACA;AACA;AAEA;AACA;AAGN,SAAK,eAAe;AACpB,SAAK,gBAAgB;AACrB,SAAK,cAAc;AACnB,SAAK,gCAAgC;AACrC,SAAK,wBAAwB;AAC7B,SAAK,0BAA0B;AAE/B,SAAK,mBAAmB,cAAc;AAEtC,SAAK,qBAAqB,IAAI,mBAAmB,KAAK,aAAa,KAAK,aAAa;AAChF,SAAA,+BAA+B,KAAK,mBAAmB,mBAAmB;AAC1E,SAAA,+BAA+B,KAAK,mBAAmB,mBAAmB;AAE/E,SAAK,mBAAmB,OAAO;AAAA,EAAA;AAAA,EAGjC,eAAe,MAAc;AAC3B,SAAK,mBAAmB,cAAc;AACtC,SAAK,mBAAmB,QAAQ;AAChC,SAAK,cAAc;AACnB,SAAK,qBAAqB,IAAI,mBAAmB,MAAM,KAAK,aAAa;AACzE,SAAK,mBAAmB,OAAO;AAAA,EAAA;AAAA,EAGjC,qBAAqB,OAAyB;AACxC,QAAA,KAAK,gBAAgB,MAAM,aAAa;AAC1C,WAAK,aAAa,KAAK,kBAAkB,EAAE,SAAS,0BAA0B,MAAM,WAAW,OAAO,KAAK,WAAW,GAAA,CAAI;AAAA,IAAA,OACrH;AACA,WAAA,mBAAmB,0BAA0B,MAAM,WAAW;AAAA,IAAA;AAAA,EACrE;AAAA,EAGF,0BAA0B,OAAyB;AAC7C,QAAA,KAAK,gBAAgB,MAAM,aAAa;AAC1C,WAAK,aAAa,KAAK,kBAAkB,EAAE,SAAS,0BAA0B,MAAM,WAAW,OAAO,KAAK,WAAW,GAAA,CAAI;AAAA,IAAA,OACrH;AACA,WAAA,mBAAmB,+BAA+B,MAAM,WAAW;AAAA,IAAA;AAAA,EAC1E;AAAA,EAGF,iCAAiC,UAAkB;AACjD,SAAK,gCAAgC;AAChC,SAAA,mBAAmB,YAAY,KAAK,6BAA6B;AAAA,EAAA;AAAA,EAGxE,yBAAyB,OAAe;AACtC,SAAK,wBAAwB;AACxB,SAAA,mBAAmB,yBAAyB,KAAK,qBAAqB;AAAA,EAAA;AAAA,EAG7E,2BAA2B,OAAe;AACxC,SAAK,0BAA0B;AAC1B,SAAA,mBAAmB,2BAA2B,KAAK,uBAAuB;AAAA,EAAA;AAAA,EAGjF,QAAQ,aAAqB;AACtB,SAAA,mBAAmB,QAAQ,WAAW;AAAA,EAAA;AAAA,EAG7C,qBAAoC;AAClC,QAAI,KAAK,UAAU,cAAc,+BAA+B,KAAK,mBAAmB,mBAAmB;AAC3G,WAAO,KAAK;AAAA,EAAA;AAAA,EAGd,qBAAoC;AAClC,QAAI,KAAK,UAAU,cAAc,+BAA+B,KAAK,mBAAmB,mBAAmB;AAC3G,WAAO,KAAK;AAAA,EAAA;AAAA,EAGd,UAAU;AACR,SAAK,mBAAmB,UAAU;AAClC,SAAK,mBAAmB,QAAQ;AAChC,SAAK,6BAA6B,QAAQ;AAC1C,SAAK,6BAA6B,QAAQ;AAAA,EAAA;AAAA,EAGpC,mBAAmB,cAA4B;AACrD,SAAK,QAAQ;AACR,SAAA,aAAa,KAAK,uBAAuB,EAAE,MAAM,cAAc,OAAO,cAAc;AAAA,EAAA;AAAA,EAG3F,uBAAuB,UAA6B;AAC7C,SAAA,mBAAmB,uBAAuB,QAAQ;AAAA,EAAA;AAAA,EAGzD,oBAAoB,UAAkB;AAC/B,SAAA,mBAAmB,oBAAoB,QAAQ;AAAA,EAAA;AAExD;ACnGA,MAAM,mBAAmB;AAAA,EAAzB;AACmB,0DAAiB,IAAgC;AAAA;AAAA,EAElE,IAAI,MAAkC;AACpC,UAAM,SAAS,KAAK,WAAW,IAAI,IAAI;AACvC,QAAI,CAAC,QAAQ;AACN,WAAA,WAAW,IAAI,MAAM,MAAM;AACzB,aAAA;AAAA,IAAA;AAEF,WAAA;AAAA,EAAA;AAAA,EAGT,IAAI,MAAsB,QAAoB;AACvC,SAAA,WAAW,IAAI,MAAM,MAAM;AAAA,EAAA;AAEpC;AAEO,MAAM,kBAAkB;AAAA,EAM7B,YAAY,cAAmC;AAL9B;AACA,2DAAmE,IAAI;AACvE;AACA,kEAAiE,IAAI;AAGpF,SAAK,eAAe;AACf,SAAA,aAAa,IAAI,mBAAmB;AACzC,SAAK,aAAa,GAAG,uBAAuB,KAAK,+BAA+B,KAAK,IAAI,CAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAS5F,QAAkC,MAAS,YAA8B,UAA6B,CAAA,GAAI;AACxG,UAAM,sBAA2C;AAAA,MAC/C,GAAG;AAAA,MACH,GAAG;AAAA,MACH,WAAW;AAAA,MACX,UAAU,WAAW,WAAW;AAAA;AAAA,IAClC;AACA,SAAK,SAAS,IAAI,EAAE,KAAK,mBAAmB;AAAA,EAAA;AAAA,EAG9C,QAAQ,aAAqB;AAC3B,SAAK,YAAY,QAAQ,CAAC,OAAO,SAAS;;AACxC,UAAI,MAAM,UAAU,CAAC,KAAK,mBAAmB,IAAI,IAAI,GAAG;AAChD,cAAA,aAAa,MAAM,MAAM;AAC/B,YAAI,YAAY;AACT,eAAA,mBAAmB,IAAI,MAAM,EAAE,GAAG,YAAY,WAAW,aAAa;AAC3E,2BAAW,sBAAX;AAAA,QAA+B;AAAA,MACjC;AAAA,IACF,CACD;AAED,SAAK,mBAAmB,QAAQ,CAAC,YAAY,SAAS;;AACpD,UAAI,WAAW,WAAW;AACxB,yBAAW,0BAAX;AACK,aAAA,mBAAmB,OAAO,IAAI;AACnC;AAAA,MAAA;AAGF,YAAM,EAAE,WAAW,UAAU,OAAW,IAAA;AAExC,YAAM,eAAe,cAAc;AAC7B,YAAA,WAAW,MAAM,OAAO,KAAK,IAAI,GAAK,eAAe,QAAQ,CAAC,GAAG,GAAK,CAAG;AAE1E,WAAA,uBAAuB,MAAM,QAAQ;AAC1C,uBAAW,yBAAX,oCAAkC;AAElC,UAAI,YAAY,GAAG;AACjB,aAAK,uBAAuB,IAAI;AAChC,yBAAW,yBAAX;AACK,aAAA,mBAAmB,OAAO,IAAI;AAAA,MAAA;AAAA,IACrC,CACD;AAAA,EAAA;AAAA,EAGK,SAAS,MAAkD;AACjE,UAAM,QAAQ,KAAK,YAAY,IAAI,IAAI;AACvC,QAAI,CAAC,OAAO;AACV,WAAK,YAAY,IAAI,MAAM,CAAA,CAAE;AAC7B,aAAO,KAAK,YAAY,IAAI,IAAI,KAAK,CAAC;AAAA,IAAA;AAEjC,WAAA;AAAA,EAAA;AAAA,EAGD,+BAA+B,EAAE,QAAkC;;AACnE,UAAA,cAAc,KAAK,SAAS,IAAI;AAC/B,WAAA,YAAY,OAAQ,aAAY,IAAI;AAE3C,UAAM,oBAAoB,KAAK,mBAAmB,IAAI,IAAI;AAC1D,QAAI,mBAAmB;AACrB,wBAAkB,YAAY;AAC9B,8BAAkB,0BAAlB;AAAA,IAA0C;AAAA,EAC5C;AAAA,EAGM,uBAAuB,MAAsB,UAAkB;AACrE,SAAK,aAAa,KAAK,wBAAwB,EAAE,MAAM,UAAU;AAAA,EAAA;AAAA,EAG3D,uBAAuB,MAAsB;AACnD,SAAK,aAAa,KAAK,sBAAsB,EAAE,MAAM;AAAA,EAAA;AAEzD;ACvFO,MAAM,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA,EAsB3B,YAAY,QAAmC;AArBvC;AACA;AACA;AAEA;AACA;AAGA;AAAA;AACA;AACA;AAEA;AACA;AAEA;AAON,UAAM,EAAE,OAAO,UAAU,QAAQ,aAAa,kBAAkB,SAAS;AAEpE,SAAA,eAAe,IAAI,oBAAoB;AACvC,SAAA,gBAAgB,KAAK,wBAAwB;AAClD,SAAK,aAAa,GAAG,uBAAuB,KAAK,0BAA0B,KAAK,IAAI,CAAC;AAErF,SAAK,QAAQ;AACb,SAAK,WAAW;AACX,SAAA,cAAc,KAAK,mBAAmB,MAAM;AAEjD,SAAK,eAAe,IAAI,aAAa,KAAK,YAAY;AACtD,SAAK,oBAAoB,IAAI,kBAAkB,KAAK,YAAY;AAChE,SAAK,qBAAqB,IAAI,mBAAmB,KAAK,cAAc,WAAW;AAC/E,SAAK,4BAA4B,IAAI,0BAA0B,KAAK,cAAc,aAAa,KAAK,QAAQ;AACvG,SAAA,uBAAuB,IAAI,qBAAqB,WAAW;AAChE,SAAK,qBAAqB,kBAAkB;AAC5C,SAAK,MAAM,IAAI,KAAK,qBAAqB,SAAS;AAElD,SAAK,sBAAsB,IAAI,oBAAoB,KAAK,cAAc,MAAM;AAC5E,QAAI,CAAC,gBAAsB,MAAA,oBAAoB,UAAU,KAAK;AAE9D,SAAK,aAAa,GAAG,wBAAwB,KAAK,yBAAyB,KAAK,IAAI,CAAC;AACrF,SAAK,aAAa,GAAG,8BAA8B,KAAK,iCAAiC,KAAK,IAAI,CAAC;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA;AAAA,EAQrG,OAAO,aAAqB;AAC1B,SAAK,oBAAoB,UAAU,KAAK,qBAAqB,SAAS;AACjE,SAAA,kBAAkB,QAAQ,WAAW;AACrC,SAAA,0BAA0B,QAAQ,WAAW;AAC7C,SAAA,qBAAqB,OAAO,WAAW;AAC5C,SAAK,qBAAqB,sBAAsB,KAAK,0BAA0B,oBAAoB;AACnG,SAAK,qBAAqB,sBAAsB,KAAK,0BAA0B,oBAAoB;AAAA,EAAA;AAAA,EAGrG,qBAAqB,QAAgB,WAAoB,OAAO;AAC1D,QAAA,eAAe,aAAa,KAAK,uBAAuB,EAAE,MAAM,gBAAgB;AAEpF,UAAM,OAAO,KAAK,aAAa,QAAQ,MAAM;AAE7C,QAAI,CAAC,MAAM;AACJ,WAAA,aAAa,KAAK,kBAAkB,EAAE,SAAS,iBAAiB,MAAM,oBAAoB;AAC/F;AAAA,IAAA;AAGF,SAAK,mBAAmB,eAAe,IAAI,EAAE,KAAK,CAAC,gBAAgB;AACjE,WAAK,YAAY,eAAe;AAC3B,WAAA,0BAA0B,qBAAqB,EAAE,aAAa,aAAa,KAAK,YAAY,aAAa;AACzG,WAAA,oBAAoB,kBAAkB,IAAI;AAAA,IAAA,CAChD;AAAA,EAAA;AAAA,EAGH,0BAA0B,QAAgB,WAAoB,OAAO;AAC/D,QAAA,eAAe,aAAa,KAAK,uBAAuB,EAAE,MAAM,gBAAgB;AAEpF,UAAM,OAAO,KAAK,aAAa,QAAQ,MAAM;AAE7C,QAAI,CAAC,MAAM;AACJ,WAAA,aAAa,KAAK,kBAAkB,EAAE,SAAS,iBAAiB,MAAM,oBAAoB;AAC/F;AAAA,IAAA;AAGF,SAAK,mBAAmB,eAAe,IAAI,EAAE,KAAK,CAAC,YAAY;AAC7D,WAAK,YAAY,oBAAoB;AACrC,WAAK,0BAA0B,0BAA0B;AAAA,QACvD,aAAa;AAAA,QACb,aAAa,KAAK,YAAY;AAAA,MAAA,CAC/B;AACI,WAAA,oBAAoB,uBAAuB,IAAI;AAAA,IAAA,CACrD;AAAA,EAAA;AAAA,EAGH,iCAAiC,UAAkB,WAAoB,OAAO;AACxE,QAAA,eAAe,aAAa,KAAK,uBAAuB,EAAE,MAAM,gBAAgB;AACpF,SAAK,YAAY,gCAAgC;AAC5C,SAAA,0BAA0B,iCAAiC,QAAQ;AACnE,SAAA,oBAAoB,YAAY,QAAQ;AAAA,EAAA;AAAA,EAG/C,gBAAgB,UAAkB,WAAoB,OAAO;AACvD,QAAA,eAAe,aAAa,KAAK,uBAAuB,EAAE,MAAM,UAAU;AAC9E,SAAK,YAAY,iBAAiB;AAClC,SAAK,qBAAqB,gBAAgB,KAAK,aAAa,UAAU,QAAQ,CAAC;AAAA,EAAA;AAAA,EAGjF,qBAAqB,UAAkB,WAAoB,OAAO;AAC5D,QAAA,eAAe,aAAa,KAAK,uBAAuB,EAAE,MAAM,UAAU;AAC9E,SAAK,YAAY,sBAAsB;AACvC,SAAK,qBAAqB,qBAAqB,KAAK,aAAa,UAAU,QAAQ,CAAC;AAAA,EAAA;AAAA,EAGtF,eAAe,OAAkC,WAAoB,OAAO;AACtE,QAAA,eAAe,aAAa,KAAK,uBAAuB,EAAE,MAAM,UAAU;AACzE,SAAA,qBAAqB,eAAe,KAAK;AAAA,EAAA;AAAA,EAGhD,oBAAoB,OAAkC,WAAoB,OAAO;AAC3E,QAAA,eAAe,aAAa,KAAK,uBAAuB,EAAE,MAAM,UAAU;AACzE,SAAA,qBAAqB,oBAAoB,KAAK;AAAA,EAAA;AAAA,EAGrD,iBAAiB,IAAwC,WAAoB,OAAO;AAC9E,QAAA,eAAe,aAAa,KAAK,uBAAuB,EAAE,MAAM,UAAU;AAE9E,QAAI,OAAO,OAAO,YAAY,KAAK,aAAa,UAAU,EAAE,GAAG;AAC7D,WAAK,gBAAgB,EAAE;AAAA,IAAA,OAClB;AACL,WAAK,eAAe,EAAE;AAAA,IAAA;AAAA,EACxB;AAAA,EAGF,sBAAsB,IAAwC,WAAoB,OAAO;AACnF,QAAA,eAAe,aAAa,KAAK,uBAAuB,EAAE,MAAM,UAAU;AAE9E,QAAI,OAAO,OAAO,YAAY,KAAK,aAAa,UAAU,EAAE,GAAG;AAC7D,WAAK,qBAAqB,EAAE;AAAA,IAAA,OACvB;AACL,WAAK,oBAAoB,EAAE;AAAA,IAAA;AAAA,EAC7B;AAAA,EAGF,kBAAkB,UAAkB,WAAoB,OAAO;AACzD,QAAA,eAAe,aAAa,KAAK,uBAAuB,EAAE,MAAM,UAAU;AAC9E,SAAK,YAAY,2BAA2B;AACvC,SAAA,qBAAqB,YAAY,QAAQ;AAAA,EAAA;AAAA,EAGhD,MAAM,eAAe,MAAc;AACjC,SAAK,YAAY,cAAc;AAC1B,SAAA,mBAAmB,eAAe,IAAI;AACtC,SAAA,0BAA0B,eAAe,IAAI;AAC7C,SAAA,qBAAqB,OAAO,IAAI;AAErC,UAAM,aAAa,KAAK,aAAa,QAAQ,KAAK,YAAY,YAAY;AAC1E,QAAI,CAAC,YAAY;AACV,WAAA,aAAa,KAAK,kBAAkB,EAAE,SAAS,iBAAiB,KAAK,YAAY,YAAY,mBAAA,CAAoB;AACtH;AAAA,IAAA;AAGF,UAAM,kBAAkB,KAAK,aAAa,QAAQ,KAAK,YAAY,iBAAiB;AACpF,QAAI,CAAC,iBAAiB;AACf,WAAA,aAAa,KAAK,kBAAkB,EAAE,SAAS,iBAAiB,KAAK,YAAY,iBAAiB,mBAAA,CAAoB;AAC3H;AAAA,IAAA;AAGG,SAAA,mBAAmB,eAAe,UAAU,EAAE;AAAA,MAAK,CAAC,YACvD,KAAK,0BAA0B,qBAAqB;AAAA,QAClD,aAAa;AAAA,QACb,aAAa;AAAA,MACd,CAAA;AAAA,IACH;AAEK,SAAA,mBAAmB,eAAe,eAAe,EAAE;AAAA,MAAK,CAAC,YAC5D,KAAK,0BAA0B,0BAA0B;AAAA,QACvD,aAAa;AAAA,QACb,aAAa;AAAA,MACd,CAAA;AAAA,IACH;AAEA,SAAK,0BAA0B,iCAAiC,KAAK,YAAY,6BAA6B;AAC9G,SAAK,0BAA0B,yBAAyB,KAAK,YAAY,qBAAqB;AAC9F,SAAK,0BAA0B,2BAA2B,KAAK,YAAY,uBAAuB;AAE7F,SAAA,qBAAqB,gBAAgB,KAAK,aAAa,UAAU,KAAK,YAAY,cAAc,CAAC;AACjG,SAAA,qBAAqB,qBAAqB,KAAK,aAAa,UAAU,KAAK,YAAY,mBAAmB,CAAC;AAChH,SAAK,qBAAqB,YAAY,KAAK,YAAY,wBAAwB;AAC/E,SAAK,qBAAqB,gBAAgB,KAAK,YAAY,qBAAqB;AAAA,EAAA;AAAA,EAGlF,aAAa,IAAY,MAAkB;AACpC,SAAA,aAAa,SAAS,IAAI,IAAI;AAAA,EAAA;AAAA,EAGrC,eAAe,IAAY,QAAuB;AAC3C,SAAA,aAAa,SAAS,IAAI,MAAM;AAAA,EAAA;AAAA,EAGvC,MAAM,qBAAqB,IAAY,KAAa;AAClD,WAAO,MAAM,KAAK,aAAa,cAAc,IAAI,GAAG;AAAA,EAAA;AAAA,EAGtD,MAAM,uBAAuB,IAAY,KAAa;AACpD,WAAO,MAAM,KAAK,aAAa,iBAAiB,IAAI,GAAG;AAAA,EAAA;AAAA,EAGzD,aAAa,KAAc;AACpB,SAAA,oBAAoB,UAAU,GAAG;AACtC,SAAK,YAAY,eAAe;AAEhC,QAAI,CAAC,KAAK;AACR,WAAK,YAAY,kBAAkB,EAAE,GAAG,WAAW,GAAG,UAAU;AAChE,WAAK,oBAAoB,mBAAmB,KAAK,YAAY,eAAe;AAAA,IAAA;AAAA,EAC9E;AAAA,EAGF,mBAAmB,UAA6B;AAC1C,QAAA,CAAC,KAAK,YAAY,aAAc;AACpC,SAAK,YAAY,kBAAkB;AAC9B,SAAA,oBAAoB,mBAAmB,QAAQ;AAAA,EAAA;AAAA,EAGtD,gBAAgB,cAAiC;AAC/C,SAAK,YAAY,wBAAwB;AACpC,SAAA,qBAAqB,gBAAgB,YAAY;AAAA,EAAA;AAAA,EAGxD,yBAAyB,OAAe;AACtC,SAAK,YAAY,wBAAwB;AACpC,SAAA,0BAA0B,yBAAyB,KAAK;AAAA,EAAA;AAAA,EAG/D,2BAA2B,OAAe;AACxC,SAAK,YAAY,0BAA0B;AACtC,SAAA,0BAA0B,2BAA2B,KAAK;AAAA,EAAA;AAAA,EAGjE,oBAAoB,UAAkB;AACpC,SAAK,YAAY,mBAAmB;AAC/B,SAAA,0BAA0B,oBAAoB,QAAQ;AAAA,EAAA;AAAA,EAG7D,uBAAuB,cAAsB,mBAA2B,SAAyB,QAAQ,WAAmB,KAAM,WAAoB,OAAO;AAC3J,SAAK,kBAAkB;AAAA,MACrB;AAAA,MACA,EAAE,QAAQ,SAAS;AAAA,MACnB;AAAA,QACE,mBAAmB,MAAM;AAClB,eAAA,qBAAqB,cAAc,QAAQ;AAC3C,eAAA,0BAA0B,mBAAmB,QAAQ;AAC1D,eAAK,iCAAiC,CAAC;AAAA,QAAA;AAAA,MACzC;AAAA,IAEJ;AAAA,EAAA;AAAA,EAGF,yBACE,gBACA,qBACA,SAAyB,QACzB,WAAmB,KACnB,WAAoB,OACpB;AACA,SAAK,kBAAkB;AAAA,MACrB;AAAA,MACA,EAAE,QAAQ,SAAS;AAAA,MACnB;AAAA,QACE,mBAAmB,MAAM;AAClB,eAAA,gBAAgB,gBAAgB,QAAQ;AACxC,eAAA,qBAAqB,qBAAqB,QAAQ;AACvD,eAAK,kBAAkB,CAAC;AAAA,QAAA;AAAA,MAC1B;AAAA,IAEJ;AAAA,EAAA;AAAA,EAGF,0BACE,QACA,aACA,SAKA;AACM,UAAA,UAAS,mCAAS,WAAU;AAC5B,UAAA,YAAW,mCAAS,aAAY;AAEtC,QAAI,mCAAS,UAAU;AACrB,WAAK,aAAa,KAAK,uBAAuB,EAAE,MAAM,UAAU;AAAA,IAAA;AAGlE,SAAK,kBAAkB;AAAA,MACrB;AAAA,MACA,EAAE,QAAQ,SAAS;AAAA,MACnB;AAAA,QACE,mBAAmB,MAAM;AACvB,eAAK,iBAAiB,MAAM;AAC5B,eAAK,sBAAsB,WAAW;AACtC,eAAK,kBAAkB,CAAC;AAAA,QAAA;AAAA,MAC1B;AAAA,IAEJ;AAAA,EAAA;AAAA,EAGF,0BAA0B,EAAE,MAAM,SAAqD;AAChF,SAAA,cAAc,IAAI,IAAI;AAAA,EAAA;AAAA,EAG7B,YAAwB;AACf,WAAA,KAAK,qBAAqB,QAAQ;AAAA,EAAA;AAAA,EAG3C,aAAa;AACJ,WAAA,KAAK,aAAa,WAAW;AAAA,EAAA;AAAA,EAGtC,eAAe;AACN,WAAA,KAAK,aAAa,cAAc;AAAA,EAAA;AAAA;AAAA;AAAA;AAAA,EAMzC,UAAU;AACR,SAAK,MAAM,OAAO,KAAK,qBAAqB,SAAS;AACrD,SAAK,0BAA0B,QAAQ;AACvC,SAAK,qBAAqB,QAAQ;AAClC,SAAK,oBAAoB,QAAQ;AACjC,SAAK,aAAa,QAAQ;AAC1B,SAAK,mBAAmB,QAAQ;AAAA,EAAA;AAAA,EAG1B,mBAAmB,QAAgD;AAClE,WAAA;AAAA,MACL,aAAa,OAAO;AAAA,MACpB,cAAc;AAAA,MACd,mBAAmB;AAAA,MACnB,+BAA+B;AAAA,MAC/B,gBAAgB;AAAA,MAChB,qBAAqB;AAAA,MACrB,0BAA0B;AAAA,MAC1B,uBAAuB;AAAA,MACvB,yBAAyB;AAAA,MACzB,kBAAkB;AAAA,MAClB,iBAAiB,EAAE,GAAG,GAAG,GAAG,EAAE;AAAA,MAC9B,uBAAuB,EAAE,GAAG,GAAG,GAAG,GAAG,GAAG,EAAE;AAAA,MAC1C,cAAc,OAAO,mBAAmB;AAAA,IAC1C;AAAA,EAAA;AAAA,EAGM,0BAAyC;AACxC,WAAA;AAAA,MACL,gBAAgB;AAAA,MAChB,kBAAkB;AAAA,MAClB,QAAQ;AAAA,MACR,YAAY;AAAA,MACZ,OAAO;AAAA,IACT;AAAA,EAAA;AAAA,EAGM,yBAAyB,EAAE,MAAM,YAAwD;AAC/F,YAAQ,MAAM;AAAA,MACZ,KAAK;AACH,aAAK,iCAAiC,QAAQ;AAC9C;AAAA,MACF,KAAK;AACH,aAAK,kBAAkB,QAAQ;AAC/B;AAAA,IAAA;AAAA,EACJ;AAAA,EAGM,iCAAiC,EAAE,YAA6C;AACjF,SAAA,0BAA0B,uBAAuB,QAAQ;AAAA,EAAA;AAElE;","x_google_ignoreList":[1,5,11,12]}
1
+ {"version":3,"file":"ionian.js","sources":["../src/lib/easing.ts","../node_modules/.pnpm/mitt@3.0.1/node_modules/mitt/dist/mitt.mjs","../src/lib/events/defaultEventEmitter.ts","../src/lib/utils.ts","../src/lib/services/assets/assetService.ts","../node_modules/.pnpm/three@0.174.0/node_modules/three/examples/jsm/math/MeshSurfaceSampler.js","../src/lib/services/dataTexture/dataTextureService.ts","../src/lib/services/instancedmesh/shaders/instanceFragmentShader.ts","../src/lib/services/instancedmesh/shaders/instanceVertexShader.ts","../src/lib/services/instancedmesh/instancedMeshManager.ts","../src/lib/services/intersection/intersectionService.ts","../node_modules/.pnpm/three@0.174.0/node_modules/three/examples/jsm/postprocessing/Pass.js","../node_modules/.pnpm/three@0.174.0/node_modules/three/examples/jsm/misc/GPUComputationRenderer.js","../src/lib/services/simulation/shaders/simulationPositionShader.ts","../src/lib/services/simulation/shaders/simulationVelocityShader.ts","../src/lib/services/simulation/simulationRenderer.ts","../src/lib/services/simulation/simulationRendererService.ts","../src/lib/services/transition/transitionService.ts","../src/lib/particlesEngine.ts"],"sourcesContent":["import { EasingFunction } from '@/lib/types';\n\n/**\n * Linear easing function.\n */\nexport const linear: EasingFunction = (n: number) => n;\n","export default function(n){return{all:n=n||new Map,on:function(t,e){var i=n.get(t);i?i.push(e):n.set(t,[e])},off:function(t,e){var i=n.get(t);i&&(e?i.splice(i.indexOf(e)>>>0,1):n.set(t,[]))},emit:function(t,e){var i=n.get(t);i&&i.slice().map(function(n){n(e)}),(i=n.get(\"*\"))&&i.slice().map(function(n){n(t,e)})}}}\n//# sourceMappingURL=mitt.mjs.map\n","import { Events } from '@/lib/events/topics';\nimport mitt from 'mitt';\nimport { EngineEventEmitter } from './engineEventEmitter';\n\nexport class DefaultEventEmitter implements EngineEventEmitter<Events> {\n private readonly emitter = mitt<Events>();\n\n emit<Key extends keyof Events>(type: Key, payload: Events[Key]): void {\n this.emitter.emit(type, payload);\n }\n\n off<Key extends keyof Events>(type: Key, handler?: (payload: Events[Key]) => void): void {\n this.emitter.off(type, handler);\n }\n\n on<Key extends keyof Events>(type: Key, handler: (payload: Events[Key]) => void): void {\n this.emitter.on(type, handler);\n }\n\n once<Key extends keyof Events>(type: Key, handler: (payload: Events[Key]) => void): void {\n this.emitter.on(type, (payload: Events[Key]) => {\n this.emitter.off(type, handler);\n handler(payload);\n });\n }\n\n dispose(): void {\n this.emitter.all.clear();\n }\n}\n","import * as THREE from 'three';\n\n/**\n * Creates a new DataTexture from the given data and size.\n * @param data - The data for the texture.\n * @param size - The size of the texture.\n * @returns The created DataTexture.\n */\nexport function createDataTexture(data: Float32Array, size: number) {\n const texture = new THREE.DataTexture(data, size, size, THREE.RGBAFormat, THREE.FloatType);\n texture.needsUpdate = true;\n return texture;\n}\n\n/**\n * Creates a blank DataTexture with the given size.\n * @param size - The size of the texture.\n * @returns The created blank DataTexture.\n */\nexport function createBlankDataTexture(size: number) {\n return createDataTexture(new Float32Array(4 * size * size), size);\n}\n\n/**\n * Creates a DataTexture representing a sphere.\n * @param size - The size of the texture.\n * @returns The created DataTexture.\n */\nexport function createSpherePoints(size: number) {\n const data = new Float32Array(size * size * 4);\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n\n let theta = Math.random() * Math.PI * 2;\n let phi = Math.acos(Math.random() * 2 - 1);\n let x = Math.sin(phi) * Math.cos(theta);\n let y = Math.sin(phi) * Math.sin(theta);\n let z = Math.cos(phi);\n\n data[4 * index] = x;\n data[4 * index + 1] = y;\n data[4 * index + 2] = z;\n data[4 * index + 3] = (Math.random() - 0.5) * 0.01;\n }\n }\n\n return createDataTexture(data, size);\n}\n\nexport function disposeMesh(mesh: THREE.Mesh) {\n mesh.geometry.dispose();\n if (mesh.material instanceof THREE.Material) {\n mesh.material.dispose();\n } else {\n mesh.material.forEach((material) => material.dispose());\n }\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n value = Math.min(value, max);\n value = Math.max(value, min);\n return value;\n}\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { ServiceState } from '@/lib/types';\nimport { disposeMesh } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { DRACOLoader, GLTFLoader } from 'three-stdlib';\n\nexport class AssetService {\n private serviceState: ServiceState = 'created';\n\n private readonly eventEmitter;\n private readonly meshes = new Map<string, THREE.Mesh>();\n private readonly textures = new Map<string, THREE.Texture>();\n\n private readonly gltfLoader = new GLTFLoader();\n private readonly textureLoader = new THREE.TextureLoader();\n private readonly dracoLoader = new DRACOLoader();\n\n private solidColorTexture = new THREE.DataTexture(new Uint8Array([127, 127, 127, 255]), 1, 1, THREE.RGBAFormat);\n\n constructor(eventEmitter: DefaultEventEmitter) {\n this.eventEmitter = eventEmitter;\n this.dracoLoader.setDecoderPath('https://www.gstatic.com/draco/versioned/decoders/1.5.7/');\n this.gltfLoader.setDRACOLoader(this.dracoLoader);\n this.updateServiceState('ready');\n }\n\n /**\n * Registers an asset.\n * @param id - The ID of the asset.\n * @param item - The asset to set.\n */\n register(id: string, item: THREE.Mesh | THREE.Texture) {\n item.name = id;\n\n if (item instanceof THREE.Mesh) {\n const prev = this.meshes.get(id);\n if (prev) disposeMesh(prev);\n this.meshes.set(id, item);\n } else {\n const prev = this.textures.get(id);\n if (prev) prev.dispose();\n this.textures.set(id, item);\n }\n\n this.eventEmitter.emit('assetRegistered', { id });\n }\n\n setSolidColor(color: THREE.ColorRepresentation) {\n this.changeColor(color);\n }\n\n getSolidColorTexture() {\n return this.solidColorTexture;\n }\n\n getMesh(id: string): THREE.Mesh | null {\n return this.meshes.get(id) ?? null;\n }\n\n getMatcap(id: string): THREE.Texture {\n const texture = this.textures.get(id);\n if (!texture) this.eventEmitter.emit('invalidRequest', { message: `texture with id \"${id}\" not found. using solid color texture instead...` });\n return texture ?? this.solidColorTexture;\n }\n\n getMeshIDs(): string[] {\n return Array.from(this.meshes.keys());\n }\n\n getTextureIDs(): string[] {\n return Array.from(this.textures.keys());\n }\n\n getMeshes(): THREE.Mesh[] {\n return Array.from(this.meshes.values());\n }\n\n getTextures(): THREE.Texture[] {\n return Array.from(this.textures.values());\n }\n\n hasMatcap(id: string) {\n return this.textures.has(id);\n }\n\n /**\n * Loads a mesh asynchronously.\n * @param id - The ID of the mesh.\n * @param url - The URL of the mesh.\n * @param options - Optional parameters.\n * @returns The loaded mesh or null.\n */\n async loadMeshAsync(id: string, url: string, options: { meshName?: string } = {}): Promise<THREE.Mesh | null> {\n const gltf = await this.gltfLoader.loadAsync(url);\n try {\n if (options.meshName) {\n const mesh = gltf.scene.getObjectByName(options.meshName) as THREE.Mesh;\n this.register(id, mesh);\n return mesh;\n } else {\n const mesh = gltf.scene.children[0] as THREE.Mesh;\n this.register(id, mesh);\n return mesh;\n }\n } catch (error) {\n this.eventEmitter.emit('invalidRequest', { message: `failed to load mesh: ${id}. ${error}` });\n return null;\n }\n }\n\n /**\n * Loads a texture asynchronously.\n * @param id - The ID of the texture.\n * @param url - The URL of the texture.\n * @returns The loaded texture or null.\n */\n async loadTextureAsync(id: string, url: string): Promise<THREE.Texture | null> {\n try {\n const texture = await this.textureLoader.loadAsync(url);\n this.register(id, texture);\n return texture;\n } catch (error) {\n this.eventEmitter.emit('invalidRequest', { message: `failed to load texture: ${id}. ${error}` });\n return null;\n }\n }\n\n dispose() {\n this.updateServiceState('disposed');\n this.meshes.forEach((mesh) => disposeMesh(mesh));\n this.meshes.clear();\n this.textures.forEach((texture) => texture.dispose());\n this.textures.clear();\n }\n\n private changeColor(color: THREE.ColorRepresentation) {\n const actual = new THREE.Color(color);\n this.solidColorTexture = new THREE.DataTexture(new Uint8Array([actual.r, actual.g, actual.b, 255]), 1, 1, THREE.RGBAFormat);\n this.solidColorTexture.needsUpdate = true;\n }\n\n private updateServiceState(serviceState: ServiceState) {\n this.serviceState = serviceState;\n this.eventEmitter.emit('serviceStateUpdated', { type: 'asset', state: serviceState });\n }\n}\n","import {\n\tTriangle,\n\tVector2,\n\tVector3\n} from 'three';\n\n/**\n * Utility class for sampling weighted random points on the surface of a mesh.\n *\n * Building the sampler is a one-time O(n) operation. Once built, any number of\n * random samples may be selected in O(logn) time. Memory usage is O(n).\n *\n * References:\n * - http://www.joesfer.com/?p=84\n * - https://stackoverflow.com/a/4322940/1314762\n */\n\nconst _face = new Triangle();\nconst _color = new Vector3();\nconst _uva = new Vector2(), _uvb = new Vector2(), _uvc = new Vector2();\n\nclass MeshSurfaceSampler {\n\n\tconstructor( mesh ) {\n\n\t\tthis.geometry = mesh.geometry;\n\t\tthis.randomFunction = Math.random;\n\n\t\tthis.indexAttribute = this.geometry.index;\n\t\tthis.positionAttribute = this.geometry.getAttribute( 'position' );\n\t\tthis.normalAttribute = this.geometry.getAttribute( 'normal' );\n\t\tthis.colorAttribute = this.geometry.getAttribute( 'color' );\n\t\tthis.uvAttribute = this.geometry.getAttribute( 'uv' );\n\t\tthis.weightAttribute = null;\n\n\t\tthis.distribution = null;\n\n\t}\n\n\tsetWeightAttribute( name ) {\n\n\t\tthis.weightAttribute = name ? this.geometry.getAttribute( name ) : null;\n\n\t\treturn this;\n\n\t}\n\n\tbuild() {\n\n\t\tconst indexAttribute = this.indexAttribute;\n\t\tconst positionAttribute = this.positionAttribute;\n\t\tconst weightAttribute = this.weightAttribute;\n\n\t\tconst totalFaces = indexAttribute ? ( indexAttribute.count / 3 ) : ( positionAttribute.count / 3 );\n\t\tconst faceWeights = new Float32Array( totalFaces );\n\n\t\t// Accumulate weights for each mesh face.\n\n\t\tfor ( let i = 0; i < totalFaces; i ++ ) {\n\n\t\t\tlet faceWeight = 1;\n\n\t\t\tlet i0 = 3 * i;\n\t\t\tlet i1 = 3 * i + 1;\n\t\t\tlet i2 = 3 * i + 2;\n\n\t\t\tif ( indexAttribute ) {\n\n\t\t\t\ti0 = indexAttribute.getX( i0 );\n\t\t\t\ti1 = indexAttribute.getX( i1 );\n\t\t\t\ti2 = indexAttribute.getX( i2 );\n\n\t\t\t}\n\n\t\t\tif ( weightAttribute ) {\n\n\t\t\t\tfaceWeight = weightAttribute.getX( i0 )\n\t\t\t\t\t+ weightAttribute.getX( i1 )\n\t\t\t\t\t+ weightAttribute.getX( i2 );\n\n\t\t\t}\n\n\t\t\t_face.a.fromBufferAttribute( positionAttribute, i0 );\n\t\t\t_face.b.fromBufferAttribute( positionAttribute, i1 );\n\t\t\t_face.c.fromBufferAttribute( positionAttribute, i2 );\n\t\t\tfaceWeight *= _face.getArea();\n\n\t\t\tfaceWeights[ i ] = faceWeight;\n\n\t\t}\n\n\t\t// Store cumulative total face weights in an array, where weight index\n\t\t// corresponds to face index.\n\n\t\tconst distribution = new Float32Array( totalFaces );\n\t\tlet cumulativeTotal = 0;\n\n\t\tfor ( let i = 0; i < totalFaces; i ++ ) {\n\n\t\t\tcumulativeTotal += faceWeights[ i ];\n\t\t\tdistribution[ i ] = cumulativeTotal;\n\n\t\t}\n\n\t\tthis.distribution = distribution;\n\t\treturn this;\n\n\t}\n\n\tsetRandomGenerator( randomFunction ) {\n\n\t\tthis.randomFunction = randomFunction;\n\t\treturn this;\n\n\t}\n\n\tsample( targetPosition, targetNormal, targetColor, targetUV ) {\n\n\t\tconst faceIndex = this.sampleFaceIndex();\n\t\treturn this.sampleFace( faceIndex, targetPosition, targetNormal, targetColor, targetUV );\n\n\t}\n\n\tsampleFaceIndex() {\n\n\t\tconst cumulativeTotal = this.distribution[ this.distribution.length - 1 ];\n\t\treturn this.binarySearch( this.randomFunction() * cumulativeTotal );\n\n\t}\n\n\tbinarySearch( x ) {\n\n\t\tconst dist = this.distribution;\n\t\tlet start = 0;\n\t\tlet end = dist.length - 1;\n\n\t\tlet index = - 1;\n\n\t\twhile ( start <= end ) {\n\n\t\t\tconst mid = Math.ceil( ( start + end ) / 2 );\n\n\t\t\tif ( mid === 0 || dist[ mid - 1 ] <= x && dist[ mid ] > x ) {\n\n\t\t\t\tindex = mid;\n\n\t\t\t\tbreak;\n\n\t\t\t} else if ( x < dist[ mid ] ) {\n\n\t\t\t\tend = mid - 1;\n\n\t\t\t} else {\n\n\t\t\t\tstart = mid + 1;\n\n\t\t\t}\n\n\t\t}\n\n\t\treturn index;\n\n\t}\n\n\tsampleFace( faceIndex, targetPosition, targetNormal, targetColor, targetUV ) {\n\n\t\tlet u = this.randomFunction();\n\t\tlet v = this.randomFunction();\n\n\t\tif ( u + v > 1 ) {\n\n\t\t\tu = 1 - u;\n\t\t\tv = 1 - v;\n\n\t\t}\n\n\t\t// get the vertex attribute indices\n\t\tconst indexAttribute = this.indexAttribute;\n\t\tlet i0 = faceIndex * 3;\n\t\tlet i1 = faceIndex * 3 + 1;\n\t\tlet i2 = faceIndex * 3 + 2;\n\t\tif ( indexAttribute ) {\n\n\t\t\ti0 = indexAttribute.getX( i0 );\n\t\t\ti1 = indexAttribute.getX( i1 );\n\t\t\ti2 = indexAttribute.getX( i2 );\n\n\t\t}\n\n\t\t_face.a.fromBufferAttribute( this.positionAttribute, i0 );\n\t\t_face.b.fromBufferAttribute( this.positionAttribute, i1 );\n\t\t_face.c.fromBufferAttribute( this.positionAttribute, i2 );\n\n\t\ttargetPosition\n\t\t\t.set( 0, 0, 0 )\n\t\t\t.addScaledVector( _face.a, u )\n\t\t\t.addScaledVector( _face.b, v )\n\t\t\t.addScaledVector( _face.c, 1 - ( u + v ) );\n\n\t\tif ( targetNormal !== undefined ) {\n\n\t\t\tif ( this.normalAttribute !== undefined ) {\n\n\t\t\t\t_face.a.fromBufferAttribute( this.normalAttribute, i0 );\n\t\t\t\t_face.b.fromBufferAttribute( this.normalAttribute, i1 );\n\t\t\t\t_face.c.fromBufferAttribute( this.normalAttribute, i2 );\n\t\t\t\ttargetNormal.set( 0, 0, 0 ).addScaledVector( _face.a, u ).addScaledVector( _face.b, v ).addScaledVector( _face.c, 1 - ( u + v ) ).normalize();\n\n\t\t\t} else {\n\n\t\t\t\t_face.getNormal( targetNormal );\n\n\t\t\t}\n\n\t\t}\n\n\t\tif ( targetColor !== undefined && this.colorAttribute !== undefined ) {\n\n\t\t\t_face.a.fromBufferAttribute( this.colorAttribute, i0 );\n\t\t\t_face.b.fromBufferAttribute( this.colorAttribute, i1 );\n\t\t\t_face.c.fromBufferAttribute( this.colorAttribute, i2 );\n\n\t\t\t_color\n\t\t\t\t.set( 0, 0, 0 )\n\t\t\t\t.addScaledVector( _face.a, u )\n\t\t\t\t.addScaledVector( _face.b, v )\n\t\t\t\t.addScaledVector( _face.c, 1 - ( u + v ) );\n\n\t\t\ttargetColor.r = _color.x;\n\t\t\ttargetColor.g = _color.y;\n\t\t\ttargetColor.b = _color.z;\n\n\t\t}\n\n\t\tif ( targetUV !== undefined && this.uvAttribute !== undefined ) {\n\n\t\t\t_uva.fromBufferAttribute( this.uvAttribute, i0 );\n\t\t\t_uvb.fromBufferAttribute( this.uvAttribute, i1 );\n\t\t\t_uvc.fromBufferAttribute( this.uvAttribute, i2 );\n\t\t\ttargetUV.set( 0, 0 ).addScaledVector( _uva, u ).addScaledVector( _uvb, v ).addScaledVector( _uvc, 1 - ( u + v ) );\n\n\t\t}\n\n\t\treturn this;\n\n\t}\n\n}\n\nexport { MeshSurfaceSampler };\n","import { DefaultEventEmitter } from '@/lib/events/defaultEventEmitter';\nimport { MeshData, ServiceState } from '@/lib/types';\nimport { createDataTexture } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { MeshSurfaceSampler } from 'three/examples/jsm/math/MeshSurfaceSampler.js';\n\n/**\n * DataTextureManager is responsible for managing data textures used for mesh sampling.\n */\nexport class DataTextureService {\n private textureSize: number;\n private dataTextures: Map<string, THREE.DataTexture>;\n private eventEmitter;\n private currentAtlas: THREE.DataTexture | null = null; // Cache the current atlas\n\n /**\n * Creates a new DataTextureManager instance.\n * @param eventEmitter\n * @param textureSize\n */\n constructor(eventEmitter: DefaultEventEmitter, textureSize: number) {\n this.eventEmitter = eventEmitter;\n this.textureSize = textureSize;\n this.dataTextures = new Map<string, THREE.DataTexture>();\n this.updateServiceState('ready');\n }\n\n setTextureSize(textureSize: number) {\n if (this.textureSize === textureSize) return;\n this.textureSize = textureSize;\n // Clear cache and dispose old textures\n this.dataTextures.forEach((texture) => texture.dispose());\n this.dataTextures.clear();\n if (this.currentAtlas) {\n this.currentAtlas.dispose();\n this.currentAtlas = null;\n }\n }\n\n /**\n * Prepares a mesh for sampling.\n * @returns The prepared data texture.\n * @param asset The asset to prepare.\n */\n async getDataTexture(asset: THREE.Mesh) {\n const cachedTexture = this.dataTextures.get(asset.uuid); // Use UUID for uniqueness\n if (cachedTexture) {\n return cachedTexture;\n }\n\n const meshData = parseMeshData(asset);\n const array = sampleMesh(meshData, this.textureSize);\n const dataTexture = createDataTexture(array, this.textureSize);\n dataTexture.name = asset.name; // Keep name for reference\n this.dataTextures.set(asset.uuid, dataTexture); // Cache using UUID\n return dataTexture;\n }\n\n async dispose() {\n this.dataTextures.forEach((texture) => texture.dispose());\n this.dataTextures.clear();\n if (this.currentAtlas) {\n this.currentAtlas.dispose();\n this.currentAtlas = null;\n }\n this.updateServiceState('disposed');\n }\n\n private updateServiceState(serviceState: ServiceState) {\n // Debounce or manage state updates if they become too frequent\n this.eventEmitter.emit('serviceStateUpdated', { type: 'data-texture', state: serviceState });\n }\n\n /**\n * Creates a Texture Atlas containing position data for a sequence of meshes.\n * @param meshes An array of THREE.Mesh objects in the desired sequence.\n * @param singleTextureSize The desired resolution (width/height) for each mesh's data within the atlas.\n * @returns A Promise resolving to the generated DataTexture atlas.\n */\n async createSequenceDataTextureAtlas(meshes: THREE.Mesh[], singleTextureSize: number): Promise<THREE.DataTexture> {\n this.updateServiceState('loading');\n if (this.currentAtlas) {\n this.currentAtlas.dispose(); // Dispose previous atlas\n this.currentAtlas = null;\n }\n\n const numMeshes = meshes.length;\n if (numMeshes === 0) {\n throw new Error('Mesh array cannot be empty.');\n }\n\n const atlasWidth = singleTextureSize * numMeshes;\n const atlasHeight = singleTextureSize; // Atlas height should be the height of a single texture\n const atlasData = new Float32Array(atlasWidth * atlasHeight * 4); // Correct size for RGBA Float32Array\n\n try {\n for (let i = 0; i < numMeshes; i++) {\n const mesh = meshes[i];\n const meshDataTexture = await this.getDataTexture(mesh);\n const meshTextureData = meshDataTexture.image.data as Float32Array;\n\n for (let y = 0; y < singleTextureSize; y++) {\n for (let x = 0; x < singleTextureSize; x++) {\n const sourceIndex = (y * singleTextureSize + x) * 4;\n const targetX = x + i * singleTextureSize;\n const targetIndex = (y * atlasWidth + targetX) * 4;\n\n atlasData[targetIndex] = meshTextureData[sourceIndex]; // R (x)\n atlasData[targetIndex + 1] = meshTextureData[sourceIndex + 1]; // G (y)\n atlasData[targetIndex + 2] = meshTextureData[sourceIndex + 2]; // B (z)\n atlasData[targetIndex + 3] = meshTextureData[sourceIndex + 3]; // A (w)\n }\n }\n }\n\n const atlasTexture = new THREE.DataTexture(atlasData, atlasWidth, atlasHeight, THREE.RGBAFormat, THREE.FloatType);\n atlasTexture.needsUpdate = true; // createDataTexture utility likely sets this, but be explicit\n atlasTexture.name = `atlas-${meshes.map((m) => m.name).join('-')}`;\n this.currentAtlas = atlasTexture; // Cache the new atlas\n this.updateServiceState('ready');\n return atlasTexture;\n } catch (error) {\n this.updateServiceState('error');\n throw error; // Re-throw error for ParticlesEngine to catch\n }\n }\n}\n\n/**\n * Parses mesh data into a simplified format.\n * @param mesh The mesh to parse.\n * @returns The parsed mesh data.\n */\nfunction parseMeshData(mesh: THREE.Mesh): MeshData {\n return {\n position: mesh.geometry.attributes.position.array,\n normal: (mesh.geometry.attributes.normal as THREE.BufferAttribute)?.array,\n scale: { x: mesh.scale.x, y: mesh.scale.y, z: mesh.scale.z },\n };\n}\n\nfunction sampleMesh(meshData: MeshData, size: number): Float32Array {\n const geometry = new THREE.BufferGeometry();\n geometry.setAttribute('position', new THREE.BufferAttribute(new Float32Array(meshData.position), 3));\n if (meshData.normal) {\n geometry.setAttribute('normal', new THREE.BufferAttribute(new Float32Array(meshData.normal), 3));\n }\n const material = new THREE.MeshBasicMaterial();\n const mesh = new THREE.Mesh(geometry, material);\n mesh.scale.set(meshData.scale.x, meshData.scale.y, meshData.scale.z);\n\n const sampler = new MeshSurfaceSampler(mesh).build();\n const data = new Float32Array(size * size * 4);\n const position = new THREE.Vector3();\n\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n sampler.sample(position);\n data[4 * index] = position.x * meshData.scale.x;\n data[4 * index + 1] = position.y * meshData.scale.y;\n data[4 * index + 2] = position.z * meshData.scale.z;\n data[4 * index + 3] = (Math.random() - 0.5) * 0.01;\n }\n }\n\n return data;\n}\n","export default `\nvarying vec2 vUv;\nuniform sampler2D uTexture;\n\nuniform sampler2D uOriginTexture;\nuniform sampler2D uDestinationTexture;\n\nuniform float uProgress;\nvarying vec3 vNormal;\nvarying vec3 vViewPosition;\nvoid main() {\n vec3 viewDir = normalize( vViewPosition );\n vec3 x = normalize( vec3( viewDir.z, 0.0, - viewDir.x ) );\n vec3 y = cross( viewDir, x );\n vec2 uv = vec2( dot( x, vNormal ), dot( y, vNormal ) ) * 0.495 + 0.5; // 0.495 to remove artifacts caused by undersized matcap disks\n\n vec4 sourceMatcap = texture2D( uOriginTexture, uv );\n vec4 targetMatcap = texture2D( uDestinationTexture, uv );\n\n vec4 matcap = mix(sourceMatcap, targetMatcap, uProgress);\n gl_FragColor = matcap;\n}\n`;\n","export default `\nvarying vec2 vUv;\nuniform sampler2D uTexture;\nuniform sampler2D uVelocity;\nuniform float uTime;\nvarying vec3 vNormal;\nattribute vec2 uvRef;\nvarying vec3 vViewPosition;\n\nvec3 rotate3D(vec3 v, vec3 vel) {\n vec3 pos = v;\n vec3 up = vec3(0, 1, 0);\n vec3 axis = normalize(cross(up, vel));\n float angle = acos(dot(up, normalize(vel)));\n pos = pos * cos(angle) + cross(axis, pos) * sin(angle) + axis * dot(axis, pos) * (1. - cos(angle));\n return pos;\n}\n\nvoid main() {\n vUv = uv;\n vNormal = normal;\n\n vec4 color = texture2D(uTexture, uvRef);\n vec4 velocity = texture2D(uVelocity, uvRef);\n vec3 pos = color.xyz;// apply the texture to the vertex distribution.\n\n vec3 localPosition = position.xyz;\n if (length (velocity.xyz) < 0.0001) {\n velocity.xyz = vec3(0.0, 0.0001, 0.0001);\n }\n localPosition.y *= max(1.0, length(velocity.xyz) * 1000.0);\n localPosition = rotate3D(localPosition, velocity.xyz);\n vNormal = rotate3D(normal, velocity.xyz);\n\n mat4 instanceMat = instanceMatrix;\n instanceMat[3].xyz = pos.xyz;\n\n // unlike the traditional mvMatrix * position, we need to additional multiplication with the instance matrix.\n vec4 modelViewPosition = modelViewMatrix * instanceMat * vec4(localPosition, 1.0);\n\n vViewPosition = - modelViewPosition.xyz;\n\n gl_Position = projectionMatrix * modelViewPosition;\n}\n`;\n","import * as THREE from 'three';\nimport { Vector3Like } from 'three';\nimport instanceFragmentShader from './shaders/instanceFragmentShader';\nimport instanceVertexShader from './shaders/instanceVertexShader';\n\ntype MaterialUniforms = {\n uTime: { value: number };\n uProgress: { value: number };\n uTexture: { value: THREE.DataTexture | null };\n uVelocity: { value: THREE.DataTexture | null };\n uOriginTexture: { value: THREE.Texture | null };\n uDestinationTexture: { value: THREE.Texture | null };\n};\n\n/**\n * InstancedMeshManager is responsible for managing instanced meshes.\n */\nexport class InstancedMeshManager {\n private size: number;\n private mesh: THREE.InstancedMesh;\n\n private readonly matcapMaterial: THREE.ShaderMaterial;\n private readonly fallbackGeometry: THREE.BufferGeometry;\n\n private readonly uniforms: MaterialUniforms;\n\n private originColor: THREE.ColorRepresentation | null;\n private destinationColor: THREE.ColorRepresentation | null;\n\n private geometries: Map<string, THREE.BufferGeometry>;\n private uvRefsCache: Map<number, THREE.InstancedBufferAttribute>;\n\n private previousScale: Vector3Like;\n\n /**\n * Creates a new InstancedMeshManager instance.\n * @param initialSize The initial size of the instanced mesh.\n */\n constructor(initialSize: number) {\n this.size = initialSize;\n this.geometries = new Map();\n this.uvRefsCache = new Map();\n\n this.previousScale = { x: 1, y: 1, z: 1 };\n this.originColor = 'grey';\n this.destinationColor = 'grey';\n\n this.uniforms = {\n uTime: { value: 0 },\n uProgress: { value: 0 },\n uTexture: { value: null },\n uVelocity: { value: null },\n uOriginTexture: { value: null },\n uDestinationTexture: { value: null },\n };\n\n this.matcapMaterial = new THREE.ShaderMaterial({\n uniforms: this.uniforms,\n vertexShader: instanceVertexShader,\n fragmentShader: instanceFragmentShader,\n });\n\n this.setOriginColor(this.originColor);\n this.setDestinationColor(this.destinationColor);\n\n this.fallbackGeometry = new THREE.BoxGeometry(0.001, 0.001, 0.001);\n this.mesh = this.createInstancedMesh(initialSize, this.fallbackGeometry, this.matcapMaterial);\n }\n\n /**\n * Gets the instanced mesh.\n * @returns The instanced mesh.\n */\n getMesh() {\n return this.mesh;\n }\n\n /**\n * Updates the instanced mesh.\n * @param elapsedTime The elapsed time.\n */\n update(elapsedTime: number) {\n const material = this.mesh.material;\n if (material instanceof THREE.ShaderMaterial || material instanceof THREE.RawShaderMaterial) {\n material.uniforms.uTime.value = elapsedTime;\n }\n }\n\n /**\n * Sets the matcap texture.\n * @param matcap The matcap texture to set.\n */\n setOriginMatcap(matcap: THREE.Texture) {\n this.disposeSolidColorOriginTexture();\n this.matcapMaterial.uniforms.uOriginTexture.value = matcap;\n }\n\n setDestinationMatcap(matcap: THREE.Texture) {\n this.disposeSolidColorDestinationTexture();\n this.matcapMaterial.uniforms.uDestinationTexture.value = matcap;\n }\n\n setProgress(float: number) {\n float = Math.max(0, float);\n float = Math.min(1, float);\n this.matcapMaterial.uniforms.uProgress.value = float;\n }\n\n setGeometrySize(size: THREE.Vector3Like) {\n this.mesh.geometry.scale(1 / this.previousScale.x, 1 / this.previousScale.y, 1 / this.previousScale.z);\n this.mesh.geometry.scale(size.x, size.y, size.z);\n this.previousScale = size;\n }\n\n /**\n * Use the matcap material for the instanced mesh.\n */\n useMatcapMaterial() {\n this.mesh.material = this.matcapMaterial;\n }\n\n /**\n * Use the specified geometry for the instanced mesh.\n * @param id The ID of the geometry to use.\n */\n useGeometry(id: string) {\n const geometry = this.geometries.get(id);\n if (geometry) {\n this.mesh.geometry = geometry;\n }\n }\n\n /**\n * Updates the velocity texture.\n * @param texture The velocity texture to update with.\n */\n updateVelocityTexture(texture: THREE.Texture) {\n this.matcapMaterial.uniforms.uVelocity.value = texture;\n }\n\n /**\n * Updates the position texture.\n * @param texture The position texture to update with.\n */\n updatePositionTexture(texture: THREE.Texture) {\n this.matcapMaterial.uniforms.uTexture.value = texture;\n }\n\n /**\n * Resizes or replaces the instanced mesh.\n * @param size The new size of the instanced mesh.\n * @returns An object containing the updated mesh, the previous mesh, and a boolean indicating whether the mesh was updated.\n */\n resize(size: number): { current: THREE.InstancedMesh; previous: THREE.InstancedMesh } {\n if (this.size === size) return { current: this.mesh, previous: this.mesh };\n\n this.size = size;\n\n // create new instances since it is greater than the last known value\n const prev = this.mesh;\n\n this.mesh = this.createInstancedMesh(size, prev.geometry, prev.material);\n\n return { current: this.mesh, previous: prev };\n }\n\n /**\n * Disposes the resources used by the InstancedMeshManager.\n */\n dispose() {\n this.mesh.dispose();\n\n this.geometries.forEach((geometry) => geometry.dispose());\n this.disposeSolidColorOriginTexture();\n this.disposeSolidColorDestinationTexture();\n this.matcapMaterial.dispose();\n\n this.uvRefsCache.clear();\n this.geometries.clear();\n }\n\n /**\n * Registers a geometry.\n * @param id The ID of the geometry to register.\n * @param geometry The geometry to register.\n */\n registerGeometry(id: string, geometry: THREE.BufferGeometry) {\n const previous = this.geometries.get(id);\n\n if (previous) {\n if (previous === geometry) {\n return;\n }\n }\n\n // finally, we are attaching uvRefs.\n const uvRefs = this.createUVRefs(this.size);\n geometry.setAttribute('uvRef', uvRefs);\n\n this.geometries.set(id, geometry);\n\n if (this.mesh.geometry === previous) {\n this.mesh.geometry = geometry;\n }\n\n previous?.dispose();\n }\n\n setOriginColor(color: THREE.ColorRepresentation) {\n this.disposeSolidColorOriginTexture();\n this.originColor = color;\n this.uniforms.uOriginTexture.value = this.createSolidColorDataTexture(color);\n }\n\n setDestinationColor(color: THREE.ColorRepresentation) {\n this.disposeSolidColorDestinationTexture();\n this.destinationColor = color;\n this.uniforms.uDestinationTexture.value = this.createSolidColorDataTexture(color);\n }\n\n /**\n * Gets the UV references for the specified size.\n * @param size The size for which to generate UV references.\n * @returns The UV references.\n */\n private createUVRefs(size: number) {\n const cached = this.uvRefsCache.get(size);\n\n if (cached) {\n return cached;\n }\n\n const uvRefs = new Float32Array(size * size * 2);\n\n for (let i = 0; i < size; i++) {\n for (let j = 0; j < size; j++) {\n const index = i * size + j;\n uvRefs[2 * index] = j / (size - 1);\n uvRefs[2 * index + 1] = i / (size - 1);\n }\n }\n\n const attr = new THREE.InstancedBufferAttribute(uvRefs, 2);\n\n this.uvRefsCache.set(size, attr);\n return attr;\n }\n\n /**\n * Creates a new instanced mesh.\n * @param size The size of the instanced mesh.\n * @param geometry The geometry to use for the instanced mesh.\n * @param material The material to use for the instanced mesh.\n * @returns The created instanced mesh.\n */\n private createInstancedMesh(size: number, geometry: THREE.BufferGeometry, material: THREE.Material | THREE.Material[]) {\n geometry = geometry || this.fallbackGeometry;\n geometry.setAttribute('uvRef', this.createUVRefs(size));\n const count = size * size;\n return new THREE.InstancedMesh(geometry, material, count);\n }\n\n private createSolidColorDataTexture(color: THREE.ColorRepresentation, size: number = 16): THREE.DataTexture {\n const col = new THREE.Color(color);\n const width = size;\n const height = size;\n const data = new Uint8Array(width * height * 4); // RGBA\n\n const r = Math.floor(col.r * 255);\n const g = Math.floor(col.g * 255);\n const b = Math.floor(col.b * 255);\n\n for (let i = 0; i < width * height; i++) {\n const index = i * 4;\n data[index] = r;\n data[index + 1] = g;\n data[index + 2] = b;\n data[index + 3] = 255; // Alpha\n }\n\n const texture = new THREE.DataTexture(data, width, height, THREE.RGBAFormat);\n texture.type = THREE.UnsignedByteType;\n texture.wrapS = THREE.RepeatWrapping; // Or ClampToEdgeWrapping\n texture.wrapT = THREE.RepeatWrapping; // Or ClampToEdgeWrapping\n texture.minFilter = THREE.NearestFilter; // Ensure sharp color\n texture.magFilter = THREE.NearestFilter;\n texture.needsUpdate = true;\n return texture;\n }\n\n private disposeSolidColorOriginTexture() {\n if (this.originColor) {\n this.originColor = null;\n if (this.uniforms.uOriginTexture.value) {\n this.uniforms.uOriginTexture.value.dispose();\n }\n }\n }\n\n private disposeSolidColorDestinationTexture() {\n if (this.destinationColor) {\n this.destinationColor = null;\n if (this.uniforms.uDestinationTexture.value) {\n this.uniforms.uDestinationTexture.value.dispose();\n }\n }\n }\n}\n","import { DefaultEventEmitter, EngineEventEmitter, Events } from '@/lib/events';\nimport * as THREE from 'three';\n\n/**\n * Service for calculating intersections between a ray and a morphed geometry.\n */\nexport class IntersectionService {\n private active: boolean = true;\n\n private raycaster = new THREE.Raycaster();\n private mousePosition = new THREE.Vector2();\n\n private camera?: THREE.Camera;\n\n private meshSequenceGeometries: THREE.BufferGeometry[] = []; // ADDED: Store cloned geometries\n private meshSequenceUUIDs: string[] = []; // ADDED: Track UUIDs to avoid redundant cloning\n\n private overallProgress: number = 0; // ADDED: Store overall progress (0-1)\n private intersectionMesh = new THREE.Mesh(); // Use a single mesh for intersection target\n\n private geometryNeedsUpdate: boolean;\n private eventEmitter: EngineEventEmitter<Events>;\n\n private blendedGeometry?: THREE.BufferGeometry; // Keep for the final blended result\n private intersection?: THREE.Vector4;\n\n /**\n * Creates a new IntersectionService instance.\n * @param eventEmitter The event emitter used for emitting events.\n * @param camera The camera used for raycasting.\n */\n constructor(eventEmitter: DefaultEventEmitter, camera?: THREE.Camera) {\n this.camera = camera;\n this.eventEmitter = eventEmitter;\n this.geometryNeedsUpdate = true;\n }\n\n setActive(active: boolean) {\n this.active = active;\n if (!active) {\n // Clear intersection when deactivated\n this.intersection = undefined;\n this.eventEmitter.emit('interactionPositionUpdated', { position: { x: 0, y: 0, z: 0, w: 0 } });\n }\n }\n\n getIntersectionMesh(): THREE.Mesh {\n return this.intersectionMesh;\n }\n\n /**\n * Set the camera used for raycasting.\n * @param camera\n */\n setCamera(camera: THREE.Camera) {\n this.camera = camera;\n }\n\n /**\n * Sets the sequence of meshes used for intersection calculations.\n * Clones the geometries to avoid modifying originals.\n * @param meshes An array of THREE.Mesh objects in sequence.\n */\n setMeshSequence(meshes: THREE.Mesh[]) {\n // Dispose old geometries\n this.meshSequenceGeometries.forEach((geom) => geom.dispose());\n this.meshSequenceGeometries = [];\n this.meshSequenceUUIDs = [];\n\n if (!meshes || meshes.length === 0) {\n this.geometryNeedsUpdate = true; // Need update to potentially clear geometry\n return;\n }\n\n meshes.forEach((mesh) => {\n if (mesh && mesh.geometry) {\n const clonedGeometry = mesh.geometry.clone();\n // IMPORTANT: Apply the mesh's world matrix to the cloned geometry\n // so the intersection calculation uses world coordinates.\n clonedGeometry.applyMatrix4(mesh.matrixWorld);\n this.meshSequenceGeometries.push(clonedGeometry);\n this.meshSequenceUUIDs.push(mesh.uuid); // Store UUID for reference\n } else {\n console.warn('Invalid mesh provided to IntersectionService sequence.');\n // Add a placeholder or handle error? For now, just skip.\n }\n });\n this.geometryNeedsUpdate = true; // Geometry has changed\n }\n\n /**\n * Set the overall progress through the mesh sequence.\n * @param progress Value between 0.0 (first mesh) and 1.0 (last mesh).\n */\n setOverallProgress(progress: number) {\n const newProgress = THREE.MathUtils.clamp(progress, 0.0, 1.0);\n if (this.overallProgress !== newProgress) {\n this.overallProgress = newProgress;\n this.geometryNeedsUpdate = true; // Progress change requires geometry update\n }\n }\n\n /**\n * Set the mouse position.\n * @param mousePosition\n */\n setPointerPosition(mousePosition?: THREE.Vector2Like) {\n if (mousePosition) this.mousePosition.copy(mousePosition);\n }\n\n /**\n * Calculate the intersection.\n * @returns The intersection point or undefined if no intersection was found.\n */\n calculate(instancedMesh: THREE.Mesh): THREE.Vector4 | undefined {\n if (!this.active || !this.camera || this.meshSequenceGeometries.length === 0) {\n // If inactive or no camera/geometry, ensure no intersection is reported\n if (this.intersection) {\n // Only emit update if state changes\n this.intersection = undefined;\n this.eventEmitter.emit('interactionPositionUpdated', { position: { x: 0, y: 0, z: 0, w: 0 } });\n }\n return undefined;\n }\n\n if (this.geometryNeedsUpdate) {\n // Dispose previous blended geometry before creating a new one\n if (this.blendedGeometry && this.blendedGeometry !== this.intersectionMesh.geometry) {\n this.blendedGeometry.dispose();\n }\n this.blendedGeometry = this.getBlendedGeometry(); // Calculate the new blended geometry\n this.geometryNeedsUpdate = false; // Mark as updated\n\n // Update the mesh used for raycasting\n if (this.blendedGeometry) {\n // Only replace geometry if it's different to avoid unnecessary disposal\n if (this.intersectionMesh.geometry !== this.blendedGeometry) {\n if (this.intersectionMesh.geometry) this.intersectionMesh.geometry.dispose(); // Dispose old one first\n this.intersectionMesh.geometry = this.blendedGeometry;\n }\n } else {\n // If no blended geometry, clear the intersection mesh's geometry\n if (this.intersectionMesh.geometry) this.intersectionMesh.geometry.dispose();\n this.intersectionMesh.geometry = new THREE.BufferGeometry(); // Empty geometry\n }\n }\n\n // Ensure the intersection mesh's world matrix matches the instanced mesh\n // This is crucial if the instanced mesh itself moves or rotates\n this.intersectionMesh.matrixWorld.copy(instancedMesh.matrixWorld);\n\n let newIntersection: THREE.Vector4 | undefined = undefined;\n if (this.blendedGeometry && this.blendedGeometry.attributes.position) {\n // Check if geometry is valid\n newIntersection = this.getFirstIntersection(this.camera, this.intersectionMesh); // Use intersectionMesh now\n }\n\n // Only emit update if intersection state changes\n const hasChanged =\n this.intersection?.x !== newIntersection?.x ||\n this.intersection?.y !== newIntersection?.y ||\n this.intersection?.z !== newIntersection?.z ||\n (this.intersection && !newIntersection) ||\n (!this.intersection && newIntersection);\n\n if (hasChanged) {\n this.intersection = newIntersection;\n if (this.intersection) {\n // Convert world intersection point to the instanced mesh's local space\n const worldPoint = new THREE.Vector3(this.intersection.x, this.intersection.y, this.intersection.z);\n const localPoint = instancedMesh.worldToLocal(worldPoint.clone()); // Use clone\n this.intersection.set(localPoint.x, localPoint.y, localPoint.z, 1); // w=1 indicates intersection found\n\n this.eventEmitter.emit('interactionPositionUpdated', { position: this.intersection });\n } else {\n this.eventEmitter.emit('interactionPositionUpdated', { position: { x: 0, y: 0, z: 0, w: 0 } }); // w=0 indicates no intersection\n }\n }\n\n return this.intersection; // Return the local space intersection vector\n }\n\n /**\n * Dispose the resources used by the IntersectionService.\n */\n dispose() {\n this.meshSequenceGeometries.forEach((geom) => geom.dispose());\n this.meshSequenceGeometries = [];\n this.meshSequenceUUIDs = [];\n if (this.blendedGeometry && this.blendedGeometry !== this.intersectionMesh.geometry) {\n this.blendedGeometry.dispose();\n }\n this.intersectionMesh.geometry?.dispose(); // Dispose geometry held by intersectionMesh\n }\n\n private updateIntersectionMesh(instancedMesh: THREE.Mesh) {\n if (this.blendedGeometry) {\n if (this.blendedGeometry.uuid !== this.intersectionMesh.geometry.uuid) {\n this.intersectionMesh.geometry.dispose();\n this.intersectionMesh.geometry = this.blendedGeometry;\n }\n }\n this.intersectionMesh.matrix.copy(instancedMesh.matrixWorld);\n this.intersectionMesh.matrixWorld.copy(instancedMesh.matrixWorld);\n this.intersectionMesh.matrixAutoUpdate = false;\n this.intersectionMesh.updateMatrixWorld(true);\n }\n\n private getFirstIntersection(camera: THREE.Camera, targetMesh: THREE.Mesh): THREE.Vector4 | undefined {\n this.raycaster.setFromCamera(this.mousePosition, camera);\n\n // Intersect with the provided target mesh (which should have the blended geometry)\n const intersects = this.raycaster.intersectObject(targetMesh, false);\n\n if (intersects.length > 0 && intersects[0].point) {\n const worldPoint = intersects[0].point;\n // Return world point here, conversion to local happens in calculate()\n return new THREE.Vector4(worldPoint.x, worldPoint.y, worldPoint.z, 1);\n }\n return undefined;\n }\n\n private getBlendedGeometry(): THREE.BufferGeometry | undefined {\n const numGeometries = this.meshSequenceGeometries.length;\n if (numGeometries === 0) {\n return undefined;\n }\n if (numGeometries === 1) {\n return this.meshSequenceGeometries[0]; // No blending needed\n }\n\n // Calculate which two geometries to blend and the local progress\n const totalSegments = numGeometries - 1;\n const progressPerSegment = 1.0 / totalSegments;\n const scaledProgress = this.overallProgress * totalSegments;\n\n let indexA = Math.floor(scaledProgress);\n let indexB = indexA + 1;\n\n // Clamp indices to be within bounds\n indexA = THREE.MathUtils.clamp(indexA, 0, totalSegments);\n indexB = THREE.MathUtils.clamp(indexB, 0, totalSegments);\n\n // Calculate local progress between indexA and indexB\n // Avoid division by zero if progressPerSegment is 0 (only one mesh)\n let localProgress = 0;\n if (progressPerSegment > 0) {\n // localProgress = (this.overallProgress - (indexA * progressPerSegment)) / progressPerSegment;\n localProgress = scaledProgress - indexA; // Simpler way: fraction part of scaledProgress\n }\n\n // Handle edge case: progress is exactly 1.0\n if (this.overallProgress >= 1.0) {\n indexA = totalSegments;\n indexB = totalSegments;\n localProgress = 1.0; // Should blend fully to the last mesh\n }\n\n // Ensure localProgress is clamped (due to potential float inaccuracies)\n localProgress = THREE.MathUtils.clamp(localProgress, 0.0, 1.0);\n\n const geomA = this.meshSequenceGeometries[indexA];\n const geomB = this.meshSequenceGeometries[indexB];\n\n if (!geomA || !geomB) {\n console.error('IntersectionService: Invalid geometries found for blending at indices', indexA, indexB);\n return this.meshSequenceGeometries[0]; // Fallback\n }\n\n // If the two geometries are the same (e.g., at progress 0 or 1), return one directly\n if (indexA === indexB) {\n return geomA;\n }\n\n // Perform the blending\n return this.blendGeometry(geomA, geomB, localProgress);\n }\n\n private blendGeometry(from: THREE.BufferGeometry, to: THREE.BufferGeometry, progress: number): THREE.BufferGeometry {\n const blended = new THREE.BufferGeometry();\n const originPositions = from.attributes.position.array;\n const destinationPositions = to.attributes.position.array;\n const blendedPositions = new Float32Array(originPositions.length);\n\n for (let i = 0; i < originPositions.length; i += 3) {\n const originVert = new THREE.Vector3(originPositions[i], originPositions[i + 1], originPositions[i + 2]);\n const destinationVert = new THREE.Vector3(destinationPositions[i], destinationPositions[i + 1], destinationPositions[i + 2]);\n const blendedVert = new THREE.Vector3().lerpVectors(originVert, destinationVert, progress);\n\n blendedPositions[i] = blendedVert.x;\n blendedPositions[i + 1] = blendedVert.y;\n blendedPositions[i + 2] = blendedVert.z;\n }\n\n blended.setAttribute('position', new THREE.BufferAttribute(blendedPositions, 3));\n\n if (from.attributes.normal) blended.setAttribute('normal', from.attributes.normal.clone());\n if (from.attributes.uv) blended.setAttribute('uv', from.attributes.uv.clone());\n if (from.index) blended.setIndex(from.index.clone());\n\n return blended;\n }\n}\n","import {\n\tBufferGeometry,\n\tFloat32BufferAttribute,\n\tOrthographicCamera,\n\tMesh\n} from 'three';\n\nclass Pass {\n\n\tconstructor() {\n\n\t\tthis.isPass = true;\n\n\t\t// if set to true, the pass is processed by the composer\n\t\tthis.enabled = true;\n\n\t\t// if set to true, the pass indicates to swap read and write buffer after rendering\n\t\tthis.needsSwap = true;\n\n\t\t// if set to true, the pass clears its buffer before rendering\n\t\tthis.clear = false;\n\n\t\t// if set to true, the result of the pass is rendered to screen. This is set automatically by EffectComposer.\n\t\tthis.renderToScreen = false;\n\n\t}\n\n\tsetSize( /* width, height */ ) {}\n\n\trender( /* renderer, writeBuffer, readBuffer, deltaTime, maskActive */ ) {\n\n\t\tconsole.error( 'THREE.Pass: .render() must be implemented in derived pass.' );\n\n\t}\n\n\tdispose() {}\n\n}\n\n// Helper for passes that need to fill the viewport with a single quad.\n\nconst _camera = new OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\n// https://github.com/mrdoob/three.js/pull/21358\n\nclass FullscreenTriangleGeometry extends BufferGeometry {\n\n\tconstructor() {\n\n\t\tsuper();\n\n\t\tthis.setAttribute( 'position', new Float32BufferAttribute( [ - 1, 3, 0, - 1, - 1, 0, 3, - 1, 0 ], 3 ) );\n\t\tthis.setAttribute( 'uv', new Float32BufferAttribute( [ 0, 2, 0, 0, 2, 0 ], 2 ) );\n\n\t}\n\n}\n\nconst _geometry = new FullscreenTriangleGeometry();\n\nclass FullScreenQuad {\n\n\tconstructor( material ) {\n\n\t\tthis._mesh = new Mesh( _geometry, material );\n\n\t}\n\n\tdispose() {\n\n\t\tthis._mesh.geometry.dispose();\n\n\t}\n\n\trender( renderer ) {\n\n\t\trenderer.render( this._mesh, _camera );\n\n\t}\n\n\tget material() {\n\n\t\treturn this._mesh.material;\n\n\t}\n\n\tset material( value ) {\n\n\t\tthis._mesh.material = value;\n\n\t}\n\n}\n\nexport { Pass, FullScreenQuad };\n","import {\n\tClampToEdgeWrapping,\n\tDataTexture,\n\tFloatType,\n\tNearestFilter,\n\tRGBAFormat,\n\tShaderMaterial,\n\tWebGLRenderTarget\n} from 'three';\n\nimport { FullScreenQuad } from '../postprocessing/Pass.js';\n\n/**\n * GPUComputationRenderer, based on SimulationRenderer by zz85\n *\n * The GPUComputationRenderer uses the concept of variables. These variables are RGBA float textures that hold 4 floats\n * for each compute element (texel)\n *\n * Each variable has a fragment shader that defines the computation made to obtain the variable in question.\n * You can use as many variables you need, and make dependencies so you can use textures of other variables in the shader\n * (the sampler uniforms are added automatically) Most of the variables will need themselves as dependency.\n *\n * The renderer has actually two render targets per variable, to make ping-pong. Textures from the current frame are used\n * as inputs to render the textures of the next frame.\n *\n * The render targets of the variables can be used as input textures for your visualization shaders.\n *\n * Variable names should be valid identifiers and should not collide with THREE GLSL used identifiers.\n * a common approach could be to use 'texture' prefixing the variable name; i.e texturePosition, textureVelocity...\n *\n * The size of the computation (sizeX * sizeY) is defined as 'resolution' automatically in the shader. For example:\n * #DEFINE resolution vec2( 1024.0, 1024.0 )\n *\n * -------------\n *\n * Basic use:\n *\n * // Initialization...\n *\n * // Create computation renderer\n * const gpuCompute = new GPUComputationRenderer( 1024, 1024, renderer );\n *\n * // Create initial state float textures\n * const pos0 = gpuCompute.createTexture();\n * const vel0 = gpuCompute.createTexture();\n * // and fill in here the texture data...\n *\n * // Add texture variables\n * const velVar = gpuCompute.addVariable( \"textureVelocity\", fragmentShaderVel, vel0 );\n * const posVar = gpuCompute.addVariable( \"texturePosition\", fragmentShaderPos, pos0 );\n *\n * // Add variable dependencies\n * gpuCompute.setVariableDependencies( velVar, [ velVar, posVar ] );\n * gpuCompute.setVariableDependencies( posVar, [ velVar, posVar ] );\n *\n * // Add custom uniforms\n * velVar.material.uniforms.time = { value: 0.0 };\n *\n * // Check for completeness\n * const error = gpuCompute.init();\n * if ( error !== null ) {\n *\t\tconsole.error( error );\n * }\n *\n *\n * // In each frame...\n *\n * // Compute!\n * gpuCompute.compute();\n *\n * // Update texture uniforms in your visualization materials with the gpu renderer output\n * myMaterial.uniforms.myTexture.value = gpuCompute.getCurrentRenderTarget( posVar ).texture;\n *\n * // Do your rendering\n * renderer.render( myScene, myCamera );\n *\n * -------------\n *\n * Also, you can use utility functions to create ShaderMaterial and perform computations (rendering between textures)\n * Note that the shaders can have multiple input textures.\n *\n * const myFilter1 = gpuCompute.createShaderMaterial( myFilterFragmentShader1, { theTexture: { value: null } } );\n * const myFilter2 = gpuCompute.createShaderMaterial( myFilterFragmentShader2, { theTexture: { value: null } } );\n *\n * const inputTexture = gpuCompute.createTexture();\n *\n * // Fill in here inputTexture...\n *\n * myFilter1.uniforms.theTexture.value = inputTexture;\n *\n * const myRenderTarget = gpuCompute.createRenderTarget();\n * myFilter2.uniforms.theTexture.value = myRenderTarget.texture;\n *\n * const outputRenderTarget = gpuCompute.createRenderTarget();\n *\n * // Now use the output texture where you want:\n * myMaterial.uniforms.map.value = outputRenderTarget.texture;\n *\n * // And compute each frame, before rendering to screen:\n * gpuCompute.doRenderTarget( myFilter1, myRenderTarget );\n * gpuCompute.doRenderTarget( myFilter2, outputRenderTarget );\n */\n\nclass GPUComputationRenderer {\n\n\t/**\n\t * @param {number} sizeX Computation problem size is always 2d: sizeX * sizeY elements.\n \t * @param {number} sizeY Computation problem size is always 2d: sizeX * sizeY elements.\n \t * @param {WebGLRenderer} renderer The renderer\n\t */\n\tconstructor( sizeX, sizeY, renderer ) {\n\n\t\tthis.variables = [];\n\n\t\tthis.currentTextureIndex = 0;\n\n\t\tlet dataType = FloatType;\n\n\t\tconst passThruUniforms = {\n\t\t\tpassThruTexture: { value: null }\n\t\t};\n\n\t\tconst passThruShader = createShaderMaterial( getPassThroughFragmentShader(), passThruUniforms );\n\n\t\tconst quad = new FullScreenQuad( passThruShader );\n\n\t\tthis.setDataType = function ( type ) {\n\n\t\t\tdataType = type;\n\t\t\treturn this;\n\n\t\t};\n\n\t\tthis.addVariable = function ( variableName, computeFragmentShader, initialValueTexture ) {\n\n\t\t\tconst material = this.createShaderMaterial( computeFragmentShader );\n\n\t\t\tconst variable = {\n\t\t\t\tname: variableName,\n\t\t\t\tinitialValueTexture: initialValueTexture,\n\t\t\t\tmaterial: material,\n\t\t\t\tdependencies: null,\n\t\t\t\trenderTargets: [],\n\t\t\t\twrapS: null,\n\t\t\t\twrapT: null,\n\t\t\t\tminFilter: NearestFilter,\n\t\t\t\tmagFilter: NearestFilter\n\t\t\t};\n\n\t\t\tthis.variables.push( variable );\n\n\t\t\treturn variable;\n\n\t\t};\n\n\t\tthis.setVariableDependencies = function ( variable, dependencies ) {\n\n\t\t\tvariable.dependencies = dependencies;\n\n\t\t};\n\n\t\tthis.init = function () {\n\n\t\t\tif ( renderer.capabilities.maxVertexTextures === 0 ) {\n\n\t\t\t\treturn 'No support for vertex shader textures.';\n\n\t\t\t}\n\n\t\t\tfor ( let i = 0; i < this.variables.length; i ++ ) {\n\n\t\t\t\tconst variable = this.variables[ i ];\n\n\t\t\t\t// Creates rendertargets and initialize them with input texture\n\t\t\t\tvariable.renderTargets[ 0 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter );\n\t\t\t\tvariable.renderTargets[ 1 ] = this.createRenderTarget( sizeX, sizeY, variable.wrapS, variable.wrapT, variable.minFilter, variable.magFilter );\n\t\t\t\tthis.renderTexture( variable.initialValueTexture, variable.renderTargets[ 0 ] );\n\t\t\t\tthis.renderTexture( variable.initialValueTexture, variable.renderTargets[ 1 ] );\n\n\t\t\t\t// Adds dependencies uniforms to the ShaderMaterial\n\t\t\t\tconst material = variable.material;\n\t\t\t\tconst uniforms = material.uniforms;\n\n\t\t\t\tif ( variable.dependencies !== null ) {\n\n\t\t\t\t\tfor ( let d = 0; d < variable.dependencies.length; d ++ ) {\n\n\t\t\t\t\t\tconst depVar = variable.dependencies[ d ];\n\n\t\t\t\t\t\tif ( depVar.name !== variable.name ) {\n\n\t\t\t\t\t\t\t// Checks if variable exists\n\t\t\t\t\t\t\tlet found = false;\n\n\t\t\t\t\t\t\tfor ( let j = 0; j < this.variables.length; j ++ ) {\n\n\t\t\t\t\t\t\t\tif ( depVar.name === this.variables[ j ].name ) {\n\n\t\t\t\t\t\t\t\t\tfound = true;\n\t\t\t\t\t\t\t\t\tbreak;\n\n\t\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif ( ! found ) {\n\n\t\t\t\t\t\t\t\treturn 'Variable dependency not found. Variable=' + variable.name + ', dependency=' + depVar.name;\n\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t}\n\n\t\t\t\t\t\tuniforms[ depVar.name ] = { value: null };\n\n\t\t\t\t\t\tmaterial.fragmentShader = '\\nuniform sampler2D ' + depVar.name + ';\\n' + material.fragmentShader;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t\tthis.currentTextureIndex = 0;\n\n\t\t\treturn null;\n\n\t\t};\n\n\t\tthis.compute = function () {\n\n\t\t\tconst currentTextureIndex = this.currentTextureIndex;\n\t\t\tconst nextTextureIndex = this.currentTextureIndex === 0 ? 1 : 0;\n\n\t\t\tfor ( let i = 0, il = this.variables.length; i < il; i ++ ) {\n\n\t\t\t\tconst variable = this.variables[ i ];\n\n\t\t\t\t// Sets texture dependencies uniforms\n\t\t\t\tif ( variable.dependencies !== null ) {\n\n\t\t\t\t\tconst uniforms = variable.material.uniforms;\n\n\t\t\t\t\tfor ( let d = 0, dl = variable.dependencies.length; d < dl; d ++ ) {\n\n\t\t\t\t\t\tconst depVar = variable.dependencies[ d ];\n\n\t\t\t\t\t\tuniforms[ depVar.name ].value = depVar.renderTargets[ currentTextureIndex ].texture;\n\n\t\t\t\t\t}\n\n\t\t\t\t}\n\n\t\t\t\t// Performs the computation for this variable\n\t\t\t\tthis.doRenderTarget( variable.material, variable.renderTargets[ nextTextureIndex ] );\n\n\t\t\t}\n\n\t\t\tthis.currentTextureIndex = nextTextureIndex;\n\n\t\t};\n\n\t\tthis.getCurrentRenderTarget = function ( variable ) {\n\n\t\t\treturn variable.renderTargets[ this.currentTextureIndex ];\n\n\t\t};\n\n\t\tthis.getAlternateRenderTarget = function ( variable ) {\n\n\t\t\treturn variable.renderTargets[ this.currentTextureIndex === 0 ? 1 : 0 ];\n\n\t\t};\n\n\t\tthis.dispose = function () {\n\n\t\t\tquad.dispose();\n\n\t\t\tconst variables = this.variables;\n\n\t\t\tfor ( let i = 0; i < variables.length; i ++ ) {\n\n\t\t\t\tconst variable = variables[ i ];\n\n\t\t\t\tif ( variable.initialValueTexture ) variable.initialValueTexture.dispose();\n\n\t\t\t\tconst renderTargets = variable.renderTargets;\n\n\t\t\t\tfor ( let j = 0; j < renderTargets.length; j ++ ) {\n\n\t\t\t\t\tconst renderTarget = renderTargets[ j ];\n\t\t\t\t\trenderTarget.dispose();\n\n\t\t\t\t}\n\n\t\t\t}\n\n\t\t};\n\n\t\tfunction addResolutionDefine( materialShader ) {\n\n\t\t\tmaterialShader.defines.resolution = 'vec2( ' + sizeX.toFixed( 1 ) + ', ' + sizeY.toFixed( 1 ) + ' )';\n\n\t\t}\n\n\t\tthis.addResolutionDefine = addResolutionDefine;\n\n\n\t\t// The following functions can be used to compute things manually\n\n\t\tfunction createShaderMaterial( computeFragmentShader, uniforms ) {\n\n\t\t\tuniforms = uniforms || {};\n\n\t\t\tconst material = new ShaderMaterial( {\n\t\t\t\tname: 'GPUComputationShader',\n\t\t\t\tuniforms: uniforms,\n\t\t\t\tvertexShader: getPassThroughVertexShader(),\n\t\t\t\tfragmentShader: computeFragmentShader\n\t\t\t} );\n\n\t\t\taddResolutionDefine( material );\n\n\t\t\treturn material;\n\n\t\t}\n\n\t\tthis.createShaderMaterial = createShaderMaterial;\n\n\t\tthis.createRenderTarget = function ( sizeXTexture, sizeYTexture, wrapS, wrapT, minFilter, magFilter ) {\n\n\t\t\tsizeXTexture = sizeXTexture || sizeX;\n\t\t\tsizeYTexture = sizeYTexture || sizeY;\n\n\t\t\twrapS = wrapS || ClampToEdgeWrapping;\n\t\t\twrapT = wrapT || ClampToEdgeWrapping;\n\n\t\t\tminFilter = minFilter || NearestFilter;\n\t\t\tmagFilter = magFilter || NearestFilter;\n\n\t\t\tconst renderTarget = new WebGLRenderTarget( sizeXTexture, sizeYTexture, {\n\t\t\t\twrapS: wrapS,\n\t\t\t\twrapT: wrapT,\n\t\t\t\tminFilter: minFilter,\n\t\t\t\tmagFilter: magFilter,\n\t\t\t\tformat: RGBAFormat,\n\t\t\t\ttype: dataType,\n\t\t\t\tdepthBuffer: false\n\t\t\t} );\n\n\t\t\treturn renderTarget;\n\n\t\t};\n\n\t\tthis.createTexture = function () {\n\n\t\t\tconst data = new Float32Array( sizeX * sizeY * 4 );\n\t\t\tconst texture = new DataTexture( data, sizeX, sizeY, RGBAFormat, FloatType );\n\t\t\ttexture.needsUpdate = true;\n\t\t\treturn texture;\n\n\t\t};\n\n\t\tthis.renderTexture = function ( input, output ) {\n\n\t\t\t// Takes a texture, and render out in rendertarget\n\t\t\t// input = Texture\n\t\t\t// output = RenderTarget\n\n\t\t\tpassThruUniforms.passThruTexture.value = input;\n\n\t\t\tthis.doRenderTarget( passThruShader, output );\n\n\t\t\tpassThruUniforms.passThruTexture.value = null;\n\n\t\t};\n\n\t\tthis.doRenderTarget = function ( material, output ) {\n\n\t\t\tconst currentRenderTarget = renderer.getRenderTarget();\n\n\t\t\tconst currentXrEnabled = renderer.xr.enabled;\n\t\t\tconst currentShadowAutoUpdate = renderer.shadowMap.autoUpdate;\n\n\t\t\trenderer.xr.enabled = false; // Avoid camera modification\n\t\t\trenderer.shadowMap.autoUpdate = false; // Avoid re-computing shadows\n\t\t\tquad.material = material;\n\t\t\trenderer.setRenderTarget( output );\n\t\t\tquad.render( renderer );\n\t\t\tquad.material = passThruShader;\n\n\t\t\trenderer.xr.enabled = currentXrEnabled;\n\t\t\trenderer.shadowMap.autoUpdate = currentShadowAutoUpdate;\n\n\t\t\trenderer.setRenderTarget( currentRenderTarget );\n\n\t\t};\n\n\t\t// Shaders\n\n\t\tfunction getPassThroughVertexShader() {\n\n\t\t\treturn\t'void main()\t{\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tgl_Position = vec4( position, 1.0 );\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'}\\n';\n\n\t\t}\n\n\t\tfunction getPassThroughFragmentShader() {\n\n\t\t\treturn\t'uniform sampler2D passThruTexture;\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'void main() {\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tvec2 uv = gl_FragCoord.xy / resolution.xy;\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'\tgl_FragColor = texture2D( passThruTexture, uv );\\n' +\n\t\t\t\t\t'\\n' +\n\t\t\t\t\t'}\\n';\n\n\t\t}\n\n\t}\n\n}\n\nexport { GPUComputationRenderer };\n","export default `\nuniform vec4 uInteractionPosition;\nuniform float uTime;\nuniform float uTractionForce;\nuniform sampler2D uPositionAtlas;\nuniform float uOverallProgress; // (0.0 to 1.0)\nuniform int uNumMeshes;\nuniform float uSingleTextureSize;\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\n// Helper function to get position from atlas\nvec3 getAtlasPosition(vec2 uv, int meshIndex) {\n float atlasWidth = uSingleTextureSize * float(uNumMeshes);\n float atlasHeight = uSingleTextureSize; // Assuming height is single texture size\n\n // Calculate UV within the specific mesh's section of the atlas\n float segmentWidthRatio = uSingleTextureSize / atlasWidth;\n vec2 atlasUV = vec2(\n uv.x * segmentWidthRatio + segmentWidthRatio * float(meshIndex),\n uv.y // Assuming vertical layout doesn't change y\n );\n\n return texture2D(uPositionAtlas, atlasUV).xyz;\n}\n\nvoid main() {\n // GPGPU UV calculation\n vec2 uv = gl_FragCoord.xy / resolution.xy; // resolution is the size of the *output* texture (e.g., 256x256)\n\n vec3 currentPosition = texture2D(uCurrentPosition, uv).xyz;\n vec3 currentVelocity = texture2D(uCurrentVelocity, uv).xyz;\n\n // --- Calculate Target Position from Atlas ---\n vec3 targetPosition;\n if (uNumMeshes <= 1) {\n targetPosition = getAtlasPosition(uv, 0);\n } else {\n float totalSegments = float(uNumMeshes - 1);\n float progressPerSegment = 1.0 / totalSegments;\n float scaledProgress = uOverallProgress * totalSegments;\n\n int indexA = int(floor(scaledProgress));\n // Clamp indexB to avoid going out of bounds\n int indexB = min(indexA + 1, uNumMeshes - 1);\n\n // Ensure indexA is also within bounds (important if uOverallProgress is exactly 1.0)\n indexA = min(indexA, uNumMeshes - 1);\n\n\n float localProgress = fract(scaledProgress);\n\n // Handle edge case where progress is exactly 1.0\n if (uOverallProgress == 1.0) {\n indexA = uNumMeshes - 1;\n indexB = uNumMeshes - 1;\n localProgress = 1.0; // or 0.0 depending on how you want to handle it\n }\n\n\n vec3 positionA = getAtlasPosition(uv, indexA);\n vec3 positionB = getAtlasPosition(uv, indexB);\n\n targetPosition = mix(positionA, positionB, localProgress);\n }\n // --- End Target Position Calculation ---\n\n // Particle attraction to target position\n vec3 direction = normalize(targetPosition - currentPosition);\n float dist = length(targetPosition - currentPosition);\n\n vec3 finalPosition = currentPosition;\n\n // Apply attraction force (simplified mix)\n if (dist > 0.01) { // Only apply if significantly far\n finalPosition = mix(currentPosition, targetPosition, 0.1 * uTractionForce);\n }\n\n finalPosition += currentVelocity;\n gl_FragColor = vec4(finalPosition, 1.0);\n}\n`;\n","export default `\nuniform vec4 uInteractionPosition;\nuniform float uTime;\nuniform float uTractionForce;\nuniform float uMaxRepelDistance;\nuniform sampler2D uPositionAtlas;\nuniform float uOverallProgress;\nuniform int uNumMeshes;\nuniform float uSingleTextureSize;\n\nfloat rand(vec2 co) {\n return fract(sin(dot(co, vec2(12.9898, 78.233))) * 43758.5453);\n}\n\n// Helper function (same as in position shader)\nvec3 getAtlasPosition(vec2 uv, int meshIndex) {\n float atlasWidth = uSingleTextureSize * float(uNumMeshes);\n float atlasHeight = uSingleTextureSize;\n float segmentWidthRatio = uSingleTextureSize / atlasWidth;\n vec2 atlasUV = vec2(uv.x * segmentWidthRatio + segmentWidthRatio * float(meshIndex), uv.y);\n return texture2D(uPositionAtlas, atlasUV).xyz;\n}\n\nvoid main() {\n vec2 uv = gl_FragCoord.xy / resolution.xy;\n float offset = rand(uv);\n\n vec3 currentPosition = texture2D(uCurrentPosition, uv).xyz;\n vec3 currentVelocity = texture2D(uCurrentVelocity, uv).xyz;\n\n // --- Calculate Target Position from Atlas (same logic as position shader) ---\n vec3 targetPosition;\n if (uNumMeshes <= 1) {\n targetPosition = getAtlasPosition(uv, 0);\n } else {\n float totalSegments = float(uNumMeshes - 1);\n float progressPerSegment = 1.0 / totalSegments;\n float scaledProgress = uOverallProgress * totalSegments;\n int indexA = int(floor(scaledProgress));\n int indexB = min(indexA + 1, uNumMeshes - 1);\n indexA = min(indexA, uNumMeshes - 1);\n float localProgress = fract(scaledProgress);\n if (uOverallProgress == 1.0) {\n indexA = uNumMeshes - 1;\n indexB = uNumMeshes - 1;\n localProgress = 1.0;\n }\n vec3 positionA = getAtlasPosition(uv, indexA);\n vec3 positionB = getAtlasPosition(uv, indexB);\n targetPosition = mix(positionA, positionB, localProgress);\n }\n // --- End Target Position Calculation ---\n\n vec3 finalVelocity = currentVelocity * 0.9; // Dampening\n\n // Particle traction force towards target (influences velocity)\n vec3 direction = normalize(targetPosition - currentPosition);\n float dist = length(targetPosition - currentPosition);\n if (dist > 0.01) {\n // Add force proportional to distance and traction setting\n finalVelocity += direction * dist * 0.01 * uTractionForce; // Adjust multiplier as needed\n }\n\n // Mouse repel force\n if (uInteractionPosition.w > 0.0) { // Check if interaction is active (w component)\n float pointerDistance = distance(currentPosition, uInteractionPosition.xyz);\n if (pointerDistance < uMaxRepelDistance) {\n float mouseRepelModifier = smoothstep(uMaxRepelDistance, 0.0, pointerDistance); // Smoother falloff\n vec3 repelDirection = normalize(currentPosition - uInteractionPosition.xyz);\n // Apply force based on proximity and interaction strength (w)\n finalVelocity += repelDirection * mouseRepelModifier * uInteractionPosition.w * 0.01; // Adjust multiplier\n }\n }\n\n // Optional: Reset position if particle \"dies\" and respawns (lifespan logic)\n float lifespan = 20.0;\n float age = mod(uTime * 0.1 + lifespan * offset, lifespan); // Adjust time scale\n if (age < 0.05) { // Small window for reset\n finalVelocity = vec3(0.0); // Reset velocity on respawn\n // Note: Resetting position directly here might cause jumps.\n // It's often better handled in the position shader or by ensuring\n // strong attraction force when dist is large.\n }\n\n\n gl_FragColor = vec4(finalVelocity, 1.0);\n}\n`;\n","// --- START OF FILE simulationRenderer.ts ---\n\nimport { clamp, createBlankDataTexture, createSpherePoints } from '@/lib/utils';\nimport * as THREE from 'three';\nimport { GPUComputationRenderer, Variable } from 'three/examples/jsm/misc/GPUComputationRenderer.js';\n// import mixShader from './shaders/simulationMixShader'; // Assuming unused\nimport positionShader from './shaders/simulationPositionShader';\nimport velocityShader from './shaders/simulationVelocityShader';\n\nexport type PositionAtlasEntry = {\n dataTexture: THREE.DataTexture;\n numMeshes: number;\n singleTextureSize: number;\n textureSize: number; // Size of the GPGPU output texture\n};\n\n/**\n * SimulationRenderer is responsible for running the particle simulation using the GPU.\n */\nexport class SimulationRenderer {\n gpuComputationRenderer: GPUComputationRenderer;\n webGLRenderer: THREE.WebGLRenderer;\n\n // GPGPU Variables\n private readonly velocityVar: Variable;\n private readonly positionVar: Variable;\n\n // Input Data Textures (References)\n private readonly initialPositionDataTexture: THREE.DataTexture; // Used only for first init\n private readonly initialVelocityDataTexture: THREE.DataTexture; // Blank texture for init\n private positionAtlasTexture: THREE.Texture | null = null; // Holds the current mesh sequence atlas\n\n // Uniforms\n readonly interactionPosition: THREE.Vector4;\n\n // Cache last known output textures\n private lastKnownPositionDataTexture: THREE.Texture;\n private lastKnownVelocityDataTexture: THREE.Texture;\n\n /**\n * Creates a new SimulationRenderer instance.\n * @param size The size of the simulation textures (width/height).\n * @param webGLRenderer The WebGL renderer.\n * @param initialPosition The initial position data texture (optional, defaults to sphere).\n */\n constructor(size: number, webGLRenderer: THREE.WebGLRenderer, initialPosition?: THREE.DataTexture) {\n this.webGLRenderer = webGLRenderer;\n this.gpuComputationRenderer = new GPUComputationRenderer(size, size, this.webGLRenderer);\n\n // Set data type (important for precision)\n if (!webGLRenderer.capabilities.isWebGL2 && webGLRenderer.extensions.get('OES_texture_float')) {\n this.gpuComputationRenderer.setDataType(THREE.FloatType);\n } else if (!webGLRenderer.capabilities.isWebGL2) {\n this.gpuComputationRenderer.setDataType(THREE.HalfFloatType); // Fallback for WebGL1 without float support\n }\n\n // Create initial data textures that will be passed to GPGPU variables\n this.initialPositionDataTexture = initialPosition ?? createSpherePoints(size);\n this.initialVelocityDataTexture = createBlankDataTexture(size);\n this.interactionPosition = new THREE.Vector4(0, 0, 0, 0);\n\n // Initialize GPGPU variables with the initial data textures\n this.velocityVar = this.gpuComputationRenderer.addVariable('uCurrentVelocity', velocityShader, this.initialVelocityDataTexture);\n this.positionVar = this.gpuComputationRenderer.addVariable('uCurrentPosition', positionShader, this.initialPositionDataTexture);\n\n // --- Configure Uniforms ---\n // Velocity Shader Uniforms\n this.velocityVar.material.uniforms.uTime = { value: 0 };\n this.velocityVar.material.uniforms.uInteractionPosition = { value: this.interactionPosition };\n this.velocityVar.material.uniforms.uCurrentPosition = { value: null }; // Dependency\n this.velocityVar.material.uniforms.uTractionForce = { value: 0.1 };\n this.velocityVar.material.uniforms.uMaxRepelDistance = { value: 0.3 };\n this.velocityVar.material.uniforms.uPositionAtlas = { value: null }; // Will be set by setPositionAtlas or initially below\n this.velocityVar.material.uniforms.uOverallProgress = { value: 0.0 };\n this.velocityVar.material.uniforms.uNumMeshes = { value: 1 }; // Start with 1 (for initial texture)\n this.velocityVar.material.uniforms.uSingleTextureSize = { value: size }; // Current GPGPU size\n\n // Position Shader Uniforms\n this.positionVar.material.uniforms.uTime = { value: 0 };\n this.positionVar.material.uniforms.uTractionForce = { value: 0.1 };\n this.positionVar.material.uniforms.uInteractionPosition = { value: this.interactionPosition };\n this.positionVar.material.uniforms.uCurrentPosition = { value: null }; // Dependency\n this.positionVar.material.uniforms.uCurrentVelocity = { value: null }; // Dependency\n this.positionVar.material.uniforms.uPositionAtlas = { value: null }; // Will be set by setPositionAtlas or initially below\n this.positionVar.material.uniforms.uOverallProgress = { value: 0.0 };\n this.positionVar.material.uniforms.uNumMeshes = { value: 1 }; // Start with 1\n this.positionVar.material.uniforms.uSingleTextureSize = { value: size }; // Current GPGPU size\n\n // --- Set Dependencies ---\n this.gpuComputationRenderer.setVariableDependencies(this.positionVar, [this.positionVar, this.velocityVar]);\n this.gpuComputationRenderer.setVariableDependencies(this.velocityVar, [this.velocityVar, this.positionVar]);\n\n // --- Initialize GPGPU ---\n const initError = this.gpuComputationRenderer.init();\n if (initError !== null) {\n throw new Error('Failed to initialize SimulationRenderer: ' + initError);\n }\n\n // Use the initial texture as the 'atlas' before the real one is set\n this.positionVar.material.uniforms.uPositionAtlas.value = this.initialPositionDataTexture;\n // Ensure numMeshes and size reflect this initial single texture state\n this.positionVar.material.uniforms.uNumMeshes.value = 1;\n this.velocityVar.material.uniforms.uNumMeshes.value = 1;\n this.positionVar.material.uniforms.uSingleTextureSize.value = size;\n this.velocityVar.material.uniforms.uSingleTextureSize.value = size;\n // Set initial texture dependencies correctly\n this.positionVar.material.uniforms.uCurrentVelocity.value = this.gpuComputationRenderer.getCurrentRenderTarget(this.velocityVar).texture;\n this.velocityVar.material.uniforms.uCurrentPosition.value = this.gpuComputationRenderer.getCurrentRenderTarget(this.positionVar).texture;\n\n // Cache the initial output textures\n this.lastKnownVelocityDataTexture = this.gpuComputationRenderer.getCurrentRenderTarget(this.velocityVar).texture;\n this.lastKnownPositionDataTexture = this.gpuComputationRenderer.getCurrentRenderTarget(this.positionVar).texture;\n }\n\n /**\n * Sets the mesh sequence position atlas texture and related uniforms.\n * @param entry Information about the atlas texture.\n */\n setPositionAtlas(entry: PositionAtlasEntry) {\n // Validate texture dimensions (optional but good practice)\n const expectedAtlasWidth = entry.singleTextureSize * entry.numMeshes;\n if (entry.dataTexture.image.width !== expectedAtlasWidth || entry.dataTexture.image.height !== entry.singleTextureSize) {\n console.error(\n `SimulationRenderer: Atlas texture dimension mismatch! Expected ${expectedAtlasWidth}x${entry.singleTextureSize}, Got ${entry.dataTexture.image.width}x${entry.dataTexture.image.height}`,\n );\n }\n\n this.positionAtlasTexture = entry.dataTexture;\n const numMeshes = entry.numMeshes > 0 ? entry.numMeshes : 1; // Avoid 0\n\n // Update uniforms that depend on the atlas\n this.positionVar.material.uniforms.uPositionAtlas.value = this.positionAtlasTexture;\n this.positionVar.material.uniforms.uNumMeshes.value = numMeshes;\n this.positionVar.material.uniforms.uSingleTextureSize.value = entry.singleTextureSize; // The size of one mesh's data within the atlas\n\n this.velocityVar.material.uniforms.uPositionAtlas.value = this.positionAtlasTexture;\n this.velocityVar.material.uniforms.uNumMeshes.value = numMeshes;\n this.velocityVar.material.uniforms.uSingleTextureSize.value = entry.singleTextureSize;\n\n // IMPORTANT: Ensure texture dependencies are updated.\n // The GPGPU library handles the ping-pong swap. We just need to tell\n // the shader which texture (the *output* of the other variable from the *last* frame)\n // to read from *this* frame.\n this.positionVar.material.uniforms.uCurrentVelocity.value = this.gpuComputationRenderer.getCurrentRenderTarget(this.velocityVar).texture;\n this.velocityVar.material.uniforms.uCurrentPosition.value = this.gpuComputationRenderer.getCurrentRenderTarget(this.positionVar).texture;\n // Note: We don't reset progress here; that's handled by setOverallProgress.\n }\n\n /**\n * Sets the overall progress for blending between meshes in the atlas.\n * @param progress Value between 0.0 and 1.0.\n */\n setOverallProgress(progress: number) {\n const clampedProgress = clamp(progress, 0.0, 1.0);\n // Update progress in both shaders\n this.positionVar.material.uniforms.uOverallProgress.value = clampedProgress;\n this.velocityVar.material.uniforms.uOverallProgress.value = clampedProgress;\n }\n\n setMaxRepelDistance(distance: number) {\n this.velocityVar.material.uniforms.uMaxRepelDistance.value = distance;\n }\n\n setVelocityTractionForce(force: number) {\n this.velocityVar.material.uniforms.uTractionForce.value = force;\n }\n\n setPositionalTractionForce(force: number) {\n this.positionVar.material.uniforms.uTractionForce.value = force;\n }\n\n setInteractionPosition(position: THREE.Vector4Like) {\n this.interactionPosition.copy(position);\n // The uniform 'uInteractionPosition' directly references this object,\n // so changes are automatically picked up by the shader.\n }\n\n /**\n * Disposes the resources used by the simulation renderer.\n */\n dispose() {\n // Dispose GPGPU resources FIRST\n this.gpuComputationRenderer.dispose(); // Should dispose variables, materials, programs, render targets\n\n // Dispose textures we created or hold references to\n this.initialPositionDataTexture?.dispose();\n this.initialVelocityDataTexture?.dispose();\n // Dispose the atlas texture if it exists and is managed here\n // If the atlas is managed externally (e.g., DataTextureService), it shouldn't be disposed here.\n // Assuming DataTextureService manages its lifecycle.\n // this.positionAtlasTexture?.dispose(); -> Let DataTextureService handle this.\n this.positionAtlasTexture = null;\n }\n\n /**\n * Computes the next step of the simulation.\n * @param deltaTime The time elapsed since the last frame, in seconds.\n */\n compute(deltaTime: number) {\n // Update time uniforms if they are used for time-dependent effects (like lifespan)\n this.velocityVar.material.uniforms.uTime.value += deltaTime; // Accumulate time\n this.positionVar.material.uniforms.uTime.value += deltaTime; // Accumulate time\n\n // Update texture uniforms (dependencies) for the *next* computation step.\n // This ensures the shaders read the output from the previous step.\n this.positionVar.material.uniforms.uCurrentVelocity.value = this.gpuComputationRenderer.getCurrentRenderTarget(this.velocityVar).texture;\n this.velocityVar.material.uniforms.uCurrentPosition.value = this.gpuComputationRenderer.getCurrentRenderTarget(this.positionVar).texture;\n\n // Run the GPGPU computation\n this.gpuComputationRenderer.compute();\n\n // Update the references to the *latest* output textures *after* computation\n this.lastKnownVelocityDataTexture = this.gpuComputationRenderer.getCurrentRenderTarget(this.velocityVar).texture;\n this.lastKnownPositionDataTexture = this.gpuComputationRenderer.getCurrentRenderTarget(this.positionVar).texture;\n }\n\n /** Gets the current velocity texture (output from the last compute step). */\n getVelocityTexture(): THREE.Texture {\n return this.lastKnownVelocityDataTexture;\n }\n\n /** Gets the current position texture (output from the last compute step). */\n getPositionTexture(): THREE.Texture {\n return this.lastKnownPositionDataTexture;\n }\n}\n\n// --- END OF FILE simulationRenderer.ts ---\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { ServiceState } from '@/lib/types';\nimport * as THREE from 'three';\nimport { PositionAtlasEntry, SimulationRenderer } from './simulationRenderer';\n\nexport class SimulationRendererService {\n private state!: ServiceState;\n private textureSize: number;\n private overallProgress: number; // ADDED: Store overall progress\n private velocityTractionForce: number;\n private positionalTractionForce: number;\n\n private simulationRenderer;\n private webGLRenderer;\n private eventEmitter;\n\n // Store atlas info\n private currentAtlasEntry: PositionAtlasEntry | null = null; // ADDED\n\n private lastKnownVelocityDataTexture: THREE.Texture;\n private lastKnownPositionDataTexture: THREE.Texture;\n\n constructor(eventEmitter: DefaultEventEmitter, size: number, webGLRenderer: THREE.WebGLRenderer) {\n this.eventEmitter = eventEmitter;\n this.webGLRenderer = webGLRenderer;\n this.textureSize = size;\n this.overallProgress = 0; // ADDED: Initialize overall progress\n this.velocityTractionForce = 0.1;\n this.positionalTractionForce = 0.1;\n\n this.updateServiceState('initializing');\n\n this.simulationRenderer = new SimulationRenderer(this.textureSize, this.webGLRenderer);\n this.lastKnownVelocityDataTexture = this.simulationRenderer.getVelocityTexture();\n this.lastKnownPositionDataTexture = this.simulationRenderer.getPositionTexture();\n\n this.updateServiceState('ready');\n }\n\n /**\n * Sets the position data texture atlas for the simulation.\n * @param entry An object containing the atlas texture and related parameters.\n */\n setPositionAtlas(entry: PositionAtlasEntry) {\n // Validate texture size consistency if needed (atlas width vs textureSize * numMeshes)\n const expectedWidth = entry.singleTextureSize * entry.numMeshes;\n if (entry.dataTexture.image.width !== expectedWidth) {\n this.eventEmitter.emit('invalidRequest', { message: `Atlas texture width mismatch.` });\n return;\n }\n this.currentAtlasEntry = entry; // Store the current atlas info\n this.simulationRenderer.setPositionAtlas(entry);\n }\n\n /**\n * Sets the overall progress for the mesh sequence transition.\n * @param progress The progress value (0.0 to 1.0).\n */\n setOverallProgress(progress: number) {\n this.overallProgress = progress; // Store progress\n this.simulationRenderer.setOverallProgress(this.overallProgress);\n }\n\n setTextureSize(size: number) {\n this.updateServiceState('initializing');\n this.simulationRenderer.dispose();\n this.textureSize = size;\n this.simulationRenderer = new SimulationRenderer(size, this.webGLRenderer);\n this.updateServiceState('ready');\n }\n\n setVelocityTractionForce(force: number) {\n this.velocityTractionForce = force;\n this.simulationRenderer.setVelocityTractionForce(this.velocityTractionForce);\n }\n\n setPositionalTractionForce(force: number) {\n this.positionalTractionForce = force;\n this.simulationRenderer.setPositionalTractionForce(this.positionalTractionForce);\n }\n\n compute(elapsedTime: number) {\n if (this.state !== 'ready') return; // Don't compute if not ready\n this.simulationRenderer.compute(elapsedTime);\n // Update last known textures after computation\n this.lastKnownVelocityDataTexture = this.simulationRenderer.getVelocityTexture();\n this.lastKnownPositionDataTexture = this.simulationRenderer.getPositionTexture();\n }\n\n getVelocityTexture(): THREE.Texture {\n // Return the latest texture obtained during compute()\n return this.lastKnownVelocityDataTexture;\n }\n\n getPositionTexture(): THREE.Texture {\n // Return the latest texture obtained during compute()\n return this.lastKnownPositionDataTexture;\n }\n\n dispose() {\n this.updateServiceState('disposed');\n this.simulationRenderer.dispose();\n // Dispose last known textures only if they are managed solely here (unlikely)\n // this.lastKnownVelocityDataTexture.dispose();\n // this.lastKnownPositionDataTexture.dispose();\n this.currentAtlasEntry = null; // Clear reference\n }\n\n private updateServiceState(serviceState: ServiceState) {\n this.state = serviceState;\n this.eventEmitter.emit('serviceStateUpdated', { type: 'simulation', state: serviceState });\n }\n\n setInteractionPosition(position: THREE.Vector4Like) {\n // Pass through to the renderer\n this.simulationRenderer.setInteractionPosition(position);\n }\n\n setMaxRepelDistance(distance: number) {\n // Pass through to the renderer\n this.simulationRenderer.setMaxRepelDistance(distance);\n }\n}\n","import { DefaultEventEmitter } from '@/lib/events';\nimport { TransitionDetail, TransitionOptions, TransitionType } from '@/lib/types';\nimport { clamp } from '@/lib/utils';\n\ntype ExecStatus = 'idle' | 'running';\n\ntype TransitionQueueItem = { cancelled: boolean; startTime?: number } & TransitionDetail & TransitionOptions;\ntype OngoingTransition = { startTime: number } & TransitionQueueItem;\n\nclass ExecutionStatusMap {\n private readonly execStatus = new Map<TransitionType, ExecStatus>();\n\n get(type: TransitionType): ExecStatus {\n const status = this.execStatus.get(type);\n if (!status) {\n this.execStatus.set(type, 'idle');\n return 'idle';\n }\n return status;\n }\n\n set(type: TransitionType, status: ExecStatus) {\n this.execStatus.set(type, status);\n }\n}\n\nexport class TransitionService {\n private readonly eventEmitter;\n private readonly transitions: Map<TransitionType, Array<TransitionQueueItem>> = new Map();\n private readonly execStatus: ExecutionStatusMap;\n private readonly ongoingTransitions: Map<TransitionType, OngoingTransition> = new Map();\n\n constructor(eventEmitter: DefaultEventEmitter) {\n this.eventEmitter = eventEmitter;\n this.execStatus = new ExecutionStatusMap();\n this.eventEmitter.on('transitionCancelled', this.handleTransitionCancelledEvent.bind(this));\n }\n\n /**\n * Enqueues a transition.\n * @param type - The type of transition.\n * @param transition - The transition details.\n * @param options - Optional transition options.\n */\n enqueue<T extends TransitionType>(type: T, transition: TransitionDetail, options: TransitionOptions = {}) {\n const transitionQueueItem: TransitionQueueItem = {\n ...transition,\n ...options,\n cancelled: false,\n duration: transition.duration * 0.001, // convert to seconds\n };\n this.getQueue(type).push(transitionQueueItem);\n }\n\n compute(elapsedTime: number) {\n this.transitions.forEach((queue, type) => {\n if (queue.length && !this.ongoingTransitions.has(type)) {\n const transition = queue.shift();\n if (transition) {\n this.ongoingTransitions.set(type, { ...transition, startTime: elapsedTime });\n transition.onTransitionBegin?.();\n }\n }\n });\n\n this.ongoingTransitions.forEach((transition, type) => {\n if (transition.cancelled) {\n transition.onTransitionCancelled?.();\n this.ongoingTransitions.delete(type);\n return;\n }\n\n const { startTime, duration, easing } = transition;\n\n const timeDistance = elapsedTime - startTime;\n const progress = clamp(easing(Math.min(1.0, timeDistance / duration)), 0.0, 1.0);\n\n this.emitTransitionProgress(type, progress);\n transition.onTransitionProgress?.(progress);\n\n if (progress >= 1) {\n this.emitTransitionFinished(type);\n transition.onTransitionFinished?.();\n this.ongoingTransitions.delete(type);\n }\n });\n }\n\n private getQueue(type: TransitionType): Array<TransitionQueueItem> {\n const queue = this.transitions.get(type);\n if (!queue) {\n this.transitions.set(type, []);\n return this.transitions.get(type) ?? [];\n }\n return queue;\n }\n\n private handleTransitionCancelledEvent({ type }: { type: TransitionType }) {\n const transitions = this.getQueue(type);\n while (transitions.length) transitions.pop();\n\n const ongoingTransition = this.ongoingTransitions.get(type);\n if (ongoingTransition) {\n ongoingTransition.cancelled = true;\n ongoingTransition.onTransitionCancelled?.();\n }\n }\n\n private emitTransitionProgress(type: TransitionType, progress: number) {\n this.eventEmitter.emit('transitionProgressed', { type, progress });\n }\n\n private emitTransitionFinished(type: TransitionType) {\n this.eventEmitter.emit('transitionFinished', { type });\n }\n}\n","import { linear } from '@/lib/easing';\nimport { DefaultEventEmitter } from '@/lib/events/defaultEventEmitter';\nimport { AssetService } from '@/lib/services/assets/assetService';\nimport { DataTextureService } from '@/lib/services/dataTexture/dataTextureService';\nimport { InstancedMeshManager } from '@/lib/services/instancedmesh/instancedMeshManager';\nimport { IntersectionService } from '@/lib/services/intersection/intersectionService';\nimport { SimulationRendererService } from '@/lib/services/simulation/simulationRendererService';\nimport { TransitionService } from '@/lib/services/transition/transitionService';\nimport { Callback, EasingFunction, ServiceState, ServiceType, TransitionCallback, TransitionDetail, TransitionOptions } from '@/lib/types';\nimport { EngineState } from '@/lib/types/state';\nimport { clamp } from '@/lib/utils';\nimport * as THREE from 'three';\n\n/**\n * Parameters for creating a ParticlesEngine instance.\n */\ntype ParticlesEngineParameters = {\n textureSize: number;\n scene: THREE.Scene;\n renderer: THREE.WebGLRenderer;\n camera?: THREE.Camera;\n useIntersection?: boolean;\n};\n\ntype ServiceStates = Record<ServiceType, ServiceState>;\n\n/**\n * The main class for the particle engine.\n */\nexport class ParticlesEngine {\n private simulationRendererService: SimulationRendererService;\n private renderer: THREE.WebGLRenderer;\n\n private scene: THREE.Scene;\n private serviceStates: ServiceStates;\n\n // assets\n private assetService: AssetService;\n private dataTextureManager: DataTextureService;\n private instancedMeshManager: InstancedMeshManager;\n\n private transitionService: TransitionService;\n private engineState: EngineState;\n\n private intersectionService: IntersectionService;\n\n private meshSequenceAtlasTexture: THREE.DataTexture | null = null; // ADDED: To store the generated atlas\n\n public eventEmitter: DefaultEventEmitter;\n\n /**\n * Creates a new ParticlesEngine instance.\n * @param params The parameters for creating the instance.\n */\n constructor(params: ParticlesEngineParameters) {\n const { scene, renderer, camera, textureSize, useIntersection = true } = params;\n\n this.eventEmitter = new DefaultEventEmitter();\n this.serviceStates = this.getInitialServiceStates();\n this.eventEmitter.on('serviceStateUpdated', this.handleServiceStateUpdated.bind(this));\n\n this.scene = scene;\n this.renderer = renderer;\n this.engineState = this.initialEngineState(params);\n\n this.assetService = new AssetService(this.eventEmitter);\n this.transitionService = new TransitionService(this.eventEmitter);\n this.dataTextureManager = new DataTextureService(this.eventEmitter, textureSize);\n this.simulationRendererService = new SimulationRendererService(this.eventEmitter, textureSize, this.renderer);\n this.instancedMeshManager = new InstancedMeshManager(textureSize);\n this.instancedMeshManager.useMatcapMaterial();\n this.scene.add(this.instancedMeshManager.getMesh());\n\n this.intersectionService = new IntersectionService(this.eventEmitter, camera);\n if (!useIntersection) this.intersectionService.setActive(false);\n\n this.eventEmitter.on('interactionPositionUpdated', this.handleInteractionPositionUpdated.bind(this));\n }\n\n /**\n * Renders the scene.\n * @param elapsedTime The elapsed time since the last frame.\n */\n\n render(elapsedTime: number) {\n const dt = elapsedTime / 1000.0; // Convert to seconds\n this.transitionService.compute(dt);\n this.intersectionService.calculate(this.instancedMeshManager.getMesh());\n this.simulationRendererService.compute(dt); // Use seconds\n this.instancedMeshManager.update(dt); // Use seconds\n this.instancedMeshManager.updateVelocityTexture(this.simulationRendererService.getVelocityTexture());\n this.instancedMeshManager.updatePositionTexture(this.simulationRendererService.getPositionTexture());\n }\n\n setOriginMatcap(matcapID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.originMatcapID = matcapID;\n this.instancedMeshManager.setOriginMatcap(this.assetService.getMatcap(matcapID));\n }\n\n setDestinationMatcap(matcapID: string, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.destinationMatcapID = matcapID;\n this.instancedMeshManager.setDestinationMatcap(this.assetService.getMatcap(matcapID));\n }\n\n setOriginColor(color: THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.instancedMeshManager.setOriginColor(color);\n }\n\n setDestinationColor(color: THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.instancedMeshManager.setDestinationColor(color);\n }\n\n setOriginTexture(id: string | THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n\n if (typeof id === 'string' && this.assetService.hasMatcap(id)) {\n this.setOriginMatcap(id);\n } else {\n this.setOriginColor(id);\n }\n }\n\n setDestinationTexture(id: string | THREE.ColorRepresentation, override: boolean = false) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n if (typeof id === 'string' && this.assetService.hasMatcap(id)) {\n this.setDestinationMatcap(id);\n } else {\n this.setDestinationColor(id);\n }\n }\n\n setMatcapProgress(progress: number, override: boolean = false) {\n const clampedProgress = clamp(progress, 0.0, 1.0);\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n this.engineState.matcapTransitionProgress = clampedProgress;\n this.instancedMeshManager.setProgress(clampedProgress);\n }\n\n // --- Update setTextureSize ---\n async setTextureSize(size: number) {\n if (this.engineState.textureSize === size) {\n return;\n }\n this.engineState.textureSize = size;\n\n // Resize core services\n this.dataTextureManager.setTextureSize(size); // This will clear its cache\n this.simulationRendererService.setTextureSize(size); // Recreates GPGPU\n this.instancedMeshManager.resize(size);\n\n if (this.engineState.meshSequence.length > 0) {\n await this.setMeshSequence(this.engineState.meshSequence);\n }\n\n // Re-apply mesh sequence if it exists. This regenerates the atlas with the new size\n // and updates simulation/intersection services via setMeshSequence internal calls.\n if (this.engineState.meshSequence.length > 0) {\n await this.setMeshSequence(this.engineState.meshSequence);\n }\n\n // Update other simulation parameters (these might need re-application after GPGPU recreation)\n this.simulationRendererService.setVelocityTractionForce(this.engineState.velocityTractionForce);\n this.simulationRendererService.setPositionalTractionForce(this.engineState.positionalTractionForce);\n this.simulationRendererService.setMaxRepelDistance(this.engineState.maxRepelDistance);\n // Ensure progress is reapplied (setMeshSequence resets it to 0, restore if needed, though usually 0 is correct after resize)\n this.simulationRendererService.setOverallProgress(this.engineState.overallProgress);\n this.intersectionService.setOverallProgress(this.engineState.overallProgress); // Also update intersection\n\n // Update InstancedMeshManager appearance parameters\n this.instancedMeshManager.setOriginMatcap(this.assetService.getMatcap(this.engineState.originMatcapID));\n this.instancedMeshManager.setDestinationMatcap(this.assetService.getMatcap(this.engineState.destinationMatcapID));\n this.instancedMeshManager.setProgress(this.engineState.matcapTransitionProgress);\n this.instancedMeshManager.setGeometrySize(this.engineState.instanceGeometryScale);\n }\n\n registerMesh(id: string, mesh: THREE.Mesh) {\n this.assetService.register(id, mesh);\n }\n\n registerMatcap(id: string, matcap: THREE.Texture) {\n this.assetService.register(id, matcap);\n }\n\n async fetchAndRegisterMesh(id: string, url: string) {\n return await this.assetService.loadMeshAsync(id, url);\n }\n\n async fetchAndRegisterMatcap(id: string, url: string) {\n return await this.assetService.loadTextureAsync(id, url);\n }\n\n useIntersect(use: boolean) {\n this.intersectionService.setActive(use);\n this.engineState.useIntersect = use;\n\n // When disabling, ensure the simulation also gets zero interaction\n if (!use) {\n this.engineState.pointerPosition = { x: -99999999, y: -99999999 }; // Keep this for internal state if needed\n // Explicitly send zero interaction to simulation\n this.simulationRendererService.setInteractionPosition({ x: 0, y: 0, z: 0, w: 0 });\n }\n }\n\n setPointerPosition(position: THREE.Vector2Like) {\n if (!this.engineState.useIntersect) return;\n this.engineState.pointerPosition = position;\n this.intersectionService.setPointerPosition(position);\n }\n\n setGeometrySize(geometrySize: THREE.Vector3Like) {\n this.engineState.instanceGeometryScale = geometrySize;\n this.instancedMeshManager.setGeometrySize(geometrySize);\n }\n\n setVelocityTractionForce(force: number) {\n this.engineState.velocityTractionForce = force;\n this.simulationRendererService.setVelocityTractionForce(force);\n }\n\n setPositionalTractionForce(force: number) {\n this.engineState.positionalTractionForce = force;\n this.simulationRendererService.setPositionalTractionForce(force);\n }\n\n setMaxRepelDistance(distance: number) {\n this.engineState.maxRepelDistance = distance;\n this.simulationRendererService.setMaxRepelDistance(distance);\n }\n\n /**\n * Sets the sequence of meshes for particle transitions.\n * This will generate a texture atlas containing position data for all meshes.\n * @param meshIDs An array of registered mesh IDs in the desired sequence order.\n */\n async setMeshSequence(meshIDs: string[]) {\n if (!meshIDs || meshIDs.length < 1) {\n this.eventEmitter.emit('invalidRequest', { message: 'Mesh sequence must contain at least one mesh ID.' });\n this.engineState.meshSequence = []; // Clear sequence state\n this.intersectionService.setMeshSequence([]); // Clear intersection sequence\n return;\n }\n this.engineState.meshSequence = meshIDs;\n this.engineState.overallProgress = 0; // Reset progress when sequence changes\n\n // Get valid mesh objects\n const meshes = meshIDs.map((id) => this.assetService.getMesh(id)).filter((mesh) => mesh !== null) as THREE.Mesh[];\n\n // Handle missing meshes\n if (meshes.length !== meshIDs.length) {\n const missing = meshIDs.filter((id) => !this.assetService.getMesh(id));\n console.warn(`Could not find meshes for IDs: ${missing.join(', ')}. Proceeding with ${meshes.length} found meshes.`);\n this.eventEmitter.emit('invalidRequest', { message: `Could not find meshes for IDs: ${missing.join(', ')}` });\n if (meshes.length < 1) {\n this.engineState.meshSequence = []; // Clear sequence state if none found\n this.intersectionService.setMeshSequence([]);\n return; // Stop if no valid meshes\n }\n // Update sequence state to only include valid meshes found\n this.engineState.meshSequence = meshes.map((m) => m.name);\n }\n\n try {\n // Generate the atlas texture\n this.meshSequenceAtlasTexture = await this.dataTextureManager.createSequenceDataTextureAtlas(meshes, this.engineState.textureSize);\n\n // Update the simulation renderer\n this.simulationRendererService.setPositionAtlas({\n dataTexture: this.meshSequenceAtlasTexture,\n textureSize: this.engineState.textureSize, // Pass the size of the *output* GPGPU texture\n numMeshes: this.engineState.meshSequence.length, // Use the potentially updated count\n singleTextureSize: this.engineState.textureSize, // Size of one mesh's data within atlas\n });\n // Set initial progress in simulation (should be 0 after sequence change)\n this.simulationRendererService.setOverallProgress(this.engineState.overallProgress);\n\n // Update IntersectionService with the valid meshes\n this.intersectionService.setMeshSequence(meshes);\n this.intersectionService.setOverallProgress(this.engineState.overallProgress); // Set initial progress\n } catch (error) {\n console.error('Failed during mesh sequence setup:', error);\n this.meshSequenceAtlasTexture = null;\n // Consider resetting related states or services\n }\n }\n\n /**\n * Sets the overall progress through the mesh sequence.\n * @param progress A value between 0.0 (first mesh) and 1.0 (last mesh).\n * @param override If true, cancels any ongoing mesh sequence transition before setting the value. Defaults to true.\n */\n setOverallProgress(progress: number, override: boolean = true) {\n if (override) {\n this.eventEmitter.emit('transitionCancelled', { type: 'mesh-sequence' });\n }\n\n const clampedProgress = clamp(progress, 0.0, 1.0);\n this.engineState.overallProgress = clampedProgress;\n this.simulationRendererService.setOverallProgress(clampedProgress);\n this.intersectionService.setOverallProgress(clampedProgress);\n }\n\n // --- Transition scheduling methods remain the same ---\n scheduleMatcapTransition(\n originMatcapID: string,\n destinationMatcapID: string,\n easing: EasingFunction = linear,\n duration: number = 1000,\n override: boolean = false,\n options: TransitionOptions = {},\n ) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n const handleProgressUpdate = (transitionProgress: number) => {\n this.setMatcapProgress(transitionProgress, false); // Pass override=false here\n options.onTransitionProgress?.(transitionProgress);\n };\n this.transitionService.enqueue(\n 'matcap',\n { easing, duration },\n {\n ...options,\n onTransitionProgress: handleProgressUpdate,\n onTransitionBegin: () => {\n this.setOriginMatcap(originMatcapID, false);\n this.setDestinationMatcap(destinationMatcapID, false);\n this.setMatcapProgress(0, false);\n options.onTransitionBegin?.();\n },\n onTransitionFinished: () => {\n this.setMatcapProgress(1, false);\n options.onTransitionFinished?.();\n },\n onTransitionCancelled: options.onTransitionCancelled,\n },\n );\n }\n\n scheduleTextureTransition(\n origin: string | THREE.ColorRepresentation,\n destination: string | THREE.ColorRepresentation,\n options: {\n easing?: EasingFunction;\n duration?: number;\n override?: boolean;\n onTransitionBegin?: Callback;\n onTransitionProgress?: TransitionCallback;\n onTransitionFinished?: Callback;\n onTransitionCancelled?: Callback;\n } = {}, // Default to empty object\n ) {\n const easing = options?.easing ?? linear;\n const duration = options?.duration ?? 1000;\n const userCallbacks = {\n // Extract user callbacks\n onTransitionBegin: options?.onTransitionBegin,\n onTransitionProgress: options?.onTransitionProgress,\n onTransitionFinished: options?.onTransitionFinished,\n onTransitionCancelled: options?.onTransitionCancelled,\n };\n\n if (options?.override) this.eventEmitter.emit('transitionCancelled', { type: 'matcap' });\n\n const handleProgressUpdate = (transitionProgress: number) => {\n this.setMatcapProgress(transitionProgress, false); // Pass override=false\n userCallbacks.onTransitionProgress?.(transitionProgress);\n };\n\n this.transitionService.enqueue(\n 'matcap', // Still uses matcap type internally\n { easing, duration },\n {\n ...userCallbacks, // Pass user callbacks\n onTransitionProgress: handleProgressUpdate,\n onTransitionBegin: () => {\n this.setOriginTexture(origin);\n this.setDestinationTexture(destination);\n this.setMatcapProgress(0);\n userCallbacks.onTransitionBegin?.();\n },\n onTransitionFinished: () => {\n this.setMatcapProgress(1);\n // Optional: Set origin to destination\n // this.setOriginTexture(destination);\n userCallbacks.onTransitionFinished?.();\n },\n onTransitionCancelled: () => {\n userCallbacks.onTransitionCancelled?.();\n },\n },\n );\n }\n\n /**\n * Schedules a smooth transition for the overall mesh sequence progress.\n * @param targetProgress The final progress value (0.0 to 1.0) to transition to.\n * @param duration Duration of the transition in milliseconds.\n * @param easing Easing function to use.\n * @param options Transition options (onBegin, onProgress, onFinished, onCancelled).\n * @param override If true, cancels any ongoing mesh sequence transitions.\n */\n scheduleMeshSequenceTransition(\n targetProgress: number,\n duration: number = 1000,\n easing: EasingFunction = linear,\n options: TransitionOptions = {},\n override: boolean = true, // Default to override for simplicity\n ) {\n if (override) this.eventEmitter.emit('transitionCancelled', { type: 'mesh-sequence' });\n const startProgress = this.engineState.overallProgress;\n const progressDiff = targetProgress - startProgress;\n const handleProgressUpdate = (transitionProgress: number) => {\n const currentOverallProgress = startProgress + progressDiff * transitionProgress;\n // Call setOverallProgress with override=false as this is part of a transition\n this.setOverallProgress(currentOverallProgress, false);\n options.onTransitionProgress?.(currentOverallProgress);\n };\n const transitionDetail: TransitionDetail = { duration, easing };\n const transitionOptions: TransitionOptions = {\n ...options,\n onTransitionProgress: handleProgressUpdate,\n onTransitionBegin: options.onTransitionBegin,\n onTransitionFinished: () => {\n // Ensure final value is set precisely, again with override=false\n this.setOverallProgress(targetProgress, false);\n options.onTransitionFinished?.();\n },\n onTransitionCancelled: options.onTransitionCancelled,\n };\n this.transitionService.enqueue('mesh-sequence', transitionDetail, transitionOptions);\n }\n\n handleServiceStateUpdated({ type, state }: { type: ServiceType; state: ServiceState }) {\n this.serviceStates[type] = state;\n }\n\n getObject(): THREE.Mesh {\n return this.instancedMeshManager.getMesh();\n }\n\n getMeshIDs() {\n return this.assetService.getMeshIDs();\n }\n\n getMatcapIDs() {\n return this.assetService.getTextureIDs();\n }\n\n getMeshes() {\n return this.assetService.getMeshes();\n }\n\n getTextures() {\n return this.assetService.getTextures();\n }\n\n public getTextureSize(): number {\n return this.engineState.textureSize;\n }\n\n public getUseIntersect(): boolean {\n return this.engineState.useIntersect;\n }\n\n public getEngineStateSnapshot(): Readonly<EngineState> {\n return { ...this.engineState }; // Return a copy or make EngineState properties readonly\n }\n\n /**\n * Disposes the resources used by the engine.\n */\n dispose() {\n // Check if scene exists before removing\n if (this.scene && this.instancedMeshManager) {\n this.scene.remove(this.instancedMeshManager.getMesh());\n }\n // Dispose services safely\n this.simulationRendererService?.dispose();\n this.instancedMeshManager?.dispose();\n this.intersectionService?.dispose();\n this.assetService?.dispose();\n this.dataTextureManager?.dispose();\n this.eventEmitter?.dispose(); // Dispose event emitter too\n }\n\n private initialEngineState(params: ParticlesEngineParameters): EngineState {\n return {\n textureSize: params.textureSize,\n meshSequence: [], // ADDED\n overallProgress: 0, // ADDED\n originMatcapID: '',\n destinationMatcapID: '',\n matcapTransitionProgress: 0,\n velocityTractionForce: 0.1,\n positionalTractionForce: 0.1,\n maxRepelDistance: 0.3,\n pointerPosition: { x: 0, y: 0 },\n instanceGeometryScale: { x: 1, y: 1, z: 1 },\n useIntersect: params.useIntersection ?? true,\n };\n }\n\n private getInitialServiceStates(): ServiceStates {\n return {\n 'data-texture': 'created',\n 'instanced-mesh': 'created',\n matcap: 'created',\n simulation: 'created',\n asset: 'created',\n };\n }\n\n private handleInteractionPositionUpdated({ position }: { position: THREE.Vector4Like }) {\n this.simulationRendererService.setInteractionPosition(position);\n }\n}\n"],"names":["n"],"mappings":"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","x_google_ignoreList":[1,5,11,12]}