ecspresso 0.16.2 → 0.16.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var $j=((j)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(j,{get:(D,$)=>(typeof require<"u"?require:D)[$]}):j)(function(j){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+j+'" is not supported')});class H{parentMap=new Map;childrenMap=new Map;_bfsQueue=[];setParent(j,D){if(j===D)throw Error(`Cannot set entity ${j} as its own parent`);if(this.wouldCreateCycle(j,D))throw Error("Cannot set parent: would create circular reference");let $=this.parentMap.get(j);if($!==void 0){let J=this.childrenMap.get($);if(J){let X=J.indexOf(j);if(X!==-1)J.splice(X,1)}}this.parentMap.set(j,D);let G=this.childrenMap.get(D);if(G)G.push(j);else this.childrenMap.set(D,[j]);return this}removeParent(j){let D=this.parentMap.get(j);if(D===void 0)return!1;let $=this.childrenMap.get(D);if($){let G=$.indexOf(j);if(G!==-1)$.splice(G,1)}return this.parentMap.delete(j),!0}getParent(j){return this.parentMap.get(j)??null}getChildren(j){let D=this.childrenMap.get(j);return D?[...D]:[]}getChildAt(j,D){if(D<0)return null;let $=this.childrenMap.get(j);if(!$||D>=$.length)return null;return $[D]??null}getChildIndex(j,D){let $=this.childrenMap.get(j);if(!$)return-1;return $.indexOf(D)}removeEntity(j){let D=this.parentMap.get(j)??null;if(D!==null){let J=this.childrenMap.get(D);if(J){let X=J.indexOf(j);if(X!==-1)J.splice(X,1)}}this.parentMap.delete(j);let $=this.childrenMap.get(j)??[],G=[...$];for(let J of $)this.parentMap.delete(J);return this.childrenMap.delete(j),{oldParent:D,orphanedChildren:G}}getAncestors(j){let D=[],$=this.parentMap.get(j);while($!==void 0)D.push($),$=this.parentMap.get($);return D}getDescendants(j){let D=[],$=this.childrenMap.get(j);if(!$)return D;let G=$.slice().reverse();while(G.length>0){let J=G.pop();D.push(J);let X=this.childrenMap.get(J);if(X)for(let Z=X.length-1;Z>=0;Z--)G.push(X[Z])}return D}getRoot(j){let D=j,$=this.parentMap.get(D);while($!==void 0)D=$,$=this.parentMap.get(D);return D}getSiblings(j){let D=this.parentMap.get(j);if(D===void 0)return[];let $=this.childrenMap.get(D);if(!$)return[];return $.filter((G)=>G!==j)}isDescendantOf(j,D){if(j===D)return!1;let $=this.parentMap.get(j);while($!==void 0){if($===D)return!0;$=this.parentMap.get($)}return!1}isAncestorOf(j,D){return this.isDescendantOf(D,j)}get hasHierarchy(){return this.childrenMap.size>0}getRootEntities(){let j=[];for(let D of this.childrenMap.keys())if(!this.parentMap.has(D))j.push(D);return j}wouldCreateCycle(j,D){let $=D;while($!==void 0){if($===j)return!0;$=this.parentMap.get($)}return!1}forEachInHierarchy(j,D){let $=D?.roots??this.getRootEntities(),G=this._bfsQueue;G.length=0;for(let J of $)G.push(J,-1,0);for(let J=0;J<G.length;J+=3){let X=G[J],Z=G[J+1],W=G[J+2];j(X,Z===-1?null:Z,W);let A=this.childrenMap.get(X);if(A){let L=W+1;for(let O of A)G.push(O,X,L)}}}*hierarchyIterator(j){let D=j?.roots??this.getRootEntities(),$=[];for(let G of D)$.push({entityId:G,parentId:null,depth:0});for(let G of $){yield G;let J=this.childrenMap.get(G.entityId);if(J)for(let X of J)$.push({entityId:X,parentId:G.entityId,depth:G.depth+1})}}}function R(j,D,$,G,J){let X=j.components;for(let Z of D)if(!(Z in X))return!1;if($){for(let Z of $)if(Z in X)return!1}if(G&&G.length>0){let Z=J.getParent(j.id);if(Z===null)return!1;let W=J.getEntity(Z);if(!W)return!1;let A=W.components;for(let L of G)if(!(L in A))return!1}return!0}function a(j,D,$){let G=j.length===0?"":[...j].map(String).sort().join(","),J=D.length===0?"":[...D].map(String).sort().join(","),X=$.length===0?"":[...$].map(String).sort().join(",");return`${G}|${J}|${X}`}class S{host;caches=new Map;byComp=new Map;byParentComp=new Map;constructor(j){this.host=j}getOrCreate(j,D,$){let G=a(j,D,$),J=this.caches.get(G);if(J)return J.members;let X={with:[...j],without:[...D],parentHas:[...$],members:new Map};this.caches.set(G,X);for(let Z of X.with)v(this.byComp,Z,X);for(let Z of X.without)v(this.byComp,Z,X);for(let Z of X.parentHas)v(this.byParentComp,Z,X);return this.populate(X),X.members}get cacheCount(){return this.caches.size}populate(j){let D=this.host,$=j.with;if($.length===0){for(let Z of D.allEntities())if(this.matches(Z,j))j.members.set(Z.id,Z);return}let G=$[0];if(G===void 0)return;let J=D.componentIndex(G)?.size??0;for(let Z=1;Z<$.length;Z++){let W=$[Z];if(W===void 0)continue;let A=D.componentIndex(W)?.size??0;if(A<J)G=W,J=A}let X=D.componentIndex(G);if(!X||X.size===0)return;for(let Z of X){let W=D.getEntity(Z);if(!W)continue;if(this.matches(W,j))j.members.set(Z,W)}}matches(j,D){return R(j,D.with,D.without,D.parentHas,this.host)}reeval(j,D){let $=this.host.getEntity(j);if(!$){D.members.delete(j);return}if(this.matches($,D))D.members.set(j,$);else D.members.delete(j)}onComponentChanged(j,D){let $=this.byComp.get(D);if($)for(let J of $)this.reeval(j,J);let G=this.byParentComp.get(D);if(G&&G.length>0){let J=this.host.getChildren(j);if(J.length>0)for(let X of G)for(let Z of J)this.reeval(Z,X)}}onParentChanged(j){for(let D of this.caches.values())if(D.parentHas.length>0)this.reeval(j,D)}onEntityRemoved(j){let D=!1;for(let G of this.caches.values())if(G.members.delete(j),G.parentHas.length>0)D=!0;if(!D)return;let $=this.host.getChildren(j);if($.length===0)return;for(let G of this.caches.values()){if(G.parentHas.length===0)continue;for(let J of $)G.members.delete(J)}}}function v(j,D,$){let G=j.get(D);if(G)G.push($);else j.set(D,[$])}function m(j,D,$){if(!j)return!1;for(let G of D)if((j.get(G)??-1)>$)return!0;return!1}class N{callbacks=[];_iterDepth=0;_pendingRemovals=[];add(j){this.callbacks.push(j)}remove(j){if(this._iterDepth>0){this._pendingRemovals.push(j);return}let D=this.callbacks.indexOf(j);if(D!==-1)this.callbacks.splice(D,1)}invoke(j){this._iterDepth++;let D=this.callbacks.length;for(let $=0;$<D;$++){let G=this.callbacks[$];if(G)G(j)}if(this._iterDepth--,this._iterDepth===0&&this._pendingRemovals.length>0){for(let $ of this._pendingRemovals){let G=this.callbacks.indexOf($);if(G!==-1)this.callbacks.splice(G,1)}this._pendingRemovals.length=0}}}class T{nextId=1;entities=new Map;componentIndices=new Map;addedCallbacks=new Map;removedCallbacks=new Map;hierarchyManager=new H;disposeCallbacks=new Map;changeSeqs=new Map;_changeSeq=0;_afterComponentAddedHooks=[];_afterEntityMutatedHooks=[];_afterComponentRemovedHooks=[];_beforeEntityRemovedHooks=[];_afterParentChangedHooks=[];_queryCache=new S({getEntity:(j)=>this.entities.get(j),getParent:(j)=>this.hierarchyManager.getParent(j),getChildren:(j)=>this.hierarchyManager.getChildren(j),allEntities:()=>this.entities.values(),componentIndex:(j)=>this.componentIndices.get(j)});_batchingDepth=0;_batchedEntityIds=new Set;_pendingBatchKeys=null;get entityCount(){return this.entities.size}createEntity(){let j=this.nextId++,D={id:j,components:{}};return this.entities.set(j,D),D}registerDispose(j,D){this.disposeCallbacks.set(j,D)}getDisposeCallbacks(){return this.disposeCallbacks}invokeDispose(j,D,$){let G=this.disposeCallbacks.get(j);if(!G)return;try{G({value:D,entityId:$})}catch(J){console.warn(`Component dispose callback for '${String(j)}' threw:`,J)}}addComponent(j,D,$){let G=this.entities.get(j);if(!G)throw Error(`Cannot add component '${String(D)}': Entity with ID ${j} does not exist`);let J=G.components[D];if(J!==void 0)this.invokeDispose(D,J,G.id);if(G.components[D]=$,!this.componentIndices.has(D))this.componentIndices.set(D,new Set);this.componentIndices.get(D)?.add(G.id);let X=this.addedCallbacks.get(D);if(X)X.invoke({value:$,entity:G});this._queryCache.onComponentChanged(G.id,D),this._batchingDepth++;for(let Z of this._afterComponentAddedHooks)Z(G.id,D);if(this._batchedEntityIds.add(G.id),this._batchingDepth--,this._batchingDepth===0){for(let Z of this._batchedEntityIds)for(let W of this._afterEntityMutatedHooks)W(Z);this._batchedEntityIds.clear()}return this}addComponents(j,D){let $=this.entities.get(j);if(!$)throw Error(`Cannot add components: Entity with ID ${j} does not exist`);let G=this._pendingBatchKeys;this._pendingBatchKeys=new Set(Object.keys(D)),this._batchingDepth++;for(let J in D)this.addComponent($.id,J,D[J]);if(this._batchingDepth--,this._pendingBatchKeys=G,this._batchingDepth===0){for(let J of this._batchedEntityIds)for(let X of this._afterEntityMutatedHooks)X(J);this._batchedEntityIds.clear()}return this}removeComponent(j,D){let $=this.entities.get(j);if(!$)throw Error(`Cannot remove component '${String(D)}': Entity with ID ${j} does not exist`);let G=$.components[D];if(G!==void 0)this.invokeDispose(D,G,$.id);delete $.components[D];let J=this.removedCallbacks.get(D);if(J&&G!==void 0)J.invoke({value:G,entity:$});if(this.componentIndices.get(D)?.delete($.id),G!==void 0){this._queryCache.onComponentChanged($.id,D);for(let X of this._afterComponentRemovedHooks)X($.id,D)}return this}getComponent(j,D){return this.entities.get(j)?.components[D]}getEntitiesWithQuery(j=[],D=[],$,G,J){return this.getEntitiesWithQueryInto([],j,D,$,G,J)}getEntitiesWithQueryInto(j,D=[],$=[],G,J,X){j.length=0;let Z=G!==void 0&&G.length>0&&J!==void 0,W=X!==void 0&&X.length>0;if(D.length===0&&$.length===0&&!W){if(!Z){for(let L of this.entities.values())j.push(L);return j}for(let L of this.entities.values()){if(!m(this.changeSeqs.get(L.id),G,J))continue;j.push(L)}return j}let A=this._queryCache.getOrCreate(D,$,X??[]);if(A.size===0)return j;if(Z){for(let L of A.values()){if(!m(this.changeSeqs.get(L.id),G,J))continue;j.push(L)}return j}for(let L of A.values())j.push(L);return j}get _queryCacheForTesting(){return this._queryCache}removeEntity(j,D){let $=this.entities.get(j);if(!$)return!1;if(D?.cascade??!0){let J=this.hierarchyManager.getDescendants($.id);for(let X=J.length-1;X>=0;X--){let Z=J[X];if(Z===void 0)continue;this._queryCache.onEntityRemoved(Z);for(let W of this._beforeEntityRemovedHooks)W(Z)}this._queryCache.onEntityRemoved($.id);for(let X of this._beforeEntityRemovedHooks)X($.id);for(let X=J.length-1;X>=0;X--){let Z=J[X];if(Z===void 0)continue;this.removeEntityInternal(Z)}}else{this._queryCache.onEntityRemoved($.id);for(let J of this._beforeEntityRemovedHooks)J($.id)}return this.removeEntityInternal($.id)}removeEntityInternal(j){let D=this.entities.get(j);if(!D)return!1;this.hierarchyManager.removeEntity(j);for(let $ of Object.keys(D.components)){let G=D.components[$];if(G!==void 0){this.invokeDispose($,G,D.id);let J=this.removedCallbacks.get($);if(J)J.invoke({value:G,entity:D})}this.componentIndices.get($)?.delete(D.id)}return this.changeSeqs.delete(D.id),this.entities.delete(D.id)}getEntity(j){return this.entities.get(j)}onComponentAdded(j,D){let $=D,G=this.addedCallbacks.get(j);if(!G)G=new N,this.addedCallbacks.set(j,G);return G.add($),()=>{this.addedCallbacks.get(j)?.remove($)}}onComponentRemoved(j,D){let $=D,G=this.removedCallbacks.get(j);if(!G)G=new N,this.removedCallbacks.set(j,G);return G.add($),()=>{this.removedCallbacks.get(j)?.remove($)}}onAfterComponentAdded(j){return this._afterComponentAddedHooks.push(j),()=>{let D=this._afterComponentAddedHooks.indexOf(j);if(D!==-1)this._afterComponentAddedHooks.splice(D,1)}}onAfterEntityMutated(j){return this._afterEntityMutatedHooks.push(j),()=>{let D=this._afterEntityMutatedHooks.indexOf(j);if(D!==-1)this._afterEntityMutatedHooks.splice(D,1)}}onAfterComponentRemoved(j){return this._afterComponentRemovedHooks.push(j),()=>{let D=this._afterComponentRemovedHooks.indexOf(j);if(D!==-1)this._afterComponentRemovedHooks.splice(D,1)}}onBeforeEntityRemoved(j){return this._beforeEntityRemovedHooks.push(j),()=>{let D=this._beforeEntityRemovedHooks.indexOf(j);if(D!==-1)this._beforeEntityRemovedHooks.splice(D,1)}}onAfterParentChanged(j){return this._afterParentChangedHooks.push(j),()=>{let D=this._afterParentChangedHooks.indexOf(j);if(D!==-1)this._afterParentChangedHooks.splice(D,1)}}get changeSeq(){return this._changeSeq}markChanged(j,D){let $=++this._changeSeq,G=this.changeSeqs.get(j);if(!G)G=new Map,this.changeSeqs.set(j,G);G.set(D,$)}getChangeSeq(j,D){return this.changeSeqs.get(j)?.get(D)??-1}spawnChild(j,D){let $=this.createEntity();return this.addComponents($.id,D),this.setParent($.id,j),$}setParent(j,D){this.hierarchyManager.setParent(j,D),this._queryCache.onParentChanged(j);for(let $ of this._afterParentChangedHooks)$(j);return this}removeParent(j){let D=this.hierarchyManager.removeParent(j);if(D){this._queryCache.onParentChanged(j);for(let $ of this._afterParentChangedHooks)$(j)}return D}getParent(j){return this.hierarchyManager.getParent(j)}getChildren(j){return this.hierarchyManager.getChildren(j)}getChildAt(j,D){return this.hierarchyManager.getChildAt(j,D)}getChildIndex(j,D){return this.hierarchyManager.getChildIndex(j,D)}getAncestors(j){return this.hierarchyManager.getAncestors(j)}getDescendants(j){return this.hierarchyManager.getDescendants(j)}getRoot(j){return this.hierarchyManager.getRoot(j)}getSiblings(j){return this.hierarchyManager.getSiblings(j)}isDescendantOf(j,D){return this.hierarchyManager.isDescendantOf(j,D)}isAncestorOf(j,D){return this.hierarchyManager.isAncestorOf(j,D)}get hasHierarchy(){return this.hierarchyManager.hasHierarchy}getRootEntities(){return this.hierarchyManager.getRootEntities()}forEachInHierarchy(j,D){this.hierarchyManager.forEachInHierarchy(j,D)}hierarchyIterator(j){return this.hierarchyManager.hierarchyIterator(j)}}class x{handlers=new Map;subscribe(j,D){return this.addHandler(j,D,!1)}once(j,D){return this.addHandler(j,D,!0)}unsubscribe(j,D){let $=this.handlers.get(j);if(!$)return!1;let G=$.findIndex((J)=>J.callback===D);if(G===-1)return!1;return $.splice(G,1),!0}addHandler(j,D,$){let G=this.handlers.get(j);if(!G)G=[],this.handlers.set(j,G);let J={callback:D,once:$};return G.push(J),()=>{let X=this.handlers.get(j);if(X){let Z=X.indexOf(J);if(Z!==-1)X.splice(Z,1)}}}publish(...[j,D]){let $=this.handlers.get(j);if(!$||$.length===0)return;let G=!1,J=$.length;for(let X=0;X<J&&X<$.length;X++){let Z=$[X];if(!Z)continue;if(Z.callback(D),Z.once)G=!0}if(G){for(let X=$.length-1;X>=0;X--)if($[X]?.once)$.splice(X,1)}}clear(){this.handlers.clear()}clearEvent(j){this.handlers.delete(j)}}var p=Symbol("resource-direct");function n(j){return{[p]:j}}function b(j){if(typeof j==="object"&&j!==null&&!Array.isArray(j))return{...j};return{$value:j}}function t(j,D){if(typeof j==="object"&&j!==null&&!Array.isArray(j)){let $=j;for(let G in D)if(!Object.is($[G],D[G]))return!0;return!1}return!Object.is(j,D.$value)}function e(j){return typeof j==="object"&&j!==null&&"factory"in j&&typeof j.factory==="function"}function jj(j){return typeof j==="object"&&j!==null&&p in j}function l(j,D){let $=[],G=new Set,J=new Set;function X(Z,W=[]){if(G.has(Z))return;if(J.has(Z))throw Error(`Circular resource dependency: ${[...W,Z].join(" -> ")}`);J.add(Z);for(let A of D(Z)){let L=j.find((O)=>O===A);if(L)X(L,[...W,Z])}J.delete(Z),G.add(Z),$.push(Z)}for(let Z of j)X(Z);return $}class w{resources=new Map;resourceFactories=new Map;resourceDependencies=new Map;resourceDisposers=new Map;initializedResourceKeys=new Set;_changeSubscribers=new Map;_observedSnapshots=new Map;add(j,D){let $=(G)=>{this.resources.set(j,G),this.initializedResourceKeys.add(j),this.resourceDependencies.set(j,[])};if(e(D)){if(this.resourceFactories.set(j,D.factory),this.resourceDependencies.set(j,D.dependsOn??[]),D.onDispose)this.resourceDisposers.set(j,D.onDispose)}else if(jj(D))$(D[p]);else if(typeof D==="function")this.resourceFactories.set(j,D),this.resourceDependencies.set(j,[]);else $(D);return this}tryGet(j,...D){if(!this.has(j))return;return this.get(j,...D)}get(j,...D){let $=this.resources.get(j);if($!==void 0)return $;let G=this.resourceFactories.get(j);if(G===void 0)throw Error(`Resource ${String(j)} not found`);let J=D[0],X=G(J);if(!(X instanceof Promise))this.resources.set(j,X),this.initializedResourceKeys.add(j);return X}has(j){return this.resources.has(j)||this.resourceFactories.has(j)}remove(j){let D=this.resources.delete(j),$=this.resourceFactories.delete(j);return this.resourceDependencies.delete(j),this.resourceDisposers.delete(j),this.initializedResourceKeys.delete(j),D||$}getKeys(){let j=new Set([...this.resources.keys(),...this.resourceFactories.keys()]);return Array.from(j)}needsInitialization(j){return this.resourceFactories.has(j)&&!this.initializedResourceKeys.has(j)}getPendingInitializationKeys(){return Array.from(this.resourceFactories.keys()).filter((j)=>!this.initializedResourceKeys.has(j))}async initializeResource(j,...D){if(!this.resourceFactories.has(j)||this.initializedResourceKeys.has(j))return;let $=this.resourceFactories.get(j);if(!$)return;let G=D[0],J=await $(G);this.resources.set(j,J),this.initializedResourceKeys.add(j),this.resourceFactories.delete(j)}async initializeResources(...j){let D=j.slice(1),$=D.length===0?this.getPendingInitializationKeys():D;if($.length===0)return;let G=l($,(J)=>[...this.resourceDependencies.get(J)??[]]);for(let J of G)await this.initializeResource(J,...j.slice(0,1))}getDependencies(j){return this.resourceDependencies.get(j)??[]}async disposeResource(j,...D){if(!this.resources.has(j)&&!this.resourceFactories.has(j))return!1;if(this.initializedResourceKeys.has(j)){let $=this.resourceDisposers.get(j),G=this.resources.get(j);if($&&G!==void 0){let J=D[0];await $(G,J)}}return this.resources.delete(j),this.resourceFactories.delete(j),this.resourceDependencies.delete(j),this.resourceDisposers.delete(j),this.initializedResourceKeys.delete(j),this._changeSubscribers.delete(j),!0}onResourceChange(j,D){let $=this._changeSubscribers.get(j),G=$??new Set;if(!$){this._changeSubscribers.set(j,G);let X=this.resources.get(j);this._observedSnapshots.set(j,b(X))}let J=D;return G.add(J),()=>{if(G.delete(J),G.size===0)this._changeSubscribers.delete(j),this._observedSnapshots.delete(j)}}notifyChange(j,D,$){if(Object.is(D,$))return;let G=this._changeSubscribers.get(j);if(!G||G.size===0)return;if(this._observedSnapshots.has(j))this._observedSnapshots.set(j,b(D));let J=[...G];for(let X of J)X(D,$)}isObserved(j){return this._observedSnapshots.has(j)}flushObserved(){if(this._observedSnapshots.size===0)return;for(let[j,D]of this._observedSnapshots){let $=this.resources.get(j);if(!t($,D))continue;let G="$value"in D?D.$value:D,J=b($),X=this._changeSubscribers.get(j);for(let Z of X)Z($,G);this._observedSnapshots.set(j,J)}}async disposeResources(...j){let D=Array.from(this.initializedResourceKeys);if(D.length===0)return;let $=l(D,(G)=>[...this.resourceDependencies.get(G)??[]]).reverse();for(let G of $)await this.disposeResource(G,...j)}}class q{queries=new Map;entityManager;_hasParentHasQueries=!1;constructor(j){this.entityManager=j}get hasParentHasQueries(){return this._hasParentHasQueries}addQuery(j,D){let $={definition:D,matchingEntities:new Set};if(this.queries.set(j,$),D.parentHas?.length)this._hasParentHasQueries=!0;let G=this.entityManager.getEntitiesWithQuery(D.with,D.without??[]);for(let J of G)if(this.entityMatchesQuery(J,$.definition))$.matchingEntities.add(J.id),$.definition.onEnter?.(J)}removeQuery(j){let D=this.queries.delete(j);if(D)this._recalcParentHasFlag();return D}entityMatchesQuery(j,D){return R(j,D.with,D.without,D.parentHas,this.entityManager)}_applyQueryTransition(j,D){let $=D.matchingEntities.has(j.id),G=this.entityMatchesQuery(j,D.definition);if(!$&&G)D.matchingEntities.add(j.id),D.definition.onEnter?.(j);else if($&&!G)D.matchingEntities.delete(j.id),D.definition.onExit?.(j.id)}onComponentAdded(j,D){for(let[,$]of this.queries)this._applyQueryTransition(j,$);if(this._hasParentHasQueries)this._recheckChildren(j.id)}onComponentRemoved(j,D){for(let[,$]of this.queries)this._applyQueryTransition(j,$);if(this._hasParentHasQueries)this._recheckChildren(j.id)}onEntityRemoved(j){for(let[D,$]of this.queries)if($.matchingEntities.has(j))$.matchingEntities.delete(j),$.definition.onExit?.(j)}recheckEntity(j){for(let[,D]of this.queries)this._applyQueryTransition(j,D)}recheckEntityAndChildren(j){if(this.recheckEntity(j),this._hasParentHasQueries)this._recheckChildren(j.id)}_recheckChildren(j){let D=this.entityManager.getChildren(j);for(let $ of D){let G=this.entityManager.getEntity($);if(G)this.recheckEntity(G)}}_recalcParentHasFlag(){this._hasParentHasQueries=!1;for(let[,j]of this.queries)if(j.definition.parentHas?.length){this._hasParentHasQueries=!0;return}}}class C{parent;commands=[];constructor(j){this.parent=j}removeEntity(j,D){this.commands.push(($)=>{$.removeEntity(j,D)})}addComponent(j,D,$){this.commands.push((G)=>{G.addComponent(j,D,$)})}removeComponent(j,D){this.commands.push(($)=>{$.removeComponent(j,D)})}spawn(j,D){let $=this._resolveScope(D);this.commands.push((G)=>{G.spawn(j,$)})}spawnChild(j,D,$){let G=this._resolveScope($);this.commands.push((J)=>{J.spawnChild(j,D,G)})}_resolveScope(j){if(j?.scope!==void 0)return j;let D=this.parent?._getActiveScopeHint();if(!D)return j;return{scope:D}}addComponents(j,D){this.commands.push(($)=>{$.addComponents(j,D)})}setParent(j,D){this.commands.push(($)=>{$.setParent(j,D)})}mutateComponent(j,D,$){this.commands.push((G)=>{G.mutateComponent(j,D,$)})}markChanged(j,D){this.commands.push(($)=>{$.markChanged(j,D)})}removeParent(j){this.commands.push((D)=>{D.removeParent(j)})}playback(j){for(let D of this.commands)try{D(j)}catch($){console.warn("CommandBuffer: Command failed during playback:",$)}this.commands.length=0}clear(){this.commands.length=0}get length(){return this.commands.length}}class s{_id;constructor(j){this._id=j}_systemDefaults;setSystemDefaults(j){return this._systemDefaults=j,this}withComponentTypes(){return this}withEventTypes(){return this}withResourceTypes(){return this}withAssetTypes(){return this}withScreenTypes(){return this}withLabels(){return this}withGroups(){return this}withAssetGroupNames(){return this}withReactiveQueryNames(){return this}requires(){return this}install(j){return{id:this._id,install:j,...this._systemDefaults?{systemDefaults:this._systemDefaults}:{}}}}function E(j){return new s(j)}var i="__each";class g{_label;queries={};singletons={};processFunction;detachFunction;initializeFunction;eventHandlers;_priority=0;_phase="update";_groups=[];_inScreens;_excludeScreens;_requiredAssets;_runWhenEmpty=!1;_entityEnterHandlers={};_resourceKeys;constructor(j,D){this._label=j;if(D){if(D.phase!==void 0)this._phase=D.phase;if(D.priority!==void 0)this._priority=D.priority;if(D.inScreens!==void 0)this._inScreens=D.inScreens;if(D.excludeScreens!==void 0)this._excludeScreens=D.excludeScreens}}get label(){return this._label}_createSystemObject(){let j={label:this._label,entityQueries:this.queries,priority:this._priority,phase:this._phase};if(Object.keys(this.singletons).length>0)j.entitySingletons=this.singletons;if(this.processFunction)j.process=this.processFunction;if(this.detachFunction)j.onDetach=this.detachFunction;if(this.initializeFunction)j.onInitialize=this.initializeFunction;if(this.eventHandlers)j.eventHandlers=this.eventHandlers;if(this._groups.length>0)j.groups=[...this._groups];if(this._inScreens)j.inScreens=this._inScreens;if(this._excludeScreens)j.excludeScreens=this._excludeScreens;if(this._requiredAssets)j.requiredAssets=this._requiredAssets;if(this._runWhenEmpty)j.runWhenEmpty=!0;if(Object.keys(this._entityEnterHandlers).length>0)j.onEntityEnter={...this._entityEnterHandlers};return j}setPriority(j){return this._priority=j,this}inPhase(j){return this._phase=j,this}inGroup(j){if(!this._groups.includes(j))this._groups.push(j);return this}inScreens(j){return this._inScreens=[...j],this}excludeScreens(j){return this._excludeScreens=[...j],this}requiresAssets(j){return this._requiredAssets=[...j],this}runWhenEmpty(){return this._runWhenEmpty=!0,this}withResources(j){return this._resourceKeys=[...j],this}addQuery(j,D){let $=this;return $.queries={...this.queries,[j]:D},$}addSingleton(j,D){let $=this;return $.singletons={...this.singletons,[j]:D},$}setProcess(j){return this.processFunction=this._wrapWithResources(j),this}_wrapWithResources(j){if(!this._resourceKeys?.length)return j;let D=this._resourceKeys,$={},G=!1;return(J)=>{for(let X of D)if(!G||J.ecs.isResourceObserved(X))$[X]=J.ecs.getResource(X);G=!0,J.resources=$,j(J)}}setProcessEach(j,D){let $=this;if(Object.keys($.queries).length>0||Object.keys($.singletons).length>0||$.processFunction!==void 0)throw Error("setProcessEach requires a SystemBuilder with no prior queries, singletons, or process function. Use addQuery + setProcess for multi-query systems.");$.queries.__each=j;let G={entity:void 0,dt:0,ecs:void 0,resources:void 0},J=j.mutates&&j.mutates.length>0?j.mutates:void 0,X=(Z)=>{let W=Z,A=W.queries.__each;if(!A)return;G.dt=W.dt,G.ecs=W.ecs,G.resources=W.resources;for(let L=0;L<A.length;L++){let O=A[L];if(!O)continue;G.entity=O;let _=D(G);if(J===void 0||_===!1)continue;for(let Y=0;Y<J.length;Y++){let F=J[Y];if(F!==void 0)W.ecs.markChanged(O.id,F)}}};return $.processFunction=$._wrapWithResources(X),this}setOnEntityEnter(j,D){return this._entityEnterHandlers[j]=D,this}setOnDetach(j){return this.detachFunction=j,this}setOnInitialize(j){return this.initializeFunction=j,this}setEventHandlers(j){return this.eventHandlers=j,this}}function c(j,D,$){let G=new Set,J=[D];while(J.length>0){let X=J.pop();if(X===void 0)break;if(X===j)throw Error(`Circular required component dependency: '${String(j)}' -> '${String(D)}' -> ... -> '${String(j)}'`);if(G.has(X))continue;G.add(X);let Z=$(X);if(Z)for(let W of Z)J.push(W.component)}}var d="0.16.2";class z{assets=new Map;groups=new Map;eventBus=null;setEventBus(j){this.eventBus=j}register(j,D){if(this.assets.set(j,{definition:D,status:"pending"}),D.group){let $=this.groups.get(D.group)??new Set;$.add(j),this.groups.set(D.group,$)}}async loadEagerAssets(){let j=[];for(let[D,$]of this.assets)if($.definition.eager&&$.status==="pending")j.push(D);await Promise.all(j.map((D)=>this.loadAsset(D)))}async loadAsset(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);if(D.status==="loaded"&&D.value!==void 0)return D.value;if(D.status==="loading"&&D.loadPromise)return D.loadPromise;if(D.status==="failed")D.status="pending";D.status="loading",D.loadPromise=D.definition.loader();try{let $=await D.loadPromise;return D.value=$,D.status="loaded",D.loadPromise=void 0,this.eventBus?.publish("assetLoaded",{key:j}),this.checkGroupProgress(D.definition.group),$}catch($){let G=$ instanceof Error?$:Error(String($));throw D.status="failed",D.error=G,D.loadPromise=void 0,this.eventBus?.publish("assetFailed",{key:j,error:G}),G}}async loadAssetGroup(j){let D=this.groups.get(j);if(!D||D.size===0)throw Error(`Asset group '${j}' not found or empty`);await Promise.all(Array.from(D).map(($)=>this.loadAsset($)))}get(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);if(D.status!=="loaded"||D.value===void 0)throw Error(`Asset '${String(j)}' is not loaded (status: ${D.status})`);return D.value}tryGet(j){let D=this.assets.get(j);if(!D||D.status!=="loaded")return;return D.value}getHandle(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);let $=this;return{get status(){return D.status},get isLoaded(){return D.status==="loaded"},get(){return $.get(j)},tryGet(){return $.tryGet(j)}}}getStatus(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);return D.status}isLoaded(j){return this.assets.get(j)?.status==="loaded"}isGroupLoaded(j){let D=this.groups.get(j);if(!D||D.size===0)return!1;for(let $ of D){let G=this.assets.get($);if(!G||G.status!=="loaded")return!1}return!0}getGroupProgress(j){return this.getGroupProgressDetails(j).progress}getGroupProgressDetails(j){let D=this.groups.get(j);if(!D||D.size===0)return{loaded:0,total:0,progress:0};let $=0;for(let J of D)if(this.assets.get(J)?.status==="loaded")$++;let G=D.size;return{loaded:$,total:G,progress:$/G}}checkGroupProgress(j){if(!j||!this.eventBus)return;let D=j,$=this.getGroupProgressDetails(D);if(this.eventBus.publish("assetGroupProgress",{group:D,...$}),$.loaded===$.total)this.eventBus.publish("assetGroupLoaded",{group:D})}createResource(){let j=this;return{getStatus(D){return j.getStatus(D)},isLoaded(D){return j.isLoaded(D)},isGroupLoaded(D){return j.isGroupLoaded(D)},getGroupProgress(D){return j.getGroupProgress(D)},get(D){return j.get(D)},tryGet(D){return j.tryGet(D)},getHandle(D){return j.getHandle(D)}}}getKeys(){return Array.from(this.assets.keys())}getGroupNames(){return Array.from(this.groups.keys())}getGroupKeys(j){let D=this.groups.get(j);return D?Array.from(D):[]}}class y{manager;constructor(j){this.manager=j}add(j,D){return this.manager.register(j,{loader:D,eager:!0}),this}addWithConfig(j,D){return this.manager.register(j,D),this}addGroup(j,D){for(let[$,G]of Object.entries(D))this.manager.register($,{loader:G,eager:!1,group:j});return this}getManager(){return this.manager}}function k(j){return new y(j??new z)}class P{screens=new Map;currentScreen=null;screenStack=[];eventBus=null;assetManager=null;ecs=null;setDependencies(j,D,$){this.eventBus=j,this.assetManager=D,this.ecs=$}requireEcs(){if(!this.ecs)throw Error("ScreenManager: dependencies not set. Call setDependencies() first.");return this.ecs}register(j,D){this.screens.set(j,{definition:D})}async setScreen(j,D){let $=this.screens.get(j);if(!$)throw Error(`Screen '${String(j)}' not found`);await this.verifyRequiredAssets($.definition.requiredAssets,$.definition.requiredAssetGroups);while(this.screenStack.length>0){let J=this.screenStack.pop();if(J)await this.exitScreen(J.name)}if(this.currentScreen)await this.exitScreen(this.currentScreen.name);let G=$.definition.initialState(D);this.currentScreen={name:j,config:D,state:G},await $.definition.onEnter?.({config:D,ecs:this.requireEcs()}),this.eventBus?.publish("screenEnter",{screen:j,config:D})}async pushScreen(j,D){let $=this.screens.get(j);if(!$)throw Error(`Screen '${String(j)}' not found`);if(await this.verifyRequiredAssets($.definition.requiredAssets,$.definition.requiredAssetGroups),this.currentScreen)this.screenStack.push(this.currentScreen);let G=$.definition.initialState(D);this.currentScreen={name:j,config:D,state:G},await $.definition.onEnter?.({config:D,ecs:this.requireEcs()}),this.eventBus?.publish("screenPush",{screen:j,config:D})}async popScreen(){if(this.screenStack.length===0)throw Error("Cannot pop screen: stack is empty");if(this.currentScreen)await this.exitScreen(this.currentScreen.name),this.eventBus?.publish("screenPop",{screen:this.currentScreen.name});this.currentScreen=this.screenStack.pop()??null}async exitScreen(j){let D=this.screens.get(j);if(D?.definition.onExit)await D.definition.onExit(this.requireEcs());this.eventBus?.publish("screenExit",{screen:j})}async verifyRequiredAssets(j,D){if(!this.assetManager)return;if(j){for(let $ of j)if(!this.assetManager.isLoaded($))await this.assetManager.loadAsset($)}if(D){for(let $ of D)if(!this.assetManager.isGroupLoaded($))await this.assetManager.loadAssetGroup($)}}getCurrentScreen(){return this.currentScreen?.name??null}getConfig(j){if(!this.currentScreen)throw Error("No current screen");if(j!==void 0&&this.currentScreen.name!==j)throw Error(`Expected current screen '${String(j)}', but current is '${String(this.currentScreen.name)}'`);return this.currentScreen.config}tryGetConfig(j){if(!this.currentScreen)return;if(j!==void 0&&this.currentScreen.name!==j)return;return this.currentScreen.config}getState(j){if(!this.currentScreen)throw Error("No current screen");if(j!==void 0&&this.currentScreen.name!==j)throw Error(`Expected current screen '${String(j)}', but current is '${String(this.currentScreen.name)}'`);return this.currentScreen.state}tryGetState(j){if(!this.currentScreen)return;if(j!==void 0&&this.currentScreen.name!==j)return;return this.currentScreen.state}updateState(j,D){if(!this.currentScreen)throw Error("No current screen");if(D!==void 0&&this.currentScreen.name!==D)throw Error(`Expected current screen '${String(D)}', but current is '${String(this.currentScreen.name)}'`);let $=typeof j==="function"?j(this.currentScreen.state):j;this.currentScreen.state={...this.currentScreen.state,...$}}getStackDepth(){return this.screenStack.length}isOverlay(){return this.screenStack.length>0}isActive(j){if(this.currentScreen?.name===j)return!0;return this.screenStack.some((D)=>D.name===j)}isCurrent(j){return this.currentScreen?.name===j}createResource(){let j=this;return{get current(){return j.getCurrentScreen()},get config(){return j.tryGetConfig()??null},get state(){return j.tryGetState()??null},set state(D){if(j.currentScreen&&D!==null)j.currentScreen.state=D},get stack(){return j.screenStack},get isOverlay(){return j.isOverlay()},get stackDepth(){return j.getStackDepth()},isActive(D){return j.isActive(D)},isCurrent(D){return j.isCurrent(D)}}}getScreenNames(){return Array.from(this.screens.keys())}hasScreen(j){return this.screens.has(j)}}class o{manager;constructor(j){this.manager=j}add(j,D){return this.manager.register(j,D),this}getManager(){return this.manager}}function I(j){return new o(j??new P)}class h{assetConfigurator=null;screenConfigurator=null;pendingResources=[];pendingDisposeCallbacks=[];pendingRequiredComponents=[];pendingPlugins=[];_fixedDt=null;constructor(){}withPlugin(j){return this.pendingPlugins.push(j),this}withComponentTypes(){return this}withEventTypes(){return this}withResourceTypes(){return this}withResource(j,D){return this.pendingResources.push({key:j,value:D}),this}withDispose(j,D){return this.pendingDisposeCallbacks.push({key:j,callback:D}),this}withRequired(j,D,$){return this.pendingRequiredComponents.push({trigger:j,required:D,factory:$}),this}withAssets(j){let D=k();return j(D),this.assetConfigurator=D,this}withScreens(j){let D=I();return j(D),this.screenConfigurator=D,this}withFixedTimestep(j){return this._fixedDt=j,this}withReactiveQueryNames(){return this}pluginFactory(){return(j)=>E(j.id).install(j.install)}build(){let j=new V;for(let D of this.pendingPlugins)j._installPluginUnchecked(D);for(let{key:D,value:$}of this.pendingResources)j.addResource(D,$);for(let{key:D,callback:$}of this.pendingDisposeCallbacks)j.registerDispose(D,$);for(let{trigger:D,required:$,factory:G}of this.pendingRequiredComponents)j.registerRequired(D,$,G);if(this.assetConfigurator)j._setAssetManager(this.assetConfigurator.getManager());else if(j._hasPendingPluginAssets())j._setAssetManager(new z);if(this.screenConfigurator)j._setScreenManager(this.screenConfigurator.getManager());else if(j._hasPendingPluginScreens())j._setScreenManager(new P);if(this._fixedDt!==null)j._setFixedDt(this._fixedDt);return j}}var r=["preUpdate","fixedUpdate","update","postUpdate","render"];class V{static VERSION=d;_entityManager;_eventBus;_resourceManager;_commandBuffer;_systems=[];_phaseSystems={preUpdate:[],fixedUpdate:[],update:[],postUpdate:[],render:[]};_installedPlugins=new Set;_pluginCleanups=new Map;_currentSystemDefaults;_screenScopedEntities=new Map;_entityScreenScope=new Map;_activeScopeHint=null;_disabledGroups=new Set;_assetManager=null;_screenManager=null;_reactiveQueryManager;_postUpdateHooks=[];_currentTick=0;_systemLastSeqs=new Map;_changeThreshold=0;_fixedDt=0.016666666666666666;_fixedAccumulator=0;_interpolationAlpha=0;_maxFixedSteps=8;_requiredComponents=new Map;_pendingPluginAssets=[];_pendingPluginScreens=[];_diagnosticsEnabled=!1;_systemTimings=new Map;_phaseTimings={preUpdate:0,fixedUpdate:0,update:0,postUpdate:0,render:0};_entityEnterTracking=new Map;_entityEnterFrameSet=new Set;_systemContexts=new WeakMap;_singletonScratch=[];_pendingFinalizers=[];_batchingRegistrations=!1;_initializeFired=!1;_systemsInitialized=new WeakSet;constructor(){this._entityManager=new T,this._eventBus=new x,this._resourceManager=new w,this._reactiveQueryManager=new q(this._entityManager),this._commandBuffer=new C(this),this._subscribeLifecycleHooks()}_subscribeLifecycleHooks(){this._entityManager.onAfterComponentAdded((j,D)=>{this._entityManager.markChanged(j,D);let $=this._requiredComponents.get(D);if($){let G=this._entityManager.getEntity(j);if(G){let J=G.components[D];for(let{component:X,factory:Z}of $){if(this._entityManager._pendingBatchKeys?.has(X))continue;if(!(X in G.components))this._entityManager.addComponent(j,X,Z(J))}}}}),this._entityManager.onAfterEntityMutated((j)=>{let D=this._entityManager.getEntity(j);if(D)this._reactiveQueryManager.recheckEntityAndChildren(D)}),this._entityManager.onAfterComponentRemoved((j,D)=>{let $=this._entityManager.getEntity(j);if($)this._reactiveQueryManager.onComponentRemoved($,D)}),this._entityManager.onBeforeEntityRemoved((j)=>{this._reactiveQueryManager.onEntityRemoved(j);let D=this._entityScreenScope.get(j);if(D!==void 0)this._entityScreenScope.delete(j),this._screenScopedEntities.get(D)?.delete(j)}),this._entityManager.onAfterParentChanged((j)=>{if(this._reactiveQueryManager.hasParentHasQueries){let D=this._entityManager.getEntity(j);if(D)this._reactiveQueryManager.recheckEntity(D)}})}static create(){return new h}addSystem(j){let D=new g(j,this._currentSystemDefaults);return this._pendingFinalizers.push(()=>{this._registerSystem(D._createSystemObject())}),D}_finalizePendingBuilders(){if(this._pendingFinalizers.length===0)return;this._batchingRegistrations=!0;while(this._pendingFinalizers.length>0){let j=this._pendingFinalizers;this._pendingFinalizers=[];for(let D of j)D()}this._batchingRegistrations=!1,this._rebuildPhaseSystems()}update(j){this._finalizePendingBuilders();let D=this._screenManager?.getCurrentScreen()??null,$=this._diagnosticsEnabled;this._runPhase("preUpdate",j,D,$);let G=$?performance.now():0;this._fixedAccumulator+=j;let J=0;while(this._fixedAccumulator>=this._fixedDt&&J<this._maxFixedSteps)this._executePhase(this._phaseSystems.fixedUpdate,this._fixedDt,D),this._commandBuffer.playback(this),this._fixedAccumulator-=this._fixedDt,J++;if(this._fixedAccumulator>=this._fixedDt)this._fixedAccumulator=0;if($)this._phaseTimings.fixedUpdate=performance.now()-G;this._interpolationAlpha=this._fixedAccumulator/this._fixedDt,this._runPhase("update",j,D,$),this._runPhase("postUpdate",j,D,$);for(let X of this._postUpdateHooks)X({ecs:this,dt:j});this._runPhase("render",j,D,$),this._resourceManager.flushObserved(),this._changeThreshold=this._entityManager.changeSeq,this._currentTick++}_executePhase(j,D,$){for(let G of j){if(!G.process&&!G.onEntityEnter)continue;if(G.groups?.length){let _=!1;for(let Y of G.groups)if(this._disabledGroups.has(Y)){_=!0;break}if(_)continue}if(G.inScreens?.length){if($===null||!G.inScreens.includes($))continue}if(G.excludeScreens?.length){if($!==null&&G.excludeScreens.includes($))continue}if(G.requiredAssets?.length&&this._assetManager){let _=!0;for(let Y of G.requiredAssets)if(!this._assetManager.isLoaded(Y)){_=!1;break}if(!_)continue}let J=this._systemLastSeqs.get(G)??0;this._changeThreshold=J;let X=this._systemContexts.get(G);if(!X)X={queries:{},dt:0,ecs:this},this._systemContexts.set(G,X);X.dt=D;let Z=X.queries,W=!1,A=!1;if(G.entityQueries)for(let _ in G.entityQueries){A=!0;let Y=G.entityQueries[_];if(Y){let Q=Z[_]??(Z[_]=[]);if(this._entityManager.getEntitiesWithQueryInto(Q,Y.with,Y.without||[],Y.changed,Y.changed?this._changeThreshold:void 0,Y.parentHas),Q.length)W=!0}}if(G.entitySingletons){let _=this._singletonScratch;for(let Y in G.entitySingletons){A=!0;let F=G.entitySingletons[Y];if(F){if(this._entityManager.getEntitiesWithQueryInto(_,F.with,F.without||[],F.changed,F.changed?this._changeThreshold:void 0,F.parentHas),Z[Y]=_[0],_.length)W=!0}}}let L=this._entityEnterTracking.get(G);if(L&&G.onEntityEnter)for(let _ in G.onEntityEnter){let Y=Z[_],F=L.get(_);if(!Y||!F)continue;let Q=G.onEntityEnter[_];if(!Q)continue;let K=this._entityEnterFrameSet;K.clear();for(let B of Y)if(K.add(B.id),!F.has(B.id))F.add(B.id),Q({entity:B,ecs:this});for(let B of F)if(!K.has(B))F.delete(B)}if(G.process){if(W||G.runWhenEmpty||!A){let Y=this._activeScopeHint;this._activeScopeHint=G.inScreens?.length&&$!==null?$:null;let F=this._diagnosticsEnabled?performance.now():0;try{G.process(X)}finally{if(this._activeScopeHint=Y,this._diagnosticsEnabled)this._systemTimings.set(G.label,performance.now()-F)}}}let O=G._autoMarkPairs;if(O){let _=this._entityManager;for(let Y=0;Y<O.length;Y++){let F=O[Y];if(!F)continue;let Q=F.mutates,K=Q.length;if(F.kind==="list"){let B=Z[F.queryName];if(!B)continue;for(let U=0;U<B.length;U++){let M=B[U];if(!M)continue;for(let f=0;f<K;f++){let u=Q[f];if(u!==void 0)_.markChanged(M.id,u)}}}else{let B=Z[F.queryName];if(!B)continue;for(let U=0;U<K;U++){let M=Q[U];if(M!==void 0)_.markChanged(B.id,M)}}}}this._systemLastSeqs.set(G,this._entityManager.changeSeq)}}_runPhase(j,D,$,G){if(G){let J=performance.now();this._executePhase(this._phaseSystems[j],D,$),this._phaseTimings[j]=performance.now()-J}else this._executePhase(this._phaseSystems[j],D,$);this._commandBuffer.playback(this)}async initialize(){if(this._finalizePendingBuilders(),await this.initializeResources(),this._assetManager)this._assetManager.setEventBus(this._eventBus),await this._assetManager.loadEagerAssets(),this._resourceManager.add("$assets",this._assetManager.createResource());if(this._screenManager){let j=this._eventBus;this._screenManager.setDependencies(j,this._assetManager,this),this._resourceManager.add("$screen",this._screenManager.createResource()),j.subscribe("screenExit",({screen:D})=>{let $=this._screenScopedEntities.get(D);if(!$||$.size===0)return;this._screenScopedEntities.delete(D);for(let G of Array.from($))this._entityScreenScope.delete(G),this.removeEntity(G)})}for(let j of this._systems){if(this._systemsInitialized.has(j))continue;this._systemsInitialized.add(j),await j.onInitialize?.(this)}this._initializeFired=!0}async initializeResources(...j){await this._resourceManager.initializeResources(this,...j)}_rebuildPhaseSystems(){for(let j of r)this._phaseSystems[j]=[];for(let j of this._systems){let D=j.phase??"update";this._phaseSystems[D].push(j)}for(let j of r)this._phaseSystems[j].sort((D,$)=>{let G=D.priority??0;return($.priority??0)-G})}updateSystemPriority(j,D){this._finalizePendingBuilders();let $=this._systems.find((G)=>G.label===j);if(!$)return!1;return $.priority=D,this._rebuildPhaseSystems(),!0}updateSystemPhase(j,D){this._finalizePendingBuilders();let $=this._systems.find((G)=>G.label===j);if(!$)return!1;return $.phase=D,this._rebuildPhaseSystems(),!0}get interpolationAlpha(){return this._interpolationAlpha}get fixedDt(){return this._fixedDt}disableSystemGroup(j){this._disabledGroups.add(j)}enableSystemGroup(j){this._disabledGroups.delete(j)}isSystemGroupEnabled(j){return!this._disabledGroups.has(j)}getSystemsInGroup(j){return this._finalizePendingBuilders(),this._systems.filter((D)=>D.groups?.includes(j)).map((D)=>D.label)}removeSystem(j){this._finalizePendingBuilders();let D=this._systems.findIndex((G)=>G.label===j);if(D===-1)return!1;let $=this._systems[D];if(!$)return!1;if($.onDetach)$.onDetach(this);return this._systems.splice(D,1),this._systemLastSeqs.delete($),this._entityEnterTracking.delete($),this._systemsInitialized.delete($),this._rebuildPhaseSystems(),!0}_registerSystem(j){if(this._systems.push(j),this._systemLastSeqs.set(j,this._changeThreshold),!this._batchingRegistrations)this._rebuildPhaseSystems();let D=[];if(j.entityQueries)for(let $ in j.entityQueries){if($===i)continue;let J=j.entityQueries[$]?.mutates;if(J&&J.length>0)D.push({queryName:$,mutates:J,kind:"list"})}if(j.entitySingletons)for(let $ in j.entitySingletons){let J=j.entitySingletons[$]?.mutates;if(J&&J.length>0)D.push({queryName:$,mutates:J,kind:"singleton"})}if(j._autoMarkPairs=D.length>0?D:null,j.onEntityEnter){let $=new Map;for(let G in j.onEntityEnter)$.set(G,new Set);this._entityEnterTracking.set(j,$)}if(j.eventHandlers)for(let $ in j.eventHandlers){let G=j.eventHandlers[$];if(G)this._eventBus.subscribe($,(J)=>{G({data:J,ecs:this})})}if(this._initializeFired&&!this._systemsInitialized.has(j)){this._systemsInitialized.add(j);let $=j.onInitialize?.(this);if($ instanceof Promise)$.catch((G)=>{console.error(`onInitialize for system "${j.label}" rejected:`,G)})}}hasResource(j){return this._resourceManager.has(j)}getResource(j){if(!this._resourceManager.has(j))throw Error(`Resource '${String(j)}' not found. Available resources: [${this.getResourceKeys().map((D)=>String(D)).join(", ")}]`);return this._resourceManager.get(j,this)}tryGetResource(j){let D=j;if(!this._resourceManager.has(D))return;return this._resourceManager.get(D,this)}addResource(j,D){return this._resourceManager.add(j,D),this}removeResource(j){return this._resourceManager.remove(j)}async disposeResource(j){return this._resourceManager.disposeResource(j,this)}async disposeResources(){return this._resourceManager.disposeResources(this)}updateResource(j,D){let $=this.getResource(j),G=D($);return this._resourceManager.add(j,G),this._resourceManager.notifyChange(j,G,$),this}setResource(j,D){let $=this.tryGetResource(j);if(this._resourceManager.add(j,D),$!==void 0)this._resourceManager.notifyChange(j,D,$);return this}onResourceChange(j,D){return this._resourceManager.onResourceChange(j,D)}isResourceObserved(j){return this._resourceManager.isObserved(j)}getResourceKeys(){return this._resourceManager.getKeys()}resourceNeedsInitialization(j){return this._resourceManager.needsInitialization(j)}getEntity(j){return this._entityManager.getEntity(j)}getComponent(j,D){return this._entityManager.getComponent(j,D)}addComponent(j,D,$){this._entityManager.addComponent(j,D,$)}addComponents(j,D){this._entityManager.addComponents(j,D)}removeComponent(j,D){this._entityManager.removeComponent(j,D)}hasComponent(j,D){return this._entityManager.getComponent(j,D)!==void 0}spawn(j,D){let $=this._entityManager.createEntity();return this._entityManager.addComponents($.id,j),this._applyScreenScope($.id,D),$}_getActiveScopeHint(){return this._activeScopeHint}_applyScreenScope(j,D){let $=D?.scope!==void 0?D.scope:this._activeScopeHint;if($===null)return;let G=this._screenScopedEntities.get($)??new Set;G.add(j),this._screenScopedEntities.set($,G),this._entityScreenScope.set(j,$)}getEntitiesWithQuery(j,D=[],$,G){return this._entityManager.getEntitiesWithQuery(j,D,$,$?this._changeThreshold:void 0,G)}getSingleton(j,D=[]){let $=this._entityManager.getEntitiesWithQuery(j,D);if($.length===0)throw Error(`getSingleton: no entity matches query with=[${String(j)}] without=[${String(D)}]`);if($.length>1)throw Error(`getSingleton: expected 1 entity but found ${$.length} matching query with=[${String(j)}] without=[${String(D)}]`);let G=$[0];if(!G)throw Error("getSingleton: unexpected empty result");return G}tryGetSingleton(j,D=[]){let $=this._entityManager.getEntitiesWithQuery(j,D);if($.length===0)return;if($.length>1)throw Error(`tryGetSingleton: expected 0 or 1 entity but found ${$.length} matching query with=[${String(j)}] without=[${String(D)}]`);return $[0]}removeEntity(j,D){return this._entityManager.removeEntity(j,D)}spawnChild(j,D,$){let G=this._entityManager.spawnChild(j,D);return this._emitHierarchyChanged(G.id,null,j),this._applyScreenScope(G.id,$),G}setParent(j,D){let $=this._entityManager.getParent(j);return this._entityManager.setParent(j,D),this._emitHierarchyChanged(j,$,D),this}removeParent(j){let D=this._entityManager.getParent(j),$=this._entityManager.removeParent(j);if($)this._emitHierarchyChanged(j,D,null);return $}getParent(j){return this._entityManager.getParent(j)}getChildren(j){return this._entityManager.getChildren(j)}getChildAt(j,D){return this._entityManager.getChildAt(j,D)}getChildIndex(j,D){return this._entityManager.getChildIndex(j,D)}getAncestors(j){return this._entityManager.getAncestors(j)}getDescendants(j){return this._entityManager.getDescendants(j)}getRoot(j){return this._entityManager.getRoot(j)}getSiblings(j){return this._entityManager.getSiblings(j)}isDescendantOf(j,D){return this._entityManager.isDescendantOf(j,D)}isAncestorOf(j,D){return this._entityManager.isAncestorOf(j,D)}getRootEntities(){return this._entityManager.getRootEntities()}forEachInHierarchy(j,D){this._entityManager.forEachInHierarchy(j,D)}hierarchyIterator(j){return this._entityManager.hierarchyIterator(j)}_emitHierarchyChanged(j,D,$){this._eventBus.publish("hierarchyChanged",{entityId:j,oldParent:D,newParent:$})}get installedPlugins(){return Array.from(this._installedPlugins)}get entityManager(){return this._entityManager}get eventBus(){return this._finalizePendingBuilders(),this._eventBus}get commands(){return this._commandBuffer}get currentTick(){return this._currentTick}get changeThreshold(){return this._changeThreshold}enableDiagnostics(j){if(this._diagnosticsEnabled=j,!j)this._systemTimings.clear(),this._phaseTimings={preUpdate:0,fixedUpdate:0,update:0,postUpdate:0,render:0}}get diagnosticsEnabled(){return this._diagnosticsEnabled}get systemTimings(){return this._systemTimings}get phaseTimings(){return this._phaseTimings}get entityCount(){return this._entityManager.entityCount}mutateComponent(j,D,$){let G=this._entityManager.getComponent(j,D);if(G===void 0)throw Error(`Entity ${j} does not have component "${String(D)}"`);return $(G),this._entityManager.markChanged(j,D),G}markChanged(j,D){this._entityManager.markChanged(j,D)}registerDispose(j,D){this._entityManager.registerDispose(j,D)}registerRequired(j,D,$){if(String(j)===String(D))throw Error(`Cannot require a component to depend on itself: '${String(j)}'`);let G=this._requiredComponents.get(j)??[];if(G.some((J)=>J.component===D))throw Error(`Required component '${String(D)}' already registered for trigger '${String(j)}'`);this._checkRequiredCycle(j,D),G.push({component:D,factory:$}),this._requiredComponents.set(j,G)}_checkRequiredCycle(j,D){c(j,D,($)=>this._requiredComponents.get($))}onComponentAdded(j,D){return this._entityManager.onComponentAdded(j,D)}onComponentRemoved(j,D){return this._entityManager.onComponentRemoved(j,D)}addReactiveQuery(j,D){this._reactiveQueryManager.addQuery(j,D)}removeReactiveQuery(j){return this._reactiveQueryManager.removeQuery(j)}on(j,D){return this._eventBus.subscribe(j,D)}off(j,D){return this._eventBus.unsubscribe(j,D)}onPostUpdate(j){return this._postUpdateHooks.push(j),()=>{let D=this._postUpdateHooks.indexOf(j);if(D!==-1)this._postUpdateHooks.splice(D,1)}}requireAssetManager(){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager}getAsset(j){return this.requireAssetManager().get(j)}tryGetAsset(j){return this._assetManager?.tryGet(j)}getAssetHandle(j){return this.requireAssetManager().getHandle(j)}isAssetLoaded(j){return this._assetManager?.isLoaded(j)??!1}async loadAsset(j){return this.requireAssetManager().loadAsset(j)}async loadAssetGroup(j){return this.requireAssetManager().loadAssetGroup(j)}isAssetGroupLoaded(j){return this._assetManager?.isGroupLoaded(j)??!1}getAssetGroupProgress(j){return this._assetManager?.getGroupProgress(j)??0}requireScreenManager(){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager}async setScreen(j,D){return this.requireScreenManager().setScreen(j,D)}async pushScreen(j,D){return this.requireScreenManager().pushScreen(j,D)}async popScreen(){return this.requireScreenManager().popScreen()}getCurrentScreen(){return this._screenManager?.getCurrentScreen()??null}getScreenConfig(j){return this.requireScreenManager().getConfig(j)}tryGetScreenConfig(j){return this._screenManager?.tryGetConfig(j)??void 0}getScreenState(j){return this.requireScreenManager().getState(j)}tryGetScreenState(j){return this._screenManager?.tryGetState(j)??void 0}updateScreenState(j,D){if(typeof j==="string")this.requireScreenManager().updateState(D,j);else this.requireScreenManager().updateState(j)}isCurrentScreen(j){return this._screenManager?.isCurrent(j)??!1}isScreenActive(j){return this._screenManager?.isActive(j)??!1}getScreenStackDepth(){return this._screenManager?.getStackDepth()??0}onScreenEnter(j,D){let $=this._eventBus,G=(Z)=>{if(Z.screen!==j)return;D({config:Z.config,ecs:this})},J=$.subscribe("screenEnter",G),X=$.subscribe("screenPush",G);return()=>{J(),X()}}onScreenExit(j,D){return this._eventBus.subscribe("screenExit",(G)=>{if(G.screen!==j)return;D({ecs:this})})}_setAssetManager(j){this._assetManager=j;for(let[D,$]of this._pendingPluginAssets)this._assetManager.register(D,$);this._pendingPluginAssets=[]}_setScreenManager(j){this._screenManager=j;for(let[D,$]of this._pendingPluginScreens)this._screenManager.register(D,$);this._pendingPluginScreens=[]}_hasPendingPluginAssets(){return this._pendingPluginAssets.length>0}_hasPendingPluginScreens(){return this._pendingPluginScreens.length>0}_setFixedDt(j){this._fixedDt=j}_registerAsset(j,D){this._pendingPluginAssets.push([j,D])}_registerScreen(j,D){this._pendingPluginScreens.push([j,D])}installPlugin(j){return this._installPluginUnchecked(j)}_installPluginUnchecked(j){if(this._installedPlugins.has(j.id))return this;this._installedPlugins.add(j.id);let D=[];this._pluginCleanups.set(j.id,D);let $=(J)=>{D.push(J)},G=this._currentSystemDefaults;this._currentSystemDefaults=j.systemDefaults;try{j.install(this,$)}finally{this._currentSystemDefaults=G}return this}uninstallPlugin(j){if(!this._installedPlugins.has(j))return!1;let D=this._pluginCleanups.get(j);if(this._pluginCleanups.delete(j),this._installedPlugins.delete(j),D)for(let $=D.length-1;$>=0;$--){let G=D[$];if(!G)continue;try{G()}catch(J){console.warn(`Plugin '${j}' cleanup threw:`,J)}}return!0}dispose(){let j=Array.from(this._installedPlugins);for(let D=j.length-1;D>=0;D--){let $=j[D];if($!==void 0)this.uninstallPlugin($)}}pluginFactory(){return(j)=>E(j.id).install(j.install)}getHelpers(j){return j(this)}}function uj(j){return j}function lj(j,D){return{x:j,y:D}}function sj(){return{x:0,y:0}}function ij(j,D){return{x:j.x+D.x,y:j.y+D.y}}function cj(j,D){return{x:j.x-D.x,y:j.y-D.y}}function dj(j,D){return{x:j.x*D,y:j.y*D}}function yj(j){return{x:-j.x,y:-j.y}}function oj(j,D){return j.x*D.x+j.y*D.y}function rj(j,D){return j.x*D.y-j.y*D.x}function aj(j){return j.x*j.x+j.y*j.y}function nj(j){return Math.sqrt(j.x*j.x+j.y*j.y)}function tj(j){let D=Math.sqrt(j.x*j.x+j.y*j.y);if(D===0)return{x:0,y:0};return{x:j.x/D,y:j.y/D}}function ej(j,D){let $=j.x-D.x,G=j.y-D.y;return $*$+G*G}function j3(j,D){let $=j.x-D.x,G=j.y-D.y;return Math.sqrt($*$+G*G)}function D3(j,D,$=0.0000000001){return Math.abs(j.x-D.x)<=$&&Math.abs(j.y-D.y)<=$}function $3(j,D,$){return{x:j,y:D,z:$}}function G3(){return{x:0,y:0,z:0}}function J3(j,D){return{x:j.x+D.x,y:j.y+D.y,z:j.z+D.z}}function X3(j,D){return{x:j.x-D.x,y:j.y-D.y,z:j.z-D.z}}function Z3(j,D){return{x:j.x*D,y:j.y*D,z:j.z*D}}function W3(j){return{x:-j.x,y:-j.y,z:-j.z}}function Y3(j,D){return j.x*D.x+j.y*D.y+j.z*D.z}function F3(j,D){return{x:j.y*D.z-j.z*D.y,y:j.z*D.x-j.x*D.z,z:j.x*D.y-j.y*D.x}}function L3(j){return j.x*j.x+j.y*j.y+j.z*j.z}function _3(j){return Math.sqrt(j.x*j.x+j.y*j.y+j.z*j.z)}function A3(j){let D=Math.sqrt(j.x*j.x+j.y*j.y+j.z*j.z);if(D===0)return{x:0,y:0,z:0};return{x:j.x/D,y:j.y/D,z:j.z/D}}function B3(j,D){let $=j.x-D.x,G=j.y-D.y,J=j.z-D.z;return $*$+G*G+J*J}function O3(j,D){let $=j.x-D.x,G=j.y-D.y,J=j.z-D.z;return Math.sqrt($*$+G*G+J*J)}function Q3(j,D,$=0.0000000001){return Math.abs(j.x-D.x)<=$&&Math.abs(j.y-D.y)<=$&&Math.abs(j.z-D.z)<=$}var w3=V;export{G3 as vec3Zero,X3 as vec3Sub,Z3 as vec3Scale,A3 as vec3Normalize,W3 as vec3Negate,L3 as vec3LengthSq,_3 as vec3Length,Q3 as vec3Equals,Y3 as vec3Dot,B3 as vec3DistanceSq,O3 as vec3Distance,F3 as vec3Cross,J3 as vec3Add,$3 as vec3,sj as vec2Zero,cj as vec2Sub,dj as vec2Scale,tj as vec2Normalize,yj as vec2Negate,aj as vec2LengthSq,nj as vec2Length,D3 as vec2Equals,oj as vec2Dot,ej as vec2DistanceSq,j3 as vec2Distance,rj as vec2Cross,ij as vec2Add,lj as vec2,n as directValue,E as definePlugin,w3 as default,I as createScreenConfigurator,uj as createQueryDefinition,k as createAssetConfigurator,g as SystemBuilder,P as ScreenManager,z as AssetManager};
1
+ var $j=((j)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(j,{get:(D,$)=>(typeof require<"u"?require:D)[$]}):j)(function(j){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+j+'" is not supported')});class H{parentMap=new Map;childrenMap=new Map;_bfsQueue=[];setParent(j,D){if(j===D)throw Error(`Cannot set entity ${j} as its own parent`);if(this.wouldCreateCycle(j,D))throw Error("Cannot set parent: would create circular reference");let $=this.parentMap.get(j);if($!==void 0){let J=this.childrenMap.get($);if(J){let X=J.indexOf(j);if(X!==-1)J.splice(X,1)}}this.parentMap.set(j,D);let G=this.childrenMap.get(D);if(G)G.push(j);else this.childrenMap.set(D,[j]);return this}removeParent(j){let D=this.parentMap.get(j);if(D===void 0)return!1;let $=this.childrenMap.get(D);if($){let G=$.indexOf(j);if(G!==-1)$.splice(G,1)}return this.parentMap.delete(j),!0}getParent(j){return this.parentMap.get(j)??null}getChildren(j){let D=this.childrenMap.get(j);return D?[...D]:[]}getChildAt(j,D){if(D<0)return null;let $=this.childrenMap.get(j);if(!$||D>=$.length)return null;return $[D]??null}getChildIndex(j,D){let $=this.childrenMap.get(j);if(!$)return-1;return $.indexOf(D)}removeEntity(j){let D=this.parentMap.get(j)??null;if(D!==null){let J=this.childrenMap.get(D);if(J){let X=J.indexOf(j);if(X!==-1)J.splice(X,1)}}this.parentMap.delete(j);let $=this.childrenMap.get(j)??[],G=[...$];for(let J of $)this.parentMap.delete(J);return this.childrenMap.delete(j),{oldParent:D,orphanedChildren:G}}getAncestors(j){let D=[],$=this.parentMap.get(j);while($!==void 0)D.push($),$=this.parentMap.get($);return D}getDescendants(j){let D=[],$=this.childrenMap.get(j);if(!$)return D;let G=$.slice().reverse();while(G.length>0){let J=G.pop();D.push(J);let X=this.childrenMap.get(J);if(X)for(let Z=X.length-1;Z>=0;Z--)G.push(X[Z])}return D}getRoot(j){let D=j,$=this.parentMap.get(D);while($!==void 0)D=$,$=this.parentMap.get(D);return D}getSiblings(j){let D=this.parentMap.get(j);if(D===void 0)return[];let $=this.childrenMap.get(D);if(!$)return[];return $.filter((G)=>G!==j)}isDescendantOf(j,D){if(j===D)return!1;let $=this.parentMap.get(j);while($!==void 0){if($===D)return!0;$=this.parentMap.get($)}return!1}isAncestorOf(j,D){return this.isDescendantOf(D,j)}get hasHierarchy(){return this.childrenMap.size>0}getRootEntities(){let j=[];for(let D of this.childrenMap.keys())if(!this.parentMap.has(D))j.push(D);return j}wouldCreateCycle(j,D){let $=D;while($!==void 0){if($===j)return!0;$=this.parentMap.get($)}return!1}forEachInHierarchy(j,D){let $=D?.roots??this.getRootEntities(),G=this._bfsQueue;G.length=0;for(let J of $)G.push(J,-1,0);for(let J=0;J<G.length;J+=3){let X=G[J],Z=G[J+1],W=G[J+2];j(X,Z===-1?null:Z,W);let A=this.childrenMap.get(X);if(A){let L=W+1;for(let O of A)G.push(O,X,L)}}}*hierarchyIterator(j){let D=j?.roots??this.getRootEntities(),$=[];for(let G of D)$.push({entityId:G,parentId:null,depth:0});for(let G of $){yield G;let J=this.childrenMap.get(G.entityId);if(J)for(let X of J)$.push({entityId:X,parentId:G.entityId,depth:G.depth+1})}}}function R(j,D,$,G,J){let X=j.components;for(let Z of D)if(!(Z in X))return!1;if($){for(let Z of $)if(Z in X)return!1}if(G&&G.length>0){let Z=J.getParent(j.id);if(Z===null)return!1;let W=J.getEntity(Z);if(!W)return!1;let A=W.components;for(let L of G)if(!(L in A))return!1}return!0}function a(j,D,$){let G=j.length===0?"":[...j].map(String).sort().join(","),J=D.length===0?"":[...D].map(String).sort().join(","),X=$.length===0?"":[...$].map(String).sort().join(",");return`${G}|${J}|${X}`}class S{host;caches=new Map;byComp=new Map;byParentComp=new Map;constructor(j){this.host=j}getOrCreate(j,D,$){let G=a(j,D,$),J=this.caches.get(G);if(J)return J.members;let X={with:[...j],without:[...D],parentHas:[...$],members:new Map};this.caches.set(G,X);for(let Z of X.with)v(this.byComp,Z,X);for(let Z of X.without)v(this.byComp,Z,X);for(let Z of X.parentHas)v(this.byParentComp,Z,X);return this.populate(X),X.members}get cacheCount(){return this.caches.size}populate(j){let D=this.host,$=j.with;if($.length===0){for(let Z of D.allEntities())if(this.matches(Z,j))j.members.set(Z.id,Z);return}let G=$[0];if(G===void 0)return;let J=D.componentIndex(G)?.size??0;for(let Z=1;Z<$.length;Z++){let W=$[Z];if(W===void 0)continue;let A=D.componentIndex(W)?.size??0;if(A<J)G=W,J=A}let X=D.componentIndex(G);if(!X||X.size===0)return;for(let Z of X){let W=D.getEntity(Z);if(!W)continue;if(this.matches(W,j))j.members.set(Z,W)}}matches(j,D){return R(j,D.with,D.without,D.parentHas,this.host)}reeval(j,D){let $=this.host.getEntity(j);if(!$){D.members.delete(j);return}if(this.matches($,D))D.members.set(j,$);else D.members.delete(j)}onComponentChanged(j,D){let $=this.byComp.get(D);if($)for(let J of $)this.reeval(j,J);let G=this.byParentComp.get(D);if(G&&G.length>0){let J=this.host.getChildren(j);if(J.length>0)for(let X of G)for(let Z of J)this.reeval(Z,X)}}onParentChanged(j){for(let D of this.caches.values())if(D.parentHas.length>0)this.reeval(j,D)}onEntityRemoved(j){let D=!1;for(let G of this.caches.values())if(G.members.delete(j),G.parentHas.length>0)D=!0;if(!D)return;let $=this.host.getChildren(j);if($.length===0)return;for(let G of this.caches.values()){if(G.parentHas.length===0)continue;for(let J of $)G.members.delete(J)}}}function v(j,D,$){let G=j.get(D);if(G)G.push($);else j.set(D,[$])}function m(j,D,$){if(!j)return!1;for(let G of D)if((j.get(G)??-1)>$)return!0;return!1}class N{callbacks=[];_iterDepth=0;_pendingRemovals=[];add(j){this.callbacks.push(j)}remove(j){if(this._iterDepth>0){this._pendingRemovals.push(j);return}let D=this.callbacks.indexOf(j);if(D!==-1)this.callbacks.splice(D,1)}invoke(j){this._iterDepth++;let D=this.callbacks.length;for(let $=0;$<D;$++){let G=this.callbacks[$];if(G)G(j)}if(this._iterDepth--,this._iterDepth===0&&this._pendingRemovals.length>0){for(let $ of this._pendingRemovals){let G=this.callbacks.indexOf($);if(G!==-1)this.callbacks.splice(G,1)}this._pendingRemovals.length=0}}}class T{nextId=1;entities=new Map;componentIndices=new Map;addedCallbacks=new Map;removedCallbacks=new Map;hierarchyManager=new H;disposeCallbacks=new Map;changeSeqs=new Map;_changeSeq=0;_afterComponentAddedHooks=[];_afterEntityMutatedHooks=[];_afterComponentRemovedHooks=[];_beforeEntityRemovedHooks=[];_afterParentChangedHooks=[];_queryCache=new S({getEntity:(j)=>this.entities.get(j),getParent:(j)=>this.hierarchyManager.getParent(j),getChildren:(j)=>this.hierarchyManager.getChildren(j),allEntities:()=>this.entities.values(),componentIndex:(j)=>this.componentIndices.get(j)});_batchingDepth=0;_batchedEntityIds=new Set;_pendingBatchKeys=null;get entityCount(){return this.entities.size}createEntity(){let j=this.nextId++,D={id:j,components:{}};return this.entities.set(j,D),D}registerDispose(j,D){this.disposeCallbacks.set(j,D)}getDisposeCallbacks(){return this.disposeCallbacks}invokeDispose(j,D,$){let G=this.disposeCallbacks.get(j);if(!G)return;try{G({value:D,entityId:$})}catch(J){console.warn(`Component dispose callback for '${String(j)}' threw:`,J)}}addComponent(j,D,$){let G=this.entities.get(j);if(!G)throw Error(`Cannot add component '${String(D)}': Entity with ID ${j} does not exist`);let J=G.components[D];if(J!==void 0)this.invokeDispose(D,J,G.id);if(G.components[D]=$,!this.componentIndices.has(D))this.componentIndices.set(D,new Set);this.componentIndices.get(D)?.add(G.id);let X=this.addedCallbacks.get(D);if(X)X.invoke({value:$,entity:G});this._queryCache.onComponentChanged(G.id,D),this._batchingDepth++;for(let Z of this._afterComponentAddedHooks)Z(G.id,D);if(this._batchedEntityIds.add(G.id),this._batchingDepth--,this._batchingDepth===0){for(let Z of this._batchedEntityIds)for(let W of this._afterEntityMutatedHooks)W(Z);this._batchedEntityIds.clear()}return this}addComponents(j,D){let $=this.entities.get(j);if(!$)throw Error(`Cannot add components: Entity with ID ${j} does not exist`);let G=this._pendingBatchKeys;this._pendingBatchKeys=new Set(Object.keys(D)),this._batchingDepth++;for(let J in D)this.addComponent($.id,J,D[J]);if(this._batchingDepth--,this._pendingBatchKeys=G,this._batchingDepth===0){for(let J of this._batchedEntityIds)for(let X of this._afterEntityMutatedHooks)X(J);this._batchedEntityIds.clear()}return this}removeComponent(j,D){let $=this.entities.get(j);if(!$)throw Error(`Cannot remove component '${String(D)}': Entity with ID ${j} does not exist`);let G=$.components[D];if(G!==void 0)this.invokeDispose(D,G,$.id);delete $.components[D];let J=this.removedCallbacks.get(D);if(J&&G!==void 0)J.invoke({value:G,entity:$});if(this.componentIndices.get(D)?.delete($.id),G!==void 0){this._queryCache.onComponentChanged($.id,D);for(let X of this._afterComponentRemovedHooks)X($.id,D)}return this}getComponent(j,D){return this.entities.get(j)?.components[D]}getEntitiesWithQuery(j=[],D=[],$,G,J){return this.getEntitiesWithQueryInto([],j,D,$,G,J)}getEntitiesWithQueryInto(j,D=[],$=[],G,J,X){j.length=0;let Z=G!==void 0&&G.length>0&&J!==void 0,W=X!==void 0&&X.length>0;if(D.length===0&&$.length===0&&!W){if(!Z){for(let L of this.entities.values())j.push(L);return j}for(let L of this.entities.values()){if(!m(this.changeSeqs.get(L.id),G,J))continue;j.push(L)}return j}let A=this._queryCache.getOrCreate(D,$,X??[]);if(A.size===0)return j;if(Z){for(let L of A.values()){if(!m(this.changeSeqs.get(L.id),G,J))continue;j.push(L)}return j}for(let L of A.values())j.push(L);return j}get _queryCacheForTesting(){return this._queryCache}removeEntity(j,D){let $=this.entities.get(j);if(!$)return!1;if(D?.cascade??!0){let J=this.hierarchyManager.getDescendants($.id);for(let X=J.length-1;X>=0;X--){let Z=J[X];if(Z===void 0)continue;this._queryCache.onEntityRemoved(Z);for(let W of this._beforeEntityRemovedHooks)W(Z)}this._queryCache.onEntityRemoved($.id);for(let X of this._beforeEntityRemovedHooks)X($.id);for(let X=J.length-1;X>=0;X--){let Z=J[X];if(Z===void 0)continue;this.removeEntityInternal(Z)}}else{this._queryCache.onEntityRemoved($.id);for(let J of this._beforeEntityRemovedHooks)J($.id)}return this.removeEntityInternal($.id)}removeEntityInternal(j){let D=this.entities.get(j);if(!D)return!1;this.hierarchyManager.removeEntity(j);for(let $ of Object.keys(D.components)){let G=D.components[$];if(G!==void 0){this.invokeDispose($,G,D.id);let J=this.removedCallbacks.get($);if(J)J.invoke({value:G,entity:D})}this.componentIndices.get($)?.delete(D.id)}return this.changeSeqs.delete(D.id),this.entities.delete(D.id)}getEntity(j){return this.entities.get(j)}onComponentAdded(j,D){let $=D,G=this.addedCallbacks.get(j);if(!G)G=new N,this.addedCallbacks.set(j,G);return G.add($),()=>{this.addedCallbacks.get(j)?.remove($)}}onComponentRemoved(j,D){let $=D,G=this.removedCallbacks.get(j);if(!G)G=new N,this.removedCallbacks.set(j,G);return G.add($),()=>{this.removedCallbacks.get(j)?.remove($)}}onAfterComponentAdded(j){return this._afterComponentAddedHooks.push(j),()=>{let D=this._afterComponentAddedHooks.indexOf(j);if(D!==-1)this._afterComponentAddedHooks.splice(D,1)}}onAfterEntityMutated(j){return this._afterEntityMutatedHooks.push(j),()=>{let D=this._afterEntityMutatedHooks.indexOf(j);if(D!==-1)this._afterEntityMutatedHooks.splice(D,1)}}onAfterComponentRemoved(j){return this._afterComponentRemovedHooks.push(j),()=>{let D=this._afterComponentRemovedHooks.indexOf(j);if(D!==-1)this._afterComponentRemovedHooks.splice(D,1)}}onBeforeEntityRemoved(j){return this._beforeEntityRemovedHooks.push(j),()=>{let D=this._beforeEntityRemovedHooks.indexOf(j);if(D!==-1)this._beforeEntityRemovedHooks.splice(D,1)}}onAfterParentChanged(j){return this._afterParentChangedHooks.push(j),()=>{let D=this._afterParentChangedHooks.indexOf(j);if(D!==-1)this._afterParentChangedHooks.splice(D,1)}}get changeSeq(){return this._changeSeq}markChanged(j,D){let $=++this._changeSeq,G=this.changeSeqs.get(j);if(!G)G=new Map,this.changeSeqs.set(j,G);G.set(D,$)}getChangeSeq(j,D){return this.changeSeqs.get(j)?.get(D)??-1}spawnChild(j,D){let $=this.createEntity();return this.addComponents($.id,D),this.setParent($.id,j),$}setParent(j,D){this.hierarchyManager.setParent(j,D),this._queryCache.onParentChanged(j);for(let $ of this._afterParentChangedHooks)$(j);return this}removeParent(j){let D=this.hierarchyManager.removeParent(j);if(D){this._queryCache.onParentChanged(j);for(let $ of this._afterParentChangedHooks)$(j)}return D}getParent(j){return this.hierarchyManager.getParent(j)}getChildren(j){return this.hierarchyManager.getChildren(j)}getChildAt(j,D){return this.hierarchyManager.getChildAt(j,D)}getChildIndex(j,D){return this.hierarchyManager.getChildIndex(j,D)}getAncestors(j){return this.hierarchyManager.getAncestors(j)}getDescendants(j){return this.hierarchyManager.getDescendants(j)}getRoot(j){return this.hierarchyManager.getRoot(j)}getSiblings(j){return this.hierarchyManager.getSiblings(j)}isDescendantOf(j,D){return this.hierarchyManager.isDescendantOf(j,D)}isAncestorOf(j,D){return this.hierarchyManager.isAncestorOf(j,D)}get hasHierarchy(){return this.hierarchyManager.hasHierarchy}getRootEntities(){return this.hierarchyManager.getRootEntities()}forEachInHierarchy(j,D){this.hierarchyManager.forEachInHierarchy(j,D)}hierarchyIterator(j){return this.hierarchyManager.hierarchyIterator(j)}}class x{handlers=new Map;subscribe(j,D){return this.addHandler(j,D,!1)}once(j,D){return this.addHandler(j,D,!0)}unsubscribe(j,D){let $=this.handlers.get(j);if(!$)return!1;let G=$.findIndex((J)=>J.callback===D);if(G===-1)return!1;return $.splice(G,1),!0}addHandler(j,D,$){let G=this.handlers.get(j);if(!G)G=[],this.handlers.set(j,G);let J={callback:D,once:$};return G.push(J),()=>{let X=this.handlers.get(j);if(X){let Z=X.indexOf(J);if(Z!==-1)X.splice(Z,1)}}}publish(...[j,D]){let $=this.handlers.get(j);if(!$||$.length===0)return;let G=!1,J=$.length;for(let X=0;X<J&&X<$.length;X++){let Z=$[X];if(!Z)continue;if(Z.callback(D),Z.once)G=!0}if(G){for(let X=$.length-1;X>=0;X--)if($[X]?.once)$.splice(X,1)}}clear(){this.handlers.clear()}clearEvent(j){this.handlers.delete(j)}}var p=Symbol("resource-direct");function n(j){return{[p]:j}}function b(j){if(typeof j==="object"&&j!==null&&!Array.isArray(j))return{...j};return{$value:j}}function t(j,D){if(typeof j==="object"&&j!==null&&!Array.isArray(j)){let $=j;for(let G in D)if(!Object.is($[G],D[G]))return!0;return!1}return!Object.is(j,D.$value)}function e(j){return typeof j==="object"&&j!==null&&"factory"in j&&typeof j.factory==="function"}function jj(j){return typeof j==="object"&&j!==null&&p in j}function l(j,D){let $=[],G=new Set,J=new Set;function X(Z,W=[]){if(G.has(Z))return;if(J.has(Z))throw Error(`Circular resource dependency: ${[...W,Z].join(" -> ")}`);J.add(Z);for(let A of D(Z)){let L=j.find((O)=>O===A);if(L)X(L,[...W,Z])}J.delete(Z),G.add(Z),$.push(Z)}for(let Z of j)X(Z);return $}class w{resources=new Map;resourceFactories=new Map;resourceDependencies=new Map;resourceDisposers=new Map;initializedResourceKeys=new Set;_changeSubscribers=new Map;_observedSnapshots=new Map;add(j,D){let $=(G)=>{this.resources.set(j,G),this.initializedResourceKeys.add(j),this.resourceDependencies.set(j,[])};if(e(D)){if(this.resourceFactories.set(j,D.factory),this.resourceDependencies.set(j,D.dependsOn??[]),D.onDispose)this.resourceDisposers.set(j,D.onDispose)}else if(jj(D))$(D[p]);else if(typeof D==="function")this.resourceFactories.set(j,D),this.resourceDependencies.set(j,[]);else $(D);return this}tryGet(j,...D){if(!this.has(j))return;return this.get(j,...D)}get(j,...D){let $=this.resources.get(j);if($!==void 0)return $;let G=this.resourceFactories.get(j);if(G===void 0)throw Error(`Resource ${String(j)} not found`);let J=D[0],X=G(J);if(!(X instanceof Promise))this.resources.set(j,X),this.initializedResourceKeys.add(j);return X}has(j){return this.resources.has(j)||this.resourceFactories.has(j)}remove(j){let D=this.resources.delete(j),$=this.resourceFactories.delete(j);return this.resourceDependencies.delete(j),this.resourceDisposers.delete(j),this.initializedResourceKeys.delete(j),D||$}getKeys(){let j=new Set([...this.resources.keys(),...this.resourceFactories.keys()]);return Array.from(j)}needsInitialization(j){return this.resourceFactories.has(j)&&!this.initializedResourceKeys.has(j)}getPendingInitializationKeys(){return Array.from(this.resourceFactories.keys()).filter((j)=>!this.initializedResourceKeys.has(j))}async initializeResource(j,...D){if(!this.resourceFactories.has(j)||this.initializedResourceKeys.has(j))return;let $=this.resourceFactories.get(j);if(!$)return;let G=D[0],J=await $(G);this.resources.set(j,J),this.initializedResourceKeys.add(j),this.resourceFactories.delete(j)}async initializeResources(...j){let D=j.slice(1),$=D.length===0?this.getPendingInitializationKeys():D;if($.length===0)return;let G=l($,(J)=>[...this.resourceDependencies.get(J)??[]]);for(let J of G)await this.initializeResource(J,...j.slice(0,1))}getDependencies(j){return this.resourceDependencies.get(j)??[]}async disposeResource(j,...D){if(!this.resources.has(j)&&!this.resourceFactories.has(j))return!1;if(this.initializedResourceKeys.has(j)){let $=this.resourceDisposers.get(j),G=this.resources.get(j);if($&&G!==void 0){let J=D[0];await $(G,J)}}return this.resources.delete(j),this.resourceFactories.delete(j),this.resourceDependencies.delete(j),this.resourceDisposers.delete(j),this.initializedResourceKeys.delete(j),this._changeSubscribers.delete(j),!0}onResourceChange(j,D){let $=this._changeSubscribers.get(j),G=$??new Set;if(!$){this._changeSubscribers.set(j,G);let X=this.resources.get(j);this._observedSnapshots.set(j,b(X))}let J=D;return G.add(J),()=>{if(G.delete(J),G.size===0)this._changeSubscribers.delete(j),this._observedSnapshots.delete(j)}}notifyChange(j,D,$){if(Object.is(D,$))return;let G=this._changeSubscribers.get(j);if(!G||G.size===0)return;if(this._observedSnapshots.has(j))this._observedSnapshots.set(j,b(D));let J=[...G];for(let X of J)X(D,$)}isObserved(j){return this._observedSnapshots.has(j)}flushObserved(){if(this._observedSnapshots.size===0)return;for(let[j,D]of this._observedSnapshots){let $=this.resources.get(j);if(!t($,D))continue;let G="$value"in D?D.$value:D,J=b($),X=this._changeSubscribers.get(j);for(let Z of X)Z($,G);this._observedSnapshots.set(j,J)}}async disposeResources(...j){let D=Array.from(this.initializedResourceKeys);if(D.length===0)return;let $=l(D,(G)=>[...this.resourceDependencies.get(G)??[]]).reverse();for(let G of $)await this.disposeResource(G,...j)}}class q{queries=new Map;entityManager;_hasParentHasQueries=!1;constructor(j){this.entityManager=j}get hasParentHasQueries(){return this._hasParentHasQueries}addQuery(j,D){let $={definition:D,matchingEntities:new Set};if(this.queries.set(j,$),D.parentHas?.length)this._hasParentHasQueries=!0;let G=this.entityManager.getEntitiesWithQuery(D.with,D.without??[]);for(let J of G)if(this.entityMatchesQuery(J,$.definition))$.matchingEntities.add(J.id),$.definition.onEnter?.(J)}removeQuery(j){let D=this.queries.delete(j);if(D)this._recalcParentHasFlag();return D}entityMatchesQuery(j,D){return R(j,D.with,D.without,D.parentHas,this.entityManager)}_applyQueryTransition(j,D){let $=D.matchingEntities.has(j.id),G=this.entityMatchesQuery(j,D.definition);if(!$&&G)D.matchingEntities.add(j.id),D.definition.onEnter?.(j);else if($&&!G)D.matchingEntities.delete(j.id),D.definition.onExit?.(j.id)}onComponentAdded(j,D){for(let[,$]of this.queries)this._applyQueryTransition(j,$);if(this._hasParentHasQueries)this._recheckChildren(j.id)}onComponentRemoved(j,D){for(let[,$]of this.queries)this._applyQueryTransition(j,$);if(this._hasParentHasQueries)this._recheckChildren(j.id)}onEntityRemoved(j){for(let[D,$]of this.queries)if($.matchingEntities.has(j))$.matchingEntities.delete(j),$.definition.onExit?.(j)}recheckEntity(j){for(let[,D]of this.queries)this._applyQueryTransition(j,D)}recheckEntityAndChildren(j){if(this.recheckEntity(j),this._hasParentHasQueries)this._recheckChildren(j.id)}_recheckChildren(j){let D=this.entityManager.getChildren(j);for(let $ of D){let G=this.entityManager.getEntity($);if(G)this.recheckEntity(G)}}_recalcParentHasFlag(){this._hasParentHasQueries=!1;for(let[,j]of this.queries)if(j.definition.parentHas?.length){this._hasParentHasQueries=!0;return}}}class C{parent;commands=[];constructor(j){this.parent=j}removeEntity(j,D){this.commands.push(($)=>{$.removeEntity(j,D)})}addComponent(j,D,$){this.commands.push((G)=>{G.addComponent(j,D,$)})}removeComponent(j,D){this.commands.push(($)=>{$.removeComponent(j,D)})}spawn(j,D){let $=this._resolveScope(D);this.commands.push((G)=>{G.spawn(j,$)})}spawnChild(j,D,$){let G=this._resolveScope($);this.commands.push((J)=>{J.spawnChild(j,D,G)})}_resolveScope(j){if(j?.scope!==void 0)return j;let D=this.parent?._getActiveScopeHint();if(!D)return j;return{scope:D}}addComponents(j,D){this.commands.push(($)=>{$.addComponents(j,D)})}setParent(j,D){this.commands.push(($)=>{$.setParent(j,D)})}mutateComponent(j,D,$){this.commands.push((G)=>{G.mutateComponent(j,D,$)})}markChanged(j,D){this.commands.push(($)=>{$.markChanged(j,D)})}removeParent(j){this.commands.push((D)=>{D.removeParent(j)})}playback(j){for(let D of this.commands)try{D(j)}catch($){console.warn("CommandBuffer: Command failed during playback:",$)}this.commands.length=0}clear(){this.commands.length=0}get length(){return this.commands.length}}class s{_id;constructor(j){this._id=j}_systemDefaults;setSystemDefaults(j){return this._systemDefaults=j,this}withComponentTypes(){return this}withEventTypes(){return this}withResourceTypes(){return this}withAssetTypes(){return this}withScreenTypes(){return this}withLabels(){return this}withGroups(){return this}withAssetGroupNames(){return this}withReactiveQueryNames(){return this}requires(){return this}install(j){return{id:this._id,install:j,...this._systemDefaults?{systemDefaults:this._systemDefaults}:{}}}}function E(j){return new s(j)}var i="__each";class g{_label;queries={};singletons={};processFunction;detachFunction;initializeFunction;eventHandlers;_priority=0;_phase="update";_groups=[];_inScreens;_excludeScreens;_requiredAssets;_runWhenEmpty=!1;_entityEnterHandlers={};_resourceKeys;constructor(j,D){this._label=j;if(D){if(D.phase!==void 0)this._phase=D.phase;if(D.priority!==void 0)this._priority=D.priority;if(D.inScreens!==void 0)this._inScreens=D.inScreens;if(D.excludeScreens!==void 0)this._excludeScreens=D.excludeScreens}}get label(){return this._label}_createSystemObject(){let j={label:this._label,entityQueries:this.queries,priority:this._priority,phase:this._phase};if(Object.keys(this.singletons).length>0)j.entitySingletons=this.singletons;if(this.processFunction)j.process=this.processFunction;if(this.detachFunction)j.onDetach=this.detachFunction;if(this.initializeFunction)j.onInitialize=this.initializeFunction;if(this.eventHandlers)j.eventHandlers=this.eventHandlers;if(this._groups.length>0)j.groups=[...this._groups];if(this._inScreens)j.inScreens=this._inScreens;if(this._excludeScreens)j.excludeScreens=this._excludeScreens;if(this._requiredAssets)j.requiredAssets=this._requiredAssets;if(this._runWhenEmpty)j.runWhenEmpty=!0;if(Object.keys(this._entityEnterHandlers).length>0)j.onEntityEnter={...this._entityEnterHandlers};return j}setPriority(j){return this._priority=j,this}inPhase(j){return this._phase=j,this}inGroup(j){if(!this._groups.includes(j))this._groups.push(j);return this}inScreens(j){return this._inScreens=[...j],this}excludeScreens(j){return this._excludeScreens=[...j],this}requiresAssets(j){return this._requiredAssets=[...j],this}runWhenEmpty(){return this._runWhenEmpty=!0,this}withResources(j){return this._resourceKeys=[...j],this}addQuery(j,D){let $=this;return $.queries={...this.queries,[j]:D},$}addSingleton(j,D){let $=this;return $.singletons={...this.singletons,[j]:D},$}setProcess(j){return this.processFunction=this._wrapWithResources(j),this}_wrapWithResources(j){if(!this._resourceKeys?.length)return j;let D=this._resourceKeys,$={},G=!1;return(J)=>{for(let X of D)if(!G||J.ecs.isResourceObserved(X))$[X]=J.ecs.getResource(X);G=!0,J.resources=$,j(J)}}setProcessEach(j,D){let $=this;if(Object.keys($.queries).length>0||Object.keys($.singletons).length>0||$.processFunction!==void 0)throw Error("setProcessEach requires a SystemBuilder with no prior queries, singletons, or process function. Use addQuery + setProcess for multi-query systems.");$.queries.__each=j;let G={entity:void 0,dt:0,ecs:void 0,resources:void 0},J=j.mutates&&j.mutates.length>0?j.mutates:void 0,X=(Z)=>{let W=Z,A=W.queries.__each;if(!A)return;G.dt=W.dt,G.ecs=W.ecs,G.resources=W.resources;for(let L=0;L<A.length;L++){let O=A[L];if(!O)continue;G.entity=O;let _=D(G);if(J===void 0||_===!1)continue;for(let Y=0;Y<J.length;Y++){let F=J[Y];if(F!==void 0)W.ecs.markChanged(O.id,F)}}};return $.processFunction=$._wrapWithResources(X),this}setOnEntityEnter(j,D){return this._entityEnterHandlers[j]=D,this}setOnDetach(j){return this.detachFunction=j,this}setOnInitialize(j){return this.initializeFunction=j,this}setEventHandlers(j){return this.eventHandlers=j,this}}function c(j,D,$){let G=new Set,J=[D];while(J.length>0){let X=J.pop();if(X===void 0)break;if(X===j)throw Error(`Circular required component dependency: '${String(j)}' -> '${String(D)}' -> ... -> '${String(j)}'`);if(G.has(X))continue;G.add(X);let Z=$(X);if(Z)for(let W of Z)J.push(W.component)}}var d="0.16.3";class z{assets=new Map;groups=new Map;eventBus=null;setEventBus(j){this.eventBus=j}register(j,D){if(this.assets.set(j,{definition:D,status:"pending"}),D.group){let $=this.groups.get(D.group)??new Set;$.add(j),this.groups.set(D.group,$)}}async loadEagerAssets(){let j=[];for(let[D,$]of this.assets)if($.definition.eager&&$.status==="pending")j.push(D);await Promise.all(j.map((D)=>this.loadAsset(D)))}async loadAsset(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);if(D.status==="loaded"&&D.value!==void 0)return D.value;if(D.status==="loading"&&D.loadPromise)return D.loadPromise;if(D.status==="failed")D.status="pending";D.status="loading",D.loadPromise=D.definition.loader();try{let $=await D.loadPromise;return D.value=$,D.status="loaded",D.loadPromise=void 0,this.eventBus?.publish("assetLoaded",{key:j}),this.checkGroupProgress(D.definition.group),$}catch($){let G=$ instanceof Error?$:Error(String($));throw D.status="failed",D.error=G,D.loadPromise=void 0,this.eventBus?.publish("assetFailed",{key:j,error:G}),G}}async loadAssetGroup(j){let D=this.groups.get(j);if(!D||D.size===0)throw Error(`Asset group '${j}' not found or empty`);await Promise.all(Array.from(D).map(($)=>this.loadAsset($)))}get(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);if(D.status!=="loaded"||D.value===void 0)throw Error(`Asset '${String(j)}' is not loaded (status: ${D.status})`);return D.value}tryGet(j){let D=this.assets.get(j);if(!D||D.status!=="loaded")return;return D.value}getHandle(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);let $=this;return{get status(){return D.status},get isLoaded(){return D.status==="loaded"},get(){return $.get(j)},tryGet(){return $.tryGet(j)}}}getStatus(j){let D=this.assets.get(j);if(!D)throw Error(`Asset '${String(j)}' not found`);return D.status}isLoaded(j){return this.assets.get(j)?.status==="loaded"}isGroupLoaded(j){let D=this.groups.get(j);if(!D||D.size===0)return!1;for(let $ of D){let G=this.assets.get($);if(!G||G.status!=="loaded")return!1}return!0}getGroupProgress(j){return this.getGroupProgressDetails(j).progress}getGroupProgressDetails(j){let D=this.groups.get(j);if(!D||D.size===0)return{loaded:0,total:0,progress:0};let $=0;for(let J of D)if(this.assets.get(J)?.status==="loaded")$++;let G=D.size;return{loaded:$,total:G,progress:$/G}}checkGroupProgress(j){if(!j||!this.eventBus)return;let D=j,$=this.getGroupProgressDetails(D);if(this.eventBus.publish("assetGroupProgress",{group:D,...$}),$.loaded===$.total)this.eventBus.publish("assetGroupLoaded",{group:D})}createResource(){let j=this;return{getStatus(D){return j.getStatus(D)},isLoaded(D){return j.isLoaded(D)},isGroupLoaded(D){return j.isGroupLoaded(D)},getGroupProgress(D){return j.getGroupProgress(D)},get(D){return j.get(D)},tryGet(D){return j.tryGet(D)},getHandle(D){return j.getHandle(D)}}}getKeys(){return Array.from(this.assets.keys())}getGroupNames(){return Array.from(this.groups.keys())}getGroupKeys(j){let D=this.groups.get(j);return D?Array.from(D):[]}}class y{manager;constructor(j){this.manager=j}add(j,D){return this.manager.register(j,{loader:D,eager:!0}),this}addWithConfig(j,D){return this.manager.register(j,D),this}addGroup(j,D){for(let[$,G]of Object.entries(D))this.manager.register($,{loader:G,eager:!1,group:j});return this}getManager(){return this.manager}}function k(j){return new y(j??new z)}class P{screens=new Map;currentScreen=null;screenStack=[];eventBus=null;assetManager=null;ecs=null;setDependencies(j,D,$){this.eventBus=j,this.assetManager=D,this.ecs=$}requireEcs(){if(!this.ecs)throw Error("ScreenManager: dependencies not set. Call setDependencies() first.");return this.ecs}register(j,D){this.screens.set(j,{definition:D})}async setScreen(j,D){let $=this.screens.get(j);if(!$)throw Error(`Screen '${String(j)}' not found`);await this.verifyRequiredAssets($.definition.requiredAssets,$.definition.requiredAssetGroups);while(this.screenStack.length>0){let J=this.screenStack.pop();if(J)await this.exitScreen(J.name)}if(this.currentScreen)await this.exitScreen(this.currentScreen.name);let G=$.definition.initialState(D);this.currentScreen={name:j,config:D,state:G},await $.definition.onEnter?.({config:D,ecs:this.requireEcs()}),this.eventBus?.publish("screenEnter",{screen:j,config:D})}async pushScreen(j,D){let $=this.screens.get(j);if(!$)throw Error(`Screen '${String(j)}' not found`);if(await this.verifyRequiredAssets($.definition.requiredAssets,$.definition.requiredAssetGroups),this.currentScreen)this.screenStack.push(this.currentScreen);let G=$.definition.initialState(D);this.currentScreen={name:j,config:D,state:G},await $.definition.onEnter?.({config:D,ecs:this.requireEcs()}),this.eventBus?.publish("screenPush",{screen:j,config:D})}async popScreen(){if(this.screenStack.length===0)throw Error("Cannot pop screen: stack is empty");if(this.currentScreen)await this.exitScreen(this.currentScreen.name),this.eventBus?.publish("screenPop",{screen:this.currentScreen.name});this.currentScreen=this.screenStack.pop()??null}async exitScreen(j){let D=this.screens.get(j);if(D?.definition.onExit)await D.definition.onExit(this.requireEcs());this.eventBus?.publish("screenExit",{screen:j})}async verifyRequiredAssets(j,D){if(!this.assetManager)return;if(j){for(let $ of j)if(!this.assetManager.isLoaded($))await this.assetManager.loadAsset($)}if(D){for(let $ of D)if(!this.assetManager.isGroupLoaded($))await this.assetManager.loadAssetGroup($)}}getCurrentScreen(){return this.currentScreen?.name??null}getConfig(j){if(!this.currentScreen)throw Error("No current screen");if(j!==void 0&&this.currentScreen.name!==j)throw Error(`Expected current screen '${String(j)}', but current is '${String(this.currentScreen.name)}'`);return this.currentScreen.config}tryGetConfig(j){if(!this.currentScreen)return;if(j!==void 0&&this.currentScreen.name!==j)return;return this.currentScreen.config}getState(j){if(!this.currentScreen)throw Error("No current screen");if(j!==void 0&&this.currentScreen.name!==j)throw Error(`Expected current screen '${String(j)}', but current is '${String(this.currentScreen.name)}'`);return this.currentScreen.state}tryGetState(j){if(!this.currentScreen)return;if(j!==void 0&&this.currentScreen.name!==j)return;return this.currentScreen.state}updateState(j,D){if(!this.currentScreen)throw Error("No current screen");if(D!==void 0&&this.currentScreen.name!==D)throw Error(`Expected current screen '${String(D)}', but current is '${String(this.currentScreen.name)}'`);let $=typeof j==="function"?j(this.currentScreen.state):j;this.currentScreen.state={...this.currentScreen.state,...$}}getStackDepth(){return this.screenStack.length}isOverlay(){return this.screenStack.length>0}isActive(j){if(this.currentScreen?.name===j)return!0;return this.screenStack.some((D)=>D.name===j)}isCurrent(j){return this.currentScreen?.name===j}createResource(){let j=this;return{get current(){return j.getCurrentScreen()},get config(){return j.tryGetConfig()??null},get state(){return j.tryGetState()??null},set state(D){if(j.currentScreen&&D!==null)j.currentScreen.state=D},get stack(){return j.screenStack},get isOverlay(){return j.isOverlay()},get stackDepth(){return j.getStackDepth()},isActive(D){return j.isActive(D)},isCurrent(D){return j.isCurrent(D)}}}getScreenNames(){return Array.from(this.screens.keys())}hasScreen(j){return this.screens.has(j)}}class o{manager;constructor(j){this.manager=j}add(j,D){return this.manager.register(j,D),this}getManager(){return this.manager}}function I(j){return new o(j??new P)}class h{assetConfigurator=null;screenConfigurator=null;pendingResources=[];pendingDisposeCallbacks=[];pendingRequiredComponents=[];pendingPlugins=[];_fixedDt=null;constructor(){}withPlugin(j){return this.pendingPlugins.push(j),this}withComponentTypes(){return this}withEventTypes(){return this}withResourceTypes(){return this}withResource(j,D){return this.pendingResources.push({key:j,value:D}),this}withDispose(j,D){return this.pendingDisposeCallbacks.push({key:j,callback:D}),this}withRequired(j,D,$){return this.pendingRequiredComponents.push({trigger:j,required:D,factory:$}),this}withAssets(j){let D=k();return j(D),this.assetConfigurator=D,this}withScreens(j){let D=I();return j(D),this.screenConfigurator=D,this}withFixedTimestep(j){return this._fixedDt=j,this}withReactiveQueryNames(){return this}pluginFactory(){return(j)=>E(j.id).install(j.install)}build(){let j=new V;for(let D of this.pendingPlugins)j._installPluginUnchecked(D);for(let{key:D,value:$}of this.pendingResources)j.addResource(D,$);for(let{key:D,callback:$}of this.pendingDisposeCallbacks)j.registerDispose(D,$);for(let{trigger:D,required:$,factory:G}of this.pendingRequiredComponents)j.registerRequired(D,$,G);if(this.assetConfigurator)j._setAssetManager(this.assetConfigurator.getManager());else if(j._hasPendingPluginAssets())j._setAssetManager(new z);if(this.screenConfigurator)j._setScreenManager(this.screenConfigurator.getManager());else if(j._hasPendingPluginScreens())j._setScreenManager(new P);if(this._fixedDt!==null)j._setFixedDt(this._fixedDt);return j}}var r=["preUpdate","fixedUpdate","update","postUpdate","render"];class V{static VERSION=d;_entityManager;_eventBus;_resourceManager;_commandBuffer;_systems=[];_phaseSystems={preUpdate:[],fixedUpdate:[],update:[],postUpdate:[],render:[]};_installedPlugins=new Set;_pluginCleanups=new Map;_currentSystemDefaults;_screenScopedEntities=new Map;_entityScreenScope=new Map;_activeScopeHint=null;_disabledGroups=new Set;_assetManager=null;_screenManager=null;_reactiveQueryManager;_postUpdateHooks=[];_currentTick=0;_systemLastSeqs=new Map;_changeThreshold=0;_fixedDt=0.016666666666666666;_fixedAccumulator=0;_interpolationAlpha=0;_maxFixedSteps=8;_requiredComponents=new Map;_pendingPluginAssets=[];_pendingPluginScreens=[];_diagnosticsEnabled=!1;_systemTimings=new Map;_phaseTimings={preUpdate:0,fixedUpdate:0,update:0,postUpdate:0,render:0};_entityEnterTracking=new Map;_entityEnterFrameSet=new Set;_systemContexts=new WeakMap;_singletonScratch=[];_pendingFinalizers=[];_batchingRegistrations=!1;_initializeFired=!1;_systemsInitialized=new WeakSet;constructor(){this._entityManager=new T,this._eventBus=new x,this._resourceManager=new w,this._reactiveQueryManager=new q(this._entityManager),this._commandBuffer=new C(this),this._subscribeLifecycleHooks()}_subscribeLifecycleHooks(){this._entityManager.onAfterComponentAdded((j,D)=>{this._entityManager.markChanged(j,D);let $=this._requiredComponents.get(D);if($){let G=this._entityManager.getEntity(j);if(G){let J=G.components[D];for(let{component:X,factory:Z}of $){if(this._entityManager._pendingBatchKeys?.has(X))continue;if(!(X in G.components))this._entityManager.addComponent(j,X,Z(J))}}}}),this._entityManager.onAfterEntityMutated((j)=>{let D=this._entityManager.getEntity(j);if(D)this._reactiveQueryManager.recheckEntityAndChildren(D)}),this._entityManager.onAfterComponentRemoved((j,D)=>{let $=this._entityManager.getEntity(j);if($)this._reactiveQueryManager.onComponentRemoved($,D)}),this._entityManager.onBeforeEntityRemoved((j)=>{this._reactiveQueryManager.onEntityRemoved(j);let D=this._entityScreenScope.get(j);if(D!==void 0)this._entityScreenScope.delete(j),this._screenScopedEntities.get(D)?.delete(j)}),this._entityManager.onAfterParentChanged((j)=>{if(this._reactiveQueryManager.hasParentHasQueries){let D=this._entityManager.getEntity(j);if(D)this._reactiveQueryManager.recheckEntity(D)}})}static create(){return new h}addSystem(j){let D=new g(j,this._currentSystemDefaults);return this._pendingFinalizers.push(()=>{this._registerSystem(D._createSystemObject())}),D}_finalizePendingBuilders(){if(this._pendingFinalizers.length===0)return;this._batchingRegistrations=!0;while(this._pendingFinalizers.length>0){let j=this._pendingFinalizers;this._pendingFinalizers=[];for(let D of j)D()}this._batchingRegistrations=!1,this._rebuildPhaseSystems()}update(j){this._finalizePendingBuilders();let D=this._screenManager?.getCurrentScreen()??null,$=this._diagnosticsEnabled;this._runPhase("preUpdate",j,D,$);let G=$?performance.now():0;this._fixedAccumulator+=j;let J=0;while(this._fixedAccumulator>=this._fixedDt&&J<this._maxFixedSteps)this._executePhase(this._phaseSystems.fixedUpdate,this._fixedDt,D),this._commandBuffer.playback(this),this._fixedAccumulator-=this._fixedDt,J++;if(this._fixedAccumulator>=this._fixedDt)this._fixedAccumulator=0;if($)this._phaseTimings.fixedUpdate=performance.now()-G;this._interpolationAlpha=this._fixedAccumulator/this._fixedDt,this._runPhase("update",j,D,$),this._runPhase("postUpdate",j,D,$);for(let X of this._postUpdateHooks)X({ecs:this,dt:j});this._runPhase("render",j,D,$),this._resourceManager.flushObserved(),this._changeThreshold=this._entityManager.changeSeq,this._currentTick++}_executePhase(j,D,$){for(let G of j){if(!G.process&&!G.onEntityEnter)continue;if(G.groups?.length){let _=!1;for(let Y of G.groups)if(this._disabledGroups.has(Y)){_=!0;break}if(_)continue}if(G.inScreens?.length){if($===null||!G.inScreens.includes($))continue}if(G.excludeScreens?.length){if($!==null&&G.excludeScreens.includes($))continue}if(G.requiredAssets?.length&&this._assetManager){let _=!0;for(let Y of G.requiredAssets)if(!this._assetManager.isLoaded(Y)){_=!1;break}if(!_)continue}let J=this._systemLastSeqs.get(G)??0;this._changeThreshold=J;let X=this._systemContexts.get(G);if(!X)X={queries:{},dt:0,ecs:this},this._systemContexts.set(G,X);X.dt=D;let Z=X.queries,W=!1,A=!1;if(G.entityQueries)for(let _ in G.entityQueries){A=!0;let Y=G.entityQueries[_];if(Y){let Q=Z[_]??(Z[_]=[]);if(this._entityManager.getEntitiesWithQueryInto(Q,Y.with,Y.without||[],Y.changed,Y.changed?this._changeThreshold:void 0,Y.parentHas),Q.length)W=!0}}if(G.entitySingletons){let _=this._singletonScratch;for(let Y in G.entitySingletons){A=!0;let F=G.entitySingletons[Y];if(F){if(this._entityManager.getEntitiesWithQueryInto(_,F.with,F.without||[],F.changed,F.changed?this._changeThreshold:void 0,F.parentHas),Z[Y]=_[0],_.length)W=!0}}}let L=this._entityEnterTracking.get(G);if(L&&G.onEntityEnter)for(let _ in G.onEntityEnter){let Y=Z[_],F=L.get(_);if(!Y||!F)continue;let Q=G.onEntityEnter[_];if(!Q)continue;let K=this._entityEnterFrameSet;K.clear();for(let B of Y)if(K.add(B.id),!F.has(B.id))F.add(B.id),Q({entity:B,ecs:this});for(let B of F)if(!K.has(B))F.delete(B)}if(G.process){if(W||G.runWhenEmpty||!A){let Y=this._activeScopeHint;this._activeScopeHint=G.inScreens?.length&&$!==null?$:null;let F=this._diagnosticsEnabled?performance.now():0;try{G.process(X)}finally{if(this._activeScopeHint=Y,this._diagnosticsEnabled)this._systemTimings.set(G.label,performance.now()-F)}}}let O=G._autoMarkPairs;if(O){let _=this._entityManager;for(let Y=0;Y<O.length;Y++){let F=O[Y];if(!F)continue;let Q=F.mutates,K=Q.length;if(F.kind==="list"){let B=Z[F.queryName];if(!B)continue;for(let U=0;U<B.length;U++){let M=B[U];if(!M)continue;for(let f=0;f<K;f++){let u=Q[f];if(u!==void 0)_.markChanged(M.id,u)}}}else{let B=Z[F.queryName];if(!B)continue;for(let U=0;U<K;U++){let M=Q[U];if(M!==void 0)_.markChanged(B.id,M)}}}}this._systemLastSeqs.set(G,this._entityManager.changeSeq)}}_runPhase(j,D,$,G){if(G){let J=performance.now();this._executePhase(this._phaseSystems[j],D,$),this._phaseTimings[j]=performance.now()-J}else this._executePhase(this._phaseSystems[j],D,$);this._commandBuffer.playback(this)}async initialize(){if(this._finalizePendingBuilders(),await this.initializeResources(),this._assetManager)this._assetManager.setEventBus(this._eventBus),await this._assetManager.loadEagerAssets(),this._resourceManager.add("$assets",this._assetManager.createResource());if(this._screenManager){let j=this._eventBus;this._screenManager.setDependencies(j,this._assetManager,this),this._resourceManager.add("$screen",this._screenManager.createResource()),j.subscribe("screenExit",({screen:D})=>{let $=this._screenScopedEntities.get(D);if(!$||$.size===0)return;this._screenScopedEntities.delete(D);for(let G of Array.from($))this._entityScreenScope.delete(G),this.removeEntity(G)})}for(let j of this._systems){if(this._systemsInitialized.has(j))continue;this._systemsInitialized.add(j),await j.onInitialize?.(this)}this._initializeFired=!0}async initializeResources(...j){await this._resourceManager.initializeResources(this,...j)}_rebuildPhaseSystems(){for(let j of r)this._phaseSystems[j]=[];for(let j of this._systems){let D=j.phase??"update";this._phaseSystems[D].push(j)}for(let j of r)this._phaseSystems[j].sort((D,$)=>{let G=D.priority??0;return($.priority??0)-G})}updateSystemPriority(j,D){this._finalizePendingBuilders();let $=this._systems.find((G)=>G.label===j);if(!$)return!1;return $.priority=D,this._rebuildPhaseSystems(),!0}updateSystemPhase(j,D){this._finalizePendingBuilders();let $=this._systems.find((G)=>G.label===j);if(!$)return!1;return $.phase=D,this._rebuildPhaseSystems(),!0}get interpolationAlpha(){return this._interpolationAlpha}get fixedDt(){return this._fixedDt}disableSystemGroup(j){this._disabledGroups.add(j)}enableSystemGroup(j){this._disabledGroups.delete(j)}isSystemGroupEnabled(j){return!this._disabledGroups.has(j)}getSystemsInGroup(j){return this._finalizePendingBuilders(),this._systems.filter((D)=>D.groups?.includes(j)).map((D)=>D.label)}removeSystem(j){this._finalizePendingBuilders();let D=this._systems.findIndex((G)=>G.label===j);if(D===-1)return!1;let $=this._systems[D];if(!$)return!1;if($.onDetach)$.onDetach(this);return this._systems.splice(D,1),this._systemLastSeqs.delete($),this._entityEnterTracking.delete($),this._systemsInitialized.delete($),this._rebuildPhaseSystems(),!0}_registerSystem(j){if(this._systems.push(j),this._systemLastSeqs.set(j,this._changeThreshold),!this._batchingRegistrations)this._rebuildPhaseSystems();let D=[];if(j.entityQueries)for(let $ in j.entityQueries){if($===i)continue;let J=j.entityQueries[$]?.mutates;if(J&&J.length>0)D.push({queryName:$,mutates:J,kind:"list"})}if(j.entitySingletons)for(let $ in j.entitySingletons){let J=j.entitySingletons[$]?.mutates;if(J&&J.length>0)D.push({queryName:$,mutates:J,kind:"singleton"})}if(j._autoMarkPairs=D.length>0?D:null,j.onEntityEnter){let $=new Map;for(let G in j.onEntityEnter)$.set(G,new Set);this._entityEnterTracking.set(j,$)}if(j.eventHandlers)for(let $ in j.eventHandlers){let G=j.eventHandlers[$];if(G)this._eventBus.subscribe($,(J)=>{G({data:J,ecs:this})})}if(this._initializeFired&&!this._systemsInitialized.has(j)){this._systemsInitialized.add(j);let $=j.onInitialize?.(this);if($ instanceof Promise)$.catch((G)=>{console.error(`onInitialize for system "${j.label}" rejected:`,G)})}}hasResource(j){return this._resourceManager.has(j)}getResource(j){if(!this._resourceManager.has(j))throw Error(`Resource '${String(j)}' not found. Available resources: [${this.getResourceKeys().map((D)=>String(D)).join(", ")}]`);return this._resourceManager.get(j,this)}tryGetResource(j){let D=j;if(!this._resourceManager.has(D))return;return this._resourceManager.get(D,this)}addResource(j,D){return this._resourceManager.add(j,D),this}removeResource(j){return this._resourceManager.remove(j)}async disposeResource(j){return this._resourceManager.disposeResource(j,this)}async disposeResources(){return this._resourceManager.disposeResources(this)}updateResource(j,D){let $=this.getResource(j),G=D($);return this._resourceManager.add(j,G),this._resourceManager.notifyChange(j,G,$),this}setResource(j,D){let $=this.tryGetResource(j);if(this._resourceManager.add(j,D),$!==void 0)this._resourceManager.notifyChange(j,D,$);return this}onResourceChange(j,D){return this._resourceManager.onResourceChange(j,D)}isResourceObserved(j){return this._resourceManager.isObserved(j)}getResourceKeys(){return this._resourceManager.getKeys()}resourceNeedsInitialization(j){return this._resourceManager.needsInitialization(j)}getEntity(j){return this._entityManager.getEntity(j)}getComponent(j,D){return this._entityManager.getComponent(j,D)}addComponent(j,D,$){this._entityManager.addComponent(j,D,$)}addComponents(j,D){this._entityManager.addComponents(j,D)}removeComponent(j,D){this._entityManager.removeComponent(j,D)}hasComponent(j,D){return this._entityManager.getComponent(j,D)!==void 0}spawn(j,D){let $=this._entityManager.createEntity();return this._entityManager.addComponents($.id,j),this._applyScreenScope($.id,D),$}_getActiveScopeHint(){return this._activeScopeHint}_applyScreenScope(j,D){let $=D?.scope!==void 0?D.scope:this._activeScopeHint;if($===null)return;let G=this._screenScopedEntities.get($)??new Set;G.add(j),this._screenScopedEntities.set($,G),this._entityScreenScope.set(j,$)}getEntitiesWithQuery(j,D=[],$,G){return this._entityManager.getEntitiesWithQuery(j,D,$,$?this._changeThreshold:void 0,G)}getSingleton(j,D=[]){let $=this._entityManager.getEntitiesWithQuery(j,D);if($.length===0)throw Error(`getSingleton: no entity matches query with=[${String(j)}] without=[${String(D)}]`);if($.length>1)throw Error(`getSingleton: expected 1 entity but found ${$.length} matching query with=[${String(j)}] without=[${String(D)}]`);let G=$[0];if(!G)throw Error("getSingleton: unexpected empty result");return G}tryGetSingleton(j,D=[]){let $=this._entityManager.getEntitiesWithQuery(j,D);if($.length===0)return;if($.length>1)throw Error(`tryGetSingleton: expected 0 or 1 entity but found ${$.length} matching query with=[${String(j)}] without=[${String(D)}]`);return $[0]}removeEntity(j,D){return this._entityManager.removeEntity(j,D)}spawnChild(j,D,$){let G=this._entityManager.spawnChild(j,D);return this._emitHierarchyChanged(G.id,null,j),this._applyScreenScope(G.id,$),G}setParent(j,D){let $=this._entityManager.getParent(j);return this._entityManager.setParent(j,D),this._emitHierarchyChanged(j,$,D),this}removeParent(j){let D=this._entityManager.getParent(j),$=this._entityManager.removeParent(j);if($)this._emitHierarchyChanged(j,D,null);return $}getParent(j){return this._entityManager.getParent(j)}getChildren(j){return this._entityManager.getChildren(j)}getChildAt(j,D){return this._entityManager.getChildAt(j,D)}getChildIndex(j,D){return this._entityManager.getChildIndex(j,D)}getAncestors(j){return this._entityManager.getAncestors(j)}getDescendants(j){return this._entityManager.getDescendants(j)}getRoot(j){return this._entityManager.getRoot(j)}getSiblings(j){return this._entityManager.getSiblings(j)}isDescendantOf(j,D){return this._entityManager.isDescendantOf(j,D)}isAncestorOf(j,D){return this._entityManager.isAncestorOf(j,D)}getRootEntities(){return this._entityManager.getRootEntities()}forEachInHierarchy(j,D){this._entityManager.forEachInHierarchy(j,D)}hierarchyIterator(j){return this._entityManager.hierarchyIterator(j)}_emitHierarchyChanged(j,D,$){this._eventBus.publish("hierarchyChanged",{entityId:j,oldParent:D,newParent:$})}get installedPlugins(){return Array.from(this._installedPlugins)}get entityManager(){return this._entityManager}get eventBus(){return this._finalizePendingBuilders(),this._eventBus}get commands(){return this._commandBuffer}get currentTick(){return this._currentTick}get changeThreshold(){return this._changeThreshold}enableDiagnostics(j){if(this._diagnosticsEnabled=j,!j)this._systemTimings.clear(),this._phaseTimings={preUpdate:0,fixedUpdate:0,update:0,postUpdate:0,render:0}}get diagnosticsEnabled(){return this._diagnosticsEnabled}get systemTimings(){return this._systemTimings}get phaseTimings(){return this._phaseTimings}get entityCount(){return this._entityManager.entityCount}mutateComponent(j,D,$){let G=this._entityManager.getComponent(j,D);if(G===void 0)throw Error(`Entity ${j} does not have component "${String(D)}"`);return $(G),this._entityManager.markChanged(j,D),G}markChanged(j,D){this._entityManager.markChanged(j,D)}registerDispose(j,D){this._entityManager.registerDispose(j,D)}registerRequired(j,D,$){if(String(j)===String(D))throw Error(`Cannot require a component to depend on itself: '${String(j)}'`);let G=this._requiredComponents.get(j)??[];if(G.some((J)=>J.component===D))throw Error(`Required component '${String(D)}' already registered for trigger '${String(j)}'`);this._checkRequiredCycle(j,D),G.push({component:D,factory:$}),this._requiredComponents.set(j,G)}_checkRequiredCycle(j,D){c(j,D,($)=>this._requiredComponents.get($))}onComponentAdded(j,D){return this._entityManager.onComponentAdded(j,D)}onComponentRemoved(j,D){return this._entityManager.onComponentRemoved(j,D)}addReactiveQuery(j,D){this._reactiveQueryManager.addQuery(j,D)}removeReactiveQuery(j){return this._reactiveQueryManager.removeQuery(j)}on(j,D){return this._eventBus.subscribe(j,D)}off(j,D){return this._eventBus.unsubscribe(j,D)}onPostUpdate(j){return this._postUpdateHooks.push(j),()=>{let D=this._postUpdateHooks.indexOf(j);if(D!==-1)this._postUpdateHooks.splice(D,1)}}requireAssetManager(){if(!this._assetManager)throw Error("Asset manager not configured. Use withAssets() in builder.");return this._assetManager}getAsset(j){return this.requireAssetManager().get(j)}tryGetAsset(j){return this._assetManager?.tryGet(j)}getAssetHandle(j){return this.requireAssetManager().getHandle(j)}isAssetLoaded(j){return this._assetManager?.isLoaded(j)??!1}async loadAsset(j){return this.requireAssetManager().loadAsset(j)}async loadAssetGroup(j){return this.requireAssetManager().loadAssetGroup(j)}isAssetGroupLoaded(j){return this._assetManager?.isGroupLoaded(j)??!1}getAssetGroupProgress(j){return this._assetManager?.getGroupProgress(j)??0}requireScreenManager(){if(!this._screenManager)throw Error("Screen manager not configured. Use withScreens() in builder.");return this._screenManager}async setScreen(j,D){return this.requireScreenManager().setScreen(j,D)}async pushScreen(j,D){return this.requireScreenManager().pushScreen(j,D)}async popScreen(){return this.requireScreenManager().popScreen()}getCurrentScreen(){return this._screenManager?.getCurrentScreen()??null}getScreenConfig(j){return this.requireScreenManager().getConfig(j)}tryGetScreenConfig(j){return this._screenManager?.tryGetConfig(j)??void 0}getScreenState(j){return this.requireScreenManager().getState(j)}tryGetScreenState(j){return this._screenManager?.tryGetState(j)??void 0}updateScreenState(j,D){if(typeof j==="string")this.requireScreenManager().updateState(D,j);else this.requireScreenManager().updateState(j)}isCurrentScreen(j){return this._screenManager?.isCurrent(j)??!1}isScreenActive(j){return this._screenManager?.isActive(j)??!1}getScreenStackDepth(){return this._screenManager?.getStackDepth()??0}onScreenEnter(j,D){let $=this._eventBus,G=(Z)=>{if(Z.screen!==j)return;D({config:Z.config,ecs:this})},J=$.subscribe("screenEnter",G),X=$.subscribe("screenPush",G);return()=>{J(),X()}}onScreenExit(j,D){return this._eventBus.subscribe("screenExit",(G)=>{if(G.screen!==j)return;D({ecs:this})})}_setAssetManager(j){this._assetManager=j;for(let[D,$]of this._pendingPluginAssets)this._assetManager.register(D,$);this._pendingPluginAssets=[]}_setScreenManager(j){this._screenManager=j;for(let[D,$]of this._pendingPluginScreens)this._screenManager.register(D,$);this._pendingPluginScreens=[]}_hasPendingPluginAssets(){return this._pendingPluginAssets.length>0}_hasPendingPluginScreens(){return this._pendingPluginScreens.length>0}_setFixedDt(j){this._fixedDt=j}_registerAsset(j,D){this._pendingPluginAssets.push([j,D])}_registerScreen(j,D){this._pendingPluginScreens.push([j,D])}installPlugin(j){return this._installPluginUnchecked(j)}_installPluginUnchecked(j){if(this._installedPlugins.has(j.id))return this;this._installedPlugins.add(j.id);let D=[];this._pluginCleanups.set(j.id,D);let $=(J)=>{D.push(J)},G=this._currentSystemDefaults;this._currentSystemDefaults=j.systemDefaults;try{j.install(this,$)}finally{this._currentSystemDefaults=G}return this}uninstallPlugin(j){if(!this._installedPlugins.has(j))return!1;let D=this._pluginCleanups.get(j);if(this._pluginCleanups.delete(j),this._installedPlugins.delete(j),D)for(let $=D.length-1;$>=0;$--){let G=D[$];if(!G)continue;try{G()}catch(J){console.warn(`Plugin '${j}' cleanup threw:`,J)}}return!0}dispose(){let j=Array.from(this._installedPlugins);for(let D=j.length-1;D>=0;D--){let $=j[D];if($!==void 0)this.uninstallPlugin($)}}pluginFactory(){return(j)=>E(j.id).install(j.install)}getHelpers(j){return j(this)}}function uj(j){return j}function lj(j,D){return{x:j,y:D}}function sj(){return{x:0,y:0}}function ij(j,D){return{x:j.x+D.x,y:j.y+D.y}}function cj(j,D){return{x:j.x-D.x,y:j.y-D.y}}function dj(j,D){return{x:j.x*D,y:j.y*D}}function yj(j){return{x:-j.x,y:-j.y}}function oj(j,D){return j.x*D.x+j.y*D.y}function rj(j,D){return j.x*D.y-j.y*D.x}function aj(j){return j.x*j.x+j.y*j.y}function nj(j){return Math.sqrt(j.x*j.x+j.y*j.y)}function tj(j){let D=Math.sqrt(j.x*j.x+j.y*j.y);if(D===0)return{x:0,y:0};return{x:j.x/D,y:j.y/D}}function ej(j,D){let $=j.x-D.x,G=j.y-D.y;return $*$+G*G}function j3(j,D){let $=j.x-D.x,G=j.y-D.y;return Math.sqrt($*$+G*G)}function D3(j,D,$=0.0000000001){return Math.abs(j.x-D.x)<=$&&Math.abs(j.y-D.y)<=$}function $3(j,D,$){return{x:j,y:D,z:$}}function G3(){return{x:0,y:0,z:0}}function J3(j,D){return{x:j.x+D.x,y:j.y+D.y,z:j.z+D.z}}function X3(j,D){return{x:j.x-D.x,y:j.y-D.y,z:j.z-D.z}}function Z3(j,D){return{x:j.x*D,y:j.y*D,z:j.z*D}}function W3(j){return{x:-j.x,y:-j.y,z:-j.z}}function Y3(j,D){return j.x*D.x+j.y*D.y+j.z*D.z}function F3(j,D){return{x:j.y*D.z-j.z*D.y,y:j.z*D.x-j.x*D.z,z:j.x*D.y-j.y*D.x}}function L3(j){return j.x*j.x+j.y*j.y+j.z*j.z}function _3(j){return Math.sqrt(j.x*j.x+j.y*j.y+j.z*j.z)}function A3(j){let D=Math.sqrt(j.x*j.x+j.y*j.y+j.z*j.z);if(D===0)return{x:0,y:0,z:0};return{x:j.x/D,y:j.y/D,z:j.z/D}}function B3(j,D){let $=j.x-D.x,G=j.y-D.y,J=j.z-D.z;return $*$+G*G+J*J}function O3(j,D){let $=j.x-D.x,G=j.y-D.y,J=j.z-D.z;return Math.sqrt($*$+G*G+J*J)}function Q3(j,D,$=0.0000000001){return Math.abs(j.x-D.x)<=$&&Math.abs(j.y-D.y)<=$&&Math.abs(j.z-D.z)<=$}var w3=V;export{G3 as vec3Zero,X3 as vec3Sub,Z3 as vec3Scale,A3 as vec3Normalize,W3 as vec3Negate,L3 as vec3LengthSq,_3 as vec3Length,Q3 as vec3Equals,Y3 as vec3Dot,B3 as vec3DistanceSq,O3 as vec3Distance,F3 as vec3Cross,J3 as vec3Add,$3 as vec3,sj as vec2Zero,cj as vec2Sub,dj as vec2Scale,tj as vec2Normalize,yj as vec2Negate,aj as vec2LengthSq,nj as vec2Length,D3 as vec2Equals,oj as vec2Dot,ej as vec2DistanceSq,j3 as vec2Distance,rj as vec2Cross,ij as vec2Add,lj as vec2,n as directValue,E as definePlugin,w3 as default,I as createScreenConfigurator,uj as createQueryDefinition,k as createAssetConfigurator,g as SystemBuilder,P as ScreenManager,z as AssetManager};
2
2
 
3
- //# debugId=14B467299BEDA26D64756E2164756E21
3
+ //# debugId=ACC613F98D8962CC64756E2164756E21
4
4
  //# sourceMappingURL=index.js.map
package/dist/index.js.map CHANGED
@@ -22,6 +22,6 @@
22
22
  "import ECSpresso from './ecspresso';\nimport { SystemBuilder, type ProcessContext } from './system-builder';\nimport { type Plugin, type BasePluginOptions, type PluginCleanupRegistrar, definePlugin } from './plugin';\n\nexport * from './types';\nexport * from './asset-types';\nexport * from './screen-types';\nexport * from './utils/math';\nexport type { ReactiveQueryDefinition } from './reactive-query-manager';\nexport { default as AssetManager, createAssetConfigurator } from './asset-manager';\nexport { default as ScreenManager, createScreenConfigurator } from './screen-manager';\nexport { SystemBuilder, type ProcessContext };\nexport { type Plugin, type BasePluginOptions, type PluginCleanupRegistrar, definePlugin };\nexport { directValue, type ResourceDirectValue } from './resource-manager';\nexport default ECSpresso;\n"
23
23
  ],
24
24
  "mappings": "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",
25
- "debugId": "14B467299BEDA26D64756E2164756E21",
25
+ "debugId": "ACC613F98D8962CC64756E2164756E21",
26
26
  "names": []
27
27
  }
@@ -22,11 +22,11 @@ import { type BasePluginOptions } from 'ecspresso';
22
22
  * }
23
23
  * ```
24
24
  */
25
- export interface TimerEventData {
25
+ export interface TimerEventData<Slots extends string = string> {
26
26
  /** The entity ID that owns the timer slot */
27
27
  entityId: number;
28
28
  /** The slot name within the entity's `timers` map */
29
- slot: string;
29
+ slot: Slots;
30
30
  /** The slot's configured duration in seconds */
31
31
  duration: number;
32
32
  /** The actual elapsed time (may exceed duration slightly) */
@@ -36,7 +36,7 @@ export interface TimerEventData {
36
36
  * A single timer's data. Multiple of these can live on one entity, keyed by slot name.
37
37
  * Use `justFinished` to detect completion in your systems.
38
38
  */
39
- export interface Timer {
39
+ export interface Timer<Slots extends string = string> {
40
40
  /** Time accumulated so far (seconds) */
41
41
  elapsed: number;
42
42
  /** Target duration (seconds) */
@@ -48,7 +48,7 @@ export interface Timer {
48
48
  /** True for one frame after the timer completes */
49
49
  justFinished: boolean;
50
50
  /** Optional callback invoked when the timer completes */
51
- onComplete?: (data: TimerEventData) => void;
51
+ onComplete?: (data: TimerEventData<Slots>) => void;
52
52
  }
53
53
  /**
54
54
  * Component types provided by the timer plugin.
@@ -71,14 +71,14 @@ export interface Timer {
71
71
  * });
72
72
  * ```
73
73
  */
74
- export interface TimerComponentTypes {
75
- timers: Record<string, Timer>;
74
+ export interface TimerComponentTypes<Slots extends string = string> {
75
+ timers: Partial<Record<Slots, Timer<Slots>>>;
76
76
  }
77
77
  export interface TimerPluginOptions<G extends string = 'timers'> extends BasePluginOptions<G> {
78
78
  }
79
- export interface TimerOptions {
79
+ export interface TimerOptions<Slots extends string = string> {
80
80
  /** Callback invoked when the timer completes */
81
- onComplete?: (data: TimerEventData) => void;
81
+ onComplete?: (data: TimerEventData<Slots>) => void;
82
82
  }
83
83
  /**
84
84
  * Create a one-shot `Timer` to drop into a `timers` slot.
@@ -105,7 +105,7 @@ export interface TimerOptions {
105
105
  * });
106
106
  * ```
107
107
  */
108
- export declare function createTimer(duration: number, options?: TimerOptions): Timer;
108
+ export declare function createTimer<Slots extends string = string>(duration: number, options?: TimerOptions<Slots>): Timer<Slots>;
109
109
  /**
110
110
  * Create a repeating `Timer` to drop into a `timers` slot. Fires
111
111
  * `justFinished` once per cycle and continues running.
@@ -118,7 +118,7 @@ export declare function createTimer(duration: number, options?: TimerOptions): T
118
118
  * });
119
119
  * ```
120
120
  */
121
- export declare function createRepeatingTimer(duration: number, options?: TimerOptions): Timer;
121
+ export declare function createRepeatingTimer<Slots extends string = string>(duration: number, options?: TimerOptions<Slots>): Timer<Slots>;
122
122
  /**
123
123
  * Create a timer plugin for ECSpresso.
124
124
  *
@@ -148,5 +148,30 @@ export declare function createRepeatingTimer(duration: number, options?: TimerOp
148
148
  * }
149
149
  * });
150
150
  * ```
151
+ *
152
+ * @example
153
+ * Typed slot names — pass a string-union generic to lock the set of legal
154
+ * slot names. Spawn sites reject typos, autocomplete works on slot access,
155
+ * and `slot` is narrowed in `onComplete` callbacks. Defaults to `string`
156
+ * (any slot name) when omitted.
157
+ *
158
+ * ```typescript
159
+ * const ecs = ECSpresso.create()
160
+ * .withPlugin(createTimerPlugin<'launch' | 'hangarCycle'>())
161
+ * .build();
162
+ *
163
+ * ecs.spawn({ timers: { launch: createTimer(2.0) } }); // ok
164
+ * ecs.spawn({ timers: { typo: createTimer(2.0) } }); // type error
165
+ *
166
+ * createTimer<'launch' | 'hangarCycle'>(1.0, {
167
+ * onComplete: ({ slot }) => {
168
+ * // slot is 'launch' | 'hangarCycle', not string
169
+ * },
170
+ * });
171
+ * ```
172
+ *
173
+ * Only one timer plugin can be installed per world. Feature plugins should
174
+ * re-export their slot union as a type so the app can assemble them:
175
+ * `createTimerPlugin<FighterSlots | CarrierSlots>()`.
151
176
  */
152
- export declare function createTimerPlugin<G extends string = 'timers'>(options?: TimerPluginOptions<G>): import("ecspresso").Plugin<import("ecspresso").WithComponents<import("ecspresso").EmptyConfig, TimerComponentTypes>, import("ecspresso").EmptyConfig, "timer-update", G, never, never>;
177
+ export declare function createTimerPlugin<Slots extends string = string, G extends string = 'timers'>(options?: TimerPluginOptions<G>): import("ecspresso").Plugin<import("ecspresso").WithComponents<import("ecspresso").EmptyConfig, TimerComponentTypes<Slots>>, import("ecspresso").EmptyConfig, "timer-update", G, never, never>;
@@ -1,4 +1,4 @@
1
- var V=((A)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(A,{get:(B,D)=>(typeof require<"u"?require:B)[D]}):A)(function(A){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+A+'" is not supported')});import{definePlugin as U}from"ecspresso";function Y(A,B){return{elapsed:0,duration:A,repeat:!1,active:!0,justFinished:!1,onComplete:B?.onComplete}}function Z(A,B){return{elapsed:0,duration:A,repeat:!0,active:!0,justFinished:!1,onComplete:B?.onComplete}}function _(A){let{systemGroup:B="timers",priority:D=0,phase:L="preUpdate"}=A??{};return U("timers").withComponentTypes().withLabels().withGroups().install((M)=>{M.addSystem("timer-update").setPriority(D).inPhase(L).inGroup(B).addQuery("timers",{with:["timers"]}).setProcess(({queries:N,dt:O})=>{for(let H of N.timers){let K=H.components.timers;for(let J in K){let z=K[J];if(!z)continue;if(z.justFinished=!1,!z.active)continue;if(z.elapsed+=O,z.elapsed<z.duration)continue;if(z.repeat)while(z.elapsed>=z.duration)z.justFinished=!0,z.onComplete?.({entityId:H.id,slot:J,duration:z.duration,elapsed:z.elapsed}),z.elapsed-=z.duration;else z.justFinished=!0,z.onComplete?.({entityId:H.id,slot:J,duration:z.duration,elapsed:z.elapsed}),z.active=!1}}})})}export{_ as createTimerPlugin,Y as createTimer,Z as createRepeatingTimer};
1
+ var X=((A)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(A,{get:(B,H)=>(typeof require<"u"?require:B)[H]}):A)(function(A){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+A+'" is not supported')});import{definePlugin as W}from"ecspresso";function _(A,B){return{elapsed:0,duration:A,repeat:!1,active:!0,justFinished:!1,onComplete:B?.onComplete}}function $(A,B){return{elapsed:0,duration:A,repeat:!0,active:!0,justFinished:!1,onComplete:B?.onComplete}}function D(A){let{systemGroup:B="timers",priority:H=0,phase:M="preUpdate"}=A??{};return W("timers").withComponentTypes().withLabels().withGroups().install((N)=>{N.addSystem("timer-update").setPriority(H).inPhase(M).inGroup(B).addQuery("timers",{with:["timers"]}).setProcess(({queries:U,dt:V})=>{for(let J of U.timers){let L=J.components.timers;for(let K in L){let z=L[K];if(!z)continue;if(z.justFinished=!1,!z.active)continue;if(z.elapsed+=V,z.elapsed<z.duration)continue;if(z.repeat)while(z.elapsed>=z.duration)z.justFinished=!0,z.onComplete?.({entityId:J.id,slot:K,duration:z.duration,elapsed:z.elapsed}),z.elapsed-=z.duration;else z.justFinished=!0,z.onComplete?.({entityId:J.id,slot:K,duration:z.duration,elapsed:z.elapsed}),z.active=!1}}})})}export{D as createTimerPlugin,_ as createTimer,$ as createRepeatingTimer};
2
2
 
3
- //# debugId=03F5D4A1CC15EDC764756E2164756E21
3
+ //# debugId=5793392D19F4504664756E2164756E21
4
4
  //# sourceMappingURL=timers.js.map
@@ -2,9 +2,9 @@
2
2
  "version": 3,
3
3
  "sources": ["../src/plugins/scripting/timers.ts"],
4
4
  "sourcesContent": [
5
- "/**\n * Timer Plugin for ECSpresso\n *\n * ECS-native timers as pure data. An entity may carry multiple named timer\n * slots; the plugin's update system ticks every slot each frame and exposes\n * `justFinished` for the frame a slot crosses its duration. The plugin never\n * touches entity lifecycle — callers despawn (or do anything else) themselves\n * by reacting to `justFinished` or in the slot's `onComplete` callback.\n */\n\nimport { definePlugin, type BasePluginOptions } from 'ecspresso';\n\n// ==================== Event Types ====================\n\n/**\n * Data passed to a slot's `onComplete` callback when its timer completes.\n *\n * @example\n * ```typescript\n * timers: {\n * launch: createTimer(1.5, {\n * onComplete: ({ entityId, slot, elapsed }) => {\n * console.log(`Slot ${slot} on entity ${entityId} finished after ${elapsed}s`);\n * },\n * }),\n * }\n * ```\n */\nexport interface TimerEventData {\n\t/** The entity ID that owns the timer slot */\n\tentityId: number;\n\t/** The slot name within the entity's `timers` map */\n\tslot: string;\n\t/** The slot's configured duration in seconds */\n\tduration: number;\n\t/** The actual elapsed time (may exceed duration slightly) */\n\telapsed: number;\n}\n\n// ==================== Component Types ====================\n\n/**\n * A single timer's data. Multiple of these can live on one entity, keyed by slot name.\n * Use `justFinished` to detect completion in your systems.\n */\nexport interface Timer {\n\t/** Time accumulated so far (seconds) */\n\telapsed: number;\n\t/** Target duration (seconds) */\n\tduration: number;\n\t/** Whether the timer repeats after completion */\n\trepeat: boolean;\n\t/** Whether the timer is currently running */\n\tactive: boolean;\n\t/** True for one frame after the timer completes */\n\tjustFinished: boolean;\n\t/** Optional callback invoked when the timer completes */\n\tonComplete?: (data: TimerEventData) => void;\n}\n\n/**\n * Component types provided by the timer plugin.\n *\n * Each entity carries a single `timers` component whose value is a map of\n * named slots. This lets one entity host independent phase clocks\n * (e.g. `{ launch: ..., shieldDepletion: ..., hangarCycle: ... }`) without\n * one timer's lifecycle constraining another.\n *\n * @example\n * ```typescript\n * const ecs = ECSpresso.create()\n * .withPlugin(createTimerPlugin())\n * .withComponentTypes<{ fighter: true }>()\n * .build();\n *\n * ecs.spawn({\n * fighter: true,\n * timers: { launch: createTimer(2.0) },\n * });\n * ```\n */\nexport interface TimerComponentTypes {\n\ttimers: Record<string, Timer>;\n}\n\n// ==================== Plugin Options ====================\n\nexport interface TimerPluginOptions<G extends string = 'timers'> extends BasePluginOptions<G> {}\n\n// ==================== Helper Functions ====================\n\nexport interface TimerOptions {\n\t/** Callback invoked when the timer completes */\n\tonComplete?: (data: TimerEventData) => void;\n}\n\n/**\n * Create a one-shot `Timer` to drop into a `timers` slot.\n *\n * The timer fires `justFinished` for one frame on completion and then idles\n * (`active = false`). The entity is left alone — if the slot's lifetime\n * coincides with the entity's lifetime (vfx, blasts, summon-anim), despawn\n * the host yourself in `onComplete` or in a system that watches `justFinished`.\n *\n * @example\n * ```typescript\n * ecs.spawn({\n * fighter: true,\n * timers: { launch: createTimer(2.0) },\n * });\n *\n * // Self-destructing vfx — caller owns the despawn:\n * ecs.spawn({\n * timers: {\n * fade: createTimer(1.0, {\n * onComplete: ({ entityId }) => ecs.commands.removeEntity(entityId),\n * }),\n * },\n * });\n * ```\n */\nexport function createTimer(duration: number, options?: TimerOptions): Timer {\n\treturn {\n\t\telapsed: 0,\n\t\tduration,\n\t\trepeat: false,\n\t\tactive: true,\n\t\tjustFinished: false,\n\t\tonComplete: options?.onComplete,\n\t};\n}\n\n/**\n * Create a repeating `Timer` to drop into a `timers` slot. Fires\n * `justFinished` once per cycle and continues running.\n *\n * @example\n * ```typescript\n * ecs.spawn({\n * carrier: true,\n * timers: { hangarCycle: createRepeatingTimer(5.0) },\n * });\n * ```\n */\nexport function createRepeatingTimer(duration: number, options?: TimerOptions): Timer {\n\treturn {\n\t\telapsed: 0,\n\t\tduration,\n\t\trepeat: true,\n\t\tactive: true,\n\t\tjustFinished: false,\n\t\tonComplete: options?.onComplete,\n\t};\n}\n\n// ==================== Plugin Factory ====================\n\n/**\n * Create a timer plugin for ECSpresso.\n *\n * The plugin installs one update system that ticks every slot of every\n * `timers` component each frame. It does not touch entity lifecycle —\n * react to `justFinished` (or use `onComplete`) and despawn yourself if needed.\n *\n * @example\n * ```typescript\n * const ecs = ECSpresso.create()\n * .withPlugin(createTimerPlugin())\n * .withComponentTypes<{ spawner: true }>()\n * .build();\n *\n * ecs.spawn({\n * spawner: true,\n * timers: { wave: createRepeatingTimer(5.0) },\n * });\n *\n * ecs.addSystem('spawn-on-timer')\n * .addQuery('spawners', { with: ['timers', 'spawner'] })\n * .setProcess(({ queries, ecs }) => {\n * for (const { components } of queries.spawners) {\n * if (components.timers.wave?.justFinished) {\n * ecs.spawn({ enemy: true });\n * }\n * }\n * });\n * ```\n */\nexport function createTimerPlugin<G extends string = 'timers'>(\n\toptions?: TimerPluginOptions<G>\n) {\n\tconst {\n\t\tsystemGroup = 'timers',\n\t\tpriority = 0,\n\t\tphase = 'preUpdate',\n\t} = options ?? {};\n\n\treturn definePlugin('timers')\n\t\t.withComponentTypes<TimerComponentTypes>()\n\t\t.withLabels<'timer-update'>()\n\t\t.withGroups<G>()\n\t\t.install((world) => {\n\t\t\tworld\n\t\t\t\t.addSystem('timer-update')\n\t\t\t\t.setPriority(priority)\n\t\t\t\t.inPhase(phase)\n\t\t\t\t.inGroup(systemGroup)\n\t\t\t\t.addQuery('timers', { with: ['timers'] })\n\t\t\t\t.setProcess(({ queries, dt }) => {\n\t\t\t\t\tfor (const entity of queries.timers) {\n\t\t\t\t\t\tconst slots = entity.components.timers;\n\t\t\t\t\t\tfor (const slot in slots) {\n\t\t\t\t\t\t\tconst timer = slots[slot];\n\t\t\t\t\t\t\tif (!timer) continue;\n\n\t\t\t\t\t\t\ttimer.justFinished = false;\n\t\t\t\t\t\t\tif (!timer.active) continue;\n\n\t\t\t\t\t\t\ttimer.elapsed += dt;\n\t\t\t\t\t\t\tif (timer.elapsed < timer.duration) continue;\n\n\t\t\t\t\t\t\tif (timer.repeat) {\n\t\t\t\t\t\t\t\twhile (timer.elapsed >= timer.duration) {\n\t\t\t\t\t\t\t\t\ttimer.justFinished = true;\n\t\t\t\t\t\t\t\t\ttimer.onComplete?.({\n\t\t\t\t\t\t\t\t\t\tentityId: entity.id,\n\t\t\t\t\t\t\t\t\t\tslot,\n\t\t\t\t\t\t\t\t\t\tduration: timer.duration,\n\t\t\t\t\t\t\t\t\t\telapsed: timer.elapsed,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\ttimer.elapsed -= timer.duration;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttimer.justFinished = true;\n\t\t\t\t\t\t\t\ttimer.onComplete?.({\n\t\t\t\t\t\t\t\t\tentityId: entity.id,\n\t\t\t\t\t\t\t\t\tslot,\n\t\t\t\t\t\t\t\t\tduration: timer.duration,\n\t\t\t\t\t\t\t\t\telapsed: timer.elapsed,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\ttimer.active = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t});\n}\n"
5
+ "/**\n * Timer Plugin for ECSpresso\n *\n * ECS-native timers as pure data. An entity may carry multiple named timer\n * slots; the plugin's update system ticks every slot each frame and exposes\n * `justFinished` for the frame a slot crosses its duration. The plugin never\n * touches entity lifecycle — callers despawn (or do anything else) themselves\n * by reacting to `justFinished` or in the slot's `onComplete` callback.\n */\n\nimport { definePlugin, type BasePluginOptions } from 'ecspresso';\n\n// ==================== Event Types ====================\n\n/**\n * Data passed to a slot's `onComplete` callback when its timer completes.\n *\n * @example\n * ```typescript\n * timers: {\n * launch: createTimer(1.5, {\n * onComplete: ({ entityId, slot, elapsed }) => {\n * console.log(`Slot ${slot} on entity ${entityId} finished after ${elapsed}s`);\n * },\n * }),\n * }\n * ```\n */\nexport interface TimerEventData<Slots extends string = string> {\n\t/** The entity ID that owns the timer slot */\n\tentityId: number;\n\t/** The slot name within the entity's `timers` map */\n\tslot: Slots;\n\t/** The slot's configured duration in seconds */\n\tduration: number;\n\t/** The actual elapsed time (may exceed duration slightly) */\n\telapsed: number;\n}\n\n// ==================== Component Types ====================\n\n/**\n * A single timer's data. Multiple of these can live on one entity, keyed by slot name.\n * Use `justFinished` to detect completion in your systems.\n */\nexport interface Timer<Slots extends string = string> {\n\t/** Time accumulated so far (seconds) */\n\telapsed: number;\n\t/** Target duration (seconds) */\n\tduration: number;\n\t/** Whether the timer repeats after completion */\n\trepeat: boolean;\n\t/** Whether the timer is currently running */\n\tactive: boolean;\n\t/** True for one frame after the timer completes */\n\tjustFinished: boolean;\n\t/** Optional callback invoked when the timer completes */\n\tonComplete?: (data: TimerEventData<Slots>) => void;\n}\n\n/**\n * Component types provided by the timer plugin.\n *\n * Each entity carries a single `timers` component whose value is a map of\n * named slots. This lets one entity host independent phase clocks\n * (e.g. `{ launch: ..., shieldDepletion: ..., hangarCycle: ... }`) without\n * one timer's lifecycle constraining another.\n *\n * @example\n * ```typescript\n * const ecs = ECSpresso.create()\n * .withPlugin(createTimerPlugin())\n * .withComponentTypes<{ fighter: true }>()\n * .build();\n *\n * ecs.spawn({\n * fighter: true,\n * timers: { launch: createTimer(2.0) },\n * });\n * ```\n */\nexport interface TimerComponentTypes<Slots extends string = string> {\n\ttimers: Partial<Record<Slots, Timer<Slots>>>;\n}\n\n// ==================== Plugin Options ====================\n\nexport interface TimerPluginOptions<G extends string = 'timers'> extends BasePluginOptions<G> {}\n\n// ==================== Helper Functions ====================\n\nexport interface TimerOptions<Slots extends string = string> {\n\t/** Callback invoked when the timer completes */\n\tonComplete?: (data: TimerEventData<Slots>) => void;\n}\n\n/**\n * Create a one-shot `Timer` to drop into a `timers` slot.\n *\n * The timer fires `justFinished` for one frame on completion and then idles\n * (`active = false`). The entity is left alone — if the slot's lifetime\n * coincides with the entity's lifetime (vfx, blasts, summon-anim), despawn\n * the host yourself in `onComplete` or in a system that watches `justFinished`.\n *\n * @example\n * ```typescript\n * ecs.spawn({\n * fighter: true,\n * timers: { launch: createTimer(2.0) },\n * });\n *\n * // Self-destructing vfx — caller owns the despawn:\n * ecs.spawn({\n * timers: {\n * fade: createTimer(1.0, {\n * onComplete: ({ entityId }) => ecs.commands.removeEntity(entityId),\n * }),\n * },\n * });\n * ```\n */\nexport function createTimer<Slots extends string = string>(duration: number, options?: TimerOptions<Slots>): Timer<Slots> {\n\treturn {\n\t\telapsed: 0,\n\t\tduration,\n\t\trepeat: false,\n\t\tactive: true,\n\t\tjustFinished: false,\n\t\tonComplete: options?.onComplete,\n\t};\n}\n\n/**\n * Create a repeating `Timer` to drop into a `timers` slot. Fires\n * `justFinished` once per cycle and continues running.\n *\n * @example\n * ```typescript\n * ecs.spawn({\n * carrier: true,\n * timers: { hangarCycle: createRepeatingTimer(5.0) },\n * });\n * ```\n */\nexport function createRepeatingTimer<Slots extends string = string>(duration: number, options?: TimerOptions<Slots>): Timer<Slots> {\n\treturn {\n\t\telapsed: 0,\n\t\tduration,\n\t\trepeat: true,\n\t\tactive: true,\n\t\tjustFinished: false,\n\t\tonComplete: options?.onComplete,\n\t};\n}\n\n// ==================== Plugin Factory ====================\n\n/**\n * Create a timer plugin for ECSpresso.\n *\n * The plugin installs one update system that ticks every slot of every\n * `timers` component each frame. It does not touch entity lifecycle —\n * react to `justFinished` (or use `onComplete`) and despawn yourself if needed.\n *\n * @example\n * ```typescript\n * const ecs = ECSpresso.create()\n * .withPlugin(createTimerPlugin())\n * .withComponentTypes<{ spawner: true }>()\n * .build();\n *\n * ecs.spawn({\n * spawner: true,\n * timers: { wave: createRepeatingTimer(5.0) },\n * });\n *\n * ecs.addSystem('spawn-on-timer')\n * .addQuery('spawners', { with: ['timers', 'spawner'] })\n * .setProcess(({ queries, ecs }) => {\n * for (const { components } of queries.spawners) {\n * if (components.timers.wave?.justFinished) {\n * ecs.spawn({ enemy: true });\n * }\n * }\n * });\n * ```\n *\n * @example\n * Typed slot names — pass a string-union generic to lock the set of legal\n * slot names. Spawn sites reject typos, autocomplete works on slot access,\n * and `slot` is narrowed in `onComplete` callbacks. Defaults to `string`\n * (any slot name) when omitted.\n *\n * ```typescript\n * const ecs = ECSpresso.create()\n * .withPlugin(createTimerPlugin<'launch' | 'hangarCycle'>())\n * .build();\n *\n * ecs.spawn({ timers: { launch: createTimer(2.0) } }); // ok\n * ecs.spawn({ timers: { typo: createTimer(2.0) } }); // type error\n *\n * createTimer<'launch' | 'hangarCycle'>(1.0, {\n * onComplete: ({ slot }) => {\n * // slot is 'launch' | 'hangarCycle', not string\n * },\n * });\n * ```\n *\n * Only one timer plugin can be installed per world. Feature plugins should\n * re-export their slot union as a type so the app can assemble them:\n * `createTimerPlugin<FighterSlots | CarrierSlots>()`.\n */\nexport function createTimerPlugin<\n\tSlots extends string = string,\n\tG extends string = 'timers',\n>(\n\toptions?: TimerPluginOptions<G>\n) {\n\tconst {\n\t\tsystemGroup = 'timers',\n\t\tpriority = 0,\n\t\tphase = 'preUpdate',\n\t} = options ?? {};\n\n\treturn definePlugin('timers')\n\t\t.withComponentTypes<TimerComponentTypes<Slots>>()\n\t\t.withLabels<'timer-update'>()\n\t\t.withGroups<G>()\n\t\t.install((world) => {\n\t\t\tworld\n\t\t\t\t.addSystem('timer-update')\n\t\t\t\t.setPriority(priority)\n\t\t\t\t.inPhase(phase)\n\t\t\t\t.inGroup(systemGroup)\n\t\t\t\t.addQuery('timers', { with: ['timers'] })\n\t\t\t\t.setProcess(({ queries, dt }) => {\n\t\t\t\t\tfor (const entity of queries.timers) {\n\t\t\t\t\t\tconst slots = entity.components.timers;\n\t\t\t\t\t\tfor (const slot in slots) {\n\t\t\t\t\t\t\tconst timer = slots[slot];\n\t\t\t\t\t\t\tif (!timer) continue;\n\n\t\t\t\t\t\t\ttimer.justFinished = false;\n\t\t\t\t\t\t\tif (!timer.active) continue;\n\n\t\t\t\t\t\t\ttimer.elapsed += dt;\n\t\t\t\t\t\t\tif (timer.elapsed < timer.duration) continue;\n\n\t\t\t\t\t\t\tif (timer.repeat) {\n\t\t\t\t\t\t\t\twhile (timer.elapsed >= timer.duration) {\n\t\t\t\t\t\t\t\t\ttimer.justFinished = true;\n\t\t\t\t\t\t\t\t\ttimer.onComplete?.({\n\t\t\t\t\t\t\t\t\t\tentityId: entity.id,\n\t\t\t\t\t\t\t\t\t\tslot,\n\t\t\t\t\t\t\t\t\t\tduration: timer.duration,\n\t\t\t\t\t\t\t\t\t\telapsed: timer.elapsed,\n\t\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\t\ttimer.elapsed -= timer.duration;\n\t\t\t\t\t\t\t\t}\n\t\t\t\t\t\t\t} else {\n\t\t\t\t\t\t\t\ttimer.justFinished = true;\n\t\t\t\t\t\t\t\ttimer.onComplete?.({\n\t\t\t\t\t\t\t\t\tentityId: entity.id,\n\t\t\t\t\t\t\t\t\tslot,\n\t\t\t\t\t\t\t\t\tduration: timer.duration,\n\t\t\t\t\t\t\t\t\telapsed: timer.elapsed,\n\t\t\t\t\t\t\t\t});\n\t\t\t\t\t\t\t\ttimer.active = false;\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t}\n\t\t\t\t});\n\t\t});\n}\n"
6
6
  ],
7
- "mappings": "2PAUA,uBAAS,kBA+GF,SAAS,CAAW,CAAC,EAAkB,EAA+B,CAC5E,MAAO,CACN,QAAS,EACT,WACA,OAAQ,GACR,OAAQ,GACR,aAAc,GACd,WAAY,GAAS,UACtB,EAeM,SAAS,CAAoB,CAAC,EAAkB,EAA+B,CACrF,MAAO,CACN,QAAS,EACT,WACA,OAAQ,GACR,OAAQ,GACR,aAAc,GACd,WAAY,GAAS,UACtB,EAmCM,SAAS,CAA8C,CAC7D,EACC,CACD,IACC,cAAc,SACd,WAAW,EACX,QAAQ,aACL,GAAW,CAAC,EAEhB,OAAO,EAAa,QAAQ,EAC1B,mBAAwC,EACxC,WAA2B,EAC3B,WAAc,EACd,QAAQ,CAAC,IAAU,CACnB,EACE,UAAU,cAAc,EACxB,YAAY,CAAQ,EACpB,QAAQ,CAAK,EACb,QAAQ,CAAW,EACnB,SAAS,SAAU,CAAE,KAAM,CAAC,QAAQ,CAAE,CAAC,EACvC,WAAW,EAAG,UAAS,QAAS,CAChC,QAAW,KAAU,EAAQ,OAAQ,CACpC,IAAM,EAAQ,EAAO,WAAW,OAChC,QAAW,KAAQ,EAAO,CACzB,IAAM,EAAQ,EAAM,GACpB,GAAI,CAAC,EAAO,SAGZ,GADA,EAAM,aAAe,GACjB,CAAC,EAAM,OAAQ,SAGnB,GADA,EAAM,SAAW,EACb,EAAM,QAAU,EAAM,SAAU,SAEpC,GAAI,EAAM,OACT,MAAO,EAAM,SAAW,EAAM,SAC7B,EAAM,aAAe,GACrB,EAAM,aAAa,CAClB,SAAU,EAAO,GACjB,OACA,SAAU,EAAM,SAChB,QAAS,EAAM,OAChB,CAAC,EACD,EAAM,SAAW,EAAM,SAGxB,OAAM,aAAe,GACrB,EAAM,aAAa,CAClB,SAAU,EAAO,GACjB,OACA,SAAU,EAAM,SAChB,QAAS,EAAM,OAChB,CAAC,EACD,EAAM,OAAS,KAIlB,EACF",
8
- "debugId": "03F5D4A1CC15EDC764756E2164756E21",
7
+ "mappings": "2PAUA,uBAAS,kBA+GF,SAAS,CAA0C,CAAC,EAAkB,EAA6C,CACzH,MAAO,CACN,QAAS,EACT,WACA,OAAQ,GACR,OAAQ,GACR,aAAc,GACd,WAAY,GAAS,UACtB,EAeM,SAAS,CAAmD,CAAC,EAAkB,EAA6C,CAClI,MAAO,CACN,QAAS,EACT,WACA,OAAQ,GACR,OAAQ,GACR,aAAc,GACd,WAAY,GAAS,UACtB,EA4DM,SAAS,CAGf,CACA,EACC,CACD,IACC,cAAc,SACd,WAAW,EACX,QAAQ,aACL,GAAW,CAAC,EAEhB,OAAO,EAAa,QAAQ,EAC1B,mBAA+C,EAC/C,WAA2B,EAC3B,WAAc,EACd,QAAQ,CAAC,IAAU,CACnB,EACE,UAAU,cAAc,EACxB,YAAY,CAAQ,EACpB,QAAQ,CAAK,EACb,QAAQ,CAAW,EACnB,SAAS,SAAU,CAAE,KAAM,CAAC,QAAQ,CAAE,CAAC,EACvC,WAAW,EAAG,UAAS,QAAS,CAChC,QAAW,KAAU,EAAQ,OAAQ,CACpC,IAAM,EAAQ,EAAO,WAAW,OAChC,QAAW,KAAQ,EAAO,CACzB,IAAM,EAAQ,EAAM,GACpB,GAAI,CAAC,EAAO,SAGZ,GADA,EAAM,aAAe,GACjB,CAAC,EAAM,OAAQ,SAGnB,GADA,EAAM,SAAW,EACb,EAAM,QAAU,EAAM,SAAU,SAEpC,GAAI,EAAM,OACT,MAAO,EAAM,SAAW,EAAM,SAC7B,EAAM,aAAe,GACrB,EAAM,aAAa,CAClB,SAAU,EAAO,GACjB,OACA,SAAU,EAAM,SAChB,QAAS,EAAM,OAChB,CAAC,EACD,EAAM,SAAW,EAAM,SAGxB,OAAM,aAAe,GACrB,EAAM,aAAa,CAClB,SAAU,EAAO,GACjB,OACA,SAAU,EAAM,SAChB,QAAS,EAAM,OAChB,CAAC,EACD,EAAM,OAAS,KAIlB,EACF",
8
+ "debugId": "5793392D19F4504664756E2164756E21",
9
9
  "names": []
10
10
  }
@@ -1,4 +1,4 @@
1
- var v=((j)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(j,{get:(A,B)=>(typeof require<"u"?require:A)[B]}):j)(function(j){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+j+'" is not supported')});import{definePlugin as H}from"ecspresso";function G(j,A){return j*73856093^A*19349663}function z(j){return{cellSize:j,invCellSize:1/j,cells:new Map,entries:[],_aliveGen:0,_queryGen:0}}function R(j){j._aliveGen++;for(let A of j.cells.values())A.length=0}function S(j,A,B,F,J,K){let O=j._aliveGen,M=j.entries[A],T;if(M)M.x=B,M.y=F,M.halfW=J,M.halfH=K,M._aliveGen=O,T=M;else T={entityId:A,x:B,y:F,halfW:J,halfH:K,_lastSeenGen:0,_aliveGen:O},j.entries[A]=T;let _=j.invCellSize,P=Math.floor((B-J)*_),$=Math.floor((B+J)*_),U=Math.floor((F-K)*_),Z=Math.floor((F+K)*_);for(let N=P;N<=$;N++)for(let D=U;D<=Z;D++){let V=G(N,D),L=j.cells.get(V);if(L)L.push(T);else j.cells.set(V,[T])}}function w(j,A,B,F,J,K,O=-1){let M=j.invCellSize,T=Math.floor(A*M),_=Math.floor(F*M),P=Math.floor(B*M),$=Math.floor(J*M),U=++j._queryGen;for(let Z=T;Z<=_;Z++)for(let N=P;N<=$;N++){let D=j.cells.get(G(Z,N));if(!D)continue;for(let V of D){if(V.entityId<=O||V._lastSeenGen===U)continue;V._lastSeenGen=U,K.push(V.entityId)}}}function Q(j,A,B,F,J){let K=F*F,O=j.invCellSize,M=Math.floor((A-F)*O),T=Math.floor((A+F)*O),_=Math.floor((B-F)*O),P=Math.floor((B+F)*O),$=++j._queryGen;for(let U=M;U<=T;U++)for(let Z=_;Z<=P;Z++){let N=j.cells.get(G(U,Z));if(!N)continue;for(let D of N){if(D._lastSeenGen===$)continue;D._lastSeenGen=$;let V=Math.max(D.x-D.halfW,Math.min(A,D.x+D.halfW)),L=Math.max(D.y-D.halfH,Math.min(B,D.y+D.halfH)),E=A-V,q=B-L;if(E*E+q*q<=K)J.push(D.entityId)}}}function k(j,A){let B=j.entries[A];if(!B||B._aliveGen!==j._aliveGen)return;return B}function W(j){return{grid:j,queryRect(A,B,F,J){let K=[];return w(j,A,B,F,J,K),K},queryRectInto(A,B,F,J,K,O){w(j,A,B,F,J,K,O)},queryRadius(A,B,F){let J=[];return Q(j,A,B,F,J),J},queryRadiusInto(A,B,F,J){Q(j,A,B,F,J)},getEntry(A){return k(j,A)}}}function Y(j){let{cellSize:A=64,systemGroup:B="spatialIndex",priority:F=2000,phases:J=["fixedUpdate","postUpdate"]}=j??{},K=z(A),O=W(K);return H("spatialIndex").withComponentTypes().withResourceTypes().withLabels().withGroups().install((M)=>{M.addResource("spatialIndex",O);for(let T of J){let _=T==="fixedUpdate"?"localTransform":"worldTransform";M.addSystem(`spatial-index-rebuild-${T}`).setPriority(F).inPhase(T).inGroup(B).addQuery("transforms",{with:[_]}).setProcess(({queries:P,ecs:$})=>{R(K);for(let U of P.transforms){let Z=U.components[_],N=$.getComponent(U.id,"aabbCollider"),D=$.getComponent(U.id,"circleCollider");if(!N&&!D)continue;let{x:V,y:L}=Z,E=0,q=0;if(N)V+=N.offsetX??0,L+=N.offsetY??0,E=N.width/2,q=N.height/2;if(D)V+=D.offsetX??0,L+=D.offsetY??0,E=Math.max(E,D.radius),q=Math.max(q,D.radius);S(K,U.id,V,L,E,q)}})}})}export{Y as createSpatialIndexPlugin};
1
+ var v=((j)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(j,{get:(A,B)=>(typeof require<"u"?require:A)[B]}):j)(function(j){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+j+'" is not supported')});import{definePlugin as k}from"ecspresso";function w(j,A){return j*73856093^A*19349663}function R(j){return{cellSize:j,invCellSize:1/j,cells:new Map,entries:[],_aliveGen:0,_queryGen:0}}function S(j){j._aliveGen++}function H(j,A,B,D,J,O){let U=j._aliveGen,T=j.entries[A],V;if(T)T.x=B,T.y=D,T.halfW=J,T.halfH=O,T._aliveGen=U,V=T;else V={entityId:A,x:B,y:D,halfW:J,halfH:O,_lastSeenGen:0,_aliveGen:U},j.entries[A]=V;let Z=j.invCellSize,E=Math.floor((B-J)*Z),L=Math.floor((B+J)*Z),_=Math.floor((D-O)*Z),$=Math.floor((D+O)*Z);for(let K=E;K<=L;K++)for(let M=_;M<=$;M++){let F=w(K,M),N=j.cells.get(F);if(N&&N._gen===U)N.push(V);else if(N)N.length=0,N._gen=U,N.push(V);else{let P=[V];P._gen=U,j.cells.set(F,P)}}}function Q(j,A,B,D,J,O,U=-1){let T=j.invCellSize,V=Math.floor(A*T),Z=Math.floor(D*T),E=Math.floor(B*T),L=Math.floor(J*T),_=++j._queryGen,$=j._aliveGen;for(let K=V;K<=Z;K++)for(let M=E;M<=L;M++){let F=j.cells.get(w(K,M));if(!F||F._gen!==$)continue;for(let N of F){if(N.entityId<=U||N._lastSeenGen===_)continue;N._lastSeenGen=_,O.push(N.entityId)}}}function z(j,A,B,D,J){let O=D*D,U=j.invCellSize,T=Math.floor((A-D)*U),V=Math.floor((A+D)*U),Z=Math.floor((B-D)*U),E=Math.floor((B+D)*U),L=++j._queryGen,_=j._aliveGen;for(let $=T;$<=V;$++)for(let K=Z;K<=E;K++){let M=j.cells.get(w($,K));if(!M||M._gen!==_)continue;for(let F of M){if(F._lastSeenGen===L)continue;F._lastSeenGen=L;let N=Math.max(F.x-F.halfW,Math.min(A,F.x+F.halfW)),P=Math.max(F.y-F.halfH,Math.min(B,F.y+F.halfH)),q=A-N,G=B-P;if(q*q+G*G<=O)J.push(F.entityId)}}}function W(j,A){let B=j.entries[A];if(!B||B._aliveGen!==j._aliveGen)return;return B}function p(j){return{grid:j,queryRect(A,B,D,J){let O=[];return Q(j,A,B,D,J,O),O},queryRectInto(A,B,D,J,O,U){Q(j,A,B,D,J,O,U)},queryRadius(A,B,D){let J=[];return z(j,A,B,D,J),J},queryRadiusInto(A,B,D,J){z(j,A,B,D,J)},getEntry(A){return W(j,A)}}}function b(j){let{cellSize:A=64,systemGroup:B="spatialIndex",priority:D=2000,phases:J=["fixedUpdate","postUpdate"]}=j??{},O=R(A),U=p(O);return k("spatialIndex").withComponentTypes().withResourceTypes().withLabels().withGroups().install((T)=>{T.addResource("spatialIndex",U);for(let V of J){let Z=V==="fixedUpdate"?"localTransform":"worldTransform";T.addSystem(`spatial-index-rebuild-${V}`).setPriority(D).inPhase(V).inGroup(B).addQuery("transforms",{with:[Z]}).setProcess(({queries:E,ecs:L})=>{S(O);for(let _ of E.transforms){let $=_.components[Z],K=L.getComponent(_.id,"aabbCollider"),M=L.getComponent(_.id,"circleCollider");if(!K&&!M)continue;let{x:F,y:N}=$,P=0,q=0;if(K)F+=K.offsetX??0,N+=K.offsetY??0,P=K.width/2,q=K.height/2;if(M)F+=M.offsetX??0,N+=M.offsetY??0,P=Math.max(P,M.radius),q=Math.max(q,M.radius);H(O,_.id,F,N,P,q)}})}})}export{b as createSpatialIndexPlugin};
2
2
 
3
- //# debugId=0408432B17B2791864756E2164756E21
3
+ //# debugId=9F6AD37F3DB1C43164756E2164756E21
4
4
  //# sourceMappingURL=spatial-index.js.map
@@ -3,9 +3,9 @@
3
3
  "sources": ["../src/plugins/spatial/spatial-index.ts", "../src/utils/spatial-hash.ts"],
4
4
  "sourcesContent": [
5
5
  "/**\n * Spatial Index Plugin for ECSpresso\n *\n * Provides a uniform-grid spatial hash for broadphase collision detection\n * and proximity queries. Replaces O(n²) brute-force with O(n·d) where\n * d = local density.\n *\n * Standalone usage: queryRect / queryRadius for proximity queries.\n * Automatic acceleration: collision and physics2D plugins detect the\n * spatialIndex resource at runtime and use it for broadphase when present.\n */\n\nimport { definePlugin } from 'ecspresso';\nimport type { SystemPhase } from 'ecspresso';\nimport type { TransformComponentTypes } from './transform';\nimport type { CollisionComponentTypes } from '../physics/collision';\nimport {\n\ttype SpatialEntry,\n\ttype SpatialHashGrid,\n\ttype SpatialIndex,\n\tcreateGrid,\n\tclearGrid,\n\tinsertEntity,\n\tgridQueryRect,\n\tgridQueryRadius,\n\tgetLiveEntry,\n} from '../../utils/spatial-hash';\n\n// ==================== Resource API ====================\n\nexport interface SpatialIndexResourceTypes {\n\tspatialIndex: SpatialIndex;\n}\n\nfunction createSpatialIndexResource(grid: SpatialHashGrid): SpatialIndex {\n\treturn {\n\t\tgrid,\n\t\tqueryRect(minX: number, minY: number, maxX: number, maxY: number): number[] {\n\t\t\tconst out: number[] = [];\n\t\t\tgridQueryRect(grid, minX, minY, maxX, maxY, out);\n\t\t\treturn out;\n\t\t},\n\t\tqueryRectInto(minX: number, minY: number, maxX: number, maxY: number, result: number[], minId?: number): void {\n\t\t\tgridQueryRect(grid, minX, minY, maxX, maxY, result, minId);\n\t\t},\n\t\tqueryRadius(cx: number, cy: number, radius: number): number[] {\n\t\t\tconst out: number[] = [];\n\t\t\tgridQueryRadius(grid, cx, cy, radius, out);\n\t\t\treturn out;\n\t\t},\n\t\tqueryRadiusInto(cx: number, cy: number, radius: number, result: number[]): void {\n\t\t\tgridQueryRadius(grid, cx, cy, radius, result);\n\t\t},\n\t\tgetEntry(entityId: number): SpatialEntry | undefined {\n\t\t\treturn getLiveEntry(grid, entityId);\n\t\t},\n\t};\n}\n\n// ==================== Component Types ====================\n\ntype SpatialIndexComponentTypes =\n\tTransformComponentTypes & Pick<CollisionComponentTypes<string>, 'aabbCollider' | 'circleCollider'>;\n\n// ==================== Plugin Options ====================\n\nexport type SpatialIndexPhase = 'fixedUpdate' | 'postUpdate';\ntype SpatialIndexLabel = `spatial-index-rebuild-${SpatialIndexPhase}`;\n\nexport interface SpatialIndexPluginOptions<G extends string = 'spatialIndex'> {\n\t/** Cell size for the spatial hash grid (default: 64) */\n\tcellSize?: number;\n\t/** System group name (default: 'spatialIndex') */\n\tsystemGroup?: G;\n\t/** Priority for rebuild systems (default: 2000, before collision) */\n\tpriority?: number;\n\t/** Phases to register rebuild systems in (default: ['fixedUpdate', 'postUpdate']) */\n\tphases?: ReadonlyArray<SpatialIndexPhase>;\n}\n\n// ==================== Plugin Factory ====================\n\n/**\n * Create a spatial index plugin for ECSpresso.\n *\n * Provides a uniform-grid spatial hash that accelerates collision detection.\n * When installed alongside the collision or physics2D plugins, they\n * automatically use the spatial index for broadphase instead of O(n²)\n * brute-force.\n *\n * Also provides proximity query methods for game logic (e.g. \"find all\n * enemies within 200 units\").\n *\n * @example\n * ```typescript\n * const ecs = ECSpresso.create()\n * .withPlugin(createTransformPlugin())\n * .withPlugin(createCollisionPlugin({ layers }))\n * .withPlugin(createSpatialIndexPlugin({ cellSize: 128 }))\n * .build();\n *\n * // Proximity query in a system:\n * const si = ecs.getResource('spatialIndex');\n * const nearby = si.queryRadius(playerX, playerY, 200);\n * ```\n */\nexport function createSpatialIndexPlugin<G extends string = 'spatialIndex'>(\n\toptions?: SpatialIndexPluginOptions<G>,\n) {\n\tconst {\n\t\tcellSize = 64,\n\t\tsystemGroup = 'spatialIndex',\n\t\tpriority = 2000,\n\t\tphases = ['fixedUpdate', 'postUpdate'] as const,\n\t} = options ?? {};\n\n\tconst grid = createGrid(cellSize);\n\tconst resource = createSpatialIndexResource(grid);\n\n\treturn definePlugin('spatialIndex')\n\t\t.withComponentTypes<SpatialIndexComponentTypes>()\n\t\t.withResourceTypes<SpatialIndexResourceTypes>()\n\t\t.withLabels<SpatialIndexLabel>()\n\t\t.withGroups<G>()\n\t\t.install((world) => {\n\t\t\tworld.addResource('spatialIndex', resource);\n\n\t\t\t// Register a rebuild system for each requested phase\n\t\t\tfor (const phase of phases) {\n\t\t\t\tconst transformComponent = phase === 'fixedUpdate' ? 'localTransform' : 'worldTransform';\n\n\t\t\t\tworld\n\t\t\t\t\t.addSystem(`spatial-index-rebuild-${phase}`)\n\t\t\t\t\t.setPriority(priority)\n\t\t\t\t\t.inPhase(phase as SystemPhase)\n\t\t\t\t\t.inGroup(systemGroup)\n\t\t\t\t\t.addQuery('transforms', {\n\t\t\t\t\t\twith: [transformComponent],\n\t\t\t\t\t})\n\t\t\t\t\t.setProcess(({ queries, ecs }) => {\n\t\t\t\t\t\tclearGrid(grid);\n\n\t\t\t\t\t\tfor (const entity of queries.transforms) {\n\t\t\t\t\t\t\tconst transform = entity.components[transformComponent];\n\t\t\t\t\t\t\tconst aabb = ecs.getComponent(entity.id, 'aabbCollider');\n\t\t\t\t\t\t\tconst circle = ecs.getComponent(entity.id, 'circleCollider');\n\n\t\t\t\t\t\t\t// Only insert entities that have a collider\n\t\t\t\t\t\t\tif (!aabb && !circle) continue;\n\n\t\t\t\t\t\t\tlet x = transform.x;\n\t\t\t\t\t\t\tlet y = transform.y;\n\t\t\t\t\t\t\tlet halfW = 0;\n\t\t\t\t\t\t\tlet halfH = 0;\n\n\t\t\t\t\t\t\tif (aabb) {\n\t\t\t\t\t\t\t\tx += aabb.offsetX ?? 0;\n\t\t\t\t\t\t\t\ty += aabb.offsetY ?? 0;\n\t\t\t\t\t\t\t\thalfW = aabb.width / 2;\n\t\t\t\t\t\t\t\thalfH = aabb.height / 2;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (circle) {\n\t\t\t\t\t\t\t\tx += circle.offsetX ?? 0;\n\t\t\t\t\t\t\t\ty += circle.offsetY ?? 0;\n\t\t\t\t\t\t\t\t// Circle: use radius as half-extent in both dimensions\n\t\t\t\t\t\t\t\thalfW = Math.max(halfW, circle.radius);\n\t\t\t\t\t\t\t\thalfH = Math.max(halfH, circle.radius);\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tinsertEntity(grid, entity.id, x, y, halfW, halfH);\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t}\n\t\t});\n}\n",
6
- "/**\n * Spatial Hash Grid\n *\n * Uniform-grid spatial hash for broadphase collision detection and\n * proximity queries. Pure data structure, no ECS dependencies.\n */\n\n// ==================== Data Structure ====================\n\nexport interface SpatialEntry {\n\tentityId: number;\n\tx: number;\n\ty: number;\n\thalfW: number;\n\thalfH: number;\n\t/** Generation stamp used by query functions to dedup multi-cell hits without a Set. Internal. */\n\t_lastSeenGen: number;\n\t/** Rebuild generation when this entry was last inserted. Internal. */\n\t_aliveGen: number;\n}\n\nexport interface SpatialHashGrid {\n\tcellSize: number;\n\tinvCellSize: number;\n\tcells: Map<number, SpatialEntry[]>;\n\t/**\n\t * Dense, indexed by entityId. Holes are `undefined`. Entries from previous\n\t * rebuilds remain in place for in-place reuse (zero allocation in steady\n\t * state); liveness is determined by `entry._aliveGen === grid._aliveGen`.\n\t * Internal — read live entries via `getEntry` / `liveEntryCount` helpers.\n\t *\n\t * High-water-mark grows with max entityId ever inserted; despawned ids\n\t * leave their slot occupied by a stale entry. Acceptable when the entity\n\t * manager recycles ids or peak count is bounded.\n\t */\n\tentries: (SpatialEntry | undefined)[];\n\t/** Monotonic counter bumped by each `clearGrid` call. Internal. */\n\t_aliveGen: number;\n\t/** Monotonic counter bumped on each query; entries record their last-seen gen for O(1) dedup. Internal. */\n\t_queryGen: number;\n}\n\n// ==================== Pure Functions ====================\n\n/**\n * Hash a cell coordinate pair to a single integer key.\n * Uses large-prime XOR to distribute values.\n */\nexport function hashCell(cx: number, cy: number): number {\n\t// Large primes for spatial hashing distribution\n\treturn (cx * 73856093) ^ (cy * 19349663);\n}\n\n/**\n * Create a new empty spatial hash grid.\n */\nexport function createGrid(cellSize: number): SpatialHashGrid {\n\treturn {\n\t\tcellSize,\n\t\tinvCellSize: 1 / cellSize,\n\t\tcells: new Map(),\n\t\tentries: [],\n\t\t_aliveGen: 0,\n\t\t_queryGen: 0,\n\t};\n}\n\n/**\n * Prepare the grid for a rebuild.\n *\n * Bumps the alive-generation counter so entries inserted prior to this call\n * are implicitly stale (any access via `getEntry`/`liveEntryCount` filters by\n * the current gen). Existing `SpatialEntry` objects remain in the `entries`\n * array for in-place reuse by the next `insertEntity`, so steady-state\n * rebuilds allocate zero entries.\n *\n * Cell buckets are cleared in place keys are retained so subsequent\n * inserts hit the existing array rather than allocating a fresh one.\n */\nexport function clearGrid(grid: SpatialHashGrid): void {\n\tgrid._aliveGen++;\n\n\tfor (const bucket of grid.cells.values()) {\n\t\tbucket.length = 0;\n\t}\n}\n\n/**\n * Insert an entity into all overlapping cells of the grid.\n */\nexport function insertEntity(\n\tgrid: SpatialHashGrid,\n\tentityId: number,\n\tx: number,\n\ty: number,\n\thalfW: number,\n\thalfH: number,\n): void {\n\tconst gen = grid._aliveGen;\n\tconst existing = grid.entries[entityId];\n\tlet entry: SpatialEntry;\n\tif (existing) {\n\t\texisting.x = x;\n\t\texisting.y = y;\n\t\texisting.halfW = halfW;\n\t\texisting.halfH = halfH;\n\t\texisting._aliveGen = gen;\n\t\tentry = existing;\n\t} else {\n\t\tentry = { entityId, x, y, halfW, halfH, _lastSeenGen: 0, _aliveGen: gen };\n\t\tgrid.entries[entityId] = entry;\n\t}\n\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor((x - halfW) * inv);\n\tconst maxCX = Math.floor((x + halfW) * inv);\n\tconst minCY = Math.floor((y - halfH) * inv);\n\tconst maxCY = Math.floor((y + halfH) * inv);\n\n\tfor (let cx = minCX; cx <= maxCX; cx++) {\n\t\tfor (let cy = minCY; cy <= maxCY; cy++) {\n\t\t\tconst key = hashCell(cx, cy);\n\t\t\tconst bucket = grid.cells.get(key);\n\t\t\tif (bucket) {\n\t\t\t\tbucket.push(entry);\n\t\t\t} else {\n\t\t\t\tgrid.cells.set(key, [entry]);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Collect entity IDs from all cells overlapping the given rectangle.\n *\n * Appends to `result` (caller clears/truncates first if reusing). Multi-cell\n * entries are deduplicated via a per-grid generation stamp on each\n * `SpatialEntry`.\n *\n * When `minId` is provided, only entries with `entityId > minId` are added —\n * used for symmetric broadphase pair generation.\n */\nexport function gridQueryRect(\n\tgrid: SpatialHashGrid,\n\tminX: number,\n\tminY: number,\n\tmaxX: number,\n\tmaxY: number,\n\tresult: number[],\n\tminId: number = -1,\n): void {\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor(minX * inv);\n\tconst maxCX = Math.floor(maxX * inv);\n\tconst minCY = Math.floor(minY * inv);\n\tconst maxCY = Math.floor(maxY * inv);\n\n\tconst gen = ++grid._queryGen;\n\n\tfor (let cx = minCX; cx <= maxCX; cx++) {\n\t\tfor (let cy = minCY; cy <= maxCY; cy++) {\n\t\t\tconst bucket = grid.cells.get(hashCell(cx, cy));\n\t\t\tif (!bucket) continue;\n\t\t\tfor (const entry of bucket) {\n\t\t\t\tif (entry.entityId <= minId || entry._lastSeenGen === gen) continue;\n\t\t\t\tentry._lastSeenGen = gen;\n\t\t\t\tresult.push(entry.entityId);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Collect entity IDs within a circle. AABB-to-point distance filter against\n * the cells overlapping the circle's bounding rect. Appends to `result`.\n */\nexport function gridQueryRadius(\n\tgrid: SpatialHashGrid,\n\tcx: number,\n\tcy: number,\n\tradius: number,\n\tresult: number[],\n): void {\n\tconst rSq = radius * radius;\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor((cx - radius) * inv);\n\tconst maxCX = Math.floor((cx + radius) * inv);\n\tconst minCY = Math.floor((cy - radius) * inv);\n\tconst maxCY = Math.floor((cy + radius) * inv);\n\n\tconst gen = ++grid._queryGen;\n\n\tfor (let icx = minCX; icx <= maxCX; icx++) {\n\t\tfor (let icy = minCY; icy <= maxCY; icy++) {\n\t\t\tconst bucket = grid.cells.get(hashCell(icx, icy));\n\t\t\tif (!bucket) continue;\n\t\t\tfor (const entry of bucket) {\n\t\t\t\tif (entry._lastSeenGen === gen) continue;\n\t\t\t\tentry._lastSeenGen = gen;\n\n\t\t\t\tconst closestX = Math.max(entry.x - entry.halfW, Math.min(cx, entry.x + entry.halfW));\n\t\t\t\tconst closestY = Math.max(entry.y - entry.halfH, Math.min(cy, entry.y + entry.halfH));\n\t\t\t\tconst dx = cx - closestX;\n\t\t\t\tconst dy = cy - closestY;\n\n\t\t\t\tif (dx * dx + dy * dy <= rSq) {\n\t\t\t\t\tresult.push(entry.entityId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Get the current-generation entry for an entityId, or `undefined` if the\n * entity isn't in the index for this rebuild. Stale entries from previous\n * rebuilds remain in `entries` for in-place reuse but are filtered here.\n */\nexport function getLiveEntry(grid: SpatialHashGrid, entityId: number): SpatialEntry | undefined {\n\tconst entry = grid.entries[entityId];\n\tif (!entry || entry._aliveGen !== grid._aliveGen) return undefined;\n\treturn entry;\n}\n\n/**\n * Count entries inserted in the current rebuild generation. Linear scan —\n * intended for tests and diagnostics, not hot paths.\n */\nexport function liveEntryCount(grid: SpatialHashGrid): number {\n\tconst gen = grid._aliveGen;\n\tlet n = 0;\n\tfor (const entry of grid.entries) {\n\t\tif (entry && entry._aliveGen === gen) n++;\n\t}\n\treturn n;\n}\n\n// ==================== Resource API ====================\n\n// TODO: Move SpatialIndex interface to src/plugins/spatial/spatial-index.ts.\n// It's a resource API concern, not a data structure concern. This file should\n// only contain the grid primitives (SpatialEntry, SpatialHashGrid, and the\n// pure functions that operate on them).\nexport interface SpatialIndex {\n\treadonly grid: SpatialHashGrid;\n\tqueryRect(minX: number, minY: number, maxX: number, maxY: number): number[];\n\tqueryRectInto(minX: number, minY: number, maxX: number, maxY: number, result: number[], minId?: number): void;\n\tqueryRadius(cx: number, cy: number, radius: number): number[];\n\tqueryRadiusInto(cx: number, cy: number, radius: number, result: number[]): void;\n\tgetEntry(entityId: number): SpatialEntry | undefined;\n}\n"
6
+ "/**\n * Spatial Hash Grid\n *\n * Uniform-grid spatial hash for broadphase collision detection and\n * proximity queries. Pure data structure, no ECS dependencies.\n */\n\n// ==================== Data Structure ====================\n\nexport interface SpatialEntry {\n\tentityId: number;\n\tx: number;\n\ty: number;\n\thalfW: number;\n\thalfH: number;\n\t/** Generation stamp used by query functions to dedup multi-cell hits without a Set. Internal. */\n\t_lastSeenGen: number;\n\t/** Rebuild generation when this entry was last inserted. Internal. */\n\t_aliveGen: number;\n}\n\n/**\n * A cell bucket — entries plus the alive-gen at which the bucket was last\n * filled. Buckets are reset lazily on the next insert in a new generation\n * (see `insertEntity`); queries skip buckets whose `_gen` is stale.\n *\n * Internal — exposed only through `SpatialHashGrid.cells`.\n */\ninterface CellBucket extends Array<SpatialEntry> {\n\t_gen: number;\n}\n\nexport interface SpatialHashGrid {\n\tcellSize: number;\n\tinvCellSize: number;\n\tcells: Map<number, CellBucket>;\n\t/**\n\t * Dense, indexed by entityId. Holes are `undefined`. Entries from previous\n\t * rebuilds remain in place for in-place reuse (zero allocation in steady\n\t * state); liveness is determined by `entry._aliveGen === grid._aliveGen`.\n\t * Internal — read live entries via `getEntry` / `liveEntryCount` helpers.\n\t *\n\t * High-water-mark grows with max entityId ever inserted; despawned ids\n\t * leave their slot occupied by a stale entry. Acceptable when the entity\n\t * manager recycles ids or peak count is bounded.\n\t */\n\tentries: (SpatialEntry | undefined)[];\n\t/** Monotonic counter bumped by each `clearGrid` call. Internal. */\n\t_aliveGen: number;\n\t/** Monotonic counter bumped on each query; entries record their last-seen gen for O(1) dedup. Internal. */\n\t_queryGen: number;\n}\n\n// ==================== Pure Functions ====================\n\n/**\n * Hash a cell coordinate pair to a single integer key.\n * Uses large-prime XOR to distribute values.\n */\nexport function hashCell(cx: number, cy: number): number {\n\t// Large primes for spatial hashing distribution\n\treturn (cx * 73856093) ^ (cy * 19349663);\n}\n\n/**\n * Create a new empty spatial hash grid.\n */\nexport function createGrid(cellSize: number): SpatialHashGrid {\n\treturn {\n\t\tcellSize,\n\t\tinvCellSize: 1 / cellSize,\n\t\tcells: new Map(),\n\t\tentries: [],\n\t\t_aliveGen: 0,\n\t\t_queryGen: 0,\n\t};\n}\n\n/**\n * Prepare the grid for a rebuild.\n *\n * O(1): bumps the alive-generation counter so entries inserted prior to this\n * call are implicitly stale. `getLiveEntry` / `liveEntryCount` filter\n * entries by the current gen; queries skip buckets whose own `_gen` lags\n * behind the alive gen; `insertEntity` resets a bucket's `length` lazily\n * the first time it is touched in a new generation.\n *\n * Existing `SpatialEntry` objects and `CellBucket` arrays remain in place\n * for reuse, so steady-state rebuilds allocate zero entries and zero\n * buckets, regardless of how many cells have ever been touched.\n */\nexport function clearGrid(grid: SpatialHashGrid): void {\n\tgrid._aliveGen++;\n}\n\n/**\n * Insert an entity into all overlapping cells of the grid.\n */\nexport function insertEntity(\n\tgrid: SpatialHashGrid,\n\tentityId: number,\n\tx: number,\n\ty: number,\n\thalfW: number,\n\thalfH: number,\n): void {\n\tconst gen = grid._aliveGen;\n\tconst existing = grid.entries[entityId];\n\tlet entry: SpatialEntry;\n\tif (existing) {\n\t\texisting.x = x;\n\t\texisting.y = y;\n\t\texisting.halfW = halfW;\n\t\texisting.halfH = halfH;\n\t\texisting._aliveGen = gen;\n\t\tentry = existing;\n\t} else {\n\t\tentry = { entityId, x, y, halfW, halfH, _lastSeenGen: 0, _aliveGen: gen };\n\t\tgrid.entries[entityId] = entry;\n\t}\n\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor((x - halfW) * inv);\n\tconst maxCX = Math.floor((x + halfW) * inv);\n\tconst minCY = Math.floor((y - halfH) * inv);\n\tconst maxCY = Math.floor((y + halfH) * inv);\n\n\tfor (let cx = minCX; cx <= maxCX; cx++) {\n\t\tfor (let cy = minCY; cy <= maxCY; cy++) {\n\t\t\tconst key = hashCell(cx, cy);\n\t\t\tconst bucket = grid.cells.get(key);\n\t\t\tif (bucket && bucket._gen === gen) {\n\t\t\t\t// Hot path: bucket already populated this generation.\n\t\t\t\tbucket.push(entry);\n\t\t\t} else if (bucket) {\n\t\t\t\t// First touch in this generation — drop stale entries from prior rebuilds.\n\t\t\t\tbucket.length = 0;\n\t\t\t\tbucket._gen = gen;\n\t\t\t\tbucket.push(entry);\n\t\t\t} else {\n\t\t\t\tconst fresh = [entry] as CellBucket;\n\t\t\t\tfresh._gen = gen;\n\t\t\t\tgrid.cells.set(key, fresh);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Collect entity IDs from all cells overlapping the given rectangle.\n *\n * Appends to `result` (caller clears/truncates first if reusing). Multi-cell\n * entries are deduplicated via a per-grid generation stamp on each\n * `SpatialEntry`.\n *\n * When `minId` is provided, only entries with `entityId > minId` are added —\n * used for symmetric broadphase pair generation.\n */\nexport function gridQueryRect(\n\tgrid: SpatialHashGrid,\n\tminX: number,\n\tminY: number,\n\tmaxX: number,\n\tmaxY: number,\n\tresult: number[],\n\tminId: number = -1,\n): void {\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor(minX * inv);\n\tconst maxCX = Math.floor(maxX * inv);\n\tconst minCY = Math.floor(minY * inv);\n\tconst maxCY = Math.floor(maxY * inv);\n\n\tconst gen = ++grid._queryGen;\n\tconst aliveGen = grid._aliveGen;\n\n\tfor (let cx = minCX; cx <= maxCX; cx++) {\n\t\tfor (let cy = minCY; cy <= maxCY; cy++) {\n\t\t\tconst bucket = grid.cells.get(hashCell(cx, cy));\n\t\t\tif (!bucket || bucket._gen !== aliveGen) continue;\n\t\t\tfor (const entry of bucket) {\n\t\t\t\tif (entry.entityId <= minId || entry._lastSeenGen === gen) continue;\n\t\t\t\tentry._lastSeenGen = gen;\n\t\t\t\tresult.push(entry.entityId);\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Collect entity IDs within a circle. AABB-to-point distance filter against\n * the cells overlapping the circle's bounding rect. Appends to `result`.\n */\nexport function gridQueryRadius(\n\tgrid: SpatialHashGrid,\n\tcx: number,\n\tcy: number,\n\tradius: number,\n\tresult: number[],\n): void {\n\tconst rSq = radius * radius;\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor((cx - radius) * inv);\n\tconst maxCX = Math.floor((cx + radius) * inv);\n\tconst minCY = Math.floor((cy - radius) * inv);\n\tconst maxCY = Math.floor((cy + radius) * inv);\n\n\tconst gen = ++grid._queryGen;\n\tconst aliveGen = grid._aliveGen;\n\n\tfor (let icx = minCX; icx <= maxCX; icx++) {\n\t\tfor (let icy = minCY; icy <= maxCY; icy++) {\n\t\t\tconst bucket = grid.cells.get(hashCell(icx, icy));\n\t\t\tif (!bucket || bucket._gen !== aliveGen) continue;\n\t\t\tfor (const entry of bucket) {\n\t\t\t\tif (entry._lastSeenGen === gen) continue;\n\t\t\t\tentry._lastSeenGen = gen;\n\n\t\t\t\tconst closestX = Math.max(entry.x - entry.halfW, Math.min(cx, entry.x + entry.halfW));\n\t\t\t\tconst closestY = Math.max(entry.y - entry.halfH, Math.min(cy, entry.y + entry.halfH));\n\t\t\t\tconst dx = cx - closestX;\n\t\t\t\tconst dy = cy - closestY;\n\n\t\t\t\tif (dx * dx + dy * dy <= rSq) {\n\t\t\t\t\tresult.push(entry.entityId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Get the current-generation entry for an entityId, or `undefined` if the\n * entity isn't in the index for this rebuild. Stale entries from previous\n * rebuilds remain in `entries` for in-place reuse but are filtered here.\n */\nexport function getLiveEntry(grid: SpatialHashGrid, entityId: number): SpatialEntry | undefined {\n\tconst entry = grid.entries[entityId];\n\tif (!entry || entry._aliveGen !== grid._aliveGen) return undefined;\n\treturn entry;\n}\n\n/**\n * Count entries inserted in the current rebuild generation. Linear scan —\n * intended for tests and diagnostics, not hot paths.\n */\nexport function liveEntryCount(grid: SpatialHashGrid): number {\n\tconst gen = grid._aliveGen;\n\tlet n = 0;\n\tfor (const entry of grid.entries) {\n\t\tif (entry && entry._aliveGen === gen) n++;\n\t}\n\treturn n;\n}\n\n// ==================== Resource API ====================\n\n// TODO: Move SpatialIndex interface to src/plugins/spatial/spatial-index.ts.\n// It's a resource API concern, not a data structure concern. This file should\n// only contain the grid primitives (SpatialEntry, SpatialHashGrid, and the\n// pure functions that operate on them).\nexport interface SpatialIndex {\n\treadonly grid: SpatialHashGrid;\n\tqueryRect(minX: number, minY: number, maxX: number, maxY: number): number[];\n\tqueryRectInto(minX: number, minY: number, maxX: number, maxY: number, result: number[], minId?: number): void;\n\tqueryRadius(cx: number, cy: number, radius: number): number[];\n\tqueryRadiusInto(cx: number, cy: number, radius: number, result: number[]): void;\n\tgetEntry(entityId: number): SpatialEntry | undefined;\n}\n"
7
7
  ],
8
- "mappings": "2PAYA,uBAAS,kBCoCF,SAAS,CAAQ,CAAC,EAAY,EAAoB,CAExD,OAAQ,EAAK,SAAa,EAAK,SAMzB,SAAS,CAAU,CAAC,EAAmC,CAC7D,MAAO,CACN,WACA,YAAa,EAAI,EACjB,MAAO,IAAI,IACX,QAAS,CAAC,EACV,UAAW,EACX,UAAW,CACZ,EAeM,SAAS,CAAS,CAAC,EAA6B,CACtD,EAAK,YAEL,QAAW,KAAU,EAAK,MAAM,OAAO,EACtC,EAAO,OAAS,EAOX,SAAS,CAAY,CAC3B,EACA,EACA,EACA,EACA,EACA,EACO,CACP,IAAM,EAAM,EAAK,UACX,EAAW,EAAK,QAAQ,GAC1B,EACJ,GAAI,EACH,EAAS,EAAI,EACb,EAAS,EAAI,EACb,EAAS,MAAQ,EACjB,EAAS,MAAQ,EACjB,EAAS,UAAY,EACrB,EAAQ,EAER,OAAQ,CAAE,WAAU,IAAG,IAAG,QAAO,QAAO,aAAc,EAAG,UAAW,CAAI,EACxE,EAAK,QAAQ,GAAY,EAG1B,IAAM,EAAM,EAAK,YACX,EAAQ,KAAK,OAAO,EAAI,GAAS,CAAG,EACpC,EAAQ,KAAK,OAAO,EAAI,GAAS,CAAG,EACpC,EAAQ,KAAK,OAAO,EAAI,GAAS,CAAG,EACpC,EAAQ,KAAK,OAAO,EAAI,GAAS,CAAG,EAE1C,QAAS,EAAK,EAAO,GAAM,EAAO,IACjC,QAAS,EAAK,EAAO,GAAM,EAAO,IAAM,CACvC,IAAM,EAAM,EAAS,EAAI,CAAE,EACrB,EAAS,EAAK,MAAM,IAAI,CAAG,EACjC,GAAI,EACH,EAAO,KAAK,CAAK,EAEjB,OAAK,MAAM,IAAI,EAAK,CAAC,CAAK,CAAC,GAgBxB,SAAS,CAAa,CAC5B,EACA,EACA,EACA,EACA,EACA,EACA,EAAgB,GACT,CACP,IAAM,EAAM,EAAK,YACX,EAAQ,KAAK,MAAM,EAAO,CAAG,EAC7B,EAAQ,KAAK,MAAM,EAAO,CAAG,EAC7B,EAAQ,KAAK,MAAM,EAAO,CAAG,EAC7B,EAAQ,KAAK,MAAM,EAAO,CAAG,EAE7B,EAAM,EAAE,EAAK,UAEnB,QAAS,EAAK,EAAO,GAAM,EAAO,IACjC,QAAS,EAAK,EAAO,GAAM,EAAO,IAAM,CACvC,IAAM,EAAS,EAAK,MAAM,IAAI,EAAS,EAAI,CAAE,CAAC,EAC9C,GAAI,CAAC,EAAQ,SACb,QAAW,KAAS,EAAQ,CAC3B,GAAI,EAAM,UAAY,GAAS,EAAM,eAAiB,EAAK,SAC3D,EAAM,aAAe,EACrB,EAAO,KAAK,EAAM,QAAQ,IAUvB,SAAS,CAAe,CAC9B,EACA,EACA,EACA,EACA,EACO,CACP,IAAM,EAAM,EAAS,EACf,EAAM,EAAK,YACX,EAAQ,KAAK,OAAO,EAAK,GAAU,CAAG,EACtC,EAAQ,KAAK,OAAO,EAAK,GAAU,CAAG,EACtC,EAAQ,KAAK,OAAO,EAAK,GAAU,CAAG,EACtC,EAAQ,KAAK,OAAO,EAAK,GAAU,CAAG,EAEtC,EAAM,EAAE,EAAK,UAEnB,QAAS,EAAM,EAAO,GAAO,EAAO,IACnC,QAAS,EAAM,EAAO,GAAO,EAAO,IAAO,CAC1C,IAAM,EAAS,EAAK,MAAM,IAAI,EAAS,EAAK,CAAG,CAAC,EAChD,GAAI,CAAC,EAAQ,SACb,QAAW,KAAS,EAAQ,CAC3B,GAAI,EAAM,eAAiB,EAAK,SAChC,EAAM,aAAe,EAErB,IAAM,EAAW,KAAK,IAAI,EAAM,EAAI,EAAM,MAAO,KAAK,IAAI,EAAI,EAAM,EAAI,EAAM,KAAK,CAAC,EAC9E,EAAW,KAAK,IAAI,EAAM,EAAI,EAAM,MAAO,KAAK,IAAI,EAAI,EAAM,EAAI,EAAM,KAAK,CAAC,EAC9E,EAAK,EAAK,EACV,EAAK,EAAK,EAEhB,GAAI,EAAK,EAAK,EAAK,GAAM,EACxB,EAAO,KAAK,EAAM,QAAQ,IAYxB,SAAS,CAAY,CAAC,EAAuB,EAA4C,CAC/F,IAAM,EAAQ,EAAK,QAAQ,GAC3B,GAAI,CAAC,GAAS,EAAM,YAAc,EAAK,UAAW,OAClD,OAAO,ED3LR,SAAS,CAA0B,CAAC,EAAqC,CACxE,MAAO,CACN,OACA,SAAS,CAAC,EAAc,EAAc,EAAc,EAAwB,CAC3E,IAAM,EAAgB,CAAC,EAEvB,OADA,EAAc,EAAM,EAAM,EAAM,EAAM,EAAM,CAAG,EACxC,GAER,aAAa,CAAC,EAAc,EAAc,EAAc,EAAc,EAAkB,EAAsB,CAC7G,EAAc,EAAM,EAAM,EAAM,EAAM,EAAM,EAAQ,CAAK,GAE1D,WAAW,CAAC,EAAY,EAAY,EAA0B,CAC7D,IAAM,EAAgB,CAAC,EAEvB,OADA,EAAgB,EAAM,EAAI,EAAI,EAAQ,CAAG,EAClC,GAER,eAAe,CAAC,EAAY,EAAY,EAAgB,EAAwB,CAC/E,EAAgB,EAAM,EAAI,EAAI,EAAQ,CAAM,GAE7C,QAAQ,CAAC,EAA4C,CACpD,OAAO,EAAa,EAAM,CAAQ,EAEpC,EAkDM,SAAS,CAA2D,CAC1E,EACC,CACD,IACC,WAAW,GACX,cAAc,eACd,WAAW,KACX,SAAS,CAAC,cAAe,YAAY,GAClC,GAAW,CAAC,EAEV,EAAO,EAAW,CAAQ,EAC1B,EAAW,EAA2B,CAAI,EAEhD,OAAO,EAAa,cAAc,EAChC,mBAA+C,EAC/C,kBAA6C,EAC7C,WAA8B,EAC9B,WAAc,EACd,QAAQ,CAAC,IAAU,CACnB,EAAM,YAAY,eAAgB,CAAQ,EAG1C,QAAW,KAAS,EAAQ,CAC3B,IAAM,EAAqB,IAAU,cAAgB,iBAAmB,iBAExE,EACE,UAAU,yBAAyB,GAAO,EAC1C,YAAY,CAAQ,EACpB,QAAQ,CAAoB,EAC5B,QAAQ,CAAW,EACnB,SAAS,aAAc,CACvB,KAAM,CAAC,CAAkB,CAC1B,CAAC,EACA,WAAW,EAAG,UAAS,SAAU,CACjC,EAAU,CAAI,EAEd,QAAW,KAAU,EAAQ,WAAY,CACxC,IAAM,EAAY,EAAO,WAAW,GAC9B,EAAO,EAAI,aAAa,EAAO,GAAI,cAAc,EACjD,EAAS,EAAI,aAAa,EAAO,GAAI,gBAAgB,EAG3D,GAAI,CAAC,GAAQ,CAAC,EAAQ,SAEtB,IAAkB,EAAd,EACc,EAAd,GAAI,EACJ,EAAQ,EACR,EAAQ,EAEZ,GAAI,EACH,GAAK,EAAK,SAAW,EACrB,GAAK,EAAK,SAAW,EACrB,EAAQ,EAAK,MAAQ,EACrB,EAAQ,EAAK,OAAS,EAGvB,GAAI,EACH,GAAK,EAAO,SAAW,EACvB,GAAK,EAAO,SAAW,EAEvB,EAAQ,KAAK,IAAI,EAAO,EAAO,MAAM,EACrC,EAAQ,KAAK,IAAI,EAAO,EAAO,MAAM,EAGtC,EAAa,EAAM,EAAO,GAAI,EAAG,EAAG,EAAO,CAAK,GAEjD,GAEH",
9
- "debugId": "0408432B17B2791864756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "9F6AD37F3DB1C43164756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -1,4 +1,4 @@
1
- var f=((F)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(F,{get:(J,K)=>(typeof require<"u"?require:J)[K]}):F)(function(F){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+F+'" is not supported')});import{definePlugin as D}from"ecspresso";function W(F,J,K){return F*73856093^J*19349663^K*83492791}function v(F){return{cellSize:F,invCellSize:1/F,cells:new Map,entries:[],_aliveGen:0,_queryGen:0}}function C(F){F._aliveGen++;for(let J of F.cells.values())J.length=0}function k(F,J,K,U,M,O,j,V){let P=F._aliveGen,_=F.entries[J],R;if(_)_.x=K,_.y=U,_.z=M,_.halfW=O,_.halfH=j,_.halfD=V,_._aliveGen=P,R=_;else R={entityId:J,x:K,y:U,z:M,halfW:O,halfH:j,halfD:V,_lastSeenGen:0,_aliveGen:P},F.entries[J]=R;let L=F.invCellSize,q=Math.floor((K-O)*L),A=Math.floor((K+O)*L),$=Math.floor((U-j)*L),T=Math.floor((U+j)*L),G=Math.floor((M-V)*L),E=Math.floor((M+V)*L);for(let B=q;B<=A;B++)for(let N=$;N<=T;N++)for(let w=G;w<=E;w++){let Q=W(B,N,w),S=F.cells.get(Q);if(S)S.push(R);else F.cells.set(Q,[R])}}function H(F,J,K,U,M,O,j,V,P=-1){let _=F.invCellSize,R=Math.floor(J*_),L=Math.floor(M*_),q=Math.floor(K*_),A=Math.floor(O*_),$=Math.floor(U*_),T=Math.floor(j*_),G=++F._queryGen;for(let E=R;E<=L;E++)for(let B=q;B<=A;B++)for(let N=$;N<=T;N++){let w=F.cells.get(W(E,B,N));if(!w)continue;for(let Q of w){if(Q.entityId<=P||Q._lastSeenGen===G)continue;Q._lastSeenGen=G,V.push(Q.entityId)}}}function I(F,J,K,U,M,O){let j=M*M,V=F.invCellSize,P=Math.floor((J-M)*V),_=Math.floor((J+M)*V),R=Math.floor((K-M)*V),L=Math.floor((K+M)*V),q=Math.floor((U-M)*V),A=Math.floor((U+M)*V),$=++F._queryGen;for(let T=P;T<=_;T++)for(let G=R;G<=L;G++)for(let E=q;E<=A;E++){let B=F.cells.get(W(T,G,E));if(!B)continue;for(let N of B){if(N._lastSeenGen===$)continue;N._lastSeenGen=$;let w=Math.max(N.x-N.halfW,Math.min(J,N.x+N.halfW)),Q=Math.max(N.y-N.halfH,Math.min(K,N.y+N.halfH)),S=Math.max(N.z-N.halfD,Math.min(U,N.z+N.halfD)),X=J-w,Y=K-Q,Z=U-S;if(X*X+Y*Y+Z*Z<=j)O.push(N.entityId)}}}function b(F,J){let K=F.entries[J];if(!K||K._aliveGen!==F._aliveGen)return;return K}function p(F){return{grid:F,queryBox(J,K,U,M,O,j){let V=[];return H(F,J,K,U,M,O,j,V),V},queryBoxInto(J,K,U,M,O,j,V,P){H(F,J,K,U,M,O,j,V,P)},queryRadius(J,K,U,M){let O=[];return I(F,J,K,U,M,O),O},queryRadiusInto(J,K,U,M,O){I(F,J,K,U,M,O)},getEntry(J){return b(F,J)}}}function l(F){let{cellSize:J=64,systemGroup:K="spatialIndex3D",priority:U=2000,phases:M=["fixedUpdate","postUpdate"]}=F??{},O=v(J),j=p(O);return D("spatialIndex3D").withComponentTypes().withResourceTypes().withLabels().withGroups().install((V)=>{V.addResource("spatialIndex3D",j);for(let P of M){let _=P==="fixedUpdate"?"localTransform3D":"worldTransform3D";V.addSystem(`spatial-index3D-rebuild-${P}`).setPriority(U).inPhase(P).inGroup(K).addQuery("transforms",{with:[_]}).runWhenEmpty().setProcess(({queries:R,ecs:L})=>{C(O);for(let q of R.transforms){let A=q.components[_],$=L.getComponent(q.id,"aabb3DCollider"),T=$?void 0:L.getComponent(q.id,"sphereCollider");if($){k(O,q.id,A.x+($.offsetX??0),A.y+($.offsetY??0),A.z+($.offsetZ??0),$.width/2,$.height/2,$.depth/2);continue}if(T){let G=T.radius;k(O,q.id,A.x+(T.offsetX??0),A.y+(T.offsetY??0),A.z+(T.offsetZ??0),G,G,G)}}})}})}export{l as createSpatialIndex3DPlugin};
1
+ var z=((F)=>typeof require<"u"?require:typeof Proxy<"u"?new Proxy(F,{get:(K,J)=>(typeof require<"u"?require:K)[J]}):F)(function(F){if(typeof require<"u")return require.apply(this,arguments);throw Error('Dynamic require of "'+F+'" is not supported')});import{definePlugin as b}from"ecspresso";function H(F,K,J){return F*73856093^K*19349663^J*83492791}function C(F){return{cellSize:F,invCellSize:1/F,cells:new Map,entries:[],_aliveGen:0,_queryGen:0}}function D(F){F._aliveGen++}function k(F,K,J,U,M,O,L,V){let $=F._aliveGen,_=F.entries[K],A;if(_)_.x=J,_.y=U,_.z=M,_.halfW=O,_.halfH=L,_.halfD=V,_._aliveGen=$,A=_;else A={entityId:K,x:J,y:U,z:M,halfW:O,halfH:L,halfD:V,_lastSeenGen:0,_aliveGen:$},F.entries[K]=A;let P=F.invCellSize,B=Math.floor((J-O)*P),R=Math.floor((J+O)*P),j=Math.floor((U-L)*P),E=Math.floor((U+L)*P),q=Math.floor((M-V)*P),S=Math.floor((M+V)*P);for(let Q=B;Q<=R;Q++)for(let G=j;G<=E;G++)for(let N=q;N<=S;N++){let w=H(Q,G,N),T=F.cells.get(w);if(T&&T._gen===$)T.push(A);else if(T)T.length=0,T._gen=$,T.push(A);else{let W=[A];W._gen=$,F.cells.set(w,W)}}}function I(F,K,J,U,M,O,L,V,$=-1){let _=F.invCellSize,A=Math.floor(K*_),P=Math.floor(M*_),B=Math.floor(J*_),R=Math.floor(O*_),j=Math.floor(U*_),E=Math.floor(L*_),q=++F._queryGen,S=F._aliveGen;for(let Q=A;Q<=P;Q++)for(let G=B;G<=R;G++)for(let N=j;N<=E;N++){let w=F.cells.get(H(Q,G,N));if(!w||w._gen!==S)continue;for(let T of w){if(T.entityId<=$||T._lastSeenGen===q)continue;T._lastSeenGen=q,V.push(T.entityId)}}}function X(F,K,J,U,M,O){let L=M*M,V=F.invCellSize,$=Math.floor((K-M)*V),_=Math.floor((K+M)*V),A=Math.floor((J-M)*V),P=Math.floor((J+M)*V),B=Math.floor((U-M)*V),R=Math.floor((U+M)*V),j=++F._queryGen,E=F._aliveGen;for(let q=$;q<=_;q++)for(let S=A;S<=P;S++)for(let Q=B;Q<=R;Q++){let G=F.cells.get(H(q,S,Q));if(!G||G._gen!==E)continue;for(let N of G){if(N._lastSeenGen===j)continue;N._lastSeenGen=j;let w=Math.max(N.x-N.halfW,Math.min(K,N.x+N.halfW)),T=Math.max(N.y-N.halfH,Math.min(J,N.y+N.halfH)),W=Math.max(N.z-N.halfD,Math.min(U,N.z+N.halfD)),Y=K-w,Z=J-T,v=U-W;if(Y*Y+Z*Z+v*v<=L)O.push(N.entityId)}}}function p(F,K){let J=F.entries[K];if(!J||J._aliveGen!==F._aliveGen)return;return J}function f(F){return{grid:F,queryBox(K,J,U,M,O,L){let V=[];return I(F,K,J,U,M,O,L,V),V},queryBoxInto(K,J,U,M,O,L,V,$){I(F,K,J,U,M,O,L,V,$)},queryRadius(K,J,U,M){let O=[];return X(F,K,J,U,M,O),O},queryRadiusInto(K,J,U,M,O){X(F,K,J,U,M,O)},getEntry(K){return p(F,K)}}}function m(F){let{cellSize:K=64,systemGroup:J="spatialIndex3D",priority:U=2000,phases:M=["fixedUpdate","postUpdate"]}=F??{},O=C(K),L=f(O);return b("spatialIndex3D").withComponentTypes().withResourceTypes().withLabels().withGroups().install((V)=>{V.addResource("spatialIndex3D",L);for(let $ of M){let _=$==="fixedUpdate"?"localTransform3D":"worldTransform3D";V.addSystem(`spatial-index3D-rebuild-${$}`).setPriority(U).inPhase($).inGroup(J).addQuery("transforms",{with:[_]}).runWhenEmpty().setProcess(({queries:A,ecs:P})=>{D(O);for(let B of A.transforms){let R=B.components[_],j=P.getComponent(B.id,"aabb3DCollider"),E=j?void 0:P.getComponent(B.id,"sphereCollider");if(j){k(O,B.id,R.x+(j.offsetX??0),R.y+(j.offsetY??0),R.z+(j.offsetZ??0),j.width/2,j.height/2,j.depth/2);continue}if(E){let q=E.radius;k(O,B.id,R.x+(E.offsetX??0),R.y+(E.offsetY??0),R.z+(E.offsetZ??0),q,q,q)}}})}})}export{m as createSpatialIndex3DPlugin};
2
2
 
3
- //# debugId=10C4CA741CCEA05664756E2164756E21
3
+ //# debugId=FC8F8AAE90676C3164756E2164756E21
4
4
  //# sourceMappingURL=spatial-index3D.js.map
@@ -3,9 +3,9 @@
3
3
  "sources": ["../src/plugins/spatial/spatial-index3D.ts", "../src/utils/spatial-hash3D.ts"],
4
4
  "sourcesContent": [
5
5
  "/**\n * Spatial Index 3D Plugin for ECSpresso\n *\n * Provides a uniform-grid spatial hash for broadphase collision detection\n * and proximity queries in 3D. Rebuilds the grid each frame from entity\n * transforms. Replaces O(n²) brute-force with O(n·d) where d = local density.\n *\n * Standalone usage: queryBox / queryRadius for proximity queries.\n * Automatic acceleration: collision3D and physics3D plugins detect the\n * spatialIndex3D resource at runtime and use it for broadphase when present.\n */\n\nimport { definePlugin } from 'ecspresso';\nimport type { SystemPhase } from 'ecspresso';\nimport type { Transform3DComponentTypes } from './transform3D';\nimport {\n\ttype SpatialEntry3D,\n\ttype SpatialHashGrid3D,\n\ttype SpatialIndex3D,\n\tcreateGrid3D,\n\tclearGrid3D,\n\tinsertEntity3D,\n\tgridQueryBox3D,\n\tgridQueryRadius3D,\n\tgetLiveEntry3D,\n} from '../../utils/spatial-hash3D';\n\n// ==================== Collider Component Types ====================\n\n/**\n * 3D axis-aligned bounding box collider component.\n * Defined here (spatial layer) so collision3D can import rather than redefine.\n */\nexport interface AABB3DCollider {\n\twidth: number;\n\theight: number;\n\tdepth: number;\n\toffsetX?: number;\n\toffsetY?: number;\n\toffsetZ?: number;\n}\n\n/**\n * Sphere collider component.\n * Defined here (spatial layer) so collision3D can import rather than redefine.\n */\nexport interface SphereCollider {\n\tradius: number;\n\toffsetX?: number;\n\toffsetY?: number;\n\toffsetZ?: number;\n}\n\nexport interface Spatial3DColliderComponentTypes {\n\taabb3DCollider: AABB3DCollider;\n\tsphereCollider: SphereCollider;\n}\n\n// ==================== Resource API ====================\n\nexport interface SpatialIndex3DResourceTypes {\n\tspatialIndex3D: SpatialIndex3D;\n}\n\nfunction createSpatialIndex3DResource(grid: SpatialHashGrid3D): SpatialIndex3D {\n\treturn {\n\t\tgrid,\n\t\tqueryBox(minX: number, minY: number, minZ: number, maxX: number, maxY: number, maxZ: number): number[] {\n\t\t\tconst out: number[] = [];\n\t\t\tgridQueryBox3D(grid, minX, minY, minZ, maxX, maxY, maxZ, out);\n\t\t\treturn out;\n\t\t},\n\t\tqueryBoxInto(minX: number, minY: number, minZ: number, maxX: number, maxY: number, maxZ: number, result: number[], minId?: number): void {\n\t\t\tgridQueryBox3D(grid, minX, minY, minZ, maxX, maxY, maxZ, result, minId);\n\t\t},\n\t\tqueryRadius(cx: number, cy: number, cz: number, radius: number): number[] {\n\t\t\tconst out: number[] = [];\n\t\t\tgridQueryRadius3D(grid, cx, cy, cz, radius, out);\n\t\t\treturn out;\n\t\t},\n\t\tqueryRadiusInto(cx: number, cy: number, cz: number, radius: number, result: number[]): void {\n\t\t\tgridQueryRadius3D(grid, cx, cy, cz, radius, result);\n\t\t},\n\t\tgetEntry(entityId: number): SpatialEntry3D | undefined {\n\t\t\treturn getLiveEntry3D(grid, entityId);\n\t\t},\n\t};\n}\n\n// ==================== Component Types ====================\n\ntype SpatialIndex3DComponentTypes = Transform3DComponentTypes & Spatial3DColliderComponentTypes;\n\n// ==================== Plugin Options ====================\n\nexport type SpatialIndex3DPhase = 'fixedUpdate' | 'postUpdate';\ntype SpatialIndex3DLabel = `spatial-index3D-rebuild-${SpatialIndex3DPhase}`;\n\nexport interface SpatialIndex3DPluginOptions<G extends string = 'spatialIndex3D'> {\n\t/** Cell size for the spatial hash grid (default: 64) */\n\tcellSize?: number;\n\t/** System group name (default: 'spatialIndex3D') */\n\tsystemGroup?: G;\n\t/** Priority for rebuild systems (default: 2000, before collision) */\n\tpriority?: number;\n\t/** Phases to register rebuild systems in (default: ['fixedUpdate', 'postUpdate']) */\n\tphases?: ReadonlyArray<SpatialIndex3DPhase>;\n}\n\n// ==================== Plugin Factory ====================\n\n/**\n * Create a 3D spatial index plugin for ECSpresso.\n *\n * Provides a uniform-grid spatial hash that accelerates 3D collision detection.\n * When installed alongside the collision3D or physics3D plugins, they\n * automatically use the spatial index for broadphase instead of O(n²)\n * brute-force.\n *\n * Also provides proximity query methods for game logic (e.g. \"find all\n * enemies within 200 units\").\n *\n * @example\n * ```typescript\n * const ecs = ECSpresso.create()\n * .withPlugin(createTransform3DPlugin())\n * .withPlugin(createCollision3DPlugin({ layers }))\n * .withPlugin(createSpatialIndex3DPlugin({ cellSize: 128 }))\n * .build();\n *\n * // Proximity query in a system:\n * const si = ecs.getResource('spatialIndex3D');\n * const nearby = si.queryRadius(playerX, playerY, playerZ, 200);\n * ```\n */\nexport function createSpatialIndex3DPlugin<G extends string = 'spatialIndex3D'>(\n\toptions?: SpatialIndex3DPluginOptions<G>,\n) {\n\tconst {\n\t\tcellSize = 64,\n\t\tsystemGroup = 'spatialIndex3D',\n\t\tpriority = 2000,\n\t\tphases = ['fixedUpdate', 'postUpdate'] as const,\n\t} = options ?? {};\n\n\tconst grid = createGrid3D(cellSize);\n\tconst resource = createSpatialIndex3DResource(grid);\n\n\treturn definePlugin('spatialIndex3D')\n\t\t.withComponentTypes<SpatialIndex3DComponentTypes>()\n\t\t.withResourceTypes<SpatialIndex3DResourceTypes>()\n\t\t.withLabels<SpatialIndex3DLabel>()\n\t\t.withGroups<G>()\n\t\t.install((world) => {\n\t\t\tworld.addResource('spatialIndex3D', resource);\n\n\t\t\t// Register a rebuild system for each requested phase\n\t\t\tfor (const phase of phases) {\n\t\t\t\tconst transformComponent = phase === 'fixedUpdate' ? 'localTransform3D' : 'worldTransform3D';\n\n\t\t\t\tworld\n\t\t\t\t\t.addSystem(`spatial-index3D-rebuild-${phase}`)\n\t\t\t\t\t.setPriority(priority)\n\t\t\t\t\t.inPhase(phase as SystemPhase)\n\t\t\t\t\t.inGroup(systemGroup)\n\t\t\t\t\t.addQuery('transforms', {\n\t\t\t\t\t\twith: [transformComponent],\n\t\t\t\t\t})\n\t\t\t\t\t.runWhenEmpty()\n\t\t\t\t\t.setProcess(({ queries, ecs }) => {\n\t\t\t\t\t\tclearGrid3D(grid);\n\n\t\t\t\t\t\tfor (const entity of queries.transforms) {\n\t\t\t\t\t\t\tconst transform = entity.components[transformComponent];\n\t\t\t\t\t\t\tconst aabb = ecs.getComponent(entity.id, 'aabb3DCollider');\n\t\t\t\t\t\t\t// AABB wins when both are present, matching collision3D / physics3D.\n\t\t\t\t\t\t\tconst sphere = aabb ? undefined : ecs.getComponent(entity.id, 'sphereCollider');\n\n\t\t\t\t\t\t\tif (aabb) {\n\t\t\t\t\t\t\t\tinsertEntity3D(\n\t\t\t\t\t\t\t\t\tgrid, entity.id,\n\t\t\t\t\t\t\t\t\ttransform.x + (aabb.offsetX ?? 0),\n\t\t\t\t\t\t\t\t\ttransform.y + (aabb.offsetY ?? 0),\n\t\t\t\t\t\t\t\t\ttransform.z + (aabb.offsetZ ?? 0),\n\t\t\t\t\t\t\t\t\taabb.width / 2, aabb.height / 2, aabb.depth / 2,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t\tcontinue;\n\t\t\t\t\t\t\t}\n\n\t\t\t\t\t\t\tif (sphere) {\n\t\t\t\t\t\t\t\tconst r = sphere.radius;\n\t\t\t\t\t\t\t\tinsertEntity3D(\n\t\t\t\t\t\t\t\t\tgrid, entity.id,\n\t\t\t\t\t\t\t\t\ttransform.x + (sphere.offsetX ?? 0),\n\t\t\t\t\t\t\t\t\ttransform.y + (sphere.offsetY ?? 0),\n\t\t\t\t\t\t\t\t\ttransform.z + (sphere.offsetZ ?? 0),\n\t\t\t\t\t\t\t\t\tr, r, r,\n\t\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t}\n\t\t\t\t\t});\n\t\t\t}\n\t\t});\n}\n",
6
- "/**\n * Spatial Hash Grid 3D\n *\n * Uniform-grid spatial hash for broadphase collision detection and\n * proximity queries in 3D. Pure data structure, no ECS dependencies.\n */\n\n// ==================== Data Structures ====================\n\nexport interface SpatialEntry3D {\n\tentityId: number;\n\tx: number;\n\ty: number;\n\tz: number;\n\thalfW: number;\n\thalfH: number;\n\thalfD: number;\n\t/** Generation stamp used by query functions to dedup multi-cell hits without a Set. Internal. */\n\t_lastSeenGen: number;\n\t/** Rebuild generation when this entry was last inserted. Internal. */\n\t_aliveGen: number;\n}\n\nexport interface SpatialHashGrid3D {\n\tcellSize: number;\n\tinvCellSize: number;\n\tcells: Map<number, SpatialEntry3D[]>;\n\t/**\n\t * Dense, indexed by entityId. Holes are `undefined`. Entries from previous\n\t * rebuilds remain in place for in-place reuse (zero allocation in steady\n\t * state); liveness is determined by `entry._aliveGen === grid._aliveGen`.\n\t * Internal — read live entries via `getLiveEntry3D` / `liveEntryCount3D` helpers.\n\t *\n\t * High-water-mark grows with max entityId ever inserted; despawned ids\n\t * leave their slot occupied by a stale entry. Acceptable when the entity\n\t * manager recycles ids or peak count is bounded.\n\t */\n\tentries: (SpatialEntry3D | undefined)[];\n\t/** Monotonic counter bumped by each `clearGrid3D` call. Internal. */\n\t_aliveGen: number;\n\t/** Monotonic counter bumped on each query; entries record their last-seen gen for O(1) dedup. Internal. */\n\t_queryGen: number;\n}\n\n// ==================== Pure Functions ====================\n\n/**\n * Hash a cell coordinate triple to a single integer key.\n * Uses large-prime XOR to distribute values.\n */\nexport function hashCell3D(cx: number, cy: number, cz: number): number {\n\t// Large primes for spatial hashing distribution\n\treturn (cx * 73856093) ^ (cy * 19349663) ^ (cz * 83492791);\n}\n\n/**\n * Create a new empty 3D spatial hash grid.\n */\nexport function createGrid3D(cellSize: number): SpatialHashGrid3D {\n\treturn {\n\t\tcellSize,\n\t\tinvCellSize: 1 / cellSize,\n\t\tcells: new Map(),\n\t\tentries: [],\n\t\t_aliveGen: 0,\n\t\t_queryGen: 0,\n\t};\n}\n\n/**\n * Prepare the grid for a rebuild.\n *\n * Bumps the alive-generation counter so entries inserted prior to this call\n * are implicitly stale (any access via `getLiveEntry3D` / `liveEntryCount3D`\n * filters by the current gen). Existing `SpatialEntry3D` objects remain in\n * the `entries` array for in-place reuse by the next `insertEntity3D`, so\n * steady-state rebuilds allocate zero entries.\n *\n * Cell buckets are cleared in place — keys are retained so subsequent\n * inserts hit the existing array rather than allocating a fresh one.\n */\nexport function clearGrid3D(grid: SpatialHashGrid3D): void {\n\tgrid._aliveGen++;\n\n\tfor (const bucket of grid.cells.values()) {\n\t\tbucket.length = 0;\n\t}\n}\n\n/**\n * Insert an entity into all overlapping cells of the grid.\n */\nexport function insertEntity3D(\n\tgrid: SpatialHashGrid3D,\n\tentityId: number,\n\tx: number,\n\ty: number,\n\tz: number,\n\thalfW: number,\n\thalfH: number,\n\thalfD: number,\n): void {\n\tconst gen = grid._aliveGen;\n\tconst existing = grid.entries[entityId];\n\tlet entry: SpatialEntry3D;\n\tif (existing) {\n\t\texisting.x = x;\n\t\texisting.y = y;\n\t\texisting.z = z;\n\t\texisting.halfW = halfW;\n\t\texisting.halfH = halfH;\n\t\texisting.halfD = halfD;\n\t\texisting._aliveGen = gen;\n\t\tentry = existing;\n\t} else {\n\t\tentry = { entityId, x, y, z, halfW, halfH, halfD, _lastSeenGen: 0, _aliveGen: gen };\n\t\tgrid.entries[entityId] = entry;\n\t}\n\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor((x - halfW) * inv);\n\tconst maxCX = Math.floor((x + halfW) * inv);\n\tconst minCY = Math.floor((y - halfH) * inv);\n\tconst maxCY = Math.floor((y + halfH) * inv);\n\tconst minCZ = Math.floor((z - halfD) * inv);\n\tconst maxCZ = Math.floor((z + halfD) * inv);\n\n\tfor (let cx = minCX; cx <= maxCX; cx++) {\n\t\tfor (let cy = minCY; cy <= maxCY; cy++) {\n\t\t\tfor (let cz = minCZ; cz <= maxCZ; cz++) {\n\t\t\t\tconst key = hashCell3D(cx, cy, cz);\n\t\t\t\tconst bucket = grid.cells.get(key);\n\t\t\t\tif (bucket) {\n\t\t\t\t\tbucket.push(entry);\n\t\t\t\t} else {\n\t\t\t\t\tgrid.cells.set(key, [entry]);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Collect entity IDs from all cells overlapping the given 3D box.\n *\n * Appends to `result` (caller clears/truncates first if reusing). Multi-cell\n * entries are deduplicated via a per-grid generation stamp on each\n * `SpatialEntry3D`.\n *\n * When `minId` is provided, only entries with `entityId > minId` are added —\n * used for symmetric broadphase pair generation.\n */\nexport function gridQueryBox3D(\n\tgrid: SpatialHashGrid3D,\n\tminX: number,\n\tminY: number,\n\tminZ: number,\n\tmaxX: number,\n\tmaxY: number,\n\tmaxZ: number,\n\tresult: number[],\n\tminId: number = -1,\n): void {\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor(minX * inv);\n\tconst maxCX = Math.floor(maxX * inv);\n\tconst minCY = Math.floor(minY * inv);\n\tconst maxCY = Math.floor(maxY * inv);\n\tconst minCZ = Math.floor(minZ * inv);\n\tconst maxCZ = Math.floor(maxZ * inv);\n\n\tconst gen = ++grid._queryGen;\n\n\tfor (let cx = minCX; cx <= maxCX; cx++) {\n\t\tfor (let cy = minCY; cy <= maxCY; cy++) {\n\t\t\tfor (let cz = minCZ; cz <= maxCZ; cz++) {\n\t\t\t\tconst bucket = grid.cells.get(hashCell3D(cx, cy, cz));\n\t\t\t\tif (!bucket) continue;\n\t\t\t\tfor (const entry of bucket) {\n\t\t\t\t\tif (entry.entityId <= minId || entry._lastSeenGen === gen) continue;\n\t\t\t\t\tentry._lastSeenGen = gen;\n\t\t\t\t\tresult.push(entry.entityId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Collect entity IDs within a sphere. AABB-to-point distance filter against\n * the cells overlapping the sphere's bounding box. Appends to `result`.\n */\nexport function gridQueryRadius3D(\n\tgrid: SpatialHashGrid3D,\n\tcx: number,\n\tcy: number,\n\tcz: number,\n\tradius: number,\n\tresult: number[],\n): void {\n\tconst rSq = radius * radius;\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor((cx - radius) * inv);\n\tconst maxCX = Math.floor((cx + radius) * inv);\n\tconst minCY = Math.floor((cy - radius) * inv);\n\tconst maxCY = Math.floor((cy + radius) * inv);\n\tconst minCZ = Math.floor((cz - radius) * inv);\n\tconst maxCZ = Math.floor((cz + radius) * inv);\n\n\tconst gen = ++grid._queryGen;\n\n\tfor (let icx = minCX; icx <= maxCX; icx++) {\n\t\tfor (let icy = minCY; icy <= maxCY; icy++) {\n\t\t\tfor (let icz = minCZ; icz <= maxCZ; icz++) {\n\t\t\t\tconst bucket = grid.cells.get(hashCell3D(icx, icy, icz));\n\t\t\t\tif (!bucket) continue;\n\t\t\t\tfor (const entry of bucket) {\n\t\t\t\t\tif (entry._lastSeenGen === gen) continue;\n\t\t\t\t\tentry._lastSeenGen = gen;\n\n\t\t\t\t\tconst closestX = Math.max(entry.x - entry.halfW, Math.min(cx, entry.x + entry.halfW));\n\t\t\t\t\tconst closestY = Math.max(entry.y - entry.halfH, Math.min(cy, entry.y + entry.halfH));\n\t\t\t\t\tconst closestZ = Math.max(entry.z - entry.halfD, Math.min(cz, entry.z + entry.halfD));\n\t\t\t\t\tconst dx = cx - closestX;\n\t\t\t\t\tconst dy = cy - closestY;\n\t\t\t\t\tconst dz = cz - closestZ;\n\n\t\t\t\t\tif (dx * dx + dy * dy + dz * dz <= rSq) {\n\t\t\t\t\t\tresult.push(entry.entityId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Get the current-generation entry for an entityId, or `undefined` if the\n * entity isn't in the index for this rebuild. Stale entries from previous\n * rebuilds remain in `entries` for in-place reuse but are filtered here.\n */\nexport function getLiveEntry3D(grid: SpatialHashGrid3D, entityId: number): SpatialEntry3D | undefined {\n\tconst entry = grid.entries[entityId];\n\tif (!entry || entry._aliveGen !== grid._aliveGen) return undefined;\n\treturn entry;\n}\n\n/**\n * Count entries inserted in the current rebuild generation. Linear scan —\n * intended for tests and diagnostics, not hot paths.\n */\nexport function liveEntryCount3D(grid: SpatialHashGrid3D): number {\n\tconst gen = grid._aliveGen;\n\tlet n = 0;\n\tfor (const entry of grid.entries) {\n\t\tif (entry && entry._aliveGen === gen) n++;\n\t}\n\treturn n;\n}\n\n// ==================== SpatialIndex3D Interface ====================\n\n/**\n * High-level spatial index API for 3D broadphase queries.\n *\n * Defined here (the utility layer) so that narrowphase3D can accept it\n * without importing the ECS plugin. The spatial-index3D plugin creates\n * an object that implements this interface and registers it as a resource.\n */\nexport interface SpatialIndex3D {\n\treadonly grid: SpatialHashGrid3D;\n\tqueryBox(minX: number, minY: number, minZ: number, maxX: number, maxY: number, maxZ: number): number[];\n\tqueryBoxInto(minX: number, minY: number, minZ: number, maxX: number, maxY: number, maxZ: number, result: number[], minId?: number): void;\n\tqueryRadius(cx: number, cy: number, cz: number, radius: number): number[];\n\tqueryRadiusInto(cx: number, cy: number, cz: number, radius: number, result: number[]): void;\n\tgetEntry(entityId: number): SpatialEntry3D | undefined;\n}\n"
6
+ "/**\n * Spatial Hash Grid 3D\n *\n * Uniform-grid spatial hash for broadphase collision detection and\n * proximity queries in 3D. Pure data structure, no ECS dependencies.\n */\n\n// ==================== Data Structures ====================\n\nexport interface SpatialEntry3D {\n\tentityId: number;\n\tx: number;\n\ty: number;\n\tz: number;\n\thalfW: number;\n\thalfH: number;\n\thalfD: number;\n\t/** Generation stamp used by query functions to dedup multi-cell hits without a Set. Internal. */\n\t_lastSeenGen: number;\n\t/** Rebuild generation when this entry was last inserted. Internal. */\n\t_aliveGen: number;\n}\n\n/**\n * A cell bucket — entries plus the alive-gen at which the bucket was last\n * filled. Buckets are reset lazily on the next insert in a new generation\n * (see `insertEntity3D`); queries skip buckets whose `_gen` is stale.\n *\n * Internal — exposed only through `SpatialHashGrid3D.cells`.\n */\ninterface CellBucket3D extends Array<SpatialEntry3D> {\n\t_gen: number;\n}\n\nexport interface SpatialHashGrid3D {\n\tcellSize: number;\n\tinvCellSize: number;\n\tcells: Map<number, CellBucket3D>;\n\t/**\n\t * Dense, indexed by entityId. Holes are `undefined`. Entries from previous\n\t * rebuilds remain in place for in-place reuse (zero allocation in steady\n\t * state); liveness is determined by `entry._aliveGen === grid._aliveGen`.\n\t * Internal — read live entries via `getLiveEntry3D` / `liveEntryCount3D` helpers.\n\t *\n\t * High-water-mark grows with max entityId ever inserted; despawned ids\n\t * leave their slot occupied by a stale entry. Acceptable when the entity\n\t * manager recycles ids or peak count is bounded.\n\t */\n\tentries: (SpatialEntry3D | undefined)[];\n\t/** Monotonic counter bumped by each `clearGrid3D` call. Internal. */\n\t_aliveGen: number;\n\t/** Monotonic counter bumped on each query; entries record their last-seen gen for O(1) dedup. Internal. */\n\t_queryGen: number;\n}\n\n// ==================== Pure Functions ====================\n\n/**\n * Hash a cell coordinate triple to a single integer key.\n * Uses large-prime XOR to distribute values.\n */\nexport function hashCell3D(cx: number, cy: number, cz: number): number {\n\t// Large primes for spatial hashing distribution\n\treturn (cx * 73856093) ^ (cy * 19349663) ^ (cz * 83492791);\n}\n\n/**\n * Create a new empty 3D spatial hash grid.\n */\nexport function createGrid3D(cellSize: number): SpatialHashGrid3D {\n\treturn {\n\t\tcellSize,\n\t\tinvCellSize: 1 / cellSize,\n\t\tcells: new Map(),\n\t\tentries: [],\n\t\t_aliveGen: 0,\n\t\t_queryGen: 0,\n\t};\n}\n\n/**\n * Prepare the grid for a rebuild.\n *\n * O(1): bumps the alive-generation counter so entries inserted prior to this\n * call are implicitly stale. `getLiveEntry3D` / `liveEntryCount3D` filter\n * entries by the current gen; queries skip buckets whose own `_gen` lags\n * behind the alive gen; `insertEntity3D` resets a bucket's `length` lazily\n * the first time it is touched in a new generation.\n *\n * Existing `SpatialEntry3D` objects and `CellBucket3D` arrays remain in\n * place for reuse, so steady-state rebuilds allocate zero entries and zero\n * buckets, regardless of how many cells have ever been touched.\n */\nexport function clearGrid3D(grid: SpatialHashGrid3D): void {\n\tgrid._aliveGen++;\n}\n\n/**\n * Insert an entity into all overlapping cells of the grid.\n */\nexport function insertEntity3D(\n\tgrid: SpatialHashGrid3D,\n\tentityId: number,\n\tx: number,\n\ty: number,\n\tz: number,\n\thalfW: number,\n\thalfH: number,\n\thalfD: number,\n): void {\n\tconst gen = grid._aliveGen;\n\tconst existing = grid.entries[entityId];\n\tlet entry: SpatialEntry3D;\n\tif (existing) {\n\t\texisting.x = x;\n\t\texisting.y = y;\n\t\texisting.z = z;\n\t\texisting.halfW = halfW;\n\t\texisting.halfH = halfH;\n\t\texisting.halfD = halfD;\n\t\texisting._aliveGen = gen;\n\t\tentry = existing;\n\t} else {\n\t\tentry = { entityId, x, y, z, halfW, halfH, halfD, _lastSeenGen: 0, _aliveGen: gen };\n\t\tgrid.entries[entityId] = entry;\n\t}\n\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor((x - halfW) * inv);\n\tconst maxCX = Math.floor((x + halfW) * inv);\n\tconst minCY = Math.floor((y - halfH) * inv);\n\tconst maxCY = Math.floor((y + halfH) * inv);\n\tconst minCZ = Math.floor((z - halfD) * inv);\n\tconst maxCZ = Math.floor((z + halfD) * inv);\n\n\tfor (let cx = minCX; cx <= maxCX; cx++) {\n\t\tfor (let cy = minCY; cy <= maxCY; cy++) {\n\t\t\tfor (let cz = minCZ; cz <= maxCZ; cz++) {\n\t\t\t\tconst key = hashCell3D(cx, cy, cz);\n\t\t\t\tconst bucket = grid.cells.get(key);\n\t\t\t\tif (bucket && bucket._gen === gen) {\n\t\t\t\t\t// Hot path: bucket already populated this generation.\n\t\t\t\t\tbucket.push(entry);\n\t\t\t\t} else if (bucket) {\n\t\t\t\t\t// First touch in this generation — drop stale entries from prior rebuilds.\n\t\t\t\t\tbucket.length = 0;\n\t\t\t\t\tbucket._gen = gen;\n\t\t\t\t\tbucket.push(entry);\n\t\t\t\t} else {\n\t\t\t\t\tconst fresh = [entry] as CellBucket3D;\n\t\t\t\t\tfresh._gen = gen;\n\t\t\t\t\tgrid.cells.set(key, fresh);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Collect entity IDs from all cells overlapping the given 3D box.\n *\n * Appends to `result` (caller clears/truncates first if reusing). Multi-cell\n * entries are deduplicated via a per-grid generation stamp on each\n * `SpatialEntry3D`.\n *\n * When `minId` is provided, only entries with `entityId > minId` are added —\n * used for symmetric broadphase pair generation.\n */\nexport function gridQueryBox3D(\n\tgrid: SpatialHashGrid3D,\n\tminX: number,\n\tminY: number,\n\tminZ: number,\n\tmaxX: number,\n\tmaxY: number,\n\tmaxZ: number,\n\tresult: number[],\n\tminId: number = -1,\n): void {\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor(minX * inv);\n\tconst maxCX = Math.floor(maxX * inv);\n\tconst minCY = Math.floor(minY * inv);\n\tconst maxCY = Math.floor(maxY * inv);\n\tconst minCZ = Math.floor(minZ * inv);\n\tconst maxCZ = Math.floor(maxZ * inv);\n\n\tconst gen = ++grid._queryGen;\n\tconst aliveGen = grid._aliveGen;\n\n\tfor (let cx = minCX; cx <= maxCX; cx++) {\n\t\tfor (let cy = minCY; cy <= maxCY; cy++) {\n\t\t\tfor (let cz = minCZ; cz <= maxCZ; cz++) {\n\t\t\t\tconst bucket = grid.cells.get(hashCell3D(cx, cy, cz));\n\t\t\t\tif (!bucket || bucket._gen !== aliveGen) continue;\n\t\t\t\tfor (const entry of bucket) {\n\t\t\t\t\tif (entry.entityId <= minId || entry._lastSeenGen === gen) continue;\n\t\t\t\t\tentry._lastSeenGen = gen;\n\t\t\t\t\tresult.push(entry.entityId);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Collect entity IDs within a sphere. AABB-to-point distance filter against\n * the cells overlapping the sphere's bounding box. Appends to `result`.\n */\nexport function gridQueryRadius3D(\n\tgrid: SpatialHashGrid3D,\n\tcx: number,\n\tcy: number,\n\tcz: number,\n\tradius: number,\n\tresult: number[],\n): void {\n\tconst rSq = radius * radius;\n\tconst inv = grid.invCellSize;\n\tconst minCX = Math.floor((cx - radius) * inv);\n\tconst maxCX = Math.floor((cx + radius) * inv);\n\tconst minCY = Math.floor((cy - radius) * inv);\n\tconst maxCY = Math.floor((cy + radius) * inv);\n\tconst minCZ = Math.floor((cz - radius) * inv);\n\tconst maxCZ = Math.floor((cz + radius) * inv);\n\n\tconst gen = ++grid._queryGen;\n\tconst aliveGen = grid._aliveGen;\n\n\tfor (let icx = minCX; icx <= maxCX; icx++) {\n\t\tfor (let icy = minCY; icy <= maxCY; icy++) {\n\t\t\tfor (let icz = minCZ; icz <= maxCZ; icz++) {\n\t\t\t\tconst bucket = grid.cells.get(hashCell3D(icx, icy, icz));\n\t\t\t\tif (!bucket || bucket._gen !== aliveGen) continue;\n\t\t\t\tfor (const entry of bucket) {\n\t\t\t\t\tif (entry._lastSeenGen === gen) continue;\n\t\t\t\t\tentry._lastSeenGen = gen;\n\n\t\t\t\t\tconst closestX = Math.max(entry.x - entry.halfW, Math.min(cx, entry.x + entry.halfW));\n\t\t\t\t\tconst closestY = Math.max(entry.y - entry.halfH, Math.min(cy, entry.y + entry.halfH));\n\t\t\t\t\tconst closestZ = Math.max(entry.z - entry.halfD, Math.min(cz, entry.z + entry.halfD));\n\t\t\t\t\tconst dx = cx - closestX;\n\t\t\t\t\tconst dy = cy - closestY;\n\t\t\t\t\tconst dz = cz - closestZ;\n\n\t\t\t\t\tif (dx * dx + dy * dy + dz * dz <= rSq) {\n\t\t\t\t\t\tresult.push(entry.entityId);\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t}\n}\n\n/**\n * Get the current-generation entry for an entityId, or `undefined` if the\n * entity isn't in the index for this rebuild. Stale entries from previous\n * rebuilds remain in `entries` for in-place reuse but are filtered here.\n */\nexport function getLiveEntry3D(grid: SpatialHashGrid3D, entityId: number): SpatialEntry3D | undefined {\n\tconst entry = grid.entries[entityId];\n\tif (!entry || entry._aliveGen !== grid._aliveGen) return undefined;\n\treturn entry;\n}\n\n/**\n * Count entries inserted in the current rebuild generation. Linear scan —\n * intended for tests and diagnostics, not hot paths.\n */\nexport function liveEntryCount3D(grid: SpatialHashGrid3D): number {\n\tconst gen = grid._aliveGen;\n\tlet n = 0;\n\tfor (const entry of grid.entries) {\n\t\tif (entry && entry._aliveGen === gen) n++;\n\t}\n\treturn n;\n}\n\n// ==================== SpatialIndex3D Interface ====================\n\n/**\n * High-level spatial index API for 3D broadphase queries.\n *\n * Defined here (the utility layer) so that narrowphase3D can accept it\n * without importing the ECS plugin. The spatial-index3D plugin creates\n * an object that implements this interface and registers it as a resource.\n */\nexport interface SpatialIndex3D {\n\treadonly grid: SpatialHashGrid3D;\n\tqueryBox(minX: number, minY: number, minZ: number, maxX: number, maxY: number, maxZ: number): number[];\n\tqueryBoxInto(minX: number, minY: number, minZ: number, maxX: number, maxY: number, maxZ: number, result: number[], minId?: number): void;\n\tqueryRadius(cx: number, cy: number, cz: number, radius: number): number[];\n\tqueryRadiusInto(cx: number, cy: number, cz: number, radius: number, result: number[]): void;\n\tgetEntry(entityId: number): SpatialEntry3D | undefined;\n}\n"
7
7
  ],
8
- "mappings": "2PAYA,uBAAS,kBCsCF,SAAS,CAAU,CAAC,EAAY,EAAY,EAAoB,CAEtE,OAAQ,EAAK,SAAa,EAAK,SAAa,EAAK,SAM3C,SAAS,CAAY,CAAC,EAAqC,CACjE,MAAO,CACN,WACA,YAAa,EAAI,EACjB,MAAO,IAAI,IACX,QAAS,CAAC,EACV,UAAW,EACX,UAAW,CACZ,EAeM,SAAS,CAAW,CAAC,EAA+B,CAC1D,EAAK,YAEL,QAAW,KAAU,EAAK,MAAM,OAAO,EACtC,EAAO,OAAS,EAOX,SAAS,CAAc,CAC7B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACO,CACP,IAAM,EAAM,EAAK,UACX,EAAW,EAAK,QAAQ,GAC1B,EACJ,GAAI,EACH,EAAS,EAAI,EACb,EAAS,EAAI,EACb,EAAS,EAAI,EACb,EAAS,MAAQ,EACjB,EAAS,MAAQ,EACjB,EAAS,MAAQ,EACjB,EAAS,UAAY,EACrB,EAAQ,EAER,OAAQ,CAAE,WAAU,IAAG,IAAG,IAAG,QAAO,QAAO,QAAO,aAAc,EAAG,UAAW,CAAI,EAClF,EAAK,QAAQ,GAAY,EAG1B,IAAM,EAAM,EAAK,YACX,EAAQ,KAAK,OAAO,EAAI,GAAS,CAAG,EACpC,EAAQ,KAAK,OAAO,EAAI,GAAS,CAAG,EACpC,EAAQ,KAAK,OAAO,EAAI,GAAS,CAAG,EACpC,EAAQ,KAAK,OAAO,EAAI,GAAS,CAAG,EACpC,EAAQ,KAAK,OAAO,EAAI,GAAS,CAAG,EACpC,EAAQ,KAAK,OAAO,EAAI,GAAS,CAAG,EAE1C,QAAS,EAAK,EAAO,GAAM,EAAO,IACjC,QAAS,EAAK,EAAO,GAAM,EAAO,IACjC,QAAS,EAAK,EAAO,GAAM,EAAO,IAAM,CACvC,IAAM,EAAM,EAAW,EAAI,EAAI,CAAE,EAC3B,EAAS,EAAK,MAAM,IAAI,CAAG,EACjC,GAAI,EACH,EAAO,KAAK,CAAK,EAEjB,OAAK,MAAM,IAAI,EAAK,CAAC,CAAK,CAAC,GAiBzB,SAAS,CAAc,CAC7B,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EACA,EAAgB,GACT,CACP,IAAM,EAAM,EAAK,YACX,EAAQ,KAAK,MAAM,EAAO,CAAG,EAC7B,EAAQ,KAAK,MAAM,EAAO,CAAG,EAC7B,EAAQ,KAAK,MAAM,EAAO,CAAG,EAC7B,EAAQ,KAAK,MAAM,EAAO,CAAG,EAC7B,EAAQ,KAAK,MAAM,EAAO,CAAG,EAC7B,EAAQ,KAAK,MAAM,EAAO,CAAG,EAE7B,EAAM,EAAE,EAAK,UAEnB,QAAS,EAAK,EAAO,GAAM,EAAO,IACjC,QAAS,EAAK,EAAO,GAAM,EAAO,IACjC,QAAS,EAAK,EAAO,GAAM,EAAO,IAAM,CACvC,IAAM,EAAS,EAAK,MAAM,IAAI,EAAW,EAAI,EAAI,CAAE,CAAC,EACpD,GAAI,CAAC,EAAQ,SACb,QAAW,KAAS,EAAQ,CAC3B,GAAI,EAAM,UAAY,GAAS,EAAM,eAAiB,EAAK,SAC3D,EAAM,aAAe,EACrB,EAAO,KAAK,EAAM,QAAQ,IAWxB,SAAS,CAAiB,CAChC,EACA,EACA,EACA,EACA,EACA,EACO,CACP,IAAM,EAAM,EAAS,EACf,EAAM,EAAK,YACX,EAAQ,KAAK,OAAO,EAAK,GAAU,CAAG,EACtC,EAAQ,KAAK,OAAO,EAAK,GAAU,CAAG,EACtC,EAAQ,KAAK,OAAO,EAAK,GAAU,CAAG,EACtC,EAAQ,KAAK,OAAO,EAAK,GAAU,CAAG,EACtC,EAAQ,KAAK,OAAO,EAAK,GAAU,CAAG,EACtC,EAAQ,KAAK,OAAO,EAAK,GAAU,CAAG,EAEtC,EAAM,EAAE,EAAK,UAEnB,QAAS,EAAM,EAAO,GAAO,EAAO,IACnC,QAAS,EAAM,EAAO,GAAO,EAAO,IACnC,QAAS,EAAM,EAAO,GAAO,EAAO,IAAO,CAC1C,IAAM,EAAS,EAAK,MAAM,IAAI,EAAW,EAAK,EAAK,CAAG,CAAC,EACvD,GAAI,CAAC,EAAQ,SACb,QAAW,KAAS,EAAQ,CAC3B,GAAI,EAAM,eAAiB,EAAK,SAChC,EAAM,aAAe,EAErB,IAAM,EAAW,KAAK,IAAI,EAAM,EAAI,EAAM,MAAO,KAAK,IAAI,EAAI,EAAM,EAAI,EAAM,KAAK,CAAC,EAC9E,EAAW,KAAK,IAAI,EAAM,EAAI,EAAM,MAAO,KAAK,IAAI,EAAI,EAAM,EAAI,EAAM,KAAK,CAAC,EAC9E,EAAW,KAAK,IAAI,EAAM,EAAI,EAAM,MAAO,KAAK,IAAI,EAAI,EAAM,EAAI,EAAM,KAAK,CAAC,EAC9E,EAAK,EAAK,EACV,EAAK,EAAK,EACV,EAAK,EAAK,EAEhB,GAAI,EAAK,EAAK,EAAK,EAAK,EAAK,GAAM,EAClC,EAAO,KAAK,EAAM,QAAQ,IAazB,SAAS,CAAc,CAAC,EAAyB,EAA8C,CACrG,IAAM,EAAQ,EAAK,QAAQ,GAC3B,GAAI,CAAC,GAAS,EAAM,YAAc,EAAK,UAAW,OAClD,OAAO,EDpLR,SAAS,CAA4B,CAAC,EAAyC,CAC9E,MAAO,CACN,OACA,QAAQ,CAAC,EAAc,EAAc,EAAc,EAAc,EAAc,EAAwB,CACtG,IAAM,EAAgB,CAAC,EAEvB,OADA,EAAe,EAAM,EAAM,EAAM,EAAM,EAAM,EAAM,EAAM,CAAG,EACrD,GAER,YAAY,CAAC,EAAc,EAAc,EAAc,EAAc,EAAc,EAAc,EAAkB,EAAsB,CACxI,EAAe,EAAM,EAAM,EAAM,EAAM,EAAM,EAAM,EAAM,EAAQ,CAAK,GAEvE,WAAW,CAAC,EAAY,EAAY,EAAY,EAA0B,CACzE,IAAM,EAAgB,CAAC,EAEvB,OADA,EAAkB,EAAM,EAAI,EAAI,EAAI,EAAQ,CAAG,EACxC,GAER,eAAe,CAAC,EAAY,EAAY,EAAY,EAAgB,EAAwB,CAC3F,EAAkB,EAAM,EAAI,EAAI,EAAI,EAAQ,CAAM,GAEnD,QAAQ,CAAC,EAA8C,CACtD,OAAO,EAAe,EAAM,CAAQ,EAEtC,EAiDM,SAAS,CAA+D,CAC9E,EACC,CACD,IACC,WAAW,GACX,cAAc,iBACd,WAAW,KACX,SAAS,CAAC,cAAe,YAAY,GAClC,GAAW,CAAC,EAEV,EAAO,EAAa,CAAQ,EAC5B,EAAW,EAA6B,CAAI,EAElD,OAAO,EAAa,gBAAgB,EAClC,mBAAiD,EACjD,kBAA+C,EAC/C,WAAgC,EAChC,WAAc,EACd,QAAQ,CAAC,IAAU,CACnB,EAAM,YAAY,iBAAkB,CAAQ,EAG5C,QAAW,KAAS,EAAQ,CAC3B,IAAM,EAAqB,IAAU,cAAgB,mBAAqB,mBAE1E,EACE,UAAU,2BAA2B,GAAO,EAC5C,YAAY,CAAQ,EACpB,QAAQ,CAAoB,EAC5B,QAAQ,CAAW,EACnB,SAAS,aAAc,CACvB,KAAM,CAAC,CAAkB,CAC1B,CAAC,EACA,aAAa,EACb,WAAW,EAAG,UAAS,SAAU,CACjC,EAAY,CAAI,EAEhB,QAAW,KAAU,EAAQ,WAAY,CACxC,IAAM,EAAY,EAAO,WAAW,GAC9B,EAAO,EAAI,aAAa,EAAO,GAAI,gBAAgB,EAEnD,EAAS,EAAO,OAAY,EAAI,aAAa,EAAO,GAAI,gBAAgB,EAE9E,GAAI,EAAM,CACT,EACC,EAAM,EAAO,GACb,EAAU,GAAK,EAAK,SAAW,GAC/B,EAAU,GAAK,EAAK,SAAW,GAC/B,EAAU,GAAK,EAAK,SAAW,GAC/B,EAAK,MAAQ,EAAG,EAAK,OAAS,EAAG,EAAK,MAAQ,CAC/C,EACA,SAGD,GAAI,EAAQ,CACX,IAAM,EAAI,EAAO,OACjB,EACC,EAAM,EAAO,GACb,EAAU,GAAK,EAAO,SAAW,GACjC,EAAU,GAAK,EAAO,SAAW,GACjC,EAAU,GAAK,EAAO,SAAW,GACjC,EAAG,EAAG,CACP,IAGF,GAEH",
9
- "debugId": "10C4CA741CCEA05664756E2164756E21",
8
+ "mappings": "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",
9
+ "debugId": "FC8F8AAE90676C3164756E2164756E21",
10
10
  "names": []
11
11
  }
@@ -15,10 +15,20 @@ export interface SpatialEntry {
15
15
  /** Rebuild generation when this entry was last inserted. Internal. */
16
16
  _aliveGen: number;
17
17
  }
18
+ /**
19
+ * A cell bucket — entries plus the alive-gen at which the bucket was last
20
+ * filled. Buckets are reset lazily on the next insert in a new generation
21
+ * (see `insertEntity`); queries skip buckets whose `_gen` is stale.
22
+ *
23
+ * Internal — exposed only through `SpatialHashGrid.cells`.
24
+ */
25
+ interface CellBucket extends Array<SpatialEntry> {
26
+ _gen: number;
27
+ }
18
28
  export interface SpatialHashGrid {
19
29
  cellSize: number;
20
30
  invCellSize: number;
21
- cells: Map<number, SpatialEntry[]>;
31
+ cells: Map<number, CellBucket>;
22
32
  /**
23
33
  * Dense, indexed by entityId. Holes are `undefined`. Entries from previous
24
34
  * rebuilds remain in place for in-place reuse (zero allocation in steady
@@ -47,14 +57,15 @@ export declare function createGrid(cellSize: number): SpatialHashGrid;
47
57
  /**
48
58
  * Prepare the grid for a rebuild.
49
59
  *
50
- * Bumps the alive-generation counter so entries inserted prior to this call
51
- * are implicitly stale (any access via `getEntry`/`liveEntryCount` filters by
52
- * the current gen). Existing `SpatialEntry` objects remain in the `entries`
53
- * array for in-place reuse by the next `insertEntity`, so steady-state
54
- * rebuilds allocate zero entries.
60
+ * O(1): bumps the alive-generation counter so entries inserted prior to this
61
+ * call are implicitly stale. `getLiveEntry` / `liveEntryCount` filter
62
+ * entries by the current gen; queries skip buckets whose own `_gen` lags
63
+ * behind the alive gen; `insertEntity` resets a bucket's `length` lazily
64
+ * the first time it is touched in a new generation.
55
65
  *
56
- * Cell buckets are cleared in place keys are retained so subsequent
57
- * inserts hit the existing array rather than allocating a fresh one.
66
+ * Existing `SpatialEntry` objects and `CellBucket` arrays remain in place
67
+ * for reuse, so steady-state rebuilds allocate zero entries and zero
68
+ * buckets, regardless of how many cells have ever been touched.
58
69
  */
59
70
  export declare function clearGrid(grid: SpatialHashGrid): void;
60
71
  /**
@@ -96,3 +107,4 @@ export interface SpatialIndex {
96
107
  queryRadiusInto(cx: number, cy: number, radius: number, result: number[]): void;
97
108
  getEntry(entityId: number): SpatialEntry | undefined;
98
109
  }
110
+ export {};
@@ -17,10 +17,20 @@ export interface SpatialEntry3D {
17
17
  /** Rebuild generation when this entry was last inserted. Internal. */
18
18
  _aliveGen: number;
19
19
  }
20
+ /**
21
+ * A cell bucket — entries plus the alive-gen at which the bucket was last
22
+ * filled. Buckets are reset lazily on the next insert in a new generation
23
+ * (see `insertEntity3D`); queries skip buckets whose `_gen` is stale.
24
+ *
25
+ * Internal — exposed only through `SpatialHashGrid3D.cells`.
26
+ */
27
+ interface CellBucket3D extends Array<SpatialEntry3D> {
28
+ _gen: number;
29
+ }
20
30
  export interface SpatialHashGrid3D {
21
31
  cellSize: number;
22
32
  invCellSize: number;
23
- cells: Map<number, SpatialEntry3D[]>;
33
+ cells: Map<number, CellBucket3D>;
24
34
  /**
25
35
  * Dense, indexed by entityId. Holes are `undefined`. Entries from previous
26
36
  * rebuilds remain in place for in-place reuse (zero allocation in steady
@@ -49,14 +59,15 @@ export declare function createGrid3D(cellSize: number): SpatialHashGrid3D;
49
59
  /**
50
60
  * Prepare the grid for a rebuild.
51
61
  *
52
- * Bumps the alive-generation counter so entries inserted prior to this call
53
- * are implicitly stale (any access via `getLiveEntry3D` / `liveEntryCount3D`
54
- * filters by the current gen). Existing `SpatialEntry3D` objects remain in
55
- * the `entries` array for in-place reuse by the next `insertEntity3D`, so
56
- * steady-state rebuilds allocate zero entries.
62
+ * O(1): bumps the alive-generation counter so entries inserted prior to this
63
+ * call are implicitly stale. `getLiveEntry3D` / `liveEntryCount3D` filter
64
+ * entries by the current gen; queries skip buckets whose own `_gen` lags
65
+ * behind the alive gen; `insertEntity3D` resets a bucket's `length` lazily
66
+ * the first time it is touched in a new generation.
57
67
  *
58
- * Cell buckets are cleared in place keys are retained so subsequent
59
- * inserts hit the existing array rather than allocating a fresh one.
68
+ * Existing `SpatialEntry3D` objects and `CellBucket3D` arrays remain in
69
+ * place for reuse, so steady-state rebuilds allocate zero entries and zero
70
+ * buckets, regardless of how many cells have ever been touched.
60
71
  */
61
72
  export declare function clearGrid3D(grid: SpatialHashGrid3D): void;
62
73
  /**
@@ -105,3 +116,4 @@ export interface SpatialIndex3D {
105
116
  queryRadiusInto(cx: number, cy: number, cz: number, radius: number, result: number[]): void;
106
117
  getEntry(entityId: number): SpatialEntry3D | undefined;
107
118
  }
119
+ export {};
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "ecspresso",
3
- "version": "0.16.2",
3
+ "version": "0.16.3",
4
4
  "main": "dist/index.js",
5
5
  "module": "dist/index.js",
6
6
  "types": "dist/index.d.ts",