@oasys/oecs 0.5.2 → 0.5.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/CHANGELOG.md +28 -0
- package/dist/core/ecs/ecs_memory.d.cts +6 -6
- package/dist/core/ecs/ecs_memory.d.ts +6 -6
- package/dist/core/ecs/ecs_memory.d.ts.map +1 -1
- package/dist/core/store/allocator.d.cts +44 -19
- package/dist/core/store/allocator.d.ts +44 -19
- package/dist/core/store/allocator.d.ts.map +1 -1
- package/dist/core/store/column_store.d.cts +1 -1
- package/dist/core/store/column_store.d.ts +1 -1
- package/dist/core/store/extend.d.ts.map +1 -1
- package/dist/core/store/grow.d.ts.map +1 -1
- package/dist/core/store/layout_ops.d.cts +18 -0
- package/dist/core/store/layout_ops.d.ts +18 -0
- package/dist/core/store/layout_ops.d.ts.map +1 -1
- package/dist/{host_commands-BI8pEmjH.js → host_commands-3jyFfWNg.js} +2 -2
- package/dist/{host_commands-CxhpzMx9.cjs → host_commands-DNf0f6ko.cjs} +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.d.cts +1 -1
- package/dist/index.d.ts +1 -1
- package/dist/index.development.cjs +1 -1
- package/dist/index.development.js +197 -194
- package/dist/index.js +195 -192
- package/dist/{internal-BMDgWZbt.js → internal-C9jjL90H.js} +2 -2
- package/dist/{internal-LiTSB_tG.cjs → internal-RZN14uMw.cjs} +2 -2
- package/dist/internal.cjs +1 -1
- package/dist/internal.development.cjs +1 -1
- package/dist/internal.development.js +1 -1
- package/dist/internal.js +1 -1
- package/dist/shared-BMXh9hxm.cjs +1 -0
- package/dist/{shared-BU1Cd40h.js → shared-DQKK0i-E.js} +38 -32
- package/dist/shared.cjs +1 -1
- package/dist/shared.d.cts +1 -1
- package/dist/shared.d.ts +1 -1
- package/dist/shared.development.cjs +1 -1
- package/dist/shared.development.js +1 -1
- package/dist/shared.js +1 -1
- package/dist/version.d.cts +1 -1
- package/dist/version.d.ts +1 -1
- package/package.json +1 -1
- package/dist/shared-BymrGTyR.cjs +0 -1
package/dist/index.cjs
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./host_commands-CxhpzMx9.cjs"),T=require("./typed_arrays-D3NmwtCG.cjs"),V=require("./shared-BymrGTyR.cjs"),O=!1,Rt=c=>h.validateAndCast(c),ht=Object.freeze({});function vt(c){const t=(e=>({def:t,values:e??ht}));return Object.defineProperty(t,"id",{value:c,enumerable:!1}),t}function Ft(c,...t){return{def:c,values:t[0]??ht}}function G(c){return typeof c=="function"?c:c.def}function $(c){return typeof c=="function"?ht:c.values}class B extends Error{constructor(t){super(t),this.name="StoreRestoreError"}}function Lt(c){const t=c.view.getUint32(h.STORE_HEADER_OFFSETS.capacity,!0);return new Uint8Array(c.buffer,0,t)}function Bt(c,t=V.DEFAULT_SAB_ALLOCATOR){const e=new DataView(c.buffer,c.byteOffset,c.byteLength);if(c.byteLength<h.STORE_HEADER_BYTES)throw new B(`snapshot too small: ${c.byteLength} bytes (header alone needs ${h.STORE_HEADER_BYTES})`);const s=e.getUint32(h.STORE_HEADER_OFFSETS.magic,!0);if(s!==h.STORE_MAGIC)throw new B(`bad magic: 0x${s.toString(16).padStart(8,"0")} (expected 0x${h.STORE_MAGIC.toString(16).padStart(8,"0")})`);const n=e.getUint32(h.STORE_HEADER_OFFSETS.sim_abi_version,!0);if(n!==h.SIM_ABI_VERSION)throw new B(`incompatible sim_abi_version: snapshot=${n}, build=${h.SIM_ABI_VERSION}`);const r=t(c.byteLength);new Uint8Array(r).set(c);const i=new DataView(r),o=h.readStoreHeader(i);if(o.layoutDescriptorOff<0||o.layoutDescriptorOff>r.byteLength)throw new B(`layout_descriptor_off ${o.layoutDescriptorOff} is outside the snapshot (${r.byteLength} bytes)`);try{const a=h.readLayoutDescriptorRegion(i,o.layoutDescriptorOff,o.archetypeCount),l=h.buildArchetypeViews(r,a);return{buffer:r,view:i,header:o,archetypes:l}}catch(a){throw a instanceof RangeError?new B(`snapshot layout is corrupt or truncated: a descriptor offset or column extent reads past the ${r.byteLength}-byte buffer (${a.message})`):a}}const Gt=c=>h.validateAndCast(c);class $t{fieldNames;columns;reader;_readerLen;constructor(t){this.fieldNames=t,this.columns=[];for(let n=0;n<t.length;n++)this.columns.push([]);const e={};for(let n=0;n<t.length;n++)e[t[n]]=this.columns[n];const s={length:0,...e};this._readerLen=s,this.reader=s}emit(t){const e=this.fieldNames,s=this.columns;for(let n=0;n<e.length;n++)s[n].push(t[e[n]]);this._readerLen.length++}emitSignal(){this._readerLen.length++}clear(){this._readerLen.length=0;const t=this.columns;for(let e=0;e<t.length;e++)t[e].length=0}}function Pt(c){return h.unsafeCast(Symbol(c))}function Ut(c){return h.unsafeCast(Symbol(c))}class Ht{channels=[];dirtyChannels=[];count=0;keyMap=new Map;registerEvent(t){const e=Gt(this.count++),s=new $t(t);return this.channels.push(s),h.unsafeCast(e)}emitEvent(t,e){const s=t,n=this.channels[s],r=n.reader.length===0;n.emit(e),r&&this.dirtyChannels.push(s)}emitSignal(t){const e=t,s=this.channels[e],n=s.reader.length===0;s.emitSignal(),n&&this.dirtyChannels.push(e)}getEventReader(t){return this.channels[t].reader}clearEvents(){const t=this.dirtyChannels,e=this.channels;for(let s=0;s<t.length;s++)e[t[s]].clear();t.length=0}devBufferedEventCount(){const t=this.dirtyChannels,e=this.channels;let s=0;for(let n=0;n<t.length;n++)s+=e[t[n]].reader.length;return s}registerEventByKey(t,e){if(this.keyMap.has(t))throw new h.ECSError(h.ECS_ERROR.EVENT_ALREADY_REGISTERED,`event '${t.description??"<unnamed>"}' is already registered`,{event:t.description});const s=this.registerEvent(e);return this.keyMap.set(t,s),s}getEventDefByKey(t){const e=this.keyMap.get(t);if(e===void 0)throw new h.ECSError(h.ECS_ERROR.EVENT_NOT_REGISTERED,`event '${t.description??"<unnamed>"}' is not registered — call ecs.events.register(key, fields) at world setup`,{event:t.description});return e}hasEventKey(t){return this.keyMap.has(t)}}class Vt{map=new Map;register(t,e){if(this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_ALREADY_REGISTERED,`resource '${t.description??"<unnamed>"}' is already registered — remove() it first if you meant to replace it`,{resource:t.description});this.map.set(t,e)}get(t){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource read: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});return this.map.get(t)}set(t,e){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource write: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});this.map.set(t,e)}remove(t){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource remove: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});this.map.delete(t)}has(t){return this.map.has(t)}}class z extends Error{capacity;requested;constructor(t,e){super(`BufferBackedColumn overflow: requested length ${e} exceeds capacity ${t}`),this.name="StoreColumnOverflowError",this.capacity=t,this.requested=e}}class qt{_buf;_capacity;_len=0;constructor(t){this._buf=t,this._capacity=t.length}refreshView(t){if(t.length<this._len)throw new z(t.length,this._len);this._buf=t,this._capacity=t.length}get length(){return this._len}get capacity(){return this._capacity}push(t){if(this._len>=this._capacity)throw new z(this._capacity,this._len+1);this._buf[this._len++]=t}pop(){return this._buf[--this._len]}get(t){return this._buf[t]}setAt(t,e){this._buf[t]=e}swapRemove(t){const e=this._buf[t];return this._buf[t]=this._buf[--this._len],e}clear(){this._len=0}setLength(t){if(t>this._capacity)throw new z(this._capacity,t);this._len=t}get buf(){return this._buf}view(){return this._buf.subarray(0,this._len)}[Symbol.iterator](){let t=0;const e=this._buf,s=this._len;return{next(){return t<s?{value:e[t++],done:!1}:{value:0,done:!0}}}}ensureCapacity(t){if(t>this._capacity)throw new z(this._capacity,t)}bulkAppend(t,e,s){this.ensureCapacity(this._len+s),this._buf.set(t.subarray(e,e+s),this._len),this._len+=s}bulkAppendZeroes(t){this.ensureCapacity(this._len+t),this._buf.fill(0,this._len,this._len+t),this._len+=t}bulkAppendValue(t,e){this.ensureCapacity(this._len+e),this._buf.fill(t,this._len,this._len+e),this._len+=e}}const ut=c=>h.validateAndCast(c);class at{id;mask;hasColumns;materializesRows;_entityIds;length=0;enabledCount=0;_flushSeenEpoch=-1;_flushPreLen=0;_flushPreEnabled=0;_iterDepth=0;edges=[];batchTransitionMaps=new Map;compositeAddEdges=null;_flatColumns=[];_storeArchetypeId=null;_colOffset=[];_fieldCount=[];_fieldIndex=[];_fieldNames=[];columnGroups=[];_columnIds=[];_changedTick=[];_mutGroupCache=[];_readGroupCache=[];growHandler=null;constructor(t,e,s,n=h.DEFAULT_COLUMN_CAPACITY,r){if(this.id=t,this.mask=e,this._entityIds=new T.GrowableUint32Array(n),s){let i=0;for(let o=0;o<s.length;o++){const a=s[o],l=a.componentId,u=new Array(a.fieldNames.length);if(this._colOffset[l]=i,this._fieldCount[l]=a.fieldNames.length,this._fieldIndex[l]=a.fieldIndex,this._fieldNames[l]=a.fieldNames,a.fieldNames.length>0&&!r)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`Archetype ${t}: layouts with fields require a columnFactory — use Archetype.fromColumnStore for SAB-backed columns, or pass a heap factory explicitly in tests`);for(let d=0;d<a.fieldNames.length;d++){const f=a.fieldTypes[d],p=r(a.componentId,d,f);u[d]=p,this._flatColumns[i++]=p}this.columnGroups[l]={layout:a,columns:u},this._columnIds.push(l),this._changedTick[l]=0}}this.hasColumns=this._columnIds.length>0,this.materializesRows=!e.isEmpty()}static fromColumnStore(t,e,s,n,r){const i=n.archetypes.get(r);if(!i)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`ColumnStore has no archetype ${r}`);const o=(l,u)=>{const d=i.columns.get(h.columnKey(l,u));if(!d)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`ColumnStore archetype ${r} has no column for (${l}, ${u})`);return new qt(d.view)},a=new at(t,e,s,i.rowCapacity,o);return a._storeArchetypeId=r,a}get isBufferBacked(){return this._storeArchetypeId!==null}refreshViews(t){if(this._storeArchetypeId===null)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`Archetype ${this.id} is not SAB-backed`);const e=t.archetypes.get(this._storeArchetypeId);if(!e)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`new ColumnStore has no archetype ${this._storeArchetypeId}`);const s=e.columnsInOrder,n=this._flatColumns;for(let r=0;r<s.length;r++)n[r].refreshView(s[r].view)}get entityCount(){return et?this.length:this.enabledCount}get totalCount(){return this.length}get disabledCount(){return this.length-this.enabledCount}get entityIds(){return this._entityIds.buf}swapRows(t,e){if(t===e)return;const s=this._entityIds.buf,n=s[t];s[t]=s[e],s[e]=n;const r=this._flatColumns;for(let i=0;i<r.length;i++){const o=r[i].buf,a=o[t];o[t]=o[e],o[e]=a}}_placeTail(t,e){const s=this.enabledCount;if(s===t)return this.enabledCount=t+1,t;if(this.swapRows(s,t),e!==void 0){const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t}return this.enabledCount=s+1,s}_placeTailBulk(t,e){return this.enabledCount+=e,t}disableRow(t,e){const s=this.enabledCount-1;if(t!==s){this.swapRows(t,s);const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t,e[h.getEntityIndex(n[s])]=s}this.enabledCount=s}enableRow(t,e){const s=this.enabledCount;if(t!==s){this.swapRows(t,s);const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t,e[h.getEntityIndex(n[s])]=s}this.enabledCount=s+1}removeRow(t,e){if(this.enabledCount===this.length){const s=this._entityIds.buf,n=this.length-1;if(t!==n){if(s[t]=s[n],this.hasColumns){const r=this._flatColumns;for(let i=0;i<r.length;i++)r[i].swapRemove(t)}e[h.getEntityIndex(s[t])]=t}else if(this.hasColumns){const r=this._flatColumns;for(let i=0;i<r.length;i++)r[i].pop()}this._entityIds.pop(),this.length=n,this.enabledCount=n;return}this._removeRowPartitioned(t,e)}_removeRowPartitioned(t,e){const s=this._entityIds.buf,n=this.hasColumns,r=this.enabledCount,i=this.length-1;if(t>=r){if(t!==i){if(s[t]=s[i],n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].swapRemove(t)}e[h.getEntityIndex(s[t])]=t}else if(n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].pop()}this._entityIds.pop(),this.length--;return}const o=r-1;if(t!==o&&(this.swapRows(t,o),e[h.getEntityIndex(s[t])]=t),o!==i){if(s[o]=s[i],n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].swapRemove(o)}e[h.getEntityIndex(s[o])]=o}else if(n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].pop()}this._entityIds.pop(),this.length--,this.enabledCount=o}get entityList(){return this._entityIds.view()}hasComponent(t){return this.mask.has(t)}matches(t){return this.mask.contains(t)}getColumnRead(t,e){const s=t.id,n=this._fieldIndex[s][e];return this._flatColumns[this._colOffset[s]+n].buf}getColumnsRead(t,...e){return e.map(n=>this.getColumnRead(t,n))}getOptionalColumnRead(t,e){const s=t.id,n=this._colOffset[s];if(n===void 0)return;const r=this._fieldIndex[s][e];return this._flatColumns[n+r].buf}getColumn(t,e,s){const n=t.id;this._changedTick[n]=s;const r=this._fieldIndex[n][e];return this._flatColumns[this._colOffset[n]+r].buf}columnGroupMut(t,e){const s=t.id;this._changedTick[s]=e;const n=this._colOffset[s],r=this._fieldNames[s],i=this._flatColumns;let o=this._mutGroupCache[s];o===void 0&&(o={},this._mutGroupCache[s]=o);for(let a=0;a<r.length;a++)o[r[a]]=i[n+a].buf;return o}columnGroupRead(t){const e=t.id,s=this._colOffset[e],n=this._fieldNames[e],r=this._flatColumns;let i=this._readGroupCache[e];i===void 0&&(i={},this._readGroupCache[e]=i);for(let o=0;o<n.length;o++)i[n[o]]=r[s+o].buf;return i}writeFields(t,e,s,n){const r=e,i=this._colOffset[r];if(i===void 0)return;this._changedTick[r]=n;const o=this._fieldNames[r],a=this._flatColumns;for(let l=0;l<o.length;l++)a[i+l].buf[t]=s[o[l]]??0}bulkWriteFields(t,e,s,n,r){const i=s,o=this._colOffset[i];if(o===void 0)return;this._changedTick[i]=r;const a=this._fieldNames[i],l=this._flatColumns,u=t+e;for(let d=0;d<a.length;d++)l[o+d].buf.fill(n[a[d]]??0,t,u)}writeFieldsPositional(t,e,s,n){const r=e,i=this._colOffset[r];if(i===void 0)return;this._changedTick[r]=n;const o=this._flatColumns;for(let a=0;a<s.length;a++)o[i+a].buf[t]=s[a]}readField(t,e,s){const n=e,r=this._colOffset[n];if(r===void 0)return NaN;const i=this._fieldIndex[n][s];return i===void 0?NaN:this._flatColumns[r+i].buf[t]}copySharedFrom(t,e,s,n){const r=t._colOffset,i=t._fieldCount,o=t._flatColumns,a=this._flatColumns,l=this._columnIds;for(let u=0;u<l.length;u++){const d=l[u],f=r[d];if(f===void 0)continue;this._changedTick[d]=n;const p=this._colOffset[d],y=i[d];for(let g=0;g<y;g++)a[p+g].buf[s]=o[f+g].buf[e]}}addEntity(t,e){const s=this._flatColumns;s.length>0&&this.length>=s[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const n=this.length;this._entityIds.push(t);for(let r=0;r<s.length;r++)s[r].push(0);return this.length++,this._placeTail(n,e)}removeEntity(t){const e=this.length-1;let s=h.NO_SWAP;const n=this._flatColumns,r=this._entityIds.buf;if(t!==e){r[t]=r[e],s=h.getEntityIndex(r[t]);for(let i=0;i<n.length;i++)n[i].swapRemove(t)}else for(let i=0;i<n.length;i++)n[i].pop();return this._entityIds.pop(),this.length--,t<this.enabledCount&&this.enabledCount--,s}addEntityTag(t,e){const s=this.length;return this._entityIds.push(t),this.length++,this._placeTail(s,e)}addEntities(t,e=t.length){if(e===0)return this.length;const s=this._flatColumns;s.length>0&&this.length+e>s[0].buf.length&&this.growHandler!==null&&this.growHandler(this,e);const n=this.length;this._entityIds.bulkAppend(t,0,e);for(let r=0;r<s.length;r++)s[r].bulkAppendZeroes(e);return this.length+=e,this._placeTailBulk(n,e)}addEntitiesTag(t,e=t.length){if(e===0)return this.length;const s=this.length;return this._entityIds.bulkAppend(t,0,e),this.length+=e,this._placeTailBulk(s,e)}ensureRowCapacity(t){const e=this._flatColumns;e.length>0&&this.length+t>e[0].buf.length&&this.growHandler!==null&&this.growHandler(this,t)}addEntityWithValues(t,e,s,n){const r=this._flatColumns;r.length>0&&this.length>=r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const i=this.length;this._entityIds.push(t);for(let a=0;a<r.length;a++)r[a].push(e[a]);this.length++;const o=this._columnIds;for(let a=0;a<o.length;a++)this._changedTick[o[a]]=s;return this._placeTail(i,n)}addEntitiesWithValues(t,e,s,n){if(e===0)return this.length;const r=this._flatColumns;r.length>0&&this.length+e>r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,e);const i=this.length;this._entityIds.bulkAppend(t,0,e);for(let a=0;a<r.length;a++)r[a].bulkAppendValue(s[a],e);this.length+=e;const o=this._columnIds;for(let a=0;a<o.length;a++)this._changedTick[o[a]]=n;return this._placeTailBulk(i,e)}removeEntityTag(t){const e=this.length-1;let s=h.NO_SWAP;const n=this._entityIds.buf;return t!==e&&(n[t]=n[e],s=h.getEntityIndex(n[t])),this._entityIds.pop(),this.length--,t<this.enabledCount&&this.enabledCount--,s}moveEntityFrom(t,e,s,n,r,i){const o=e>=t.enabledCount;if(!this.materializesRows){t.removeRow(e,i),A[0]=h.UNASSIGNED,A[1]=h.NO_SWAP;return}const a=this._flatColumns;a.length>0&&this.length>=a[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const l=this.length;this._entityIds.push(s);const u=t._flatColumns;for(let p=0;p<a.length;p++){const y=n[p];a[p].push(y>=0?u[y].buf[e]:0)}const d=this._columnIds;for(let p=0;p<d.length;p++)this._changedTick[d[p]]=r;this.length++;const f=o?l:this._placeTail(l,i);t.removeRow(e,i),A[0]=f,A[1]=h.NO_SWAP}moveEntityFromTag(t,e,s,n){const r=e>=t.enabledCount;if(!this.materializesRows){t.removeRow(e,n),A[0]=h.UNASSIGNED,A[1]=h.NO_SWAP;return}const i=this.length;this._entityIds.push(s),this.length++;const o=r?i:this._placeTail(i,n);t.removeRow(e,n),A[0]=o,A[1]=h.NO_SWAP}bulkMoveAllFrom(t,e,s){const n=t.length;if(n===0)return this.length;const r=this._flatColumns;r.length>0&&this.length+n>r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,n);const i=this.length,o=t._flatColumns;this._entityIds.bulkAppend(t._entityIds.buf,0,n);for(let l=0;l<r.length;l++){const u=e[l];u>=0?r[l].bulkAppend(o[u].buf,0,n):r[l].bulkAppendZeroes(n)}const a=this._columnIds;for(let l=0;l<a.length;l++)this._changedTick[a[l]]=s;return this.length+=n,this.enabledCount=i+t.enabledCount,t.clearRows(),i}clearRows(){this.length=0,this.enabledCount=0,this._entityIds.clear();const t=this._flatColumns;for(let e=0;e<t.length;e++)t[e].clear()}restoreHostRows(t,e){const s=t.length;this._entityIds.clear(),this._entityIds.ensureCapacity(s);for(let r=0;r<s;r++)this._entityIds.push(t[r]);const n=this._flatColumns;for(let r=0;r<n.length;r++)n[r].setLength(s);this.length=s,this.enabledCount=e}getEdge(t){return this.edges[t]}setEdge(t,e){this.edges[t]=e}getBatchTransitionMap(t){const e=this.batchTransitionMaps.get(t.id);if(e!==void 0)return e;const s=st(this,t);return this.batchTransitionMaps.set(t.id,s),s}getCompositeAddEdge(t){return this.compositeAddEdges===null?void 0:this.compositeAddEdges.get(t)}cacheCompositeAddEdge(t,e,s){(this.compositeAddEdges??=new Map).set(t,{target:e,map:s})}}const A=[0,h.NO_SWAP];let et=!1;function x(c){const t=et;return et=c,t}function st(c,t){const e=t._flatColumns,s=new Int16Array(e.length),n=t._columnIds,r=c._colOffset,i=t._colOffset,o=t._fieldCount;for(let a=0;a<n.length;a++){const l=n[a],u=i[l],d=o[l],f=r[l];if(f!==void 0)for(let p=0;p<d;p++)s[u+p]=f+p;else for(let p=0;p<d;p++)s[u+p]=-1}return s}const bt=c=>h.validateAndCast(c),U=Object.freeze([]);function dt(c){return typeof c=="object"&&!Array.isArray(c)}function Wt(c){let t=U;c.spawns!==void 0&&c.spawns.length>0&&(t=c.spawns.map(s=>dt(s)?s.defs:s));let e=U;if(c.despawns!==void 0&&c.despawns.length>0){const s=[];for(const n of c.despawns)dt(n)?s.push(...n.defs):s.push(n);e=s}return{reads:c.reads,writes:c.writes,spawns:t,despawns:e,transitions:c.transitions??U,resourceReads:c.resourceReads??U,resourceWrites:c.resourceWrites??U,sparseReads:c.sparseReads,sparseWrites:c.sparseWrites,relationReads:c.relationReads,relationWrites:c.relationWrites}}const nt=Object.freeze({reads:Object.freeze([]),writes:Object.freeze([]),spawns:Object.freeze([]),despawns:Object.freeze([]),transitions:Object.freeze([]),resourceReads:Object.freeze([]),resourceWrites:Object.freeze([]),sparseReads:Object.freeze([]),sparseWrites:Object.freeze([]),relationReads:Object.freeze([]),relationWrites:Object.freeze([])}),zt=Symbol.dispose??Symbol.for("Symbol.dispose"),X=(1<<20)-1;let jt=0;function Yt(c,t){const e={...nt,...t,id:bt(jt++),name:c,fn:Kt};return Object.freeze(e)}function Kt(){}function ft(c){const t=new Set;if(c)for(let e=0;e<c.length;e++)t.add(c[e].id);return t}function Xt(c){const t=(i,o)=>i.cid-o.cid||i.id-o.id,e=new Map,s=new Map;for(const i of c)e.set(i,[]),s.set(i,0);for(const i of c)if(i.writes.size!==0)for(const o of c){if(i===o)continue;let a=!1;for(const l of i.writes)if(o.reads.has(l)){a=!0;break}a&&(e.get(i).push(o),s.set(o,s.get(o)+1))}const n=c.filter(i=>s.get(i)===0).sort(t),r=[];for(;n.length>0;){const i=n.shift();r.push(i);for(const o of e.get(i)){const a=s.get(o)-1;s.set(o,a),a===0&&(n.push(o),n.sort(t))}}if(r.length!==c.length){const i=new Set(r);for(const o of c.slice().sort(t))i.has(o)||r.push(o)}return r}class Qt{constructor(t,e){this.store=t,this.ctx=e}entries=[];byCid=new Map;_topo=null;_addBuckets=new Map;_remBuckets=new Map;_disBuckets=new Map;_enaBuckets=new Map;_radixOut=[];_radixC0=new Int32Array(1024);_radixC1=new Int32Array(1024);_setDrainCache=new Map;get count(){return this.entries.length}descriptors(){const t=new Array(this.entries.length);for(let e=0;e<this.entries.length;e++)t[e]=this.entries[e].descriptor;return t}register(t,e){const s=t.id,n=e.granularity??"archetype",r=e.onSet!==void 0&&n==="entity",i=e.onSet!==void 0&&n!=="entity",o=e.access??{},a=Yt(e.name??`observer(${h.componentDebugName(t)??s})`,o),l={id:a.id,cid:s,def:t,onAdd:e.onAdd,onRemove:e.onRemove,onDisable:e.onDisable,onEnable:e.onEnable,onSetEntity:r?e.onSet:void 0,onSetArch:i?e.onSet:void 0,descriptor:a,writes:ft(o.writes),reads:ft(o.reads),yieldExisting:e.yieldExisting??!1,lastSetTick:0,disposed:!1};this.entries.push(l);let u=this.byCid.get(s);u===void 0&&(u=[],this.byCid.set(s,u)),u.push(l),this._topo=null,this._reconfigureComponent(s),l.yieldExisting&&l.onAdd!==void 0&&this._yieldExisting(l);const d=()=>this._dispose(l);return{dispose:d,[zt]:d}}_dispose(t){if(t.disposed)return;t.disposed=!0;const e=this.entries.indexOf(t);e>=0&&this.entries.splice(e,1);const s=this.byCid.get(t.cid);if(s!==void 0){const n=s.indexOf(t);n>=0&&s.splice(n,1),s.length===0&&this.byCid.delete(t.cid)}this._topo=null,this._reconfigureComponent(t.cid)}_reconfigureComponent(t){const e=this.byCid.get(t);let s=!1,n=!1,r=!1,i=!1,o=!1;if(e!==void 0)for(let a=0;a<e.length;a++){const l=e[a];l.onAdd!==void 0&&(s=!0),l.onRemove!==void 0&&(n=!0),l.onDisable!==void 0&&(r=!0),l.onEnable!==void 0&&(i=!0),l.onSetEntity!==void 0&&(o=!0)}this.store._configureComponentObservation(t,s,n,r,i,o)}getTopo(){return this._topo===null&&(this._topo=Xt(this.entries)),this._topo}dispatchStructural(t){this._bucket(t.addComp,t.addEid,t.addLen,this._addBuckets),this._bucket(t.remComp,t.remEid,t.remLen,this._remBuckets),this._bucket(t.disComp,t.disEid,t.disLen,this._disBuckets),this._bucket(t.enaComp,t.enaEid,t.enaLen,this._enaBuckets);const e=this.getTopo();for(let s=0;s<e.length;s++){const n=e[s];if(!n.disposed){if(n.onRemove!==void 0){const r=this._remBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onRemove,r,"remove")}if(n.onAdd!==void 0){const r=this._addBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onAdd,r,"add")}if(n.onDisable!==void 0){const r=this._disBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onDisable,r,"disable")}if(n.onEnable!==void 0){const r=this._enaBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onEnable,r,"enable")}}}this._clearBuckets(this._addBuckets),this._clearBuckets(this._remBuckets),this._clearBuckets(this._disBuckets),this._clearBuckets(this._enaBuckets)}_fireEach(t,e,s,n){Y(s,this._radixOut,this._radixC0,this._radixC1);try{const r=O?this.store._trace:null;for(let i=0;i<s.length;i++)e(h.unsafeCast(s[i]),this.ctx)}finally{}}_bucket(t,e,s,n){for(let r=0;r<s;r++){const i=t[r];let o=n.get(i);o===void 0&&(o=[],n.set(i,o)),o.push(e[r])}}_clearBuckets(t){for(const e of t.values())e.length=0}dispatchSet(t){if(this.entries.length===0)return;const e=this.getTopo(),s=this._setDrainCache;for(let n=0;n<e.length;n++){const r=e[n];r.onSetEntity!==void 0?this._dispatchSetEntity(r,s):r.onSetArch!==void 0&&this._dispatchSetArch(r,t)}for(const n of s.values())n.length=0;s.clear()}_dispatchSetEntity(t,e){let s=e.get(t.cid);if(s===void 0&&(s=this.store._takeDirty(t.cid),Y(s,this._radixOut,this._radixC0,this._radixC1),e.set(t.cid,s)),s.length===0)return;const n=t.def,r=t.onSetEntity;try{for(let i=0;i<s.length;i++){const o=h.unsafeCast(s[i]);this.store.isAlive(o)&&this.store.hasComponent(o,n)&&!this.store.isDisabled(o)&&r(o,this.ctx)}}finally{}}_dispatchSetArch(t,e){const s=t.onSetArch,n=t.lastSetTick;try{this.store._forEachChangedArchetype(t.cid,n,r=>{s(r,this.ctx)})}finally{}t.lastSetTick=e+1}_yieldExisting(t){const e=t.onAdd,s=this.store._collectEntitiesWithComponent(t.cid);if(s.length!==0){Y(s,this._radixOut,this._radixC0,this._radixC1);try{for(let n=0;n<s.length;n++)e(h.unsafeCast(s[n]),this.ctx)}finally{}}}}function Y(c,t,e,s){const n=c.length;if(!(n<2)){t.length<n&&(t.length=n),e.fill(0),s.fill(0);for(let r=0;r<n;r++){const i=c[r]&X;e[i&1023]++,s[i>>10&1023]++}for(let r=1;r<1024;r++)e[r]+=e[r-1],s[r]+=s[r-1];for(let r=n-1;r>=0;r--){const i=c[r];t[--e[i&X&1023]]=i}for(let r=n-1;r>=0;r--){const i=t[r];c[--s[(i&X)>>10&1023]]=i}}}class Zt{constructor(t){this.host=t}relations=[];_hasTargetCleanup=!1;_hierarchyRadixOut=[];_hierarchyRadixC0=new Int32Array(1024);_hierarchyRadixC1=new Int32Array(1024);get stores(){return this.relations}get count(){return this.relations.length}get hasTargetCleanup(){return this._hasTargetCleanup}registerRelation(t){const e=t?.multi===!0,s=t?.exclusive===!0;if(e&&s)throw new h.ECSError(h.ECS_ERROR.RELATION_MODE_INVALID,"register_relation: a relation cannot be both exclusive and multi-target");const n=!e,r=t?.onDeleteTarget??h.DEFAULT_ON_DELETE_TARGET,i=n?this.host.pushSparseStore([h.RELATION_TARGET_FIELD],["f64"]):this.host.pushSparseStore([],[]),o=this.relations.length;return this.relations.push(h.makeRelationStore(n,i,this.host.sparseStoreOf(i),r)),r!=="orphan"&&(this._hasTargetCleanup=!0),h.unsafeCast(o)}relationOf(t){const e=t,s=this.relations[e];if(s===void 0)throw new h.ECSError(h.ECS_ERROR.RELATION_NOT_REGISTERED,`relation ${e} is not registered`);return s}addRelation(t,e,s){const n=this.relationOf(e);this.host.isAlive(t)&&this.host.isAlive(s)&&n.link(t,s)}removeRelation(t,e,s){const n=this.relationOf(e);this.host.isAlive(t)&&n.unlink(t,s)}targetOf(t,e){return this.relationOf(e).singleTarget(h.getEntityIndex(t))}targetsOf(t,e){return this.relationOf(e).targetsOf(h.getEntityIndex(t))}sourcesOf(t,e){return this.relationOf(e).sourcesOf(t)}hasRelation(t,e){return this.host.hasSparse(t,this.relationOf(e).sparse)}pairsOf(t){const e=this.relationOf(t),s=[],n=this.host.entityGenerations();return e.forEachCanonicalPair(r=>h.createEntityId(r,n[r]),(r,i)=>s.push([r,i])),s}sourcesOfAny(t){const e=[],s=this.relations;for(let n=0;n<s.length;n++){const r=h.unsafeCast(n),i=s[n].sourcesOf(t);for(let o=0;o<i.length;o++)e.push([r,i[o]])}return e}relationBackingSparseId(t){return this.relationOf(t).sparse}forEachRelationTargetMatch(t,e,s,n,r,i,o,a){const l=this.relations;if(l.length===0)return;const u=new Set;for(let E=0;E<l.length;E++){const _=l[E].sourcesOf(t);for(let m=0;m<_.length;m++)u.add(_[m])}if(u.size===0)return;const d=Array.from(u).sort((E,_)=>E-_),f=this.host.sparseStores(),p=this.host.entityArchetype(),y=this.host.entityRow(),g=this.host.archetypes();for(let E=0;E<d.length;E++){const _=h.unsafeCast(d[E]),m=h.getEntityIndex(_),S=p[m];if(S===h.UNASSIGNED)continue;const v=g[S],C=v.mask;if(!C.contains(e)||s!==null&&C.overlaps(s)||n!==null&&!C.overlaps(n))continue;let R=!0;for(let w=0;w<r.length;w++)if(!f[r[w]].has(m)){R=!1;break}if(R){for(let w=0;w<i.length;w++)if(f[i[w]].has(m)){R=!1;break}if(R){if(!o){const w=y[m];if(w!==h.UNASSIGNED&&w>=v.enabledCount)continue}a(_)}}}}compactRelations(){const t=this.relations;if(t.length===0)return 0;const e=n=>this.host.isAlive(n);let s=0;for(let n=0;n<t.length;n++)s+=t[n].pruneDeadReverse(e);return s}ancestorsOf(t,e){const s=this.relationOf(e),n=this.host.sparseStoreOf(s.sparse),r=[t],i=new Set([h.getEntityIndex(t)]);let o=t;for(;;){const a=n.getField(h.getEntityIndex(o),0);if(a===void 0)break;const l=h.unsafeCast(a);if(!this.host.isAlive(l)){r.push(l);break}const u=h.getEntityIndex(l);if(i.has(u))break;i.add(u),o=l,r.push(o)}return r}rootOf(t,e){const s=this.ancestorsOf(t,e);return s[s.length-1]}cascadeOf(t,e){const s=this.relationOf(e),n=[t],r=new Set([h.getEntityIndex(t)]);for(let i=0;i<n.length;i++){const o=s.sourcesOf(n[i]);for(let a=0;a<o.length;a++){const l=o[a],u=h.getEntityIndex(l);r.has(u)||(r.add(u),n.push(l))}}return n}purgeSource(t){const e=this.relations;for(let s=0;s<e.length;s++)e[s].purgeSource(t)}cleanupTarget(t,e){const s=this.relations;for(let n=0;n<s.length;n++){const r=s[n];if(r.onDeleteTarget==="orphan")continue;const i=r.sourcesOf(t);if(i.length!==0){if(r.onDeleteTarget==="delete"){for(let o=0;o<i.length;o++)e.push(i[o]);continue}for(let o=0;o<i.length;o++)r.unlink(i[o],t)}}}forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){const d=this.relationOf(o),f=[];if(this.host.forEachSparseMatch(t,e,s,n,r,i,_=>f.push(_),l),f.length===0)return;Y(f,this._hierarchyRadixOut,this._hierarchyRadixC0,this._hierarchyRadixC1);const p=this.host.sparseStoreOf(d.sparse),y=new Map,g=new Set,E=[];for(let _=0;_<f.length;_++){const m=f[_],S=this._hierarchyDepthOf(h.getEntityIndex(m),p,y,g);if(S>a)continue;let v=E[S];v===void 0&&(v=[],E[S]=v),v.push(m)}for(let _=0;_<E.length;_++){const m=E[_];if(m!==void 0)for(let S=0;S<m.length;S++)u(m[S])}}_hierarchyDepthOf(t,e,s,n){const r=[];let i=t,o=0;for(;;){const l=s.get(i);if(l!==void 0){o=l;break}const u=e.getField(i,0);let d=-1;if(u!==void 0){const f=h.unsafeCast(u);this.host.isAlive(f)&&(d=h.getEntityIndex(f))}if(d===-1){s.set(i,0),o=0;break}if(n.has(d)){s.set(i,0),o=0;break}r.push(i),n.add(i),i=d}let a=o;for(let l=r.length-1;l>=0;l--)a+=1,s.set(r[l],a),n.delete(r[l]);return s.get(t)}}class Jt{_generations;_lengthView;_highWater=0;_freeIndices=[];_aliveCount=0;_capacity;lastIndex=0;constructor(t,e,s){this._capacity=t,this._generations=e,this._lengthView=s}replantViews(t,e){this._generations=t,this._lengthView=e}get generations(){return this._generations}get highWater(){return this._highWater}get aliveCount(){return this._aliveCount}get freeCount(){return this._freeIndices.length}alloc(){let t,e;if(this._freeIndices.length>0)t=this._freeIndices.pop(),e=this._generations[t];else{if(this._highWater>=this._capacity)throw new h.ECSError(h.ECS_ERROR.EID_MAX_INDEX_OVERFLOW,`entityIndexCapacity (${this._capacity}) exhausted; raise it in ECSOptions.memory or destroy unused entities`);t=this._highWater++,this._generations[t]=h.INITIAL_GENERATION,e=h.INITIAL_GENERATION,this._lengthView[0]=this._highWater}return this._aliveCount++,this.lastIndex=t,h.createEntityId(t,e)}ensureCapacity(t){const e=t-this._freeIndices.length;if(e>0&&this._highWater+e>this._capacity)throw new h.ECSError(h.ECS_ERROR.EID_MAX_INDEX_OVERFLOW,`entityIndexCapacity (${this._capacity}) cannot fit ${t} new entities (${this._freeIndices.length} free, high-water ${this._highWater}); raise it in ECSOptions.memory or destroy unused entities`)}recycle(t,e){const s=e+1;s<h.RETIRED_GENERATION?(this._generations[t]=s,this._freeIndices.push(t)):this._generations[t]=h.RETIRED_GENERATION,this._aliveCount--}isAliveIndex(t,e){return t<this._highWater&&this._generations[t]===e}publishLength(){this._lengthView[0]=this._highWater}snapshotFreeIndices(){return this._freeIndices.slice()}setHighWater(t){this._highWater=t}restoreHostState(t,e){this._freeIndices.length=0;for(let s=0;s<t.length;s++)this._freeIndices.push(t[s]);this._aliveCount=e}}const pt=65536;class te{destroyIds=[];addIds=[];addDefs=[];addValues=[];removeIds=[];removeDefs=[];toggleIds=[];toggleDisable=[];_flushing=!1;host;obsEvents;constructor(t,e){this.host=t,this.obsEvents=e}queueDestroy(t){this.destroyIds.push(t)}queueAdd(t,e,s){this.addIds.push(t),this.addDefs.push(e),this.addValues.push(s)}queueRemove(t,e){this.removeIds.push(t),this.removeDefs.push(e)}queueToggle(t,e){this.toggleIds.push(t),this.toggleDisable.push(e)}get destroyCount(){return this.destroyIds.length}get structuralCount(){return this.addIds.length+this.removeIds.length}get toggleCount(){return this.toggleIds.length}flushDestroyed(){this._flushing||this.host.applyDestroys()}flushStructural(){if(this.host.structuralObserverCount()===0&&this.host.toggleObserverCount()===0){this.addIds.length>0&&this.host.applyAdds(),this.removeIds.length>0&&this.host.applyRemoves(),this.toggleIds.length>0&&this.host.applyToggles();return}if(this._flushing)return;this._flushing=!0;const t=this.obsEvents,e=this.host.structuralObserverHook();try{let s=0;for(;this.addIds.length>0||this.removeIds.length>0||this.destroyIds.length>0||this.toggleIds.length>0;){if(++s>pt)throw new h.ECSError(h.ECS_ERROR.OBSERVER_NON_CONVERGENT,`observer cascade did not converge after ${pt} rounds — two observers likely enqueue each other's structural ops forever`);t.addLen=0,t.remLen=0,t.disLen=0,t.enaLen=0,this.addIds.length>0||this.removeIds.length>0?(this.addIds.length>0&&this.host.applyAdds(),this.removeIds.length>0&&this.host.applyRemoves()):this.destroyIds.length>0?this.host.applyDestroys():this.host.applyToggles(),e!==null&&(t.addLen>0||t.remLen>0||t.disLen>0||t.enaLen>0)&&e(t)}}finally{this._flushing=!1}}}function It(c,t){let e=c;const s=new Array(t.length);for(let n=0;n<t.length;n++){const r=t[n],i=new Array(r.columns.length);for(let o=0;o<r.columns.length;o++){const a=r.columns[o];e=h.alignUp(e,a.stride),i[o]={componentId:a.componentId,fieldId:a.fieldId,typeTag:a.typeTag,byteOff:e,stride:a.stride},e+=a.stride*r.rowCapacity}s[n]={archetypeId:r.archetypeId,componentMask:r.componentMask,rowCount:0,enabledCount:0,rowCapacity:r.rowCapacity,columns:i}}if(e>h.STORE_MAX_BYTE_OFFSET)throw new h.StoreLayoutOverflowError(e);return{descriptors:s,newTotal:e}}function At(c,t){const e=c._allocator(t),s=e!==c.buffer?new DataView(e):c.view;return{grownBuffer:e,newView:s}}function ee(c){const t={};for(let n=0;n<h.STORE_PREFIX_REGIONS.length;n++){const r=h.STORE_PREFIX_REGIONS[n],i=c.view.getUint32(h.STORE_HEADER_OFFSETS[r.headerOff],!0);i!==0&&r.readOptions(c.view,i,t)}const e=h.readHeaderRegionTable(c.view);e.length>0&&(t.regions=e.map(n=>({id:n.regionId,name:`region:${n.regionId}`,bytes:n.byteLength,init:()=>{}})));const s=c.view.getUint32(h.STORE_HEADER_OFFSETS.bindings_off,!0);if(s!==0){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);t.bindingsRegionBytes=n-s}return h.isColumnStoreInternal(c)&&c._reservedDescriptorBytes>0&&(t.reservedDescriptorBytes=c._reservedDescriptorBytes),t}function se(c){const t=new Map;for(let n=0;n<h.STORE_PREFIX_REGIONS.length;n++){const r=h.STORE_PREFIX_REGIONS[n],i=c.view.getUint32(h.STORE_HEADER_OFFSETS[r.headerOff],!0);if(i===0)continue;const o=r.regionBytes(c.view,i);t.set(r.headerOff,new Uint8Array(c.buffer,i,o).slice())}const e=new Map,s=h.readHeaderRegionTable(c.view);for(let n=0;n<s.length;n++){const r=s[n];e.set(r.regionId,new Uint8Array(c.buffer,r.byteOffset,r.byteLength).slice())}return{mechanism:t,consumer:e}}function ne(c,t){for(const[e,s]of t.mechanism){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS[e],!0);new Uint8Array(c.buffer,n,s.byteLength).set(s)}for(const[e,s]of t.consumer){const n=h.findRegionOffset(c.view,e);if(n===0)continue;new Uint8Array(c.buffer,n,s.byteLength).set(s)}}function re(c,t){const e=new Map;for(const[s,n]of c.archetypes){const r=t.get(s)??0;if(r===0)continue;const i=[];for(let o=0;o<n.columnsInOrder.length;o++){const a=n.columnsInOrder[o],l=r*a.stride,u=new Uint8Array(l);u.set(new Uint8Array(a.view.buffer,a.view.byteOffset,l)),i.push(u)}e.set(s,i)}return e}function ie(c,t){for(const[e,s]of t){const n=c.archetypes.get(e);if(n===void 0)throw new Error(`restore_column_snapshots: new store missing archetype ${e} (internal)`);const r=n.columnsInOrder;for(let i=0;i<s.length;i++){const o=r[i].view;new Uint8Array(o.buffer,o.byteOffset,s[i].byteLength).set(s[i])}}}function Ot(c,t,e,s){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),r=re(c,e),i=se(c),o=ee(c),a=h.createColumnStore(t,s,o);ie(a,r),ne(a,i);const l=n+1>>>0;return a.view.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,l,!0),{store:{...a,header:{...a.header,viewStamp:l}},oldViewStamp:n,newViewStamp:l}}function oe(c,t,e){const s=new Array(t.length);for(let _=0;_<t.length;_++){const m=t[_],S=c.archetypes.get(m.archetypeId);s[_]={archetypeId:m.archetypeId,componentMask:S.componentMask,rowCapacity:m.newRowCapacity,columns:S.columnsInOrder}}const{descriptors:n,newTotal:r}=It(c.buffer.byteLength,s),i=new Map;for(let _=0;_<n.length;_++)i.set(n[_].archetypeId,n[_]);const{grownBuffer:o,newView:a}=At(c,r),l=new Uint8Array(o);for(let _=0;_<t.length;_++){const m=t[_],S=c.archetypes.get(m.archetypeId),v=i.get(m.archetypeId);for(let C=0;C<S.columnsInOrder.length;C++){const R=S.columnsInOrder[C],w=m.rowCount*R.stride;w>0&&l.copyWithin(v.columns[C].byteOff,R.byteOff,R.byteOff+w)}}let u=e;for(const[_,m]of c.archetypes){const S=i.get(_);S!==void 0&&h.writeArchetypeDescriptor(a,u,S),u+=h.archetypeDescriptorBytes(m.columnsInOrder.length)}const d=a.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),f=d+1>>>0;a.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,f,!0),a.setUint32(h.STORE_HEADER_OFFSETS.capacity,r,!0);const p=h.buildArchetypeViews(o,[...i.values()]),y=new Map;for(const[_,m]of c.archetypes){const S=p.get(_);y.set(_,S??m)}const g={buffer:o,view:a,header:{...c.header,viewStamp:f,capacity:r},archetypes:y,_regionBytes:c._regionBytes,_allocator:c._allocator,_reservedDescriptorBytes:c._reservedDescriptorBytes},E=new Array(t.length);for(let _=0;_<t.length;_++)E[_]=t[_].archetypeId;return{store:g,oldViewStamp:d,newViewStamp:f,viewsPreserved:!0,grownArchetypeIds:E}}class Q extends Error{constructor(t){super(t),this.name="StoreGrowError"}}function he(c,t,e){const s=new Map;for(let u=0;u<t.archetypes.length;u++){const d=t.archetypes[u];s.set(d.archetypeId,d)}const n=[],r=[];for(const[u,d]of c.archetypes){const f=s.get(u),p=f?.newRowCapacity??d.rowCapacity;if(p<(f?.rowCount??0))throw new Q(`archetype ${u}: new_row_capacity ${p} < row_count ${f?.rowCount}`);if(p<d.rowCapacity)throw new Q(`archetype ${u}: shrinking from ${d.rowCapacity} to ${p} is not supported`);p>d.rowCapacity&&r.push({archetypeId:u,newRowCapacity:p,rowCount:f?.rowCount??0}),n.push({archetypeId:u,componentMask:d.componentMask,rowCapacity:p,columns:d.columnsInOrder})}const i=new Map;for(const[u,d]of c.archetypes){const p=s.get(u)?.rowCount??0;if(p>d.rowCapacity)throw new Q(`archetype ${u}: row_count ${p} > old row_capacity ${d.rowCapacity}`);p>0&&i.set(u,p)}if(e?.isInPlace===!0&&h.isColumnStoreInternal(c)&&c._allocator===e&&r.length>0){const u=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);return oe(c,r,u)}const{store:o,oldViewStamp:a,newViewStamp:l}=Ot(c,n,i,e);return{store:o,oldViewStamp:a,newViewStamp:l,viewsPreserved:!1,grownArchetypeIds:[]}}class L extends Error{constructor(t){super(t),this.name="StoreExtendError"}}function ae(c,t,e){if(t.newArchetypes.length===0)throw new L("extend plan has no new archetypes; use grow_column_store for resizes");const s=new Set;for(let l=0;l<t.newArchetypes.length;l++){const u=t.newArchetypes[l].archetypeId;if(s.has(u))throw new L(`duplicate archetype_id ${u} in extend plan`);if(c.archetypes.has(u))throw new L(`archetype_id ${u} already exists in the SAB; use grow_column_store to resize it`);s.add(u)}const n=new Map;if(t.existing)for(let l=0;l<t.existing.length;l++){const u=t.existing[l];if(!c.archetypes.has(u.archetypeId))throw new L(`existing row_count names unknown archetype_id ${u.archetypeId}`);if(u.rowCount<0)throw new L(`archetype ${u.archetypeId}: row_count must be non-negative (got ${u.rowCount})`);if(u.rowCount>0){const d=c.archetypes.get(u.archetypeId);if(u.rowCount>d.rowCapacity)throw new L(`archetype ${u.archetypeId}: row_count ${u.rowCount} > old row_capacity ${d.rowCapacity}`)}n.set(u.archetypeId,u.rowCount)}if(e?.isInPlace===!0&&h.isColumnStoreInternal(c)&&c._allocator===e){const l=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);let u=0;for(const[,f]of c.archetypes)u+=h.archetypeDescriptorBytes(f.columnsInOrder.length);let d=0;for(let f=0;f<t.newArchetypes.length;f++)d+=h.archetypeDescriptorBytes(t.newArchetypes[f].columns.length);if(u+d<=c._regionBytes)return ce(c,t.newArchetypes,l,u)}const r=[];for(const[l,u]of c.archetypes)r.push({archetypeId:l,componentMask:u.componentMask,rowCapacity:u.rowCapacity,columns:u.columnsInOrder});for(let l=0;l<t.newArchetypes.length;l++)r.push(t.newArchetypes[l]);const{store:i,oldViewStamp:o,newViewStamp:a}=Ot(c,r,n,e);return{store:i,oldViewStamp:o,newViewStamp:a,viewsPreserved:!1}}function ce(c,t,e,s){const n=new Array(t.length);for(let E=0;E<t.length;E++){const _=t[E];n[E]={archetypeId:_.archetypeId,componentMask:_.componentMask,rowCapacity:_.rowCapacity,columns:_.columns.map(m=>({componentId:m.componentId,fieldId:m.fieldId,typeTag:m.typeTag,stride:h.TYPE_TAG_STRIDE[m.typeTag]}))}}const{descriptors:r,newTotal:i}=It(c.buffer.byteLength,n),{grownBuffer:o,newView:a}=At(c,i);let l=e+s;for(let E=0;E<r.length;E++)l=h.writeArchetypeDescriptor(a,l,r[E]);const u=a.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),d=c.archetypes.size+t.length;a.setUint32(h.STORE_HEADER_OFFSETS.archetype_count,d,!0),a.setUint32(h.STORE_HEADER_OFFSETS.capacity,i,!0);const f=u+1>>>0;a.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,f,!0);const p=h.buildArchetypeViews(o,r),y=new Map;for(const[E,_]of c.archetypes)y.set(E,_);for(const[E,_]of p)y.set(E,_);return{store:{buffer:o,view:a,header:{...c.header,viewStamp:f,capacity:i,archetypeCount:d},archetypes:y,_regionBytes:c._regionBytes,_allocator:c._allocator,_reservedDescriptorBytes:c._reservedDescriptorBytes},oldViewStamp:u,newViewStamp:f,viewsPreserved:!0}}const rt=810766935,K=1;class b extends Error{constructor(t){super(t),this.name="ECSRestoreError"}}const P=4;function le(c){const t=c.freeIndices.length,e=c.archetypeRows.length,s=P*(4+t+1+e*3),n=new Uint8Array(s),r=new DataView(n.buffer);let i=0;const o=a=>{r.setUint32(i,a,!0),i+=P};o(c.tick),o(c.entityHighWater),o(c.entityAliveCount),o(t);for(let a=0;a<t;a++)o(c.freeIndices[a]);o(e);for(let a=0;a<e;a++){const l=c.archetypeRows[a];o(l.archetypeId),o(l.length),o(l.enabledCount)}return n}function ue(c){const t=new DataView(c.buffer,c.byteOffset,c.byteLength),e=c.byteLength;let s=0;const n=p=>{if(s+p>e)throw new b(`host-state truncated: need ${p} more bytes at offset ${s}, have ${e-s}`)},r=()=>{n(P);const p=t.getUint32(s,!0);return s+=P,p},i=r(),o=r(),a=r(),l=r(),u=new Array(l);for(let p=0;p<l;p++)u[p]=r();const d=r(),f=new Array(d);for(let p=0;p<d;p++){const y=r(),g=r(),E=r();f[p]={archetypeId:y,length:g,enabledCount:E}}if(s!==e)throw new b(`host-state has ${e-s} trailing bytes after the last archetype (not a canonical encoding)`);return{tick:i,entityHighWater:o,entityAliveCount:a,freeIndices:u,archetypeRows:f}}function de(c,t,e){const s=P*5,n=new Uint8Array(s+c.length+t.length+e.length),r=new DataView(n.buffer);return r.setUint32(0,rt,!0),r.setUint32(4,K,!0),r.setUint32(8,c.length,!0),r.setUint32(12,t.length,!0),r.setUint32(16,e.length,!0),n.set(c,s),n.set(t,s+c.length),n.set(e,s+c.length+t.length),n}function fe(c){const t=P*5;if(c.byteLength<t)throw new b(`world snapshot too small: ${c.byteLength} bytes (frame header needs ${t})`);const e=new DataView(c.buffer,c.byteOffset,c.byteLength),s=e.getUint32(0,!0);if(s!==rt)throw new b(`bad world-snapshot magic: 0x${s.toString(16).padStart(8,"0")} (expected 0x${rt.toString(16).padStart(8,"0")}). A bare dense (SAB) snapshot is not a combined world snapshot — pass the bytes from ECS.snapshot(), not snapshotColumnStore().`);const n=e.getUint32(4,!0);if(n!==K)throw new b(`incompatible world-snapshot version: snapshot=${n}, build=${K}`);const r=e.getUint32(8,!0),i=e.getUint32(12,!0),o=e.getUint32(16,!0);if(t+r+i+o!==c.byteLength)throw new b(`world-snapshot frame mismatch: header declares ${t}+${r}+${i}+${o}=${t+r+i+o} bytes, buffer is ${c.byteLength}`);const a=c.byteOffset,l=c.buffer;return{dense:new Uint8Array(l,a+t,r),sparse:new Uint8Array(l,a+t+r,i),host:new Uint8Array(l,a+t+r+i,o)}}function pe(c,t,e){if(c.byteLength<h.STORE_HEADER_BYTES)throw new b(`dense section too small: ${c.byteLength} bytes (SAB header needs ${h.STORE_HEADER_BYTES})`);const s=new DataView(c.buffer,c.byteOffset,c.byteLength),n=s.getUint32(h.STORE_HEADER_OFFSETS.magic,!0);if(n!==h.STORE_MAGIC)throw new b(`dense section bad magic: 0x${n.toString(16).padStart(8,"0")} (expected SAB magic 0x${h.STORE_MAGIC.toString(16).padStart(8,"0")})`);const r=s.getUint32(h.STORE_HEADER_OFFSETS.sim_abi_version,!0);if(r!==h.SIM_ABI_VERSION)throw new b(`dense section incompatible sim_abi_version: snapshot=${r}, build=${h.SIM_ABI_VERSION}`);const i=h.readStoreHeader(s);if(i.layoutDescriptorOff<0||i.layoutDescriptorOff>c.byteLength)throw new b(`dense layoutDescriptorOff ${i.layoutDescriptorOff} is outside the section (${c.byteLength} bytes)`);const o=i.entityIndexOff;if(o<0||o+h.ENTITY_INDEX_HEADER_BYTES>c.byteLength)throw new b(`dense entityIndexOff ${o} is outside the section (${c.byteLength} bytes)`);const a=s.getUint32(o+h.ENTITY_INDEX_HEADER_OFFSETS.capacity,!0);if(a!==e)throw new b(`entity-index capacity mismatch: live=${e}, snapshot=${a}`);let l;try{l=h.readLayoutDescriptorRegion(s,i.layoutDescriptorOff,i.archetypeCount)}catch(u){throw u instanceof RangeError?new b(`dense section layout is corrupt or truncated: a descriptor reads past the ${c.byteLength}-byte section (${u.message})`):u}if(t.size!==l.length)throw new b(`archetype-set mismatch: the live world has ${t.size} SAB archetypes, the snapshot has ${l.length}. restoreInto requires an identical archetype set (prewarm the world so its archetype set is stable, per ADR on no-lazy archetypes).`);for(let u=0;u<l.length;u++){const d=l[u],f=t.get(d.archetypeId);if(f===void 0)throw new b(`archetype-set mismatch: snapshot archetype ${d.archetypeId} is absent from the live world`);if(!_e(f.componentMask,d.componentMask))throw new b(`archetype ${d.archetypeId} component-mask mismatch between the live world and the snapshot (different component registration)`);const p=f.columnsInOrder,y=d.columns;if(p.length!==y.length)throw new b(`archetype ${d.archetypeId} column-count mismatch: live=${p.length}, snapshot=${y.length}`);for(let g=0;g<p.length;g++)if(p[g].componentId!==y[g].componentId||p[g].fieldId!==y[g].fieldId||p[g].typeTag!==y[g].typeTag)throw new b(`archetype ${d.archetypeId} column ${g} layout mismatch: live=(c${p[g].componentId},f${p[g].fieldId},t${p[g].typeTag}), snapshot=(c${y[g].componentId},f${y[g].fieldId},t${y[g].typeTag})`)}}function _e(c,t){if(c.length!==t.length)return!1;for(let e=0;e<c.length;e++)if(c[e]!==t[e])return!1;return!0}class ge{host;allocator;constructor(t,e){this.host=t,this.allocator=e}snapshotSparse(){const t=h.snapshotSparseStores(this.host.sparseStores()),e=h.snapshotRelations(this.host.relationStores()),s=new Uint8Array(8+t.length+e.length),n=new DataView(s.buffer);return n.setUint32(0,t.length,!0),n.setUint32(4,e.length,!0),s.set(t,8),s.set(e,8+t.length),s}restoreSparse(t){const e=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<8)throw new h.SparseRestoreError(`sparse snapshot truncated: need 8 header bytes, have ${t.byteLength}`);const s=e.getUint32(0,!0),n=e.getUint32(4,!0);if(8+s+n!==t.byteLength)throw new h.SparseRestoreError(`sparse snapshot frame mismatch: header declares 8+${s}+${n}=${8+s+n} bytes, buffer is ${t.byteLength}`);h.restoreSparseStores(this.host.sparseStores(),t.subarray(8,8+s)),this.rebuildRelationIndices(t.subarray(8+s,8+s+n))}rebuildRelationIndices(t){const e=this.host.generations(),s=r=>h.createEntityId(r,e[r]),n=this.host.relationStores();h.restoreRelations(n,t,s);for(let r=0;r<n.length;r++)n[r].rebuildReverseFromForward(s)}snapshot(){this.host.publishRowCounts();const t=new Uint8Array(Lt(this.host.columnStore())),e=this.snapshotSparse(),s=le(this.collectHostState());return de(t,e,s)}collectHostState(){const t=[],e=this.host.archetypes();for(let s=0;s<e.length;s++){const n=e[s];n.isBufferBacked&&t.push({archetypeId:n.id,length:n.length,enabledCount:n.enabledCount})}return{tick:this.host.tick(),entityHighWater:this.allocator.highWater,entityAliveCount:this.allocator.aliveCount,freeIndices:this.allocator.snapshotFreeIndices(),archetypeRows:t}}restoreInto(t){const e=fe(t),s=ue(e.host);pe(e.dense,this.host.columnStore().archetypes,this.host.entityIndexCapacity()),this.assertSparseSectionMatches(e.sparse);const n=Bt(e.dense,this.host.bufferAllocator());this.host.mountRestoredDense(n),this.host.reconstructHostRows(s),this.allocator.restoreHostState(s.freeIndices,s.entityAliveCount),this.host.setTick(s.tick),this.host.invalidateQueryCaches(),this.restoreSparse(e.sparse)}assertSparseSectionMatches(t){const e=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<8)throw new h.SparseRestoreError(`sparse snapshot truncated: need 8 header bytes, have ${t.byteLength}`);const s=e.getUint32(0,!0),n=e.getUint32(4,!0);if(8+s+n!==t.byteLength)throw new h.SparseRestoreError(`sparse snapshot frame mismatch: header declares 8+${s}+${n}=${8+s+n} bytes, buffer is ${t.byteLength}`);h.validateSparseStores(this.host.sparseStores(),t.subarray(8,8+s))}}function Tt(c,t,e){const s=c.get(t);s!==void 0?s.push(e):c.set(t,[e])}class ye{archetypes=[];componentIndex=[];archetypeMap=new Map;nextArchetypeId=0;host;constructor(t){this.host=t}get(t){return this.archetypes[t]}getOrCreateFromMask(t){const e=t.hash(),s=this.lookup(t,e);if(s!==null)return s;const n=ut(this.nextArchetypeId++),r=this.buildLayouts(t);return this.host.extendStore([_t(n,t,r,this.host.initialCapacity())]),this.install(n,t,r,e),n}createManyFromMasks(t){const e=new Array(t.length),s=[],n=[],r=[],i=[];for(let a=0;a<t.length;a++){const l=t[a],u=l.hash(),d=this.lookup(l,u);if(d!==null){e[a]=d;continue}let f=!1;for(let y=0;y<s.length;y++)if(n[y]===u&&s[y].equals(l)){e[a]=i[y],f=!0;break}if(f)continue;const p=ut(this.nextArchetypeId++);s.push(l),n.push(u),r.push(this.buildLayouts(l)),i.push(p),e[a]=p}if(s.length===0)return e;const o=new Array(s.length);for(let a=0;a<s.length;a++)o[a]=_t(i[a],s[a],r[a],this.host.initialCapacity());this.host.extendStore(o);for(let a=0;a<s.length;a++)this.install(i[a],s[a],r[a],n[a]);return e}lookup(t,e){const s=this.archetypeMap.get(e);if(s===void 0)return null;for(let n=0;n<s.length;n++)if(this.archetypes[s[n]].mask.equals(t))return s[n];return null}buildLayouts(t){const e=[],s=this.host.componentMetas();return t.forEach(n=>{const r=n,i=s[r];i&&i.fieldNames.length>0&&e.push({componentId:r,fieldNames:i.fieldNames,fieldIndex:i.fieldIndex,fieldTypes:i.fieldTypes})}),e}install(t,e,s,n){const r=e.copy(),i=this.host.materialize(t,r,s);this.archetypes.push(i),Tt(this.archetypeMap,n,t),e.forEach(o=>{const a=o;let l=this.componentIndex[a];l===void 0&&(l=[],this.componentIndex[a]=l),l.push(t)}),this.host.fanIntoQueries(i)}resolveAdd(t,e){const s=this.get(t);if(s.mask.has(e))return t;const n=s.getEdge(e);if(n?.add!=null)return n.add;const r=this.getOrCreateFromMask(s.mask.copyWithSet(e));return this.cacheEdge(s,this.get(r),e),r}resolveRemove(t,e){const s=this.get(t);if(!s.mask.has(e))return t;const n=s.getEdge(e);if(n?.remove!=null)return n.remove;const r=this.getOrCreateFromMask(s.mask.copyWithClear(e));return this.cacheEdge(this.get(r),s,e),r}cacheEdge(t,e,s){const n=t.getEdge(s)??{add:null,remove:null,addMap:null,removeMap:null};n.add=e.id,n.addMap=st(t,e),t.setEdge(s,n);const r=e.getEdge(s)??{add:null,remove:null,addMap:null,removeMap:null};r.remove=t.id,r.removeMap=st(e,t),e.setEdge(s,r)}}function _t(c,t,e,s){const n=[];for(let o=0;o<e.length;o++){const a=e[o],l=a.fieldTypes;for(let u=0;u<l.length;u++)n.push({componentId:a.componentId,fieldId:u,typeTag:h.TYPED_ARRAY_TAG_TO_TYPE_TAG[l[u]]})}const r=t._words,i=new Array(h.COMPONENT_MASK_WORDS);for(let o=0;o<h.COMPONENT_MASK_WORDS;o++)i[o]=(r[o]??0)>>>0;return{archetypeId:c,componentMask:i,rowCapacity:s,columns:n}}const Ee=[],gt=-1,Z=new DataView(new ArrayBuffer(8)),yt=129,me=7,J=-1;class we{entityAllocator;componentMetas=[];componentCount=0;sparseStores=[];sparseNames=[];relationService;events=new Ht;archGraph;registeredQueries=[];emptyArchetypeId;entityArchetype;entityRow;_deferred;_snapshots;_tick=0;_trace=null;_structuralObserverCount=0;_toggleObserverCount=0;_obsEvents={addComp:[],addEid:[],addLen:0,remComp:[],remEid:[],remLen:0,disComp:[],disEid:[],disLen:0,enaComp:[],enaEid:[],enaLen:0};_structuralObserverHook=null;setStructuralObserverHook(t){this._structuralObserverHook=t}_collectDestroyEid=0;_collectDestroyRemoveBit=t=>{if(!this.componentMetas[t].obsRem)return;const e=this._obsEvents;e.remComp[e.remLen]=t,e.remEid[e.remLen]=this._collectDestroyEid,e.remLen++};_collectToggleEid=0;_collectDisableBit=t=>{if(!this.componentMetas[t].obsDisable)return;const e=this._obsEvents;e.disComp[e.disLen]=t,e.disEid[e.disLen]=this._collectToggleEid,e.disLen++};_collectEnableBit=t=>{if(!this.componentMetas[t].obsEnable)return;const e=this._obsEvents;e.enaComp[e.enaLen]=t,e.enaEid[e.enaLen]=this._collectToggleEid,e.enaLen++};_toggleInitial=new Map;_anyDirtyTracked=!1;_dirtyTrackedCids=[];_dirtyLists=[];_dirtyMarks=[];_rowCountsDirty=!1;_queryDirtyEpoch=0;initialCapacity;_scratchTargetMask=new T.BitSet;_columnStore;_growHandler=(t,e)=>{const s=t.id,n=this._columnStore.archetypes.get(s);if(n===void 0)throw new h.ECSError(h.ECS_ERROR.ARCHETYPE_NOT_FOUND,`grow_handler invoked on archetype ${s} which has no SAB region`);const r=n.rowCapacity,i=t.length+e;let o=r>0?r:1;for(;o<i;)o=o*2;const a=[],l=this.archGraph.archetypes;for(let d=0;d<l.length;d++){const f=l[d],p=this._columnStore.archetypes.get(f.id);p!==void 0&&a.push({archetypeId:f.id,newRowCapacity:f.id===s?o:p.rowCapacity,rowCount:f.hasColumns?f.length:0})}let u;try{u=he(this._columnStore,{archetypes:a},this._bufferAllocator)}catch(d){throw d instanceof V.StoreCapExceededError?this._capExceededError(d):d}if(this._columnStore=u.store,u.viewsPreserved){const d=u.grownArchetypeIds;for(let f=0;f<d.length;f++){const p=this.archGet(d[f]);p.isBufferBacked&&p.refreshViews(this._columnStore)}}else for(let d=0;d<l.length;d++)l[d].isBufferBacked&&l[d].refreshViews(this._columnStore);this._handleBufferResized()};_capExceededError(t){const e=this._capContext,s=this.entityAllocator.aliveCount,n=`SAB grow refused: requested ${t.requestedBytes} bytes exceeds `+(t.capBytes!==null?`the ${t.capBytes}-byte cap.`:"the backing's ceiling.");let r;if(e===void 0)r=` The ECS holds ${s} live entities (no sizing intent declared).`;else if(e.budgetEntities!==null){const i=(s/e.budgetEntities).toFixed(1);r=` Declared ${e.intentLabel}; the ECS holds ${s} live entities (${i}× the budget) — runaway entity creation upstream, or an under-declared budget. Raise the budget only if a ${s}-entity ECS is intended.`}else r=` Declared ${e.intentLabel}; the ECS holds ${s} live entities.`;return new h.ECSError(h.ECS_ERROR.STORE_CAP_EXCEEDED,n+r+` The cap is a hard ceiling with no grow-beyond fallback (#380) — diagnose growth before raising it. Caused by: ${t.message}`)}_bufferAllocator;_capContext;_onBufferResized;constructor(t){const e=typeof t=="number"?{initialCapacity:t}:t??{};if(this.initialCapacity=e.initialCapacity??h.DEFAULT_COLUMN_CAPACITY,this._bufferAllocator=e.bufferAllocator??V.growableSabAllocator(),this._bufferAllocator.isInPlace!==!0)throw new h.ECSError(h.ECS_ERROR.INVALID_MEMORY_OPTIONS,"Store requires an in-place SAB allocator (ADR-0008): the flush loops keep writing through hoisted entity-index views across grows, so a non-in-place allocator (e.g. DEFAULT_SAB_ALLOCATOR) corrupts the entity→row mapping. Use growable_sab_allocator / wasm_memory_allocator; non-in-place allocators are snapshot/test sizing utilities only.");this._capContext=e.capContext,this._onBufferResized=e.onBufferResized,this._entityIndexCapacity=e.entityIndexCapacity??h.ENTITY_INDEX_DEFAULT_CAPACITY,this._regions=e.regions,this._bindingsRegionBytes=e.bindingsRegionBytes??0,this._deterministic=e.deterministic??!1,this._deferred=new te({applyAdds:()=>this._flushAdds(),applyRemoves:()=>this._flushRemoves(),applyDestroys:()=>this._drainDestroyed(),applyToggles:()=>this._flushToggles(),structuralObserverCount:()=>this._structuralObserverCount,toggleObserverCount:()=>this._toggleObserverCount,structuralObserverHook:()=>this._structuralObserverHook},this._obsEvents),this.relationService=new Zt({isAlive:n=>this.isAlive(n),hasSparse:(n,r)=>this.hasSparse(n,r),pushSparseStore:(n,r)=>this._pushSparseStore(n,r),sparseStoreOf:n=>this.sparseStoreOf(n),sparseStores:()=>this.sparseStores,entityGenerations:()=>this.entityAllocator.generations,entityArchetype:()=>this.entityArchetype,entityRow:()=>this.entityRow,archetypes:()=>this.archGraph.archetypes,forEachSparseMatch:(n,r,i,o,a,l,u,d)=>this._forEachSparseMatch(n,r,i,o,a,l,u,d)}),this._columnStore=h.createColumnStore([],this._bufferAllocator,{reservedDescriptorBytes:64*1024,entityIndexCapacity:this._entityIndexCapacity,eventRingCapacitySlots:h.EVENT_RING_DEFAULT_CAPACITY_SLOTS,commandRingCapacitySlots:h.COMMAND_RING_DEFAULT_CAPACITY_SLOTS,actionRingCapacitySlots:h.ACTION_RING_DEFAULT_CAPACITY_SLOTS,regions:this._regions,bindingsRegionBytes:this._bindingsRegionBytes});const s=h.buildEntityIndexViews(this._columnStore.buffer,this._columnStore.header.entityIndexOff,this._entityIndexCapacity);this.entityArchetype=s.archetypes,this.entityRow=s.rows,this.entityAllocator=new Jt(this._entityIndexCapacity,s.generations,new Uint32Array(this._columnStore.buffer,this._columnStore.header.entityIndexOff+h.ENTITY_INDEX_HEADER_OFFSETS.length,1)),this._snapshots=new ge({sparseStores:()=>this.sparseStores,relationStores:()=>this.relationService.stores,generations:()=>this.entityAllocator.generations,archetypes:()=>this.archGraph.archetypes,columnStore:()=>this._columnStore,bufferAllocator:()=>this._bufferAllocator,entityIndexCapacity:()=>this._entityIndexCapacity,tick:()=>this._tick,setTick:n=>{this._tick=n},publishRowCounts:()=>this.publishRowCountsToDescriptor(),mountRestoredDense:n=>this._mountRestoredDense(n),reconstructHostRows:n=>this._reconstructHostRows(n),invalidateQueryCaches:()=>{this._queryDirtyEpoch++,this._rowCountsDirty=!0}},this.entityAllocator),this.archGraph=new ye({componentMetas:()=>this.componentMetas,initialCapacity:()=>this.initialCapacity,extendStore:n=>this._archExtendStoreWithNewSpecs(n),materialize:(n,r,i)=>this._materializeArchetype(n,r,i),fanIntoQueries:n=>this._fanIntoQueries(n)}),this.emptyArchetypeId=this.archGetOrCreateFromMask(new T.BitSet)}_entityIndexCapacity;_regions;_bindingsRegionBytes;_deterministic;get deterministic(){return this._deterministic}_requireDeterministic(t){if(!this._deterministic)throw new h.ECSError(h.ECS_ERROR.DETERMINISM_DISABLED,`${t} requires determinism — construct the Store/ECS with { deterministic: true }. The canonical-ordering determinism surface (state_hash / snapshot_sparse / restore_sparse) is opt-in; see ADR-0020.`)}_rejectNonDeterministicFields(t,e,s){if(this._deterministic)for(let n=0;n<e.length;n++){const r=e[n];if(r==="f32"||r==="f64")throw new h.ECSError(h.ECS_ERROR.NON_DETERMINISTIC_COLUMN_TYPE,`Cannot register ${s} field "${t[n]}" as "${r}" on a { deterministic: true } world: floating-point columns round differently across V8 / Bun / Zig (1-ULP IEEE-754), breaking cross-host state_hash agreement (ADR-0020). Use an integer type (e.g. "i32") — represent fractional quantities as fixed-point (Q16.16). Note the array shorthand defaults to "f64", so pass an explicit integer type there.`,{field:t[n],type:r,kind:s})}}_refreshEntityIndexViews(){const t=this._columnStore.view.getUint32(h.STORE_HEADER_OFFSETS.entity_index_off,!0),e=h.buildEntityIndexViews(this._columnStore.buffer,t,this._entityIndexCapacity);this.entityArchetype=e.archetypes,this.entityRow=e.rows,this.entityAllocator.replantViews(e.generations,new Uint32Array(this._columnStore.buffer,t+h.ENTITY_INDEX_HEADER_OFFSETS.length,1))}_handleBufferResized(){this._refreshEntityIndexViews(),this.entityAllocator.publishLength(),this._onBufferResized?.()}get columnStore(){return this._columnStore}regionOffset(t){return h.findRegionOffset(this._columnStore.view,t)}regionHandle(t){const e=h.findRegionEntry(this._columnStore.view,t);return e===null?null:{buffer:this._columnStore.buffer,view:this._columnStore.view,offset:e.byteOffset,bytes:e.byteLength}}publishRowCountsToDescriptor(){if(!this._rowCountsDirty)return;const t=this._columnStore.view;let e=t.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);const s=this.archGraph.archetypes;for(let n=0;n<s.length;n++){const r=s[n];if(!r.isBufferBacked)continue;const i=t.getUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.column_count,!0);t.setUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.row_count,r.hasColumns?r.length:0,!0),t.setUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.enabled_count,r.hasColumns?r.enabledCount:0,!0),e+=h.ARCHETYPE_DESCRIPTOR_HEADER_BYTES+i*h.COLUMN_DESCRIPTOR_BYTES}this._rowCountsDirty=!1}stateHash(){this._requireDeterministic("state_hash()");let t=h.FNV1A_OFFSET_BASIS;const e=this.archGraph.archetypes;for(let r=0;r<e.length;r++){const i=e[r],o=i.id,a=i.length;if(t=h.fnv1aStepWord(t,o),t=h.fnv1aStepWord(t,a),t=h.fnv1aStepWord(t,i.enabledCount),a===0)continue;const l=i._flatColumns;for(let u=0;u<l.length;u++){const d=l[u].buf,f=a*d.BYTES_PER_ELEMENT,p=new Uint8Array(d.buffer,d.byteOffset,f),y=f>>>2;let g=0;for(let _=0;_<y;_++){const m=(p[g]|p[g+1]<<8|p[g+2]<<16|p[g+3]<<24)>>>0;t=(t^m)>>>0,t=Math.imul(t,h.FNV1A_PRIME),g+=4}const E=f&3;if(E!==0){let _=p[g];E>1&&(_|=p[g+1]<<8),E>2&&(_|=p[g+2]<<16),t=(t^_>>>0)>>>0,t=Math.imul(t,h.FNV1A_PRIME)}}}const s=this.sparseStores;for(let r=0;r<s.length;r++){const i=s[r];t=h.fnv1aStepWord(t,r),t=h.fnv1aStepWord(t,i.size);const o=i.canonicalIndices();for(let a=0;a<o.length;a++){const l=o[a];t=h.fnv1aStepWord(t,l);const u=i.getRow(l);for(let d=0;d<u.length;d++)Z.setFloat64(0,u[d],!0),t=h.fnv1aStepWord(t,Z.getUint32(0,!0)),t=h.fnv1aStepWord(t,Z.getUint32(4,!0))}}const n=this.relationService.stores;for(let r=0;r<n.length;r++){const i=n[r];i.exclusive||(t=h.fnv1aStepWord(t,r),i.forEachCanonicalTargetSet((o,a)=>{t=h.fnv1aStepWord(t,o),t=h.fnv1aStepWord(t,a.length);for(let l=0;l<a.length;l++)t=h.fnv1aStepWord(t,a[l])}))}return t>>>0}archGet(t){return this.archGraph.get(t)}entityIdAtRow(t,e){return this.archGet(t).entityIds[e]}archGetOrCreateFromMask(t){return this.archGraph.getOrCreateFromMask(t)}archCreateManyFromMasks(t){return this.archGraph.createManyFromMasks(t)}_archExtendStoreWithNewSpecs(t){const e=[],s=this.archGraph.archetypes;for(let r=0;r<s.length;r++){const i=s[r],o=this._columnStore.archetypes.get(i.id);o!==void 0&&e.push({archetypeId:i.id,newRowCapacity:o.rowCapacity,rowCount:i.hasColumns?i.length:0})}let n;try{n=ae(this._columnStore,{newArchetypes:t,existing:e},this._bufferAllocator)}catch(r){throw r instanceof V.StoreCapExceededError?this._capExceededError(r):r}if(this._columnStore=n.store,!n.viewsPreserved)for(let r=0;r<s.length;r++)s[r].isBufferBacked&&s[r].refreshViews(this._columnStore);this._handleBufferResized()}_materializeArchetype(t,e,s){const n=at.fromColumnStore(t,e,s,this._columnStore,t);return n.growHandler=this._growHandler,n}_fanIntoQueries(t){const e=this.registeredQueries;for(let s=0;s<e.length;s++){const n=e[s];t.matches(n.includeMask)&&(!n.excludeMask||!t.mask.overlaps(n.excludeMask))&&(!n.anyOfMask||t.mask.overlaps(n.anyOfMask))&&n.result.push(t)}}archResolveAdd(t,e){return this.archGraph.resolveAdd(t,e)}archResolveRemove(t,e){return this.archGraph.resolveRemove(t,e)}createEntity(){const t=this.entityAllocator.alloc(),e=this.entityAllocator.lastIndex;return this.entityArchetype[e]=this.emptyArchetypeId,this.entityRow[e]=h.UNASSIGNED,t}_allocEntity(){return this.entityAllocator.alloc()}_ensureEntityIndexCapacity(t){this.entityAllocator.ensureCapacity(t)}resolveTemplate(t){const e=new T.BitSet;for(let a=0;a<t.length;a++)e.set(t[a].def.id);const s=this.archGetOrCreateFromMask(e),n=this.archGet(s),r=new Array(n._flatColumns.length).fill(0),i=new Map,o=new Array(t.length);for(let a=0;a<t.length;a++){o[a]=t[a].def;const l=t[a].def.id,u=this.componentMetas[l];if(u===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`template: component ${l} is not registered`);const d=t[a].values??h.EMPTY_VALUES,f=n._colOffset[l];for(let p=0;p<u.fieldNames.length;p++){const y=u.fieldNames[p];r[f+p]=d[y]??0,i.set(y,i.has(y)?gt:f+p)}}return{archetypeId:s,flatValues:r,overrideIndex:i,defs:o}}_resolveOverrideColumn(t,e){const s=t.overrideIndex.get(e);return s===void 0||s===gt?-1:s}_applyOverrides(t,e,s,n){const r=t._flatColumns;for(const i in n){if(n[i]===void 0)continue;const o=this._resolveOverrideColumn(s,i);o>=0&&(r[o].buf[e]=n[i])}}_applyOverridesRange(t,e,s,n,r){const i=t._flatColumns;for(const o in r){if(r[o]===void 0)continue;const a=this._resolveOverrideColumn(n,o);a>=0&&i[a].buf.fill(r[o],e,e+s)}}spawn(t,e){const s=this.archGraph.archetypes[t.archetypeId];s.materializesRows&&s.ensureRowCapacity(1);const n=this._allocEntity(),r=this.entityAllocator.lastIndex;if(!s.materializesRows)return this.entityArchetype[r]=t.archetypeId,this.entityRow[r]=h.UNASSIGNED,n;const i=s.length,o=s.enabledCount,a=s.addEntityWithValues(n,t.flatValues,this._tick,this.entityRow);return e!==void 0&&this._applyOverrides(s,a,t,e),this.entityArchetype[r]=t.archetypeId,this.entityRow[r]=a,this._onArchGrow(s,i,o),n}spawnMany(t,e,s){if(e<=0)return[];const n=this.archGraph.archetypes[t.archetypeId];this._ensureEntityIndexCapacity(e),n.ensureRowCapacity(e);const r=new Array(e),i=new Uint32Array(e);for(let f=0;f<e;f++){const p=this._allocEntity();i[f]=p,r[f]=p}const o=this.entityArchetype,a=this.entityRow;if(!n.materializesRows){for(let f=0;f<e;f++){const p=h.getEntityIndex(r[f]);o[p]=t.archetypeId,a[p]=h.UNASSIGNED}return r}const l=n.length,u=n.enabledCount;if(n.disabledCount>0){for(let f=0;f<e;f++){const p=n.addEntityWithValues(r[f],t.flatValues,this._tick,a),y=h.getEntityIndex(r[f]);o[y]=t.archetypeId,a[y]=p,s!==void 0&&this._applyOverrides(n,p,t,s)}return this._onArchGrow(n,l,u),r}const d=n.addEntitiesWithValues(i,e,t.flatValues,this._tick);for(let f=0;f<e;f++){const p=h.getEntityIndex(r[f]);o[p]=t.archetypeId,a[p]=d+f}return s!==void 0&&this._applyOverridesRange(n,d,e,t,s),this._onArchGrow(n,l,u),r}destroyEntity(t){if(!this.isAlive(t))return;if(!this.relationService.hasTargetCleanup){this._destroyOne(t,null);return}const e=[t];for(let s=0;s<e.length;s++){const n=e[s];this.isAlive(n)&&this._destroyOne(n,e)}}_destroyOne(t,e){const s=h.getEntityIndex(t),n=this.entityRow[s];if(n!==h.UNASSIGNED){const r=this.archGet(this.entityArchetype[s]),i=r.length;r.removeRow(n,this.entityRow),this._onArchLenChange(r,i)}this.entityArchetype[s]=h.UNASSIGNED,this.entityRow[s]=h.UNASSIGNED,this.relationService.count>0&&(this.relationService.purgeSource(t),e!==null&&this.relationService.cleanupTarget(t,e)),this.sparseStores.length>0&&this._purgeSparse(s),this._anyDirtyTracked&&this._clearDirtyForIndex(s),this.entityAllocator.recycle(s,h.getEntityGeneration(t))}isAlive(t){if(t<0||t>h.MAX_ENTITY_ID)return!1;const e=h.getEntityGeneration(t);if(e===h.RETIRED_GENERATION)return!1;const s=h.getEntityIndex(t);return this.entityAllocator.isAliveIndex(s,e)}get entityCount(){return this.entityAllocator.aliveCount}_onArchLenChange(t,e){this._rowCountsDirty=!0,e===0!=(t.length===0)&&this._queryDirtyEpoch++}_onArchGrow(t,e,s){this._rowCountsDirty=!0,(e===0||s===0&&t.enabledCount!==0)&&this._queryDirtyEpoch++}_onArchEnabledChange(t,e){this._rowCountsDirty=!0,e===0!=(t.enabledCount===0)&&this._queryDirtyEpoch++}disableEntity(t){if(!this.isAlive(t))return;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[e]);if(s>=n.enabledCount)return;const r=n.enabledCount;n.disableRow(s,this.entityRow),this._onArchEnabledChange(n,r)}enableEntity(t){if(!this.isAlive(t))return;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[e]);if(s<n.enabledCount)return;const r=n.enabledCount;n.enableRow(s,this.entityRow),this._onArchEnabledChange(n,r)}isDisabled(t){if(!this.isAlive(t))return!1;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return!1;const n=this.archGet(this.entityArchetype[e]);return s>=n.enabledCount}_flushEpoch=0;_flushTouched=[];_settleFlushDirty(){const t=this._flushTouched;if(t.length===0)return;this._rowCountsDirty=!0;let e=!1;for(let s=0;s<t.length;s++){const n=t[s];(n._flushPreLen===0!=(n.length===0)||n._flushPreEnabled===0!=(n.enabledCount===0))&&(e=!0)}e&&this._queryDirtyEpoch++,t.length=0,this._flushEpoch++}destroyEntityDeferred(t){this._deferred.queueDestroy(t)}disableEntityDeferred(t){this._deferred.queueToggle(t,!0)}enableEntityDeferred(t){this._deferred.queueToggle(t,!1)}_flushToggles(){const t=this._deferred.toggleIds,e=this._deferred.toggleDisable,s=t.length;if(!(this._toggleObserverCount>0)){for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(e[i]?this.disableEntity(o):this.enableEntity(o))}t.length=0,e.length=0;return}const r=this._toggleInitial;for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(r.has(o)||r.set(o,this.isDisabled(o)))}for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(e[i]?this.disableEntity(o):this.enableEntity(o))}t.length=0,e.length=0;for(const[i,o]of r){if(!this.isAlive(i))continue;const a=this.isDisabled(i);o!==a&&this._collectToggle(i,a)}r.clear()}_collectToggle(t,e){const s=h.getEntityIndex(t);if(this.entityRow[s]===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[s]);this._collectToggleEid=t,n.mask.forEach(e?this._collectDisableBit:this._collectEnableBit)}get pendingToggleCount(){return this._deferred.toggleCount}flushDestroyed(){this._deferred.flushDestroyed()}_drainDestroyed(){const t=this._deferred.destroyIds;if(t.length===0)return;const e=this.entityAllocator,s=this.entityArchetype,n=this.entityRow,r=e.generations,i=this.archGraph.archetypes,o=e.highWater;let a=!1,l=!1;const u=this.sparseStores.length>0,d=this.relationService.count>0,f=d&&this.relationService.hasTargetCleanup,p=this._anyDirtyTracked,y=this._structuralObserverCount>0;for(let g=0;g<t.length;g++){const E=t[g],_=E&h.INDEX_MASK,m=E>>h.INDEX_BITS;if(_>=o||r[_]!==m)continue;const S=n[_];if(S!==h.UNASSIGNED){const v=i[s[_]];y&&(this._collectDestroyEid=E,v.mask.forEach(this._collectDestroyRemoveBit)),v.removeRow(S,n),a=!0,v.length===0&&(l=!0)}d&&this.relationService.purgeSource(E),f&&this.relationService.cleanupTarget(E,t),u&&this._purgeSparse(_),p&&this._clearDirtyForIndex(_),s[_]=h.UNASSIGNED,n[_]=h.UNASSIGNED,e.recycle(_,m)}t.length=0,a&&(this._rowCountsDirty=!0,l&&this._queryDirtyEpoch++)}get pendingDestroyCount(){return this._deferred.destroyCount}addComponentDeferred(t,e,s){this._deferred.queueAdd(t,e,s??h.EMPTY_VALUES)}removeComponentDeferred(t,e){this._deferred.queueRemove(t,e)}flushStructural(){this._deferred.flushStructural()}_flushAdds(){const t=this._deferred.addIds,e=this._deferred.addDefs,s=this._deferred.addValues,n=t.length,r=this.entityArchetype,i=this.entityRow,o=this.entityAllocator.generations,a=this.archGraph.archetypes,l=this.componentMetas,u=this.entityAllocator.highWater,d=this._tick,f=this._flushEpoch,p=this._flushTouched,y=this._structuralObserverCount>0,g=this._obsEvents;for(let E=0;E<n;E++){const _=t[E],m=_&h.INDEX_MASK,S=_>>h.INDEX_BITS;if(m>=u||o[m]!==S)continue;const v=r[m],C=e[E].id,R=a[v],w=l[C];if(R.mask.has(C)){w.fieldNames.length>0&&R.writeFields(i[m],C,s[E],d);continue}const k=this.archResolveAdd(v,C),I=a[k],F=i[m],lt=!I.hasColumns&&!R.hasColumns;F!==h.UNASSIGNED&&R._flushSeenEpoch!==f&&(R._flushSeenEpoch=f,R._flushPreLen=R.length,R._flushPreEnabled=R.enabledCount,p.push(R)),I._flushSeenEpoch!==f&&(I._flushSeenEpoch=f,I._flushPreLen=I.length,I._flushPreEnabled=I.enabledCount,p.push(I));let W;if(F!==h.UNASSIGNED){if(lt)I.moveEntityFromTag(R,F,_,i);else{const Nt=R.getEdge(C);I.moveEntityFrom(R,F,_,Nt.addMap,d,i)}W=A[0]}else W=lt?I.addEntityTag(_,i):I.addEntity(_,i);w.fieldNames.length>0&&I.writeFields(W,C,s[E],d),r[m]=k,i[m]=W,y&&w.obsAdd&&(g.addComp[g.addLen]=C,g.addEid[g.addLen]=_,g.addLen++)}t.length=0,e.length=0,s.length=0,this._settleFlushDirty()}_flushRemoves(){const t=this._deferred.removeIds,e=this._deferred.removeDefs,s=t.length,n=this.entityArchetype,r=this.entityRow,i=this.entityAllocator.generations,o=this.archGraph.archetypes,a=this.entityAllocator.highWater,l=this._tick,u=this._flushEpoch,d=this._flushTouched,f=this.componentMetas,p=this._structuralObserverCount>0,y=this._obsEvents;for(let g=0;g<s;g++){const E=t[g],_=E&h.INDEX_MASK,m=E>>h.INDEX_BITS;if(_>=a||i[_]!==m)continue;const S=n[_],v=e[g].id,C=o[S];if(!C.mask.has(v))continue;const R=this.archResolveRemove(S,v),w=o[R],k=r[_],I=!w.hasColumns&&!C.hasColumns;if(C._flushSeenEpoch!==u&&(C._flushSeenEpoch=u,C._flushPreLen=C.length,C._flushPreEnabled=C.enabledCount,d.push(C)),w._flushSeenEpoch!==u&&(w._flushSeenEpoch=u,w._flushPreLen=w.length,w._flushPreEnabled=w.enabledCount,d.push(w)),I)w.moveEntityFromTag(C,k,E,r);else{const F=C.getEdge(v);w.moveEntityFrom(C,k,E,F.removeMap,l,r)}n[_]=R,r[_]=A[0],p&&f[v].obsRem&&(y.remComp[y.remLen]=v,y.remEid[y.remLen]=E,y.remLen++)}t.length=0,e.length=0,this._settleFlushDirty()}get pendingStructuralCount(){return this._deferred.structuralCount}_configureComponentObservation(t,e,s,n,r,i){const o=this.componentMetas[t];if(o===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`observe(): component ${t} is not registered`);const a=o.obsAdd||o.obsRem;o.obsAdd=e,o.obsRem=s;const l=e||s;a&&!l?this._structuralObserverCount--:!a&&l&&this._structuralObserverCount++;const u=o.obsDisable||o.obsEnable;o.obsDisable=n,o.obsEnable=r;const d=n||r;if(u&&!d?this._toggleObserverCount--:!u&&d&&this._toggleObserverCount++,i&&!o.trackDirty)o.trackDirty=!0,this._dirtyLists[t]===void 0&&(this._dirtyLists[t]=[],this._dirtyMarks[t]=new Uint8Array(Math.max(1,this.entityAllocator.generations.length))),this._dirtyTrackedCids.push(t),this._anyDirtyTracked=!0;else if(!i&&o.trackDirty){o.trackDirty=!1;const f=this._dirtyTrackedCids.indexOf(t);f>=0&&this._dirtyTrackedCids.splice(f,1),this._anyDirtyTracked=this._dirtyTrackedCids.length>0;const p=this._dirtyLists[t],y=this._dirtyMarks[t];if(p!==void 0&&y!==void 0){for(let g=0;g<p.length;g++)y[p[g]&h.INDEX_MASK]=0;p.length=0}}}_noteSet(t,e){const s=t.id,n=this.componentMetas[s];if(n===void 0||!n.trackDirty)return;const r=e&h.INDEX_MASK;let i=this._dirtyMarks[s];r>=i.length&&(i=this._growDirtyMarks(s,r)),i[r]===0&&(i[r]=1,this._dirtyLists[s].push(e))}_growDirtyMarks(t,e){const s=this._dirtyMarks[t];let n=Math.max(1,s.length);for(;n<=e;)n*=2;const r=new Uint8Array(n);return r.set(s),this._dirtyMarks[t]=r,r}_takeDirty(t){const e=this._dirtyLists[t];if(e===void 0||e.length===0)return Ee;this._dirtyLists[t]=[];const s=this._dirtyMarks[t];for(let n=0;n<e.length;n++)s[e[n]&h.INDEX_MASK]=0;return e}_clearDirtyForIndex(t){const e=this._dirtyTrackedCids;for(let s=0;s<e.length;s++){const n=this._dirtyMarks[e[s]];n!==void 0&&t<n.length&&(n[t]=0)}}_forEachChangedArchetype(t,e,s){const n=this.archGraph.componentIndex[t];if(n===void 0)return;const r=this.archGraph.archetypes;for(let i=0;i<n.length;i++){const o=r[n[i]];o.length>0&&o._changedTick[t]>=e&&s(o)}}_collectEntitiesWithComponent(t){const e=[],s=this.archGraph.componentIndex[t];if(s===void 0)return e;const n=this.archGraph.archetypes;for(let r=0;r<s.length;r++){const i=n[s[r]],o=i.entityIds;for(let a=0;a<i.enabledCount;a++)e.push(h.unsafeCast(o[a]))}return e}registerComponent(t,e){if(this.componentCount>=h.STORE_DESCRIPTOR_COMPONENT_LIMIT)throw new h.ECSError(h.ECS_ERROR.COMPONENT_LIMIT_EXCEEDED,`Cannot register more than ${h.STORE_DESCRIPTOR_COMPONENT_LIMIT} components: the SAB archetype descriptor mask is ${h.STORE_DESCRIPTOR_COMPONENT_LIMIT} bits wide. Widen the descriptor mask (descriptor.ts + abi.zig, a SIM_ABI_VERSION bump) to raise it.`,{componentCount:this.componentCount,limit:h.STORE_DESCRIPTOR_COMPONENT_LIMIT});const s=Object.keys(t),n=new Array(s.length),r=Object.create(null);for(let a=0;a<s.length;a++)r[s[a]]=a,n[a]=t[s[a]];this._rejectNonDeterministicFields(s,n,"component");const i=Rt(this.componentCount++);this.componentMetas.push({name:e,fieldNames:s,fieldIndex:r,fieldTypes:n,obsAdd:!1,obsRem:!1,obsDisable:!1,obsEnable:!1,trackDirty:!1});const o=vt(i);return e!==void 0&&h.setComponentDebugName(o,e),o}componentLabel(t){const e=this.componentMetas[t]?.name;return e!==void 0?`'${e}' (component ${t})`:`component ${t}`}fieldIdOf(t,e){const s=t.id,n=this.componentMetas[s];if(n===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`field_id_of: component ${s} is not registered`);const r=n.fieldIndex[e];if(r===void 0)throw new h.ECSError(h.ECS_ERROR.FIELD_NOT_REGISTERED,`field_id_of: component ${s} has no field "${e}"`);return r}registerSparseComponent(t,e){const s=Object.keys(t),n=new Array(s.length);for(let r=0;r<s.length;r++)n[r]=t[s[r]];return this._rejectNonDeterministicFields(s,n,"sparse component"),this._pushSparseStore(s,n,e)}sparseLabel(t){const e=this.sparseNames[t];return e!==void 0?`'${e}' (sparse component ${t})`:`sparse component ${t}`}_pushSparseStore(t,e,s){const n=this.sparseStores.length;return this.sparseStores.push(new h.SparseComponentStore(t,e)),this.sparseNames.push(s),h.unsafeCast(n)}sparseStoreOf(t){const e=t,s=this.sparseStores[e];if(s===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`sparse component ${e} is not registered`);return s}addSparse(t,e,s){this.isAlive(t)&&this.sparseStoreOf(e).setRow(h.getEntityIndex(t),s??h.EMPTY_VALUES)}removeSparse(t,e){this.isAlive(t)&&this.sparseStoreOf(e).remove(h.getEntityIndex(t))}hasSparse(t,e){return this.isAlive(t)?this.sparseStoreOf(e).has(h.getEntityIndex(t)):!1}getSparseField(t,e,s){const n=this.sparseStoreOf(e),r=n.fieldIndex[s];if(r===void 0)return 0;const i=n.getField(h.getEntityIndex(t),r);return i===void 0?0:i}setSparseField(t,e,s,n){const r=this.sparseStoreOf(e),i=r.fieldIndex[s];i!==void 0&&r.setField(h.getEntityIndex(t),i,n)}_purgeSparse(t){const e=this.sparseStores;for(let s=0;s<e.length;s++)e[s].remove(t)}snapshotSparse(){return this._requireDeterministic("snapshot_sparse()"),this._snapshots.snapshotSparse()}restoreSparse(t){this._requireDeterministic("restore_sparse()"),this._snapshots.restoreSparse(t)}snapshot(){return this._requireDeterministic("snapshot()"),this._snapshots.snapshot()}restoreInto(t){this._requireDeterministic("restoreInto()"),this._snapshots.restoreInto(t)}_mountRestoredDense(t){this._columnStore=t;const e=this.archGraph.archetypes;for(let s=0;s<e.length;s++)e[s].isBufferBacked&&e[s].refreshViews(this._columnStore);this.entityAllocator.setHighWater(t.view.getUint32(t.header.entityIndexOff+h.ENTITY_INDEX_HEADER_OFFSETS.length,!0)),this._handleBufferResized()}_reconstructHostRows(t){const e=this.entityAllocator.highWater,s=this.entityArchetype,n=this.entityRow,r=this.entityAllocator.generations,i=new Map;for(let o=0;o<e;o++){const a=s[o];if(a===h.UNASSIGNED)continue;const l=n[o];if(l===h.UNASSIGNED)continue;let u=i.get(a);u===void 0&&(u=[],i.set(a,u)),u[l]=h.createEntityId(o,r[o])}for(let o=0;o<t.archetypeRows.length;o++){const a=t.archetypeRows[o],l=this.archGet(a.archetypeId),u=i.get(a.archetypeId)??[];l.restoreHostRows(u,a.enabledCount)}}registerRelation(t){return this.relationService.registerRelation(t)}get relationCount(){return this.relationService.count}addRelation(t,e,s){this.relationService.addRelation(t,e,s)}removeRelation(t,e,s){this.relationService.removeRelation(t,e,s)}targetOf(t,e){return this.relationService.targetOf(t,e)}targetsOf(t,e){return this.relationService.targetsOf(t,e)}sourcesOf(t,e){return this.relationService.sourcesOf(t,e)}hasRelation(t,e){return this.relationService.hasRelation(t,e)}pairsOf(t){return this.relationService.pairsOf(t)}sourcesOfAny(t){return this.relationService.sourcesOfAny(t)}relationBackingSparseId(t){return this.relationService.relationBackingSparseId(t)}_forEachRelationTargetMatch(t,e,s,n,r,i,o,a){this.relationService.forEachRelationTargetMatch(t,e,s,n,r,i,o,a)}compactRelations(){return this.relationService.compactRelations()}ancestorsOf(t,e){return this.relationService.ancestorsOf(t,e)}rootOf(t,e){return this.relationService.rootOf(t,e)}cascadeOf(t,e){return this.relationService.cascadeOf(t,e)}_forEachSparseMatch(t,e,s,n,r,i,o,a){const l=this.sparseStores;if(n.length>0){let d=l[n[0]];for(let _=1;_<n.length;_++){const m=l[n[_]];m.size<d.size&&(d=m)}const f=d.indices,p=this.entityAllocator.generations,y=this.entityArchetype,g=this.entityRow,E=this.archGraph.archetypes;for(let _=0;_<f.length;_++){const m=f[_];let S=!0;for(let w=0;w<n.length;w++){const k=l[n[w]];if(k!==d&&!k.has(m)){S=!1;break}}if(!S)continue;for(let w=0;w<r.length;w++)if(l[r[w]].has(m)){S=!1;break}if(!S)continue;const v=y[m];if(v===h.UNASSIGNED)continue;const C=E[v],R=C.mask;if(R.contains(t)&&!(e!==null&&R.overlaps(e))&&!(s!==null&&!R.overlaps(s))){if(!a){const w=g[m];if(w!==h.UNASSIGNED&&w>=C.enabledCount)continue}o(h.createEntityId(m,p[m]))}}return}const u=r.length>0;for(let d=0;d<i.length;d++){const f=i[d],p=f.entityIds,y=a?f.totalCount:f.enabledCount;for(let g=0;g<y;g++){const E=p[g];if(u){const _=h.getEntityIndex(E);let m=!1;for(let S=0;S<r.length;S++)if(l[r[S]].has(_)){m=!0;break}if(m)continue}o(E)}}}_forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){this.relationService.forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u)}addComponent(t,e,s){if(!this.isAlive(t))return;const n=h.getEntityIndex(t),r=this.entityArchetype[n],i=this.archGet(r);if(i.hasComponent(e.id)){i.writeFields(this.entityRow[n],e.id,s,this._tick);return}const o=this.archResolveAdd(r,e.id),a=this.archGet(o),l=this.entityRow[n];let u;if(l!==h.UNASSIGNED){const d=i.length,f=a.length,p=a.enabledCount,y=i.getEdge(e.id);!a.hasColumns&&!i.hasColumns?a.moveEntityFromTag(i,l,t,this.entityRow):a.moveEntityFrom(i,l,t,y.addMap,this._tick,this.entityRow),u=A[0],this._onArchLenChange(i,d),this._onArchGrow(a,f,p)}else{const d=a.length,f=a.enabledCount;u=a.hasColumns?a.addEntity(t,this.entityRow):a.addEntityTag(t,this.entityRow),this._onArchGrow(a,d,f)}a.writeFields(u,e.id,s,this._tick),this.entityArchetype[n]=o,this.entityRow[n]=u}addComponents(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n),i=e.length;let o=i;for(let f=0;f<i;f++){const p=e[f].def.id;if(p>=yt-1||i>me){o=J;break}o=o*yt+(p+1)}if(o!==J){const f=r.getCompositeAddEdge(o);if(f!==void 0){this._addComponentsInto(t,s,r,this.archGet(f.target),f.target,f.map,e);return}}let a=null;for(let f=0;f<i;f++){const p=e[f].def.id;a!==null?a.set(p):r.mask.has(p)||(a=r.mask.copyInto(this._scratchTargetMask),a.set(p))}if(a===null){const f=this.entityRow[s];for(let p=0;p<i;p++)r.writeFields(f,e[p].def.id,e[p].values??h.EMPTY_VALUES,this._tick);return}const l=this.archGetOrCreateFromMask(a),u=this.archGet(l),d=r.getBatchTransitionMap(u);o!==J&&r.cacheCompositeAddEdge(o,l,d),this._addComponentsInto(t,s,r,u,l,d,e)}_addComponentsInto(t,e,s,n,r,i,o){const a=this.entityRow[e];let l;if(a!==h.UNASSIGNED){const u=s.length,d=n.length,f=n.enabledCount;n.moveEntityFrom(s,a,t,i,this._tick,this.entityRow),l=A[0],this._onArchLenChange(s,u),this._onArchGrow(n,d,f)}else{const u=n.length,d=n.enabledCount;l=n.addEntity(t,this.entityRow),this._onArchGrow(n,u,d)}for(let u=0;u<o.length;u++)n.writeFields(l,o[u].def.id,o[u].values??h.EMPTY_VALUES,this._tick);this.entityArchetype[e]=r,this.entityRow[e]=l}removeComponent(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n);if(!r.hasComponent(e.id))return;const i=this.archResolveRemove(n,e.id),o=this.archGet(i),a=this.entityRow[s],l=r.getEdge(e.id),u=!o.hasColumns&&!r.hasColumns,d=r.length,f=o.length,p=o.enabledCount;u?o.moveEntityFromTag(r,a,t,this.entityRow):o.moveEntityFrom(r,a,t,l.removeMap,this._tick,this.entityRow),this.entityArchetype[s]=i,this.entityRow[s]=A[0],this._onArchLenChange(r,d),this._onArchGrow(o,f,p)}removeComponents(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n);let i=null;for(let y=0;y<e.length;y++){const g=e[y].id;i!==null?i.clear(g):r.mask.has(g)&&(i=r.mask.copyInto(this._scratchTargetMask),i.clear(g))}if(i===null)return;const o=this.archGetOrCreateFromMask(i),a=this.archGet(o),l=this.entityRow[s],u=r.length,d=a.length,f=a.enabledCount,p=r.getBatchTransitionMap(a);a.moveEntityFrom(r,l,t,p,this._tick,this.entityRow),this.entityArchetype[s]=o,this.entityRow[s]=A[0],this._onArchLenChange(r,u),this._onArchGrow(a,d,f)}hasComponent(t,e){if(!this.isAlive(t))return!1;const s=h.getEntityIndex(t);return this.archGet(this.entityArchetype[s]).hasComponent(e.id)}batchAddComponent(t,e,s){const n=this.archGet(t);if(n.length===0)return;const r=e.id;if(n.mask.has(r))return;const i=this.archResolveAdd(n.id,r),o=this.archGet(i);if(n.disabledCount>0||o.disabledCount>0)throw new h.ECSError(h.ECS_ERROR.PARTITION_BULK_INTO_DISABLED,"batchAddComponent is unsupported on archetypes with disabled entities — enable them first or use per-entity addComponent");const a=n.getEdge(r),l=n.length,u=l,d=o.length,f=o.enabledCount,p=this.entityArchetype,y=this.entityRow,g=o.bulkMoveAllFrom(n,a.addMap,this._tick);for(let _=0;_<l;_++){const m=h.getEntityIndex(o.entityIds[g+_]);p[m]=i,y[m]=g+_}this.componentMetas[r].fieldNames.length>0&&s&&o.bulkWriteFields(g,l,r,s,this._tick),this._onArchLenChange(n,u),this._onArchGrow(o,d,f)}batchRemoveComponent(t,e){const s=this.archGet(t);if(s.length===0)return;const n=e.id;if(!s.mask.has(n))return;const r=this.archResolveRemove(s.id,n),i=this.archGet(r);if(s.disabledCount>0||i.disabledCount>0)throw new h.ECSError(h.ECS_ERROR.PARTITION_BULK_INTO_DISABLED,"batchRemoveComponent is unsupported on archetypes with disabled entities — enable them first or use per-entity removeComponent");const o=s.getEdge(n),a=s.length,l=a,u=this.entityArchetype,d=this.entityRow;if(!i.materializesRows){const g=s.entityIds;for(let E=0;E<a;E++){const _=h.getEntityIndex(g[E]);u[_]=r,d[_]=h.UNASSIGNED}s.clearRows(),this._onArchLenChange(s,l);return}const f=i.length,p=i.enabledCount,y=i.bulkMoveAllFrom(s,o.removeMap,this._tick);for(let g=0;g<a;g++){const E=h.getEntityIndex(i.entityIds[y+g]);u[E]=r,d[E]=y+g}this._onArchLenChange(s,l),this._onArchGrow(i,f,p)}getEntityArchetype(t){return this.archGet(this.entityArchetype[h.getEntityIndex(t)])}getEntityRow(t){return this.entityRow[h.getEntityIndex(t)]}getMatchingArchetypes(t,e,s){const n=t._words;let r=!1;for(let l=0;l<n.length;l++)if(n[l]!==0){r=!0;break}if(!r){const l=this.archGraph.archetypes,u=[];for(let d=0;d<l.length;d++){const f=l[d];(!e||!f.mask.overlaps(e))&&(!s||f.mask.overlaps(s))&&u.push(f)}return u}let i,o=!1;for(let l=0;l<n.length;l++){let u=n[l];if(u===0)continue;const d=l<<T.BITS_PER_WORD_SHIFT;for(;u!==0;){const f=u&-u>>>0,p=d+(T.BITS_PER_WORD_MASK-Math.clz32(f));u^=f;const y=this.archGraph.componentIndex[p];if(y===void 0||y.length===0){o=!0;break}(!i||y.length<i.length)&&(i=y)}if(o)break}if(o||!i)return[];const a=[];for(let l=0;l<i.length;l++){const u=this.archGet(i[l]);u.matches(t)&&(!e||!u.mask.overlaps(e))&&(!s||u.mask.overlaps(s))&&a.push(u)}return a}registerQuery(t,e,s){const n=this.getMatchingArchetypes(t,e,s);return this.registeredQueries.push({includeMask:t.copy(),excludeMask:e?e.copy():null,anyOfMask:s?s.copy():null,result:n,query:null}),n}updateQueryRef(t,e){const s=this.registeredQueries;for(let n=0;n<s.length;n++)if(s[n].result===t){s[n].query=e;return}}get archetypeCount(){return this.archGraph.archetypes.length}registerEvent(t){return this.events.registerEvent(t)}emitEvent(t,e){this.events.emitEvent(t,e)}emitSignal(t){this.events.emitSignal(t)}getEventReader(t){return this.events.getEventReader(t)}clearEvents(){this.events.clearEvents()}_devBufferedEventCount(){return this.events.devBufferedEventCount()}registerEventByKey(t,e){return this.events.registerEventByKey(t,e)}getEventDefByKey(t){return this.events.getEventDefByKey(t)}hasEventKey(t){return this.events.hasEventKey(t)}resources=new Vt;registerResource(t,e){this.resources.register(t,e)}getResource(t){return this.resources.get(t)}setResource(t,e){this.resources.set(t,e)}removeResource(t){this.resources.remove(t)}hasResource(t){return this.resources.has(t)}}class Se{store;constructor(t){this.store=t}register(t){return this.store.registerRelation(t)}get count(){return this.store.relationCount}add(t,e,s){return this.store.addRelation(t,e,s),this}remove(t,e,s){return this.store.removeRelation(t,e,s),this}has(t,e){return this.store.hasRelation(t,e)}targetOf(t,e){return this.store.targetOf(t,e)}targetsOf(t,e){return this.store.targetsOf(t,e)}sourcesOf(t,e){return this.store.sourcesOf(t,e)}pairsOf(t){return this.store.pairsOf(t)}sourcesOfAny(t){return this.store.sourcesOfAny(t)}ancestorsOf(t,e){return this.store.ancestorsOf(t,e)}rootOf(t,e){return this.store.rootOf(t,e)}cascadeOf(t,e){return this.store.cascadeOf(t,e)}compact(){return this.store.compactRelations()}}class Ce{store;constructor(t){this.store=t}register(t,e){this.store.registerEventByKey(t,e)}registerSignal(t){this.store.registerEventByKey(t,[])}emit(t,e){const s=this.store.getEventDefByKey(t);e===void 0?this.store.emitSignal(s):this.store.emitEvent(s,e)}read(t){const e=this.store.getEventDefByKey(t);return this.store.getEventReader(e)}}class Re{store;constructor(t){this.store=t}register(t,e){this.store.registerResource(t,e)}get(t){return h.unsafeCast(this.store.getResource(t))}set(t,e){this.store.setResource(t,e)}remove(t){this.store.removeResource(t)}has(t){return this.store.hasResource(t)}}class ve{store;constructor(t){this.store=t}get deterministic(){return this.store.deterministic}stateHash(){return this.store.stateHash()}capture(){return this.store.snapshot()}restore(t){this.store.restoreInto(t)}captureSparse(){return this.store.snapshotSparse()}restoreSparse(t){this.store.restoreSparse(t)}}const Et=new WeakMap;function it(c,t){let e=Et.get(c);if(!e){e=Object.create(null);const{fieldNames:n}=c.layout;for(let r=0;r<n.length;r++){const i=c.columns[r];Object.defineProperty(e,n[r],{get(){return i.buf[this._row]},set(o){i.buf[this._row]=o},enumerable:!0,configurable:!1})}Et.set(c,e)}const s=Object.create(e);return s._row=t,s}class be{dedup=new Map;andSingle=new Map;notSingle=new Map;anyOfSingle=new Map;changedSingle=new Map;optionalSingle=new Map;withSparseSingle=new Map;withoutSparseSingle=new Map;withRelationSingle=new Map;withoutRelationSingle=new Map;includeDisabledSingle=new Map;hierarchySingle=new Map;findDedup(t,e,s,n){const r=this.dedup.get(t);if(r)for(let i=0;i<r.length;i++){const o=r[i];if(!(!o.includeMask.equals(e)||!(s===null?o.excludeMask===null:o.excludeMask!==null&&o.excludeMask.equals(s))||!(n===null?o.anyOfMask===null:o.anyOfMask!==null&&o.anyOfMask.equals(n))))return o}}addDedup(t,e){Tt(this.dedup,t,e)}}const mt=Object.freeze([]),Ie=Object.freeze([]),wt=Object.freeze([]),ot=Number.POSITIVE_INFINITY;function H(c,t){return(c<<16|t)>>>0}function j(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}function Ae(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}function St(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}class Dt{_arch;_tick=0;mut(t){return this._arch.columnGroupMut(t,this._tick)}read(t){return this._arch.columnGroupRead(t)}}class D{_archetypes;_defs;_resolver;_include;_exclude;_anyOf;_nonEmptyArchetypes=[];_lastSeenEpoch=-1;_id;_sparseInclude;_sparseExclude;_optional;_includeDisabled;_relationIncludes;_relationExcludes;_hierarchy;constructor(t,e,s,n,r,i,o,a=mt,l=mt,u=Ie,d=!1,f=wt,p=wt,y=null){this._archetypes=t,this._defs=e,this._resolver=s,this._include=n,this._exclude=r,this._anyOf=i,this._id=o,this._sparseInclude=a,this._sparseExclude=l,this._optional=u,this._includeDisabled=d,this._relationIncludes=f,this._relationExcludes=p,this._hierarchy=y}_assertDenseOnly(t){if(this._sparseInclude.length>0||this._sparseExclude.length>0||this._relationIncludes.length>0||this._relationExcludes.length>0||this._hierarchy!==null)throw new h.ECSError(h.ECS_ERROR.SPARSE_QUERY_DENSE_PATH,`Query.${t} ignores sparse / relation-wildcard / hierarchy terms (withSparse / withoutSparse / withRelation / withoutRelation / hierarchy) — it walks only the dense archetype list and would return the wrong result (a hierarchy term has no per-archetype span — its order spans archetypes). Iterate this query with forEachEntity instead.`)}_isDenseOnly(){return this._sparseInclude.length===0&&this._sparseExclude.length===0&&this._relationIncludes.length===0&&this._relationExcludes.length===0&&this._hierarchy===null}firstEntity(){if(this._isDenseOnly()){const e=this._nonEmpty();for(let s=0;s<e.length;s++)if((this._includeDisabled?e[s].totalCount:e[s].enabledCount)>0)return e[s].entityIds[0];return}let t;return this.forEachEntity(e=>{t===void 0&&(t=e)}),t}singleEntity(){return this.firstEntity()}_countViaWalk(){let t=0;return this.forEachEntity(()=>{t++}),t}get archetypeCount(){return this._archetypes.length}get entityCount(){const t=this._nonEmpty();let e=0;if(this._includeDisabled)for(let s=0;s<t.length;s++)e+=t[s].totalCount;else for(let s=0;s<t.length;s++)e+=t[s].enabledCount;return e}get archetypes(){return this._archetypes}_carryNondense(t){return this._optional.length===0&&this._sparseInclude.length===0&&this._sparseExclude.length===0&&!this._includeDisabled&&this._relationIncludes.length===0&&this._relationExcludes.length===0&&this._hierarchy===null?t:new D(t._archetypes,t._defs,this._resolver,t._include,t._exclude,t._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}and(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.andSingle.get(n);return r!==void 0?r:this._andMiss(t[0],s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.and(t[s]);return e}_andMiss(t,e,s){const n=this._include.copy(),r=this._defs.slice();n.has(e)||(n.set(e),r.push(t));const i=this._carryNondense(this._resolver._resolveQuery(n,this._exclude,this._anyOf,r));return this._resolver._caches.andSingle.set(s,i),i}without(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.notSingle.get(n);return r!==void 0?r:this._notMiss(s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.without(t[s]);return e}_notMiss(t,e){const s=this._exclude?this._exclude.copy():new T.BitSet;s.set(t);const n=this._carryNondense(this._resolver._resolveQuery(this._include,s,this._anyOf,this._defs));return this._resolver._caches.notSingle.set(e,n),n}withSparse(...t){if(t.length===1)return this._withSparseOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withSparseOne(t[s]);return e}_withSparseOne(t){const e=H(this._id,t),s=this._resolver._caches.withSparseSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveSparse(j(this._sparseInclude,t),this._sparseExclude);return s.set(e,r),r}withoutSparse(...t){if(t.length===1)return this._withoutSparseOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withoutSparseOne(t[s]);return e}_withoutSparseOne(t){const e=H(this._id,t),s=this._resolver._caches.withoutSparseSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveSparse(this._sparseInclude,j(this._sparseExclude,t));return s.set(e,r),r}_deriveSparse(t,e){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),t,e,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}withRelation(...t){if(t.length===1)return this._withRelationOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withRelationOne(t[s]);return e}_withRelationOne(t){const e=H(this._id,t),s=this._resolver._caches.withRelationSingle,n=s.get(e);if(n!==void 0)return n;const r=this._resolver._relationBackingSparseId(t),i=this._deriveRelation(j(this._sparseInclude,r),this._sparseExclude,St(this._relationIncludes,t),this._relationExcludes);return s.set(e,i),i}withoutRelation(...t){if(t.length===1)return this._withoutRelationOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withoutRelationOne(t[s]);return e}_withoutRelationOne(t){const e=H(this._id,t),s=this._resolver._caches.withoutRelationSingle,n=s.get(e);if(n!==void 0)return n;const r=this._resolver._relationBackingSparseId(t),i=this._deriveRelation(this._sparseInclude,j(this._sparseExclude,r),this._relationIncludes,St(this._relationExcludes,t));return s.set(e,i),i}_deriveRelation(t,e,s,n){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),t,e,this._optional,this._includeDisabled,s,n,this._hierarchy)}hierarchy(t,e=ot){if(e===ot){const s=H(this._id,t),n=this._resolver._caches.hierarchySingle,r=n.get(s);if(r!==void 0)return r;const i=this._deriveHierarchy({relation:t,maxDepth:e});return n.set(s,i),i}return this._deriveHierarchy({relation:t,maxDepth:e})}_deriveHierarchy(t){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,t)}_checkRelationAccess(){for(let t=0;t<this._relationIncludes.length;t++)h.accessCheck.checkRelationRead(this._relationIncludes[t]);for(let t=0;t<this._relationExcludes.length;t++)h.accessCheck.checkRelationRead(this._relationExcludes[t])}forEachRelatedTo(t,e){this._resolver._forEachRelationTargetMatch(t,this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._includeDisabled,e)}optional(...t){if(t.length===1)return this._optionalOne(t[0].id);let e=this;for(let s=0;s<t.length;s++)e=e._optionalOne(t[s].id);return e}_optionalOne(t){const e=(this._id<<16|t)>>>0,s=this._resolver._caches.optionalSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveOptional(Ae(this._optional,t));return s.set(e,r),r}_deriveOptional(t){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,t,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}includeDisabled(){if(this._includeDisabled)return this;const t=this._resolver._caches.includeDisabledSingle,e=t.get(this._id);if(e!==void 0)return e;const s=new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,!0,this._relationIncludes,this._relationExcludes,this._hierarchy);return t.set(this._id,s),s}forEach(t){if(this._includeDisabled){this._forEachIncludeDisabled(t);return}const e=this._nonEmpty();for(let s=0;s<e.length;s++)t(e[s])}_forEachIncludeDisabled(t){const e=x(!0);try{this._forEachInner(t)}finally{x(e)}}eachChunk(t){if(this._includeDisabled){const e=x(!0);try{this._eachChunkInner(t)}finally{x(e)}return}this._eachChunkInner(t)}_eachChunkInner(t){const e=new Dt;e._tick=this._resolver._getCurrentTick();const s=this._nonEmpty();for(let n=0;n<s.length;n++)e._arch=s[n],t(e,s[n].entityCount)}forEachUntil(t){if(this._includeDisabled){const e=x(!0);try{return this._forEachUntilInner(t)}finally{x(e)}}return this._forEachUntilInner(t)}_forEachUntilInner(t){const e=this._nonEmpty();for(let s=0;s<e.length;s++)if(t(e[s]))return!0;return!1}_forEachInner(t){const e=this._nonEmpty();for(let s=0;s<e.length;s++)t(e[s])}forEachEntity(t){if(this._hierarchy!==null){this._resolver._forEachHierarchyMatch(this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._nonEmpty(),this._hierarchy.relation,this._hierarchy.maxDepth,this._includeDisabled,t);return}this._resolver._forEachSparseMatch(this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._nonEmpty(),t,this._includeDisabled)}_nonEmpty(){const t=this._resolver._getQueryDirtyEpoch();return this._lastSeenEpoch!==t&&this._rebuildNonEmpty(t),this._nonEmptyArchetypes}_rebuildNonEmpty(t){const e=this._archetypes,s=[];if(this._includeDisabled)for(let n=0;n<e.length;n++)e[n].totalCount>0&&s.push(e[n]);else for(let n=0;n<e.length;n++)e[n].enabledCount>0&&s.push(e[n]);this._nonEmptyArchetypes=s,this._lastSeenEpoch=t}anyOf(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.anyOfSingle.get(n);return r!==void 0?r:this._anyOfMiss(s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.anyOf(t[s]);return e}_anyOfMiss(t,e){const s=this._anyOf?this._anyOf.copy():new T.BitSet;s.set(t);const n=this._carryNondense(this._resolver._resolveQuery(this._include,this._exclude,s,this._defs));return this._resolver._caches.anyOfSingle.set(e,n),n}changed(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.changedSingle.get(n);return r!==void 0?r:this._changedMiss(s,n)}const e=new Array(t.length);for(let s=0;s<t.length;s++)e[s]=t[s].id;return new M(this,e)}_changedMiss(t,e){const s=new M(this,[t]);return this._resolver._caches.changedSingle.set(e,s),s}_ctxLastRunTick(){return this._resolver._getLastRunTick()}}class kt{constructor(t){this._resolver=t}with(...t){const e=new T.BitSet;for(let s=0;s<t.length;s++)e.set(t[s].id);return this._resolver._resolveQuery(e,null,null,t)}}class xt{constructor(t){this.store=t}spawn(...t){const e=this.store.createEntity();for(let s=0;s<t.length;s++){const n=G(t[s]);this.store.addComponentDeferred(e,n,$(t[s]))}return e}add(t,...e){if(e.length===2&&typeof e[0]=="function"&&e[1]!==null&&typeof e[1]=="object"&&typeof e[1].def!="function"){const s=e[0];return this.store.addComponentDeferred(t,s,e[1]),this}for(let s=0;s<e.length;s++){const n=e[s],r=G(n);this.store.addComponentDeferred(t,r,$(n))}return this}remove(t,e){return this.store.removeComponentDeferred(t,e),this}despawn(t){const e=t;return this.store.destroyEntityDeferred(e),this}disable(t){return this.store.disableEntityDeferred(t),this}enable(t){return this.store.enableEntityDeferred(t),this}}class Mt{constructor(t){this.store=t,this.commands=new xt(t)}lastRunTick=0;commands;get ecsTick(){return this.store._tick}get _trace(){return this.store._trace}isAlive(t){return this.store.isAlive(t)}hasComponent(t,e){return this.store.hasComponent(t,e)}getField(t,e,s){const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}tryGetField(t,e,s){if(!this.store.hasComponent(t,e))return;const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}setField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=r.getColumn(e,s,this.store._tick);o[i]=n,this.store._anyDirtyTracked&&this.store._noteSet(e,t)}updateField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=n(r.readField(i,e.id,s)),a=r.getColumn(e,s,this.store._tick);return a[i]=o,this.store._anyDirtyTracked&&this.store._noteSet(e,t),o}markChanged(t,e){this.store._anyDirtyTracked&&this.store._noteSet(e,t)}ref(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return s._changedTick[t.id]=this.store._tick,it(s.columnGroups[t.id],n)}refRead(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return it(s.columnGroups[t.id],n)}isDisabled(t){return this.store.isDisabled(t)}addSparse(t,e,...s){return this.store.addSparse(t,e,s[0]),this}removeSparse(t,e){return this.store.removeSparse(t,e),this}hasSparse(t,e){return this.store.hasSparse(t,e)}getSparseField(t,e,s){return this.store.getSparseField(t,e,s)}setSparseField(t,e,s,n){this.store.setSparseField(t,e,s,n)}addRelation(t,e,s){return this.store.addRelation(t,e,s),this}removeRelation(t,e,s){return this.store.removeRelation(t,e,s),this}targetOf(t,e){return this.store.targetOf(t,e)}targetsOf(t,e){return this.store.targetsOf(t,e)}sourcesOf(t,e){return this.store.sourcesOf(t,e)}hasRelation(t,e){return this.store.hasRelation(t,e)}flush(){this.store.flushStructural(),this.store.flushDestroyed(),this.store.publishRowCountsToDescriptor()}emit(t,e){const s=this.store.getEventDefByKey(t);e===void 0?this.store.emitSignal(s):this.store.emitEvent(s,e)}read(t){const e=this.store.getEventDefByKey(t);return this.store.getEventReader(e)}getResource(t){return h.unsafeCast(this.store.getResource(t))}setResource(t,e){this.store.setResource(t,e)}removeResource(t){this.store.removeResource(t)}hasResource(t){return this.store.hasResource(t)}}class M{_query;_changedIds;constructor(t,e){this._query=t,this._changedIds=e}and(...t){return new M(this._query.and(...t),this._changedIds)}without(...t){return new M(this._query.without(...t),this._changedIds)}anyOf(...t){return new M(this._query.anyOf(...t),this._changedIds)}optional(...t){return new M(this._query.optional(...t),this._changedIds)}forEach(t){if(this._query._includeDisabled){this._forEachIncludeDisabled(t);return}const e=this._query._ctxLastRunTick(),s=this._query._nonEmpty(),n=this._changedIds;for(let r=0;r<s.length;r++){const i=s[r];for(let o=0;o<n.length;o++)if(i._changedTick[n[o]]>=e){t(i);break}}}_forEachIncludeDisabled(t){const e=x(!0);try{this._forEachInner(t)}finally{x(e)}}_forEachInner(t){const e=this._query._ctxLastRunTick(),s=this._query._nonEmpty(),n=this._changedIds;for(let r=0;r<s.length;r++){const i=s[r];for(let o=0;o<n.length;o++)if(i._changedTick[n[o]]>=e){t(i);break}}}}function Ct(c){if(!(c>0)||!Number.isFinite(c))throw new h.ECSError(h.ECS_ERROR.INVALID_FIXED_TIMESTEP,`fixedTimestep must be a finite number > 0, got ${c}`);return c}function Oe(c){if(!Number.isInteger(c)||c<1)throw new h.ECSError(h.ECS_ERROR.INVALID_MAX_FIXED_STEPS,`maxFixedSteps must be an integer >= 1, got ${c}`);return c}class Te{store;schedule;ctx;_observers;relations;events;resources;snapshots;systems=new Set;nextSystemId=0;_tick=0;_updating=!1;_fixedTimestep;_accumulator=0;_maxFixedSteps;scratchMask=new T.BitSet;_nextQueryIdCounter=0;_caches=new be;_layoutSubscribers=[];_backend=null;_memory;get memoryPlan(){return this._memory}get wasmMemory(){return this._memory.wasmMemory}constructor(t){const e=Object.prototype.hasOwnProperty;if(t!==void 0&&(e.call(t,"initial_capacity")||e.call(t,"buffer_allocator")))throw new h.ECSError(h.ECS_ERROR.INVALID_MEMORY_OPTIONS,"ECSOptions.initial_capacity / buffer_allocator were replaced by ECSOptions.memory: initial_capacity → memory.columnCapacity (or memory.budget); buffer_allocator → memory.wasm (WASM-backed) or memory.allocator (custom in-place).");const s=h.resolveECSMemory(t?.memory);this._memory=s,this.store=new we({initialCapacity:s.columnCapacity,bufferAllocator:s.allocator,entityIndexCapacity:s.entityIndexCapacity,capContext:{capBytes:s.capBytes,intentLabel:s.intentLabel,budgetEntities:s.budgetEntities},onBufferResized:()=>{const n=this._layoutSubscribers;for(let r=0;r<n.length;r++)n[r].setLayout(0)},regions:t?.regions,bindingsRegionBytes:t?.bindingsRegionBytes,deterministic:t?.deterministic}),this.schedule=new h.Schedule(t?.onWarn),this.relations=new Se(this.store),this.events=new Ce(this.store),this.resources=new Re(this.store),this.snapshots=new ve(this.store),this.ctx=new Mt(this.store),this._observers=new Qt(this.store,this.ctx),this.store.setStructuralObserverHook(n=>this._observers.dispatchStructural(n)),this._fixedTimestep=Ct(t?.fixedTimestep??h.DEFAULT_FIXED_TIMESTEP),this._maxFixedSteps=Oe(t?.maxFixedSteps??h.DEFAULT_MAX_FIXED_STEPS)}regionHandles(...t){const e=new Array(t.length);let s=null;for(let n=0;n<t.length;n++){const r=this.store.regionHandle(t[n]);r===null?(s??=[]).push(t[n]):e[n]=r}if(s!==null)throw new h.ECSError(h.ECS_ERROR.REGION_NOT_DECLARED,`region_handles: region id(s) [${s.join(", ")}] not declared — pass them via ECSOptions.regions`);return e}onStoreLayoutPublished(t){return this._layoutSubscribers.push(t),t.setLayout(0),()=>{const e=this._layoutSubscribers.indexOf(t);e>=0&&this._layoutSubscribers.splice(e,1)}}attachBackend(t){this._backend=t,this.schedule.setBackend(t);const e=this.onStoreLayoutPublished(t);return()=>{e(),this._backend===t&&(this._backend=null,this.schedule.setBackend(null))}}get fixedTimestep(){return this._fixedTimestep}set fixedTimestep(t){this._fixedTimestep=Ct(t)}get fixedAlpha(){return this._accumulator/this._fixedTimestep}setTrace(t){}registerComponent(t,e,s){if(Array.isArray(t)){const r=typeof e=="string"?e:"f64",i=Object.create(null);for(const o of t)i[o]=r;return this.store.registerComponent(i,s?.name)}const n=typeof e=="object"?e:s;return this.store.registerComponent(t,n?.name)}registerSparseComponent(t,e,s){if(Array.isArray(t)){const r=typeof e=="string"?e:"f64",i=Object.create(null);for(const o of t)i[o]=r;return this.store.registerSparseComponent(i,s?.name)}const n=typeof e=="object"?e:s;return this.store.registerSparseComponent(t,n?.name)}spawn(t,e){return t===void 0?this.store.createEntity():this.store.spawn(t,e)}spawnBundle(...t){const e=this.store.createEntity();for(let s=0;s<t.length;s++){const n=t[s],r=G(n);this.store.addComponent(e,r,$(n))}return e}spawnMany(t,e,s){return this.store.spawnMany(t,e,s)}_assertHostMutationOutsideSystem(t,e){if(this._updating&&h.accessCheck.current()!==null){const s=h.accessCheck.current(),n=s.name??`system_${s.id}`;throw new h.ECSError(h.ECS_ERROR.ACCESS_UNDECLARED,`ecs.${t} called from inside system '${n}' — host ${t} is immediate and unsafe mid-iteration (and invisible to observers); use ${e} instead`,{op:t})}}despawn(t){return this.store.destroyEntity(t),this}disable(t){return this.store.disableEntity(t),this}enable(t){return this.store.enableEntity(t),this}addComponent(t,e,s){const n=G(e);return this.store.addComponent(t,n,s??$(e)),this}addComponents(t,...e){const s=[];for(let n=0;n<e.length;n++){const r=e[n];s.push({def:G(r),values:$(r)})}return this.store.addComponents(t,s),this}removeComponent(t,e){return this.store.removeComponent(t,e),this}removeComponents(t,...e){return this.store.removeComponents(t,e),this}batchAddComponent(t,e,s){return this.store.batchAddComponent(t,e,s),this}batchRemoveComponent(t,e){return this.store.batchRemoveComponent(t,e),this}getField(t,e,s){const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}refRead(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return it(s.columnGroups[t.id],n)}tryGetField(t,e,s){if(!this.store.hasComponent(t,e))return;const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}setField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=r.getColumn(e,s,this.store._tick);o[i]=n,this.store._anyDirtyTracked&&this.store._noteSet(e,t)}updateField(t,e,s,n){const r=n(this.getField(t,e,s));return this.setField(t,e,s,r),r}query(...t){const e=this.scratchMask;e._words.fill(0);for(let s=0;s<t.length;s++)e.set(t[s].id);return this._resolveQuery(e.copy(),null,null,t)}_nextQueryId(){return this._nextQueryIdCounter++}_resolveQuery(t,e,s,n){const r=t.hash(),i=e?e.hash():0,o=s?s.hash():0,a=r^Math.imul(i,h.HASH_GOLDEN_RATIO)^Math.imul(o,h.HASH_SECONDARY_PRIME)|0,l=this._caches.findDedup(a,t,e,s);if(l!==void 0)return l.query;const u=this.store.registerQuery(t,e??void 0,s??void 0),d=new D(u,n,this,t.copy(),e?.copy()??null,s?.copy()??null,this._nextQueryIdCounter++);return this.store.updateQueryRef(u,d),this._caches.addDedup(a,{includeMask:t.copy(),excludeMask:e?.copy()??null,anyOfMask:s?.copy()??null,query:d}),d}registerSystem(t,e){let s;if(typeof t=="function")if(e!==void 0){const i=e(new kt(this)),o=this.ctx,a=t;s={...nt,fn:(l,u)=>a(i,o,u)}}else s={...nt,fn:t};else s=t;const n=bt(this.nextSystemId++),r=Object.freeze({...s,...Wt(s),id:n});return this.systems.add(r),r}removeSystem(t){return this.schedule.removeSystem(t),t.onRemoved?.(),this.systems.delete(t),this}get systemCount(){return this.systems.size}startup(){this.prewarmArchetypes();try{for(const t of this.systems.values())if(t.onAdded!==void 0)try{t.onAdded(this.ctx)}finally{}this.schedule.runStartup(this.ctx,this._tick)}finally{}this.store.clearEvents()}prewarmArchetypes(){const t=De([...this.systems,...this._observers.descriptors()]);t.length!==0&&this.store.archCreateManyFromMasks(t)}update(t){try{if(this.store._tick=this._tick,this.store.publishRowCountsToDescriptor(),this.schedule.hasFixedSystems()){this._accumulator+=t;const s=this._maxFixedSteps*this._fixedTimestep;for(this._accumulator>s&&(this._accumulator=s);this._accumulator>=this._fixedTimestep;)this.schedule.runFixedUpdate(this.ctx,this._fixedTimestep,this._tick),this._accumulator-=this._fixedTimestep}this.schedule.runUpdate(this.ctx,t,this._tick);const e=O?this.store._devBufferedEventCount():0;this._observers.dispatchSet(this._tick),O&&this.store._devBufferedEventCount(),this.store.clearEvents(),this._tick++}finally{}}dispose(){for(const t of this.systems.values())t.dispose?.(),t.onRemoved?.();this.systems.clear(),this.schedule.clear()}template(...t){const e=[];for(let s=0;s<t.length;s++){const n=t[s];e.push({def:G(n),values:$(n)})}return this.store.resolveTemplate(e)}regionOffset(t){return this.store.regionOffset(t)}regionHandle(t){return this.store.regionHandle(t)}fieldId(t,e){return this.store.fieldIdOf(t,e)}entityIdAtRow(t,e){return this.store.entityIdAtRow(t,e)}get columnStore(){return this.store.columnStore}get archetypeCount(){return this.store.archetypeCount}registerTag(){return this.store.registerComponent({})}registerSparseTag(){return this.store.registerSparseComponent({})}isAlive(t){return this.store.isAlive(t)}get entityCount(){return this.store.entityCount}hasComponent(t,e){return this.store.hasComponent(t,e)}isDisabled(t){return this.store.isDisabled(t)}addSparse(t,e,s){return this.store.addSparse(t,e,s),this}removeSparse(t,e){return this.store.removeSparse(t,e),this}hasSparse(t,e){return this.store.hasSparse(t,e)}getSparseField(t,e,s){return this.store.getSparseField(t,e,s)}setSparseField(t,e,s,n){this.store.setSparseField(t,e,s,n)}_getLastRunTick(){return this.ctx.lastRunTick}_getCurrentTick(){return this.store._tick}_getQueryDirtyEpoch(){return this.store._queryDirtyEpoch}_forEachSparseMatch(t,e,s,n,r,i,o,a){this.store._forEachSparseMatch(t,e,s,n,r,i,o,a)}_relationBackingSparseId(t){return this.store.relationBackingSparseId(t)}_forEachRelationTargetMatch(t,e,s,n,r,i,o,a){this.store._forEachRelationTargetMatch(t,e,s,n,r,i,o,a)}_forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){this.store._forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u)}addSystems(t,...e){return this.schedule.addSystems(t,...e),this}configureSet(t,e){return this.schedule.configureSet(t,e),this}observe(t,e){return this._observers.register(t,e)}publishArchetypeRowCounts(){this.store.publishRowCountsToDescriptor()}flush(){this.ctx.flush()}}function De(c){const t=new Map,e=[],s=o=>{const a=o.hash(),l=t.get(a);if(l!==void 0){for(let u=0;u<l.length;u++)if(l[u].equals(o))return;l.push(o)}else t.set(a,[o]);e.push(o)},n=o=>{const a=new T.BitSet;for(let l=0;l<o.length;l++)a.set(o[l].id);return a},r=[];for(const o of c){const a=o.transitions;for(let l=0;l<a.length;l++){const u=a[l];r.push({whenHas:n(u.whenHas),add:u.add,remove:u.remove})}}for(const o of c){const a=o.spawns;for(let l=0;l<a.length;l++)s(n(a[l]))}for(;e.length>0;){const o=e.pop();for(let a=0;a<r.length;a++){const l=r[a];if(!o.contains(l.whenHas))continue;const u=o.copy();if(l.add!==void 0)for(let d=0;d<l.add.length;d++)u.set(l.add[d].id);if(l.remove!==void 0)for(let d=0;d<l.remove.length;d++)u.clear(l.remove[d].id);s(u)}}const i=[];for(const o of t.values())for(let a=0;a<o.length;a++)i.push(o[a]);return i}function ke(c,t){return{name:`runIfResourceEq(${c.description??"?"})`,resourceReads:[c],evaluate:e=>e.getResource(c)===t}}function xe(c,t=0){const e=(t%c+c)%c;return{name:`runEveryNTicks(${c}${e!==0?`, +${e}`:""})`,evaluate:s=>(s.ecsTick-e)%c===0}}function Me(c){return{name:"runIfAnyMatch",reads:c._defs,evaluate:()=>c.entityCount>0}}function ct(c){const t=[],e=[];for(const s of c)s.reads&&t.push(...s.reads),s.resourceReads&&e.push(...s.resourceReads);return{...t.length>0?{reads:t}:{},...e.length>0?{resourceReads:e}:{}}}function Ne(c){return{name:`not(${c.name})`,...ct([c]),evaluate:t=>!c.evaluate(t)}}function Fe(...c){return{name:`allOf(${c.map(t=>t.name).join(", ")})`,...ct(c),evaluate:t=>c.every(e=>e.evaluate(t))}}function Le(...c){return{name:`anyOf(${c.map(t=>t.name).join(", ")})`,...ct(c),evaluate:t=>c.some(e=>e.evaluate(t))}}function Be(c){return c.kind==="spawn"&&c.onSpawned!==void 0?{kind:"spawn",components:c.components}:c}class Ge{seed;_startup=[];_ticks=[];sink=this._startup;constructor(t=0){this.seed=t}openTick(t,e){const s=this._ticks[this._ticks.length-1];if(s!==void 0&&s.tick===t){this.sink=s.commands;return}const n=[];this._ticks.push({tick:t,dt:e,commands:n}),this.sink=n}record=t=>{this.sink.push(Be(t))};log(){return{seed:this.seed,startup:this._startup,ticks:this._ticks}}snapshotLog(){return{seed:this.seed,startup:this._startup.map(t=>({...t})),ticks:this._ticks.map(t=>({...t,commands:t.commands.map(e=>({...e}))}))}}}const q="__component_def";function $e(c){return JSON.stringify(c,(t,e)=>{if(typeof e=="function"&&"id"in e)return{[q]:e.id};if(e!==null&&typeof e=="object"&&q in e)throw new h.ECSError(h.ECS_ERROR.COMMAND_LOG_TAG_COLLISION,`Cannot serialize the command log: a value object owns a field named "${q}", the reserved tag the serializer uses for component defs. Rename that component field so the log can round-trip losslessly.`);return e})}function Pe(c){return JSON.parse(c,(t,e)=>e!==null&&typeof e=="object"&&q in e?vt(Rt(e[q])):e)}function Ue(c,t,e,s){for(const i of e.startup)t.push(i);c.startup();const n=s?.hash??c.snapshots.deterministic,r=[];for(const i of e.ticks){for(const o of i.commands)t.push(o);c.update(i.dt),n&&r.push(c.snapshots.stateHash())}return{startupCommands:e.startup.length,ticks:e.ticks.length,stateHashes:r}}function tt(c){return c.name??`system#${c.id}`}class He{_frames=[];_current=null;tickBegin(t,e){const s={tick:t,dt:e,events:[]};this._current=s,this._frames.push(s)}tickEnd(t){this._current=null}systemStart(t,e){this._current?.events.push({kind:"system_start",system:tt(t),phase:e})}systemEnd(t){this._current?.events.push({kind:"system_end",system:tt(t)})}commandQueued(t,e,s){this._current?.events.push({kind:"command_queued",op:t,entity:e,component:s})}flushBegin(t){this._current?.events.push({kind:"flush_begin",phase:t})}flushEnd(t){this._current?.events.push({kind:"flush_end",phase:t})}phaseBoundary(t){}observerFired(t,e,s,n){this._current?.events.push({kind:"observer_fired",op:t,component:e,entity:s,observer:tt(n)})}eventEmitted(t){this._current?.events.push({kind:"event_emitted",key:t})}eventRead(t,e){this._current?.events.push({kind:"event_read",key:t,count:e})}frames(){return this._frames}reset(){this._frames.length=0,this._current=null}}function N(c,t){if(!(t>=0)||!Number.isFinite(t))throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,`${c} must be a finite number >= 0, got ${t}`);return t}function Ve(c){if(!Number.isInteger(c)||c<0)throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,`frame count must be an integer >= 0, got ${c}`);return c}class qe{ecs;requestFrame;cancelFrame;frameHandle=null;lastTimestampMs=null;running=!1;_fixedDt;_maxDt;constructor(t,e={}){this.ecs=t,this._fixedDt=N("fixedDt",e.fixedDt??1/60),this._maxDt=N("maxDt",e.maxDt??.25);const s=globalThis;this.requestFrame=e.requestFrame??s.requestAnimationFrame?.bind(globalThis),this.cancelFrame=e.cancelFrame??s.cancelAnimationFrame?.bind(globalThis),e.autoStart===!0&&this.play()}get fixedDt(){return this._fixedDt}set fixedDt(t){this._fixedDt=N("fixedDt",t)}get maxDt(){return this._maxDt}set maxDt(t){this._maxDt=N("maxDt",t)}get isRunning(){return this.running}step(t=this._fixedDt){this.ecs.update(N("dt",t))}stepFrames(t,e=this._fixedDt){Ve(t);const s=N("dt",e);for(let n=0;n<t;n++)this.ecs.update(s)}play(){if(!this.running){if(this.requestFrame===void 0)throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,"FrameStepper.play() requires requestAnimationFrame or a requestFrame option");this.running=!0,this.lastTimestampMs=null,this.scheduleNextFrame()}}pause(){this.running=!1,this.lastTimestampMs=null,this.frameHandle!==null&&this.cancelFrame!==void 0&&this.cancelFrame(this.frameHandle),this.frameHandle=null}toggle(){this.running?this.pause():this.play()}dispose(){this.pause()}scheduleNextFrame(){this.frameHandle=this.requestFrame?.(this.onFrame)??null}onFrame=t=>{if(!this.running)return;const e=this.lastTimestampMs===null?this._fixedDt:(t-this.lastTimestampMs)/1e3;this.lastTimestampMs=t,this.ecs.update(Math.min(N("dt",e),this._maxDt)),this.running&&this.scheduleNextFrame()}}function We(c,t){return c.relations.register({exclusive:!0,onDeleteTarget:t?.onDeleteTarget??"clear"})}function ze(c,t){return c.relations.register({exclusive:!0,onDeleteTarget:t?.onDeleteTarget??"delete"})}function je(c){return h.unsafeCast(Symbol(c))}const Ye="0.5.2";exports.ANY_RELATION=h.ANY_RELATION;exports.ECSError=h.ECSError;exports.ECS_ERROR=h.ECS_ERROR;exports.HostCommandQueue=h.HostCommandQueue;exports.SCHEDULE=h.SCHEDULE;exports.SparseRestoreError=h.SparseRestoreError;exports.applyHostCommand=h.applyHostCommand;exports.getEntityIndex=h.getEntityIndex;exports.installHostCommandSeam=h.installHostCommandSeam;exports.isEcsError=h.isEcsError;exports.spawnEntry=h.spawnEntry;exports.systemSet=h.systemSet;exports.uninstallHostCommandSeam=h.uninstallHostCommandSeam;exports.SabUnavailableError=V.SabUnavailableError;exports.ChangedQuery=M;exports.ChunkColumns=Dt;exports.Commands=xt;exports.ECS=Te;exports.ECSRestoreError=b;exports.ECS_SNAPSHOT_VERSION=K;exports.FrameStepper=qe;exports.FrameTraceRecorder=He;exports.HIERARCHY_UNBOUNDED=ot;exports.HostCommandRecorder=Ge;exports.Query=D;exports.QueryBuilder=kt;exports.StoreRestoreError=B;exports.SystemContext=Mt;exports.VERSION=Ye;exports.allOf=Fe;exports.anyOf=Le;exports.bundle=Ft;exports.deserializeCommandLog=Pe;exports.eventKey=Pt;exports.not=Ne;exports.registerChildOf=ze;exports.registerIsA=We;exports.replayCommandLog=Ue;exports.resourceKey=je;exports.runEveryNTicks=xe;exports.runIfAnyMatch=Me;exports.runIfResourceEq=ke;exports.serializeCommandLog=$e;exports.signalKey=Ut;
|
|
1
|
+
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const h=require("./host_commands-DNf0f6ko.cjs"),T=require("./typed_arrays-D3NmwtCG.cjs"),V=require("./shared-BMXh9hxm.cjs"),O=!1,Rt=c=>h.validateAndCast(c),ht=Object.freeze({});function vt(c){const t=(e=>({def:t,values:e??ht}));return Object.defineProperty(t,"id",{value:c,enumerable:!1}),t}function Lt(c,...t){return{def:c,values:t[0]??ht}}function G(c){return typeof c=="function"?c:c.def}function $(c){return typeof c=="function"?ht:c.values}class B extends Error{constructor(t){super(t),this.name="StoreRestoreError"}}function Bt(c){const t=c.view.getUint32(h.STORE_HEADER_OFFSETS.capacity,!0);return new Uint8Array(c.buffer,0,t)}function Gt(c,t=V.DEFAULT_SAB_ALLOCATOR){const e=new DataView(c.buffer,c.byteOffset,c.byteLength);if(c.byteLength<h.STORE_HEADER_BYTES)throw new B(`snapshot too small: ${c.byteLength} bytes (header alone needs ${h.STORE_HEADER_BYTES})`);const s=e.getUint32(h.STORE_HEADER_OFFSETS.magic,!0);if(s!==h.STORE_MAGIC)throw new B(`bad magic: 0x${s.toString(16).padStart(8,"0")} (expected 0x${h.STORE_MAGIC.toString(16).padStart(8,"0")})`);const n=e.getUint32(h.STORE_HEADER_OFFSETS.sim_abi_version,!0);if(n!==h.SIM_ABI_VERSION)throw new B(`incompatible sim_abi_version: snapshot=${n}, build=${h.SIM_ABI_VERSION}`);const r=t(c.byteLength);new Uint8Array(r).set(c);const i=new DataView(r),o=h.readStoreHeader(i);if(o.layoutDescriptorOff<0||o.layoutDescriptorOff>r.byteLength)throw new B(`layout_descriptor_off ${o.layoutDescriptorOff} is outside the snapshot (${r.byteLength} bytes)`);try{const a=h.readLayoutDescriptorRegion(i,o.layoutDescriptorOff,o.archetypeCount),l=h.buildArchetypeViews(r,a);return{buffer:r,view:i,header:o,archetypes:l}}catch(a){throw a instanceof RangeError?new B(`snapshot layout is corrupt or truncated: a descriptor offset or column extent reads past the ${r.byteLength}-byte buffer (${a.message})`):a}}const $t=c=>h.validateAndCast(c);class Pt{fieldNames;columns;reader;_readerLen;constructor(t){this.fieldNames=t,this.columns=[];for(let n=0;n<t.length;n++)this.columns.push([]);const e={};for(let n=0;n<t.length;n++)e[t[n]]=this.columns[n];const s={length:0,...e};this._readerLen=s,this.reader=s}emit(t){const e=this.fieldNames,s=this.columns;for(let n=0;n<e.length;n++)s[n].push(t[e[n]]);this._readerLen.length++}emitSignal(){this._readerLen.length++}clear(){this._readerLen.length=0;const t=this.columns;for(let e=0;e<t.length;e++)t[e].length=0}}function Ut(c){return h.unsafeCast(Symbol(c))}function Ht(c){return h.unsafeCast(Symbol(c))}class Vt{channels=[];dirtyChannels=[];count=0;keyMap=new Map;registerEvent(t){const e=$t(this.count++),s=new Pt(t);return this.channels.push(s),h.unsafeCast(e)}emitEvent(t,e){const s=t,n=this.channels[s],r=n.reader.length===0;n.emit(e),r&&this.dirtyChannels.push(s)}emitSignal(t){const e=t,s=this.channels[e],n=s.reader.length===0;s.emitSignal(),n&&this.dirtyChannels.push(e)}getEventReader(t){return this.channels[t].reader}clearEvents(){const t=this.dirtyChannels,e=this.channels;for(let s=0;s<t.length;s++)e[t[s]].clear();t.length=0}devBufferedEventCount(){const t=this.dirtyChannels,e=this.channels;let s=0;for(let n=0;n<t.length;n++)s+=e[t[n]].reader.length;return s}registerEventByKey(t,e){if(this.keyMap.has(t))throw new h.ECSError(h.ECS_ERROR.EVENT_ALREADY_REGISTERED,`event '${t.description??"<unnamed>"}' is already registered`,{event:t.description});const s=this.registerEvent(e);return this.keyMap.set(t,s),s}getEventDefByKey(t){const e=this.keyMap.get(t);if(e===void 0)throw new h.ECSError(h.ECS_ERROR.EVENT_NOT_REGISTERED,`event '${t.description??"<unnamed>"}' is not registered — call ecs.events.register(key, fields) at world setup`,{event:t.description});return e}hasEventKey(t){return this.keyMap.has(t)}}class qt{map=new Map;register(t,e){if(this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_ALREADY_REGISTERED,`resource '${t.description??"<unnamed>"}' is already registered — remove() it first if you meant to replace it`,{resource:t.description});this.map.set(t,e)}get(t){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource read: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});return this.map.get(t)}set(t,e){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource write: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});this.map.set(t,e)}remove(t){if(!this.map.has(t))throw new h.ECSError(h.ECS_ERROR.RESOURCE_NOT_REGISTERED,`resource remove: '${t.description??"<unnamed>"}' is not registered — call ecs.resources.register(key, value) at world setup`,{resource:t.description});this.map.delete(t)}has(t){return this.map.has(t)}}class z extends Error{capacity;requested;constructor(t,e){super(`BufferBackedColumn overflow: requested length ${e} exceeds capacity ${t}`),this.name="StoreColumnOverflowError",this.capacity=t,this.requested=e}}class Wt{_buf;_capacity;_len=0;constructor(t){this._buf=t,this._capacity=t.length}refreshView(t){if(t.length<this._len)throw new z(t.length,this._len);this._buf=t,this._capacity=t.length}get length(){return this._len}get capacity(){return this._capacity}push(t){if(this._len>=this._capacity)throw new z(this._capacity,this._len+1);this._buf[this._len++]=t}pop(){return this._buf[--this._len]}get(t){return this._buf[t]}setAt(t,e){this._buf[t]=e}swapRemove(t){const e=this._buf[t];return this._buf[t]=this._buf[--this._len],e}clear(){this._len=0}setLength(t){if(t>this._capacity)throw new z(this._capacity,t);this._len=t}get buf(){return this._buf}view(){return this._buf.subarray(0,this._len)}[Symbol.iterator](){let t=0;const e=this._buf,s=this._len;return{next(){return t<s?{value:e[t++],done:!1}:{value:0,done:!0}}}}ensureCapacity(t){if(t>this._capacity)throw new z(this._capacity,t)}bulkAppend(t,e,s){this.ensureCapacity(this._len+s),this._buf.set(t.subarray(e,e+s),this._len),this._len+=s}bulkAppendZeroes(t){this.ensureCapacity(this._len+t),this._buf.fill(0,this._len,this._len+t),this._len+=t}bulkAppendValue(t,e){this.ensureCapacity(this._len+e),this._buf.fill(t,this._len,this._len+e),this._len+=e}}const ut=c=>h.validateAndCast(c);class at{id;mask;hasColumns;materializesRows;_entityIds;length=0;enabledCount=0;_flushSeenEpoch=-1;_flushPreLen=0;_flushPreEnabled=0;_iterDepth=0;edges=[];batchTransitionMaps=new Map;compositeAddEdges=null;_flatColumns=[];_storeArchetypeId=null;_colOffset=[];_fieldCount=[];_fieldIndex=[];_fieldNames=[];columnGroups=[];_columnIds=[];_changedTick=[];_mutGroupCache=[];_readGroupCache=[];growHandler=null;constructor(t,e,s,n=h.DEFAULT_COLUMN_CAPACITY,r){if(this.id=t,this.mask=e,this._entityIds=new T.GrowableUint32Array(n),s){let i=0;for(let o=0;o<s.length;o++){const a=s[o],l=a.componentId,u=new Array(a.fieldNames.length);if(this._colOffset[l]=i,this._fieldCount[l]=a.fieldNames.length,this._fieldIndex[l]=a.fieldIndex,this._fieldNames[l]=a.fieldNames,a.fieldNames.length>0&&!r)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`Archetype ${t}: layouts with fields require a columnFactory — use Archetype.fromColumnStore for SAB-backed columns, or pass a heap factory explicitly in tests`);for(let d=0;d<a.fieldNames.length;d++){const f=a.fieldTypes[d],p=r(a.componentId,d,f);u[d]=p,this._flatColumns[i++]=p}this.columnGroups[l]={layout:a,columns:u},this._columnIds.push(l),this._changedTick[l]=0}}this.hasColumns=this._columnIds.length>0,this.materializesRows=!e.isEmpty()}static fromColumnStore(t,e,s,n,r){const i=n.archetypes.get(r);if(!i)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`ColumnStore has no archetype ${r}`);const o=(l,u)=>{const d=i.columns.get(h.columnKey(l,u));if(!d)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`ColumnStore archetype ${r} has no column for (${l}, ${u})`);return new Wt(d.view)},a=new at(t,e,s,i.rowCapacity,o);return a._storeArchetypeId=r,a}get isBufferBacked(){return this._storeArchetypeId!==null}refreshViews(t){if(this._storeArchetypeId===null)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`Archetype ${this.id} is not SAB-backed`);const e=t.archetypes.get(this._storeArchetypeId);if(!e)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`new ColumnStore has no archetype ${this._storeArchetypeId}`);const s=e.columnsInOrder,n=this._flatColumns;for(let r=0;r<s.length;r++)n[r].refreshView(s[r].view)}get entityCount(){return et?this.length:this.enabledCount}get totalCount(){return this.length}get disabledCount(){return this.length-this.enabledCount}get entityIds(){return this._entityIds.buf}swapRows(t,e){if(t===e)return;const s=this._entityIds.buf,n=s[t];s[t]=s[e],s[e]=n;const r=this._flatColumns;for(let i=0;i<r.length;i++){const o=r[i].buf,a=o[t];o[t]=o[e],o[e]=a}}_placeTail(t,e){const s=this.enabledCount;if(s===t)return this.enabledCount=t+1,t;if(this.swapRows(s,t),e!==void 0){const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t}return this.enabledCount=s+1,s}_placeTailBulk(t,e){return this.enabledCount+=e,t}disableRow(t,e){const s=this.enabledCount-1;if(t!==s){this.swapRows(t,s);const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t,e[h.getEntityIndex(n[s])]=s}this.enabledCount=s}enableRow(t,e){const s=this.enabledCount;if(t!==s){this.swapRows(t,s);const n=this._entityIds.buf;e[h.getEntityIndex(n[t])]=t,e[h.getEntityIndex(n[s])]=s}this.enabledCount=s+1}removeRow(t,e){if(this.enabledCount===this.length){const s=this._entityIds.buf,n=this.length-1;if(t!==n){if(s[t]=s[n],this.hasColumns){const r=this._flatColumns;for(let i=0;i<r.length;i++)r[i].swapRemove(t)}e[h.getEntityIndex(s[t])]=t}else if(this.hasColumns){const r=this._flatColumns;for(let i=0;i<r.length;i++)r[i].pop()}this._entityIds.pop(),this.length=n,this.enabledCount=n;return}this._removeRowPartitioned(t,e)}_removeRowPartitioned(t,e){const s=this._entityIds.buf,n=this.hasColumns,r=this.enabledCount,i=this.length-1;if(t>=r){if(t!==i){if(s[t]=s[i],n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].swapRemove(t)}e[h.getEntityIndex(s[t])]=t}else if(n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].pop()}this._entityIds.pop(),this.length--;return}const o=r-1;if(t!==o&&(this.swapRows(t,o),e[h.getEntityIndex(s[t])]=t),o!==i){if(s[o]=s[i],n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].swapRemove(o)}e[h.getEntityIndex(s[o])]=o}else if(n){const a=this._flatColumns;for(let l=0;l<a.length;l++)a[l].pop()}this._entityIds.pop(),this.length--,this.enabledCount=o}get entityList(){return this._entityIds.view()}hasComponent(t){return this.mask.has(t)}matches(t){return this.mask.contains(t)}getColumnRead(t,e){const s=t.id,n=this._fieldIndex[s][e];return this._flatColumns[this._colOffset[s]+n].buf}getColumnsRead(t,...e){return e.map(n=>this.getColumnRead(t,n))}getOptionalColumnRead(t,e){const s=t.id,n=this._colOffset[s];if(n===void 0)return;const r=this._fieldIndex[s][e];return this._flatColumns[n+r].buf}getColumn(t,e,s){const n=t.id;this._changedTick[n]=s;const r=this._fieldIndex[n][e];return this._flatColumns[this._colOffset[n]+r].buf}columnGroupMut(t,e){const s=t.id;this._changedTick[s]=e;const n=this._colOffset[s],r=this._fieldNames[s],i=this._flatColumns;let o=this._mutGroupCache[s];o===void 0&&(o={},this._mutGroupCache[s]=o);for(let a=0;a<r.length;a++)o[r[a]]=i[n+a].buf;return o}columnGroupRead(t){const e=t.id,s=this._colOffset[e],n=this._fieldNames[e],r=this._flatColumns;let i=this._readGroupCache[e];i===void 0&&(i={},this._readGroupCache[e]=i);for(let o=0;o<n.length;o++)i[n[o]]=r[s+o].buf;return i}writeFields(t,e,s,n){const r=e,i=this._colOffset[r];if(i===void 0)return;this._changedTick[r]=n;const o=this._fieldNames[r],a=this._flatColumns;for(let l=0;l<o.length;l++)a[i+l].buf[t]=s[o[l]]??0}bulkWriteFields(t,e,s,n,r){const i=s,o=this._colOffset[i];if(o===void 0)return;this._changedTick[i]=r;const a=this._fieldNames[i],l=this._flatColumns,u=t+e;for(let d=0;d<a.length;d++)l[o+d].buf.fill(n[a[d]]??0,t,u)}writeFieldsPositional(t,e,s,n){const r=e,i=this._colOffset[r];if(i===void 0)return;this._changedTick[r]=n;const o=this._flatColumns;for(let a=0;a<s.length;a++)o[i+a].buf[t]=s[a]}readField(t,e,s){const n=e,r=this._colOffset[n];if(r===void 0)return NaN;const i=this._fieldIndex[n][s];return i===void 0?NaN:this._flatColumns[r+i].buf[t]}copySharedFrom(t,e,s,n){const r=t._colOffset,i=t._fieldCount,o=t._flatColumns,a=this._flatColumns,l=this._columnIds;for(let u=0;u<l.length;u++){const d=l[u],f=r[d];if(f===void 0)continue;this._changedTick[d]=n;const p=this._colOffset[d],y=i[d];for(let g=0;g<y;g++)a[p+g].buf[s]=o[f+g].buf[e]}}addEntity(t,e){const s=this._flatColumns;s.length>0&&this.length>=s[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const n=this.length;this._entityIds.push(t);for(let r=0;r<s.length;r++)s[r].push(0);return this.length++,this._placeTail(n,e)}removeEntity(t){const e=this.length-1;let s=h.NO_SWAP;const n=this._flatColumns,r=this._entityIds.buf;if(t!==e){r[t]=r[e],s=h.getEntityIndex(r[t]);for(let i=0;i<n.length;i++)n[i].swapRemove(t)}else for(let i=0;i<n.length;i++)n[i].pop();return this._entityIds.pop(),this.length--,t<this.enabledCount&&this.enabledCount--,s}addEntityTag(t,e){const s=this.length;return this._entityIds.push(t),this.length++,this._placeTail(s,e)}addEntities(t,e=t.length){if(e===0)return this.length;const s=this._flatColumns;s.length>0&&this.length+e>s[0].buf.length&&this.growHandler!==null&&this.growHandler(this,e);const n=this.length;this._entityIds.bulkAppend(t,0,e);for(let r=0;r<s.length;r++)s[r].bulkAppendZeroes(e);return this.length+=e,this._placeTailBulk(n,e)}addEntitiesTag(t,e=t.length){if(e===0)return this.length;const s=this.length;return this._entityIds.bulkAppend(t,0,e),this.length+=e,this._placeTailBulk(s,e)}ensureRowCapacity(t){const e=this._flatColumns;e.length>0&&this.length+t>e[0].buf.length&&this.growHandler!==null&&this.growHandler(this,t)}addEntityWithValues(t,e,s,n){const r=this._flatColumns;r.length>0&&this.length>=r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const i=this.length;this._entityIds.push(t);for(let a=0;a<r.length;a++)r[a].push(e[a]);this.length++;const o=this._columnIds;for(let a=0;a<o.length;a++)this._changedTick[o[a]]=s;return this._placeTail(i,n)}addEntitiesWithValues(t,e,s,n){if(e===0)return this.length;const r=this._flatColumns;r.length>0&&this.length+e>r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,e);const i=this.length;this._entityIds.bulkAppend(t,0,e);for(let a=0;a<r.length;a++)r[a].bulkAppendValue(s[a],e);this.length+=e;const o=this._columnIds;for(let a=0;a<o.length;a++)this._changedTick[o[a]]=n;return this._placeTailBulk(i,e)}removeEntityTag(t){const e=this.length-1;let s=h.NO_SWAP;const n=this._entityIds.buf;return t!==e&&(n[t]=n[e],s=h.getEntityIndex(n[t])),this._entityIds.pop(),this.length--,t<this.enabledCount&&this.enabledCount--,s}moveEntityFrom(t,e,s,n,r,i){const o=e>=t.enabledCount;if(!this.materializesRows){t.removeRow(e,i),A[0]=h.UNASSIGNED,A[1]=h.NO_SWAP;return}const a=this._flatColumns;a.length>0&&this.length>=a[0].buf.length&&this.growHandler!==null&&this.growHandler(this,1);const l=this.length;this._entityIds.push(s);const u=t._flatColumns;for(let p=0;p<a.length;p++){const y=n[p];a[p].push(y>=0?u[y].buf[e]:0)}const d=this._columnIds;for(let p=0;p<d.length;p++)this._changedTick[d[p]]=r;this.length++;const f=o?l:this._placeTail(l,i);t.removeRow(e,i),A[0]=f,A[1]=h.NO_SWAP}moveEntityFromTag(t,e,s,n){const r=e>=t.enabledCount;if(!this.materializesRows){t.removeRow(e,n),A[0]=h.UNASSIGNED,A[1]=h.NO_SWAP;return}const i=this.length;this._entityIds.push(s),this.length++;const o=r?i:this._placeTail(i,n);t.removeRow(e,n),A[0]=o,A[1]=h.NO_SWAP}bulkMoveAllFrom(t,e,s){const n=t.length;if(n===0)return this.length;const r=this._flatColumns;r.length>0&&this.length+n>r[0].buf.length&&this.growHandler!==null&&this.growHandler(this,n);const i=this.length,o=t._flatColumns;this._entityIds.bulkAppend(t._entityIds.buf,0,n);for(let l=0;l<r.length;l++){const u=e[l];u>=0?r[l].bulkAppend(o[u].buf,0,n):r[l].bulkAppendZeroes(n)}const a=this._columnIds;for(let l=0;l<a.length;l++)this._changedTick[a[l]]=s;return this.length+=n,this.enabledCount=i+t.enabledCount,t.clearRows(),i}clearRows(){this.length=0,this.enabledCount=0,this._entityIds.clear();const t=this._flatColumns;for(let e=0;e<t.length;e++)t[e].clear()}restoreHostRows(t,e){const s=t.length;this._entityIds.clear(),this._entityIds.ensureCapacity(s);for(let r=0;r<s;r++)this._entityIds.push(t[r]);const n=this._flatColumns;for(let r=0;r<n.length;r++)n[r].setLength(s);this.length=s,this.enabledCount=e}getEdge(t){return this.edges[t]}setEdge(t,e){this.edges[t]=e}getBatchTransitionMap(t){const e=this.batchTransitionMaps.get(t.id);if(e!==void 0)return e;const s=st(this,t);return this.batchTransitionMaps.set(t.id,s),s}getCompositeAddEdge(t){return this.compositeAddEdges===null?void 0:this.compositeAddEdges.get(t)}cacheCompositeAddEdge(t,e,s){(this.compositeAddEdges??=new Map).set(t,{target:e,map:s})}}const A=[0,h.NO_SWAP];let et=!1;function x(c){const t=et;return et=c,t}function st(c,t){const e=t._flatColumns,s=new Int16Array(e.length),n=t._columnIds,r=c._colOffset,i=t._colOffset,o=t._fieldCount;for(let a=0;a<n.length;a++){const l=n[a],u=i[l],d=o[l],f=r[l];if(f!==void 0)for(let p=0;p<d;p++)s[u+p]=f+p;else for(let p=0;p<d;p++)s[u+p]=-1}return s}const bt=c=>h.validateAndCast(c),U=Object.freeze([]);function dt(c){return typeof c=="object"&&!Array.isArray(c)}function zt(c){let t=U;c.spawns!==void 0&&c.spawns.length>0&&(t=c.spawns.map(s=>dt(s)?s.defs:s));let e=U;if(c.despawns!==void 0&&c.despawns.length>0){const s=[];for(const n of c.despawns)dt(n)?s.push(...n.defs):s.push(n);e=s}return{reads:c.reads,writes:c.writes,spawns:t,despawns:e,transitions:c.transitions??U,resourceReads:c.resourceReads??U,resourceWrites:c.resourceWrites??U,sparseReads:c.sparseReads,sparseWrites:c.sparseWrites,relationReads:c.relationReads,relationWrites:c.relationWrites}}const nt=Object.freeze({reads:Object.freeze([]),writes:Object.freeze([]),spawns:Object.freeze([]),despawns:Object.freeze([]),transitions:Object.freeze([]),resourceReads:Object.freeze([]),resourceWrites:Object.freeze([]),sparseReads:Object.freeze([]),sparseWrites:Object.freeze([]),relationReads:Object.freeze([]),relationWrites:Object.freeze([])}),jt=Symbol.dispose??Symbol.for("Symbol.dispose"),X=(1<<20)-1;let Yt=0;function Kt(c,t){const e={...nt,...t,id:bt(Yt++),name:c,fn:Xt};return Object.freeze(e)}function Xt(){}function ft(c){const t=new Set;if(c)for(let e=0;e<c.length;e++)t.add(c[e].id);return t}function Qt(c){const t=(i,o)=>i.cid-o.cid||i.id-o.id,e=new Map,s=new Map;for(const i of c)e.set(i,[]),s.set(i,0);for(const i of c)if(i.writes.size!==0)for(const o of c){if(i===o)continue;let a=!1;for(const l of i.writes)if(o.reads.has(l)){a=!0;break}a&&(e.get(i).push(o),s.set(o,s.get(o)+1))}const n=c.filter(i=>s.get(i)===0).sort(t),r=[];for(;n.length>0;){const i=n.shift();r.push(i);for(const o of e.get(i)){const a=s.get(o)-1;s.set(o,a),a===0&&(n.push(o),n.sort(t))}}if(r.length!==c.length){const i=new Set(r);for(const o of c.slice().sort(t))i.has(o)||r.push(o)}return r}class Zt{constructor(t,e){this.store=t,this.ctx=e}entries=[];byCid=new Map;_topo=null;_addBuckets=new Map;_remBuckets=new Map;_disBuckets=new Map;_enaBuckets=new Map;_radixOut=[];_radixC0=new Int32Array(1024);_radixC1=new Int32Array(1024);_setDrainCache=new Map;get count(){return this.entries.length}descriptors(){const t=new Array(this.entries.length);for(let e=0;e<this.entries.length;e++)t[e]=this.entries[e].descriptor;return t}register(t,e){const s=t.id,n=e.granularity??"archetype",r=e.onSet!==void 0&&n==="entity",i=e.onSet!==void 0&&n!=="entity",o=e.access??{},a=Kt(e.name??`observer(${h.componentDebugName(t)??s})`,o),l={id:a.id,cid:s,def:t,onAdd:e.onAdd,onRemove:e.onRemove,onDisable:e.onDisable,onEnable:e.onEnable,onSetEntity:r?e.onSet:void 0,onSetArch:i?e.onSet:void 0,descriptor:a,writes:ft(o.writes),reads:ft(o.reads),yieldExisting:e.yieldExisting??!1,lastSetTick:0,disposed:!1};this.entries.push(l);let u=this.byCid.get(s);u===void 0&&(u=[],this.byCid.set(s,u)),u.push(l),this._topo=null,this._reconfigureComponent(s),l.yieldExisting&&l.onAdd!==void 0&&this._yieldExisting(l);const d=()=>this._dispose(l);return{dispose:d,[jt]:d}}_dispose(t){if(t.disposed)return;t.disposed=!0;const e=this.entries.indexOf(t);e>=0&&this.entries.splice(e,1);const s=this.byCid.get(t.cid);if(s!==void 0){const n=s.indexOf(t);n>=0&&s.splice(n,1),s.length===0&&this.byCid.delete(t.cid)}this._topo=null,this._reconfigureComponent(t.cid)}_reconfigureComponent(t){const e=this.byCid.get(t);let s=!1,n=!1,r=!1,i=!1,o=!1;if(e!==void 0)for(let a=0;a<e.length;a++){const l=e[a];l.onAdd!==void 0&&(s=!0),l.onRemove!==void 0&&(n=!0),l.onDisable!==void 0&&(r=!0),l.onEnable!==void 0&&(i=!0),l.onSetEntity!==void 0&&(o=!0)}this.store._configureComponentObservation(t,s,n,r,i,o)}getTopo(){return this._topo===null&&(this._topo=Qt(this.entries)),this._topo}dispatchStructural(t){this._bucket(t.addComp,t.addEid,t.addLen,this._addBuckets),this._bucket(t.remComp,t.remEid,t.remLen,this._remBuckets),this._bucket(t.disComp,t.disEid,t.disLen,this._disBuckets),this._bucket(t.enaComp,t.enaEid,t.enaLen,this._enaBuckets);const e=this.getTopo();for(let s=0;s<e.length;s++){const n=e[s];if(!n.disposed){if(n.onRemove!==void 0){const r=this._remBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onRemove,r,"remove")}if(n.onAdd!==void 0){const r=this._addBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onAdd,r,"add")}if(n.onDisable!==void 0){const r=this._disBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onDisable,r,"disable")}if(n.onEnable!==void 0){const r=this._enaBuckets.get(n.cid);r!==void 0&&r.length>0&&this._fireEach(n,n.onEnable,r,"enable")}}}this._clearBuckets(this._addBuckets),this._clearBuckets(this._remBuckets),this._clearBuckets(this._disBuckets),this._clearBuckets(this._enaBuckets)}_fireEach(t,e,s,n){Y(s,this._radixOut,this._radixC0,this._radixC1);try{const r=O?this.store._trace:null;for(let i=0;i<s.length;i++)e(h.unsafeCast(s[i]),this.ctx)}finally{}}_bucket(t,e,s,n){for(let r=0;r<s;r++){const i=t[r];let o=n.get(i);o===void 0&&(o=[],n.set(i,o)),o.push(e[r])}}_clearBuckets(t){for(const e of t.values())e.length=0}dispatchSet(t){if(this.entries.length===0)return;const e=this.getTopo(),s=this._setDrainCache;for(let n=0;n<e.length;n++){const r=e[n];r.onSetEntity!==void 0?this._dispatchSetEntity(r,s):r.onSetArch!==void 0&&this._dispatchSetArch(r,t)}for(const n of s.values())n.length=0;s.clear()}_dispatchSetEntity(t,e){let s=e.get(t.cid);if(s===void 0&&(s=this.store._takeDirty(t.cid),Y(s,this._radixOut,this._radixC0,this._radixC1),e.set(t.cid,s)),s.length===0)return;const n=t.def,r=t.onSetEntity;try{for(let i=0;i<s.length;i++){const o=h.unsafeCast(s[i]);this.store.isAlive(o)&&this.store.hasComponent(o,n)&&!this.store.isDisabled(o)&&r(o,this.ctx)}}finally{}}_dispatchSetArch(t,e){const s=t.onSetArch,n=t.lastSetTick;try{this.store._forEachChangedArchetype(t.cid,n,r=>{s(r,this.ctx)})}finally{}t.lastSetTick=e+1}_yieldExisting(t){const e=t.onAdd,s=this.store._collectEntitiesWithComponent(t.cid);if(s.length!==0){Y(s,this._radixOut,this._radixC0,this._radixC1);try{for(let n=0;n<s.length;n++)e(h.unsafeCast(s[n]),this.ctx)}finally{}}}}function Y(c,t,e,s){const n=c.length;if(!(n<2)){t.length<n&&(t.length=n),e.fill(0),s.fill(0);for(let r=0;r<n;r++){const i=c[r]&X;e[i&1023]++,s[i>>10&1023]++}for(let r=1;r<1024;r++)e[r]+=e[r-1],s[r]+=s[r-1];for(let r=n-1;r>=0;r--){const i=c[r];t[--e[i&X&1023]]=i}for(let r=n-1;r>=0;r--){const i=t[r];c[--s[(i&X)>>10&1023]]=i}}}class Jt{constructor(t){this.host=t}relations=[];_hasTargetCleanup=!1;_hierarchyRadixOut=[];_hierarchyRadixC0=new Int32Array(1024);_hierarchyRadixC1=new Int32Array(1024);get stores(){return this.relations}get count(){return this.relations.length}get hasTargetCleanup(){return this._hasTargetCleanup}registerRelation(t){const e=t?.multi===!0,s=t?.exclusive===!0;if(e&&s)throw new h.ECSError(h.ECS_ERROR.RELATION_MODE_INVALID,"register_relation: a relation cannot be both exclusive and multi-target");const n=!e,r=t?.onDeleteTarget??h.DEFAULT_ON_DELETE_TARGET,i=n?this.host.pushSparseStore([h.RELATION_TARGET_FIELD],["f64"]):this.host.pushSparseStore([],[]),o=this.relations.length;return this.relations.push(h.makeRelationStore(n,i,this.host.sparseStoreOf(i),r)),r!=="orphan"&&(this._hasTargetCleanup=!0),h.unsafeCast(o)}relationOf(t){const e=t,s=this.relations[e];if(s===void 0)throw new h.ECSError(h.ECS_ERROR.RELATION_NOT_REGISTERED,`relation ${e} is not registered`);return s}addRelation(t,e,s){const n=this.relationOf(e);this.host.isAlive(t)&&this.host.isAlive(s)&&n.link(t,s)}removeRelation(t,e,s){const n=this.relationOf(e);this.host.isAlive(t)&&n.unlink(t,s)}targetOf(t,e){return this.relationOf(e).singleTarget(h.getEntityIndex(t))}targetsOf(t,e){return this.relationOf(e).targetsOf(h.getEntityIndex(t))}sourcesOf(t,e){return this.relationOf(e).sourcesOf(t)}hasRelation(t,e){return this.host.hasSparse(t,this.relationOf(e).sparse)}pairsOf(t){const e=this.relationOf(t),s=[],n=this.host.entityGenerations();return e.forEachCanonicalPair(r=>h.createEntityId(r,n[r]),(r,i)=>s.push([r,i])),s}sourcesOfAny(t){const e=[],s=this.relations;for(let n=0;n<s.length;n++){const r=h.unsafeCast(n),i=s[n].sourcesOf(t);for(let o=0;o<i.length;o++)e.push([r,i[o]])}return e}relationBackingSparseId(t){return this.relationOf(t).sparse}forEachRelationTargetMatch(t,e,s,n,r,i,o,a){const l=this.relations;if(l.length===0)return;const u=new Set;for(let E=0;E<l.length;E++){const _=l[E].sourcesOf(t);for(let m=0;m<_.length;m++)u.add(_[m])}if(u.size===0)return;const d=Array.from(u).sort((E,_)=>E-_),f=this.host.sparseStores(),p=this.host.entityArchetype(),y=this.host.entityRow(),g=this.host.archetypes();for(let E=0;E<d.length;E++){const _=h.unsafeCast(d[E]),m=h.getEntityIndex(_),S=p[m];if(S===h.UNASSIGNED)continue;const v=g[S],C=v.mask;if(!C.contains(e)||s!==null&&C.overlaps(s)||n!==null&&!C.overlaps(n))continue;let R=!0;for(let w=0;w<r.length;w++)if(!f[r[w]].has(m)){R=!1;break}if(R){for(let w=0;w<i.length;w++)if(f[i[w]].has(m)){R=!1;break}if(R){if(!o){const w=y[m];if(w!==h.UNASSIGNED&&w>=v.enabledCount)continue}a(_)}}}}compactRelations(){const t=this.relations;if(t.length===0)return 0;const e=n=>this.host.isAlive(n);let s=0;for(let n=0;n<t.length;n++)s+=t[n].pruneDeadReverse(e);return s}ancestorsOf(t,e){const s=this.relationOf(e),n=this.host.sparseStoreOf(s.sparse),r=[t],i=new Set([h.getEntityIndex(t)]);let o=t;for(;;){const a=n.getField(h.getEntityIndex(o),0);if(a===void 0)break;const l=h.unsafeCast(a);if(!this.host.isAlive(l)){r.push(l);break}const u=h.getEntityIndex(l);if(i.has(u))break;i.add(u),o=l,r.push(o)}return r}rootOf(t,e){const s=this.ancestorsOf(t,e);return s[s.length-1]}cascadeOf(t,e){const s=this.relationOf(e),n=[t],r=new Set([h.getEntityIndex(t)]);for(let i=0;i<n.length;i++){const o=s.sourcesOf(n[i]);for(let a=0;a<o.length;a++){const l=o[a],u=h.getEntityIndex(l);r.has(u)||(r.add(u),n.push(l))}}return n}purgeSource(t){const e=this.relations;for(let s=0;s<e.length;s++)e[s].purgeSource(t)}cleanupTarget(t,e){const s=this.relations;for(let n=0;n<s.length;n++){const r=s[n];if(r.onDeleteTarget==="orphan")continue;const i=r.sourcesOf(t);if(i.length!==0){if(r.onDeleteTarget==="delete"){for(let o=0;o<i.length;o++)e.push(i[o]);continue}for(let o=0;o<i.length;o++)r.unlink(i[o],t)}}}forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){const d=this.relationOf(o),f=[];if(this.host.forEachSparseMatch(t,e,s,n,r,i,_=>f.push(_),l),f.length===0)return;Y(f,this._hierarchyRadixOut,this._hierarchyRadixC0,this._hierarchyRadixC1);const p=this.host.sparseStoreOf(d.sparse),y=new Map,g=new Set,E=[];for(let _=0;_<f.length;_++){const m=f[_],S=this._hierarchyDepthOf(h.getEntityIndex(m),p,y,g);if(S>a)continue;let v=E[S];v===void 0&&(v=[],E[S]=v),v.push(m)}for(let _=0;_<E.length;_++){const m=E[_];if(m!==void 0)for(let S=0;S<m.length;S++)u(m[S])}}_hierarchyDepthOf(t,e,s,n){const r=[];let i=t,o=0;for(;;){const l=s.get(i);if(l!==void 0){o=l;break}const u=e.getField(i,0);let d=-1;if(u!==void 0){const f=h.unsafeCast(u);this.host.isAlive(f)&&(d=h.getEntityIndex(f))}if(d===-1){s.set(i,0),o=0;break}if(n.has(d)){s.set(i,0),o=0;break}r.push(i),n.add(i),i=d}let a=o;for(let l=r.length-1;l>=0;l--)a+=1,s.set(r[l],a),n.delete(r[l]);return s.get(t)}}class te{_generations;_lengthView;_highWater=0;_freeIndices=[];_aliveCount=0;_capacity;lastIndex=0;constructor(t,e,s){this._capacity=t,this._generations=e,this._lengthView=s}replantViews(t,e){this._generations=t,this._lengthView=e}get generations(){return this._generations}get highWater(){return this._highWater}get aliveCount(){return this._aliveCount}get freeCount(){return this._freeIndices.length}alloc(){let t,e;if(this._freeIndices.length>0)t=this._freeIndices.pop(),e=this._generations[t];else{if(this._highWater>=this._capacity)throw new h.ECSError(h.ECS_ERROR.EID_MAX_INDEX_OVERFLOW,`entityIndexCapacity (${this._capacity}) exhausted; raise it in ECSOptions.memory or destroy unused entities`);t=this._highWater++,this._generations[t]=h.INITIAL_GENERATION,e=h.INITIAL_GENERATION,this._lengthView[0]=this._highWater}return this._aliveCount++,this.lastIndex=t,h.createEntityId(t,e)}ensureCapacity(t){const e=t-this._freeIndices.length;if(e>0&&this._highWater+e>this._capacity)throw new h.ECSError(h.ECS_ERROR.EID_MAX_INDEX_OVERFLOW,`entityIndexCapacity (${this._capacity}) cannot fit ${t} new entities (${this._freeIndices.length} free, high-water ${this._highWater}); raise it in ECSOptions.memory or destroy unused entities`)}recycle(t,e){const s=e+1;s<h.RETIRED_GENERATION?(this._generations[t]=s,this._freeIndices.push(t)):this._generations[t]=h.RETIRED_GENERATION,this._aliveCount--}isAliveIndex(t,e){return t<this._highWater&&this._generations[t]===e}publishLength(){this._lengthView[0]=this._highWater}snapshotFreeIndices(){return this._freeIndices.slice()}setHighWater(t){this._highWater=t}restoreHostState(t,e){this._freeIndices.length=0;for(let s=0;s<t.length;s++)this._freeIndices.push(t[s]);this._aliveCount=e}}const pt=65536;class ee{destroyIds=[];addIds=[];addDefs=[];addValues=[];removeIds=[];removeDefs=[];toggleIds=[];toggleDisable=[];_flushing=!1;host;obsEvents;constructor(t,e){this.host=t,this.obsEvents=e}queueDestroy(t){this.destroyIds.push(t)}queueAdd(t,e,s){this.addIds.push(t),this.addDefs.push(e),this.addValues.push(s)}queueRemove(t,e){this.removeIds.push(t),this.removeDefs.push(e)}queueToggle(t,e){this.toggleIds.push(t),this.toggleDisable.push(e)}get destroyCount(){return this.destroyIds.length}get structuralCount(){return this.addIds.length+this.removeIds.length}get toggleCount(){return this.toggleIds.length}flushDestroyed(){this._flushing||this.host.applyDestroys()}flushStructural(){if(this.host.structuralObserverCount()===0&&this.host.toggleObserverCount()===0){this.addIds.length>0&&this.host.applyAdds(),this.removeIds.length>0&&this.host.applyRemoves(),this.toggleIds.length>0&&this.host.applyToggles();return}if(this._flushing)return;this._flushing=!0;const t=this.obsEvents,e=this.host.structuralObserverHook();try{let s=0;for(;this.addIds.length>0||this.removeIds.length>0||this.destroyIds.length>0||this.toggleIds.length>0;){if(++s>pt)throw new h.ECSError(h.ECS_ERROR.OBSERVER_NON_CONVERGENT,`observer cascade did not converge after ${pt} rounds — two observers likely enqueue each other's structural ops forever`);t.addLen=0,t.remLen=0,t.disLen=0,t.enaLen=0,this.addIds.length>0||this.removeIds.length>0?(this.addIds.length>0&&this.host.applyAdds(),this.removeIds.length>0&&this.host.applyRemoves()):this.destroyIds.length>0?this.host.applyDestroys():this.host.applyToggles(),e!==null&&(t.addLen>0||t.remLen>0||t.disLen>0||t.enaLen>0)&&e(t)}}finally{this._flushing=!1}}}function It(c,t){let e=c;const s=new Array(t.length);for(let n=0;n<t.length;n++){const r=t[n],i=new Array(r.columns.length);for(let o=0;o<r.columns.length;o++){const a=r.columns[o];e=h.alignUp(e,a.stride),i[o]={componentId:a.componentId,fieldId:a.fieldId,typeTag:a.typeTag,byteOff:e,stride:a.stride},e+=a.stride*r.rowCapacity}s[n]={archetypeId:r.archetypeId,componentMask:r.componentMask,rowCount:0,enabledCount:0,rowCapacity:r.rowCapacity,columns:i}}if(e>h.STORE_MAX_BYTE_OFFSET)throw new h.StoreLayoutOverflowError(e);return{descriptors:s,newTotal:e}}function At(c,t){const e=c._allocator(t),s=e!==c.buffer?new DataView(e):c.view;return{grownBuffer:e,newView:s}}function Ot(c){return c.buffer instanceof ArrayBuffer?c.view.getUint32(h.STORE_HEADER_OFFSETS.capacity,!0):c.buffer.byteLength}function se(c){const t={};for(let n=0;n<h.STORE_PREFIX_REGIONS.length;n++){const r=h.STORE_PREFIX_REGIONS[n],i=c.view.getUint32(h.STORE_HEADER_OFFSETS[r.headerOff],!0);i!==0&&r.readOptions(c.view,i,t)}const e=h.readHeaderRegionTable(c.view);e.length>0&&(t.regions=e.map(n=>({id:n.regionId,name:`region:${n.regionId}`,bytes:n.byteLength,init:()=>{}})));const s=c.view.getUint32(h.STORE_HEADER_OFFSETS.bindings_off,!0);if(s!==0){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);t.bindingsRegionBytes=n-s}return h.isColumnStoreInternal(c)&&c._reservedDescriptorBytes>0&&(t.reservedDescriptorBytes=c._reservedDescriptorBytes),t}function ne(c){const t=new Map;for(let n=0;n<h.STORE_PREFIX_REGIONS.length;n++){const r=h.STORE_PREFIX_REGIONS[n],i=c.view.getUint32(h.STORE_HEADER_OFFSETS[r.headerOff],!0);if(i===0)continue;const o=r.regionBytes(c.view,i);t.set(r.headerOff,new Uint8Array(c.buffer,i,o).slice())}const e=new Map,s=h.readHeaderRegionTable(c.view);for(let n=0;n<s.length;n++){const r=s[n];e.set(r.regionId,new Uint8Array(c.buffer,r.byteOffset,r.byteLength).slice())}return{mechanism:t,consumer:e}}function re(c,t){for(const[e,s]of t.mechanism){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS[e],!0);new Uint8Array(c.buffer,n,s.byteLength).set(s)}for(const[e,s]of t.consumer){const n=h.findRegionOffset(c.view,e);if(n===0)continue;new Uint8Array(c.buffer,n,s.byteLength).set(s)}}function ie(c,t){const e=new Map;for(const[s,n]of c.archetypes){const r=t.get(s)??0;if(r===0)continue;const i=[];for(let o=0;o<n.columnsInOrder.length;o++){const a=n.columnsInOrder[o],l=r*a.stride,u=new Uint8Array(l);u.set(new Uint8Array(a.view.buffer,a.view.byteOffset,l)),i.push(u)}e.set(s,i)}return e}function oe(c,t){for(const[e,s]of t){const n=c.archetypes.get(e);if(n===void 0)throw new Error(`restore_column_snapshots: new store missing archetype ${e} (internal)`);const r=n.columnsInOrder;for(let i=0;i<s.length;i++){const o=r[i].view;new Uint8Array(o.buffer,o.byteOffset,s[i].byteLength).set(s[i])}}}function Tt(c,t,e,s){const n=c.view.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),r=ie(c,e),i=ne(c),o=se(c),a=h.createColumnStore(t,s,o);oe(a,r),re(a,i);const l=n+1>>>0;return a.view.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,l,!0),{store:{...a,header:{...a.header,viewStamp:l}},oldViewStamp:n,newViewStamp:l}}function he(c,t,e){const s=new Array(t.length);for(let _=0;_<t.length;_++){const m=t[_],S=c.archetypes.get(m.archetypeId);s[_]={archetypeId:m.archetypeId,componentMask:S.componentMask,rowCapacity:m.newRowCapacity,columns:S.columnsInOrder}}const{descriptors:n,newTotal:r}=It(Ot(c),s),i=new Map;for(let _=0;_<n.length;_++)i.set(n[_].archetypeId,n[_]);const{grownBuffer:o,newView:a}=At(c,r),l=new Uint8Array(o);for(let _=0;_<t.length;_++){const m=t[_],S=c.archetypes.get(m.archetypeId),v=i.get(m.archetypeId);for(let C=0;C<S.columnsInOrder.length;C++){const R=S.columnsInOrder[C],w=m.rowCount*R.stride;w>0&&l.copyWithin(v.columns[C].byteOff,R.byteOff,R.byteOff+w)}}let u=e;for(const[_,m]of c.archetypes){const S=i.get(_);S!==void 0&&h.writeArchetypeDescriptor(a,u,S),u+=h.archetypeDescriptorBytes(m.columnsInOrder.length)}const d=a.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),f=d+1>>>0;a.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,f,!0),a.setUint32(h.STORE_HEADER_OFFSETS.capacity,r,!0);const p=h.buildArchetypeViews(o,[...i.values()]),y=new Map;for(const[_,m]of c.archetypes){const S=p.get(_);y.set(_,S??m)}const g={buffer:o,view:a,header:{...c.header,viewStamp:f,capacity:r},archetypes:y,_regionBytes:c._regionBytes,_allocator:c._allocator,_reservedDescriptorBytes:c._reservedDescriptorBytes},E=new Array(t.length);for(let _=0;_<t.length;_++)E[_]=t[_].archetypeId;return{store:g,oldViewStamp:d,newViewStamp:f,viewsPreserved:!0,grownArchetypeIds:E}}class Q extends Error{constructor(t){super(t),this.name="StoreGrowError"}}function ae(c,t,e){const s=new Map;for(let u=0;u<t.archetypes.length;u++){const d=t.archetypes[u];s.set(d.archetypeId,d)}const n=[],r=[];for(const[u,d]of c.archetypes){const f=s.get(u),p=f?.newRowCapacity??d.rowCapacity;if(p<(f?.rowCount??0))throw new Q(`archetype ${u}: new_row_capacity ${p} < row_count ${f?.rowCount}`);if(p<d.rowCapacity)throw new Q(`archetype ${u}: shrinking from ${d.rowCapacity} to ${p} is not supported`);p>d.rowCapacity&&r.push({archetypeId:u,newRowCapacity:p,rowCount:f?.rowCount??0}),n.push({archetypeId:u,componentMask:d.componentMask,rowCapacity:p,columns:d.columnsInOrder})}const i=new Map;for(const[u,d]of c.archetypes){const p=s.get(u)?.rowCount??0;if(p>d.rowCapacity)throw new Q(`archetype ${u}: row_count ${p} > old row_capacity ${d.rowCapacity}`);p>0&&i.set(u,p)}if(e?.isInPlace===!0&&h.isColumnStoreInternal(c)&&c._allocator===e&&r.length>0){const u=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);return he(c,r,u)}const{store:o,oldViewStamp:a,newViewStamp:l}=Tt(c,n,i,e);return{store:o,oldViewStamp:a,newViewStamp:l,viewsPreserved:!1,grownArchetypeIds:[]}}class L extends Error{constructor(t){super(t),this.name="StoreExtendError"}}function ce(c,t,e){if(t.newArchetypes.length===0)throw new L("extend plan has no new archetypes; use grow_column_store for resizes");const s=new Set;for(let l=0;l<t.newArchetypes.length;l++){const u=t.newArchetypes[l].archetypeId;if(s.has(u))throw new L(`duplicate archetype_id ${u} in extend plan`);if(c.archetypes.has(u))throw new L(`archetype_id ${u} already exists in the SAB; use grow_column_store to resize it`);s.add(u)}const n=new Map;if(t.existing)for(let l=0;l<t.existing.length;l++){const u=t.existing[l];if(!c.archetypes.has(u.archetypeId))throw new L(`existing row_count names unknown archetype_id ${u.archetypeId}`);if(u.rowCount<0)throw new L(`archetype ${u.archetypeId}: row_count must be non-negative (got ${u.rowCount})`);if(u.rowCount>0){const d=c.archetypes.get(u.archetypeId);if(u.rowCount>d.rowCapacity)throw new L(`archetype ${u.archetypeId}: row_count ${u.rowCount} > old row_capacity ${d.rowCapacity}`)}n.set(u.archetypeId,u.rowCount)}if(e?.isInPlace===!0&&h.isColumnStoreInternal(c)&&c._allocator===e){const l=c.view.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);let u=0;for(const[,f]of c.archetypes)u+=h.archetypeDescriptorBytes(f.columnsInOrder.length);let d=0;for(let f=0;f<t.newArchetypes.length;f++)d+=h.archetypeDescriptorBytes(t.newArchetypes[f].columns.length);if(u+d<=c._regionBytes)return le(c,t.newArchetypes,l,u)}const r=[];for(const[l,u]of c.archetypes)r.push({archetypeId:l,componentMask:u.componentMask,rowCapacity:u.rowCapacity,columns:u.columnsInOrder});for(let l=0;l<t.newArchetypes.length;l++)r.push(t.newArchetypes[l]);const{store:i,oldViewStamp:o,newViewStamp:a}=Tt(c,r,n,e);return{store:i,oldViewStamp:o,newViewStamp:a,viewsPreserved:!1}}function le(c,t,e,s){const n=new Array(t.length);for(let E=0;E<t.length;E++){const _=t[E];n[E]={archetypeId:_.archetypeId,componentMask:_.componentMask,rowCapacity:_.rowCapacity,columns:_.columns.map(m=>({componentId:m.componentId,fieldId:m.fieldId,typeTag:m.typeTag,stride:h.TYPE_TAG_STRIDE[m.typeTag]}))}}const{descriptors:r,newTotal:i}=It(Ot(c),n),{grownBuffer:o,newView:a}=At(c,i);let l=e+s;for(let E=0;E<r.length;E++)l=h.writeArchetypeDescriptor(a,l,r[E]);const u=a.getUint32(h.STORE_HEADER_OFFSETS.view_stamp,!0),d=c.archetypes.size+t.length;a.setUint32(h.STORE_HEADER_OFFSETS.archetype_count,d,!0),a.setUint32(h.STORE_HEADER_OFFSETS.capacity,i,!0);const f=u+1>>>0;a.setUint32(h.STORE_HEADER_OFFSETS.view_stamp,f,!0);const p=h.buildArchetypeViews(o,r),y=new Map;for(const[E,_]of c.archetypes)y.set(E,_);for(const[E,_]of p)y.set(E,_);return{store:{buffer:o,view:a,header:{...c.header,viewStamp:f,capacity:i,archetypeCount:d},archetypes:y,_regionBytes:c._regionBytes,_allocator:c._allocator,_reservedDescriptorBytes:c._reservedDescriptorBytes},oldViewStamp:u,newViewStamp:f,viewsPreserved:!0}}const rt=810766935,K=1;class b extends Error{constructor(t){super(t),this.name="ECSRestoreError"}}const P=4;function ue(c){const t=c.freeIndices.length,e=c.archetypeRows.length,s=P*(4+t+1+e*3),n=new Uint8Array(s),r=new DataView(n.buffer);let i=0;const o=a=>{r.setUint32(i,a,!0),i+=P};o(c.tick),o(c.entityHighWater),o(c.entityAliveCount),o(t);for(let a=0;a<t;a++)o(c.freeIndices[a]);o(e);for(let a=0;a<e;a++){const l=c.archetypeRows[a];o(l.archetypeId),o(l.length),o(l.enabledCount)}return n}function de(c){const t=new DataView(c.buffer,c.byteOffset,c.byteLength),e=c.byteLength;let s=0;const n=p=>{if(s+p>e)throw new b(`host-state truncated: need ${p} more bytes at offset ${s}, have ${e-s}`)},r=()=>{n(P);const p=t.getUint32(s,!0);return s+=P,p},i=r(),o=r(),a=r(),l=r(),u=new Array(l);for(let p=0;p<l;p++)u[p]=r();const d=r(),f=new Array(d);for(let p=0;p<d;p++){const y=r(),g=r(),E=r();f[p]={archetypeId:y,length:g,enabledCount:E}}if(s!==e)throw new b(`host-state has ${e-s} trailing bytes after the last archetype (not a canonical encoding)`);return{tick:i,entityHighWater:o,entityAliveCount:a,freeIndices:u,archetypeRows:f}}function fe(c,t,e){const s=P*5,n=new Uint8Array(s+c.length+t.length+e.length),r=new DataView(n.buffer);return r.setUint32(0,rt,!0),r.setUint32(4,K,!0),r.setUint32(8,c.length,!0),r.setUint32(12,t.length,!0),r.setUint32(16,e.length,!0),n.set(c,s),n.set(t,s+c.length),n.set(e,s+c.length+t.length),n}function pe(c){const t=P*5;if(c.byteLength<t)throw new b(`world snapshot too small: ${c.byteLength} bytes (frame header needs ${t})`);const e=new DataView(c.buffer,c.byteOffset,c.byteLength),s=e.getUint32(0,!0);if(s!==rt)throw new b(`bad world-snapshot magic: 0x${s.toString(16).padStart(8,"0")} (expected 0x${rt.toString(16).padStart(8,"0")}). A bare dense (SAB) snapshot is not a combined world snapshot — pass the bytes from ECS.snapshot(), not snapshotColumnStore().`);const n=e.getUint32(4,!0);if(n!==K)throw new b(`incompatible world-snapshot version: snapshot=${n}, build=${K}`);const r=e.getUint32(8,!0),i=e.getUint32(12,!0),o=e.getUint32(16,!0);if(t+r+i+o!==c.byteLength)throw new b(`world-snapshot frame mismatch: header declares ${t}+${r}+${i}+${o}=${t+r+i+o} bytes, buffer is ${c.byteLength}`);const a=c.byteOffset,l=c.buffer;return{dense:new Uint8Array(l,a+t,r),sparse:new Uint8Array(l,a+t+r,i),host:new Uint8Array(l,a+t+r+i,o)}}function _e(c,t,e){if(c.byteLength<h.STORE_HEADER_BYTES)throw new b(`dense section too small: ${c.byteLength} bytes (SAB header needs ${h.STORE_HEADER_BYTES})`);const s=new DataView(c.buffer,c.byteOffset,c.byteLength),n=s.getUint32(h.STORE_HEADER_OFFSETS.magic,!0);if(n!==h.STORE_MAGIC)throw new b(`dense section bad magic: 0x${n.toString(16).padStart(8,"0")} (expected SAB magic 0x${h.STORE_MAGIC.toString(16).padStart(8,"0")})`);const r=s.getUint32(h.STORE_HEADER_OFFSETS.sim_abi_version,!0);if(r!==h.SIM_ABI_VERSION)throw new b(`dense section incompatible sim_abi_version: snapshot=${r}, build=${h.SIM_ABI_VERSION}`);const i=h.readStoreHeader(s);if(i.layoutDescriptorOff<0||i.layoutDescriptorOff>c.byteLength)throw new b(`dense layoutDescriptorOff ${i.layoutDescriptorOff} is outside the section (${c.byteLength} bytes)`);const o=i.entityIndexOff;if(o<0||o+h.ENTITY_INDEX_HEADER_BYTES>c.byteLength)throw new b(`dense entityIndexOff ${o} is outside the section (${c.byteLength} bytes)`);const a=s.getUint32(o+h.ENTITY_INDEX_HEADER_OFFSETS.capacity,!0);if(a!==e)throw new b(`entity-index capacity mismatch: live=${e}, snapshot=${a}`);let l;try{l=h.readLayoutDescriptorRegion(s,i.layoutDescriptorOff,i.archetypeCount)}catch(u){throw u instanceof RangeError?new b(`dense section layout is corrupt or truncated: a descriptor reads past the ${c.byteLength}-byte section (${u.message})`):u}if(t.size!==l.length)throw new b(`archetype-set mismatch: the live world has ${t.size} SAB archetypes, the snapshot has ${l.length}. restoreInto requires an identical archetype set (prewarm the world so its archetype set is stable, per ADR on no-lazy archetypes).`);for(let u=0;u<l.length;u++){const d=l[u],f=t.get(d.archetypeId);if(f===void 0)throw new b(`archetype-set mismatch: snapshot archetype ${d.archetypeId} is absent from the live world`);if(!ge(f.componentMask,d.componentMask))throw new b(`archetype ${d.archetypeId} component-mask mismatch between the live world and the snapshot (different component registration)`);const p=f.columnsInOrder,y=d.columns;if(p.length!==y.length)throw new b(`archetype ${d.archetypeId} column-count mismatch: live=${p.length}, snapshot=${y.length}`);for(let g=0;g<p.length;g++)if(p[g].componentId!==y[g].componentId||p[g].fieldId!==y[g].fieldId||p[g].typeTag!==y[g].typeTag)throw new b(`archetype ${d.archetypeId} column ${g} layout mismatch: live=(c${p[g].componentId},f${p[g].fieldId},t${p[g].typeTag}), snapshot=(c${y[g].componentId},f${y[g].fieldId},t${y[g].typeTag})`)}}function ge(c,t){if(c.length!==t.length)return!1;for(let e=0;e<c.length;e++)if(c[e]!==t[e])return!1;return!0}class ye{host;allocator;constructor(t,e){this.host=t,this.allocator=e}snapshotSparse(){const t=h.snapshotSparseStores(this.host.sparseStores()),e=h.snapshotRelations(this.host.relationStores()),s=new Uint8Array(8+t.length+e.length),n=new DataView(s.buffer);return n.setUint32(0,t.length,!0),n.setUint32(4,e.length,!0),s.set(t,8),s.set(e,8+t.length),s}restoreSparse(t){const e=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<8)throw new h.SparseRestoreError(`sparse snapshot truncated: need 8 header bytes, have ${t.byteLength}`);const s=e.getUint32(0,!0),n=e.getUint32(4,!0);if(8+s+n!==t.byteLength)throw new h.SparseRestoreError(`sparse snapshot frame mismatch: header declares 8+${s}+${n}=${8+s+n} bytes, buffer is ${t.byteLength}`);h.restoreSparseStores(this.host.sparseStores(),t.subarray(8,8+s)),this.rebuildRelationIndices(t.subarray(8+s,8+s+n))}rebuildRelationIndices(t){const e=this.host.generations(),s=r=>h.createEntityId(r,e[r]),n=this.host.relationStores();h.restoreRelations(n,t,s);for(let r=0;r<n.length;r++)n[r].rebuildReverseFromForward(s)}snapshot(){this.host.publishRowCounts();const t=new Uint8Array(Bt(this.host.columnStore())),e=this.snapshotSparse(),s=ue(this.collectHostState());return fe(t,e,s)}collectHostState(){const t=[],e=this.host.archetypes();for(let s=0;s<e.length;s++){const n=e[s];n.isBufferBacked&&t.push({archetypeId:n.id,length:n.length,enabledCount:n.enabledCount})}return{tick:this.host.tick(),entityHighWater:this.allocator.highWater,entityAliveCount:this.allocator.aliveCount,freeIndices:this.allocator.snapshotFreeIndices(),archetypeRows:t}}restoreInto(t){const e=pe(t),s=de(e.host);_e(e.dense,this.host.columnStore().archetypes,this.host.entityIndexCapacity()),this.assertSparseSectionMatches(e.sparse);const n=Gt(e.dense,this.host.bufferAllocator());this.host.mountRestoredDense(n),this.host.reconstructHostRows(s),this.allocator.restoreHostState(s.freeIndices,s.entityAliveCount),this.host.setTick(s.tick),this.host.invalidateQueryCaches(),this.restoreSparse(e.sparse)}assertSparseSectionMatches(t){const e=new DataView(t.buffer,t.byteOffset,t.byteLength);if(t.byteLength<8)throw new h.SparseRestoreError(`sparse snapshot truncated: need 8 header bytes, have ${t.byteLength}`);const s=e.getUint32(0,!0),n=e.getUint32(4,!0);if(8+s+n!==t.byteLength)throw new h.SparseRestoreError(`sparse snapshot frame mismatch: header declares 8+${s}+${n}=${8+s+n} bytes, buffer is ${t.byteLength}`);h.validateSparseStores(this.host.sparseStores(),t.subarray(8,8+s))}}function Dt(c,t,e){const s=c.get(t);s!==void 0?s.push(e):c.set(t,[e])}class Ee{archetypes=[];componentIndex=[];archetypeMap=new Map;nextArchetypeId=0;host;constructor(t){this.host=t}get(t){return this.archetypes[t]}getOrCreateFromMask(t){const e=t.hash(),s=this.lookup(t,e);if(s!==null)return s;const n=ut(this.nextArchetypeId++),r=this.buildLayouts(t);return this.host.extendStore([_t(n,t,r,this.host.initialCapacity())]),this.install(n,t,r,e),n}createManyFromMasks(t){const e=new Array(t.length),s=[],n=[],r=[],i=[];for(let a=0;a<t.length;a++){const l=t[a],u=l.hash(),d=this.lookup(l,u);if(d!==null){e[a]=d;continue}let f=!1;for(let y=0;y<s.length;y++)if(n[y]===u&&s[y].equals(l)){e[a]=i[y],f=!0;break}if(f)continue;const p=ut(this.nextArchetypeId++);s.push(l),n.push(u),r.push(this.buildLayouts(l)),i.push(p),e[a]=p}if(s.length===0)return e;const o=new Array(s.length);for(let a=0;a<s.length;a++)o[a]=_t(i[a],s[a],r[a],this.host.initialCapacity());this.host.extendStore(o);for(let a=0;a<s.length;a++)this.install(i[a],s[a],r[a],n[a]);return e}lookup(t,e){const s=this.archetypeMap.get(e);if(s===void 0)return null;for(let n=0;n<s.length;n++)if(this.archetypes[s[n]].mask.equals(t))return s[n];return null}buildLayouts(t){const e=[],s=this.host.componentMetas();return t.forEach(n=>{const r=n,i=s[r];i&&i.fieldNames.length>0&&e.push({componentId:r,fieldNames:i.fieldNames,fieldIndex:i.fieldIndex,fieldTypes:i.fieldTypes})}),e}install(t,e,s,n){const r=e.copy(),i=this.host.materialize(t,r,s);this.archetypes.push(i),Dt(this.archetypeMap,n,t),e.forEach(o=>{const a=o;let l=this.componentIndex[a];l===void 0&&(l=[],this.componentIndex[a]=l),l.push(t)}),this.host.fanIntoQueries(i)}resolveAdd(t,e){const s=this.get(t);if(s.mask.has(e))return t;const n=s.getEdge(e);if(n?.add!=null)return n.add;const r=this.getOrCreateFromMask(s.mask.copyWithSet(e));return this.cacheEdge(s,this.get(r),e),r}resolveRemove(t,e){const s=this.get(t);if(!s.mask.has(e))return t;const n=s.getEdge(e);if(n?.remove!=null)return n.remove;const r=this.getOrCreateFromMask(s.mask.copyWithClear(e));return this.cacheEdge(this.get(r),s,e),r}cacheEdge(t,e,s){const n=t.getEdge(s)??{add:null,remove:null,addMap:null,removeMap:null};n.add=e.id,n.addMap=st(t,e),t.setEdge(s,n);const r=e.getEdge(s)??{add:null,remove:null,addMap:null,removeMap:null};r.remove=t.id,r.removeMap=st(e,t),e.setEdge(s,r)}}function _t(c,t,e,s){const n=[];for(let o=0;o<e.length;o++){const a=e[o],l=a.fieldTypes;for(let u=0;u<l.length;u++)n.push({componentId:a.componentId,fieldId:u,typeTag:h.TYPED_ARRAY_TAG_TO_TYPE_TAG[l[u]]})}const r=t._words,i=new Array(h.COMPONENT_MASK_WORDS);for(let o=0;o<h.COMPONENT_MASK_WORDS;o++)i[o]=(r[o]??0)>>>0;return{archetypeId:c,componentMask:i,rowCapacity:s,columns:n}}const me=[],gt=-1,Z=new DataView(new ArrayBuffer(8)),yt=129,we=7,J=-1;class Se{entityAllocator;componentMetas=[];componentCount=0;sparseStores=[];sparseNames=[];relationService;events=new Vt;archGraph;registeredQueries=[];emptyArchetypeId;entityArchetype;entityRow;_deferred;_snapshots;_tick=0;_trace=null;_structuralObserverCount=0;_toggleObserverCount=0;_obsEvents={addComp:[],addEid:[],addLen:0,remComp:[],remEid:[],remLen:0,disComp:[],disEid:[],disLen:0,enaComp:[],enaEid:[],enaLen:0};_structuralObserverHook=null;setStructuralObserverHook(t){this._structuralObserverHook=t}_collectDestroyEid=0;_collectDestroyRemoveBit=t=>{if(!this.componentMetas[t].obsRem)return;const e=this._obsEvents;e.remComp[e.remLen]=t,e.remEid[e.remLen]=this._collectDestroyEid,e.remLen++};_collectToggleEid=0;_collectDisableBit=t=>{if(!this.componentMetas[t].obsDisable)return;const e=this._obsEvents;e.disComp[e.disLen]=t,e.disEid[e.disLen]=this._collectToggleEid,e.disLen++};_collectEnableBit=t=>{if(!this.componentMetas[t].obsEnable)return;const e=this._obsEvents;e.enaComp[e.enaLen]=t,e.enaEid[e.enaLen]=this._collectToggleEid,e.enaLen++};_toggleInitial=new Map;_anyDirtyTracked=!1;_dirtyTrackedCids=[];_dirtyLists=[];_dirtyMarks=[];_rowCountsDirty=!1;_queryDirtyEpoch=0;initialCapacity;_scratchTargetMask=new T.BitSet;_columnStore;_growHandler=(t,e)=>{const s=t.id,n=this._columnStore.archetypes.get(s);if(n===void 0)throw new h.ECSError(h.ECS_ERROR.ARCHETYPE_NOT_FOUND,`grow_handler invoked on archetype ${s} which has no SAB region`);const r=n.rowCapacity,i=t.length+e;let o=r>0?r:1;for(;o<i;)o=o*2;const a=[],l=this.archGraph.archetypes;for(let d=0;d<l.length;d++){const f=l[d],p=this._columnStore.archetypes.get(f.id);p!==void 0&&a.push({archetypeId:f.id,newRowCapacity:f.id===s?o:p.rowCapacity,rowCount:f.hasColumns?f.length:0})}let u;try{u=ae(this._columnStore,{archetypes:a},this._bufferAllocator)}catch(d){throw d instanceof V.StoreCapExceededError?this._capExceededError(d):d}if(this._columnStore=u.store,u.viewsPreserved){const d=u.grownArchetypeIds;for(let f=0;f<d.length;f++){const p=this.archGet(d[f]);p.isBufferBacked&&p.refreshViews(this._columnStore)}}else for(let d=0;d<l.length;d++)l[d].isBufferBacked&&l[d].refreshViews(this._columnStore);this._handleBufferResized()};_capExceededError(t){const e=this._capContext,s=this.entityAllocator.aliveCount,n=`SAB grow refused: requested ${t.requestedBytes} bytes exceeds `+(t.capBytes!==null?`the ${t.capBytes}-byte cap.`:"the backing's ceiling.");let r;if(e===void 0)r=` The ECS holds ${s} live entities (no sizing intent declared).`;else if(e.budgetEntities!==null){const i=(s/e.budgetEntities).toFixed(1);r=` Declared ${e.intentLabel}; the ECS holds ${s} live entities (${i}× the budget) — runaway entity creation upstream, or an under-declared budget. Raise the budget only if a ${s}-entity ECS is intended.`}else r=` Declared ${e.intentLabel}; the ECS holds ${s} live entities.`;return new h.ECSError(h.ECS_ERROR.STORE_CAP_EXCEEDED,n+r+` The cap is a hard ceiling with no grow-beyond fallback (#380) — diagnose growth before raising it. Caused by: ${t.message}`)}_bufferAllocator;_capContext;_onBufferResized;constructor(t){const e=typeof t=="number"?{initialCapacity:t}:t??{};if(this.initialCapacity=e.initialCapacity??h.DEFAULT_COLUMN_CAPACITY,this._bufferAllocator=e.bufferAllocator??V.growableSabAllocator(),this._bufferAllocator.isInPlace!==!0)throw new h.ECSError(h.ECS_ERROR.INVALID_MEMORY_OPTIONS,"Store requires an in-place SAB allocator (ADR-0008): the flush loops keep writing through hoisted entity-index views across grows, so a non-in-place allocator (e.g. DEFAULT_SAB_ALLOCATOR) corrupts the entity→row mapping. Use growable_sab_allocator / wasm_memory_allocator; non-in-place allocators are snapshot/test sizing utilities only.");this._capContext=e.capContext,this._onBufferResized=e.onBufferResized,this._entityIndexCapacity=e.entityIndexCapacity??h.ENTITY_INDEX_DEFAULT_CAPACITY,this._regions=e.regions,this._bindingsRegionBytes=e.bindingsRegionBytes??0,this._deterministic=e.deterministic??!1,this._deferred=new ee({applyAdds:()=>this._flushAdds(),applyRemoves:()=>this._flushRemoves(),applyDestroys:()=>this._drainDestroyed(),applyToggles:()=>this._flushToggles(),structuralObserverCount:()=>this._structuralObserverCount,toggleObserverCount:()=>this._toggleObserverCount,structuralObserverHook:()=>this._structuralObserverHook},this._obsEvents),this.relationService=new Jt({isAlive:n=>this.isAlive(n),hasSparse:(n,r)=>this.hasSparse(n,r),pushSparseStore:(n,r)=>this._pushSparseStore(n,r),sparseStoreOf:n=>this.sparseStoreOf(n),sparseStores:()=>this.sparseStores,entityGenerations:()=>this.entityAllocator.generations,entityArchetype:()=>this.entityArchetype,entityRow:()=>this.entityRow,archetypes:()=>this.archGraph.archetypes,forEachSparseMatch:(n,r,i,o,a,l,u,d)=>this._forEachSparseMatch(n,r,i,o,a,l,u,d)}),this._columnStore=h.createColumnStore([],this._bufferAllocator,{reservedDescriptorBytes:64*1024,entityIndexCapacity:this._entityIndexCapacity,eventRingCapacitySlots:h.EVENT_RING_DEFAULT_CAPACITY_SLOTS,commandRingCapacitySlots:h.COMMAND_RING_DEFAULT_CAPACITY_SLOTS,actionRingCapacitySlots:h.ACTION_RING_DEFAULT_CAPACITY_SLOTS,regions:this._regions,bindingsRegionBytes:this._bindingsRegionBytes});const s=h.buildEntityIndexViews(this._columnStore.buffer,this._columnStore.header.entityIndexOff,this._entityIndexCapacity);this.entityArchetype=s.archetypes,this.entityRow=s.rows,this.entityAllocator=new te(this._entityIndexCapacity,s.generations,new Uint32Array(this._columnStore.buffer,this._columnStore.header.entityIndexOff+h.ENTITY_INDEX_HEADER_OFFSETS.length,1)),this._snapshots=new ye({sparseStores:()=>this.sparseStores,relationStores:()=>this.relationService.stores,generations:()=>this.entityAllocator.generations,archetypes:()=>this.archGraph.archetypes,columnStore:()=>this._columnStore,bufferAllocator:()=>this._bufferAllocator,entityIndexCapacity:()=>this._entityIndexCapacity,tick:()=>this._tick,setTick:n=>{this._tick=n},publishRowCounts:()=>this.publishRowCountsToDescriptor(),mountRestoredDense:n=>this._mountRestoredDense(n),reconstructHostRows:n=>this._reconstructHostRows(n),invalidateQueryCaches:()=>{this._queryDirtyEpoch++,this._rowCountsDirty=!0}},this.entityAllocator),this.archGraph=new Ee({componentMetas:()=>this.componentMetas,initialCapacity:()=>this.initialCapacity,extendStore:n=>this._archExtendStoreWithNewSpecs(n),materialize:(n,r,i)=>this._materializeArchetype(n,r,i),fanIntoQueries:n=>this._fanIntoQueries(n)}),this.emptyArchetypeId=this.archGetOrCreateFromMask(new T.BitSet)}_entityIndexCapacity;_regions;_bindingsRegionBytes;_deterministic;get deterministic(){return this._deterministic}_requireDeterministic(t){if(!this._deterministic)throw new h.ECSError(h.ECS_ERROR.DETERMINISM_DISABLED,`${t} requires determinism — construct the Store/ECS with { deterministic: true }. The canonical-ordering determinism surface (state_hash / snapshot_sparse / restore_sparse) is opt-in; see ADR-0020.`)}_rejectNonDeterministicFields(t,e,s){if(this._deterministic)for(let n=0;n<e.length;n++){const r=e[n];if(r==="f32"||r==="f64")throw new h.ECSError(h.ECS_ERROR.NON_DETERMINISTIC_COLUMN_TYPE,`Cannot register ${s} field "${t[n]}" as "${r}" on a { deterministic: true } world: floating-point columns round differently across V8 / Bun / Zig (1-ULP IEEE-754), breaking cross-host state_hash agreement (ADR-0020). Use an integer type (e.g. "i32") — represent fractional quantities as fixed-point (Q16.16). Note the array shorthand defaults to "f64", so pass an explicit integer type there.`,{field:t[n],type:r,kind:s})}}_refreshEntityIndexViews(){const t=this._columnStore.view.getUint32(h.STORE_HEADER_OFFSETS.entity_index_off,!0),e=h.buildEntityIndexViews(this._columnStore.buffer,t,this._entityIndexCapacity);this.entityArchetype=e.archetypes,this.entityRow=e.rows,this.entityAllocator.replantViews(e.generations,new Uint32Array(this._columnStore.buffer,t+h.ENTITY_INDEX_HEADER_OFFSETS.length,1))}_handleBufferResized(){this._refreshEntityIndexViews(),this.entityAllocator.publishLength(),this._onBufferResized?.()}get columnStore(){return this._columnStore}regionOffset(t){return h.findRegionOffset(this._columnStore.view,t)}regionHandle(t){const e=h.findRegionEntry(this._columnStore.view,t);return e===null?null:{buffer:this._columnStore.buffer,view:this._columnStore.view,offset:e.byteOffset,bytes:e.byteLength}}publishRowCountsToDescriptor(){if(!this._rowCountsDirty)return;const t=this._columnStore.view;let e=t.getUint32(h.STORE_HEADER_OFFSETS.layout_descriptor_off,!0);const s=this.archGraph.archetypes;for(let n=0;n<s.length;n++){const r=s[n];if(!r.isBufferBacked)continue;const i=t.getUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.column_count,!0);t.setUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.row_count,r.hasColumns?r.length:0,!0),t.setUint32(e+h.ARCHETYPE_DESCRIPTOR_OFFSETS.enabled_count,r.hasColumns?r.enabledCount:0,!0),e+=h.ARCHETYPE_DESCRIPTOR_HEADER_BYTES+i*h.COLUMN_DESCRIPTOR_BYTES}this._rowCountsDirty=!1}stateHash(){this._requireDeterministic("state_hash()");let t=h.FNV1A_OFFSET_BASIS;const e=this.archGraph.archetypes;for(let r=0;r<e.length;r++){const i=e[r],o=i.id,a=i.length;if(t=h.fnv1aStepWord(t,o),t=h.fnv1aStepWord(t,a),t=h.fnv1aStepWord(t,i.enabledCount),a===0)continue;const l=i._flatColumns;for(let u=0;u<l.length;u++){const d=l[u].buf,f=a*d.BYTES_PER_ELEMENT,p=new Uint8Array(d.buffer,d.byteOffset,f),y=f>>>2;let g=0;for(let _=0;_<y;_++){const m=(p[g]|p[g+1]<<8|p[g+2]<<16|p[g+3]<<24)>>>0;t=(t^m)>>>0,t=Math.imul(t,h.FNV1A_PRIME),g+=4}const E=f&3;if(E!==0){let _=p[g];E>1&&(_|=p[g+1]<<8),E>2&&(_|=p[g+2]<<16),t=(t^_>>>0)>>>0,t=Math.imul(t,h.FNV1A_PRIME)}}}const s=this.sparseStores;for(let r=0;r<s.length;r++){const i=s[r];t=h.fnv1aStepWord(t,r),t=h.fnv1aStepWord(t,i.size);const o=i.canonicalIndices();for(let a=0;a<o.length;a++){const l=o[a];t=h.fnv1aStepWord(t,l);const u=i.getRow(l);for(let d=0;d<u.length;d++)Z.setFloat64(0,u[d],!0),t=h.fnv1aStepWord(t,Z.getUint32(0,!0)),t=h.fnv1aStepWord(t,Z.getUint32(4,!0))}}const n=this.relationService.stores;for(let r=0;r<n.length;r++){const i=n[r];i.exclusive||(t=h.fnv1aStepWord(t,r),i.forEachCanonicalTargetSet((o,a)=>{t=h.fnv1aStepWord(t,o),t=h.fnv1aStepWord(t,a.length);for(let l=0;l<a.length;l++)t=h.fnv1aStepWord(t,a[l])}))}return t>>>0}archGet(t){return this.archGraph.get(t)}entityIdAtRow(t,e){return this.archGet(t).entityIds[e]}archGetOrCreateFromMask(t){return this.archGraph.getOrCreateFromMask(t)}archCreateManyFromMasks(t){return this.archGraph.createManyFromMasks(t)}_archExtendStoreWithNewSpecs(t){const e=[],s=this.archGraph.archetypes;for(let r=0;r<s.length;r++){const i=s[r],o=this._columnStore.archetypes.get(i.id);o!==void 0&&e.push({archetypeId:i.id,newRowCapacity:o.rowCapacity,rowCount:i.hasColumns?i.length:0})}let n;try{n=ce(this._columnStore,{newArchetypes:t,existing:e},this._bufferAllocator)}catch(r){throw r instanceof V.StoreCapExceededError?this._capExceededError(r):r}if(this._columnStore=n.store,!n.viewsPreserved)for(let r=0;r<s.length;r++)s[r].isBufferBacked&&s[r].refreshViews(this._columnStore);this._handleBufferResized()}_materializeArchetype(t,e,s){const n=at.fromColumnStore(t,e,s,this._columnStore,t);return n.growHandler=this._growHandler,n}_fanIntoQueries(t){const e=this.registeredQueries;for(let s=0;s<e.length;s++){const n=e[s];t.matches(n.includeMask)&&(!n.excludeMask||!t.mask.overlaps(n.excludeMask))&&(!n.anyOfMask||t.mask.overlaps(n.anyOfMask))&&n.result.push(t)}}archResolveAdd(t,e){return this.archGraph.resolveAdd(t,e)}archResolveRemove(t,e){return this.archGraph.resolveRemove(t,e)}createEntity(){const t=this.entityAllocator.alloc(),e=this.entityAllocator.lastIndex;return this.entityArchetype[e]=this.emptyArchetypeId,this.entityRow[e]=h.UNASSIGNED,t}_allocEntity(){return this.entityAllocator.alloc()}_ensureEntityIndexCapacity(t){this.entityAllocator.ensureCapacity(t)}resolveTemplate(t){const e=new T.BitSet;for(let a=0;a<t.length;a++)e.set(t[a].def.id);const s=this.archGetOrCreateFromMask(e),n=this.archGet(s),r=new Array(n._flatColumns.length).fill(0),i=new Map,o=new Array(t.length);for(let a=0;a<t.length;a++){o[a]=t[a].def;const l=t[a].def.id,u=this.componentMetas[l];if(u===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`template: component ${l} is not registered`);const d=t[a].values??h.EMPTY_VALUES,f=n._colOffset[l];for(let p=0;p<u.fieldNames.length;p++){const y=u.fieldNames[p];r[f+p]=d[y]??0,i.set(y,i.has(y)?gt:f+p)}}return{archetypeId:s,flatValues:r,overrideIndex:i,defs:o}}_resolveOverrideColumn(t,e){const s=t.overrideIndex.get(e);return s===void 0||s===gt?-1:s}_applyOverrides(t,e,s,n){const r=t._flatColumns;for(const i in n){if(n[i]===void 0)continue;const o=this._resolveOverrideColumn(s,i);o>=0&&(r[o].buf[e]=n[i])}}_applyOverridesRange(t,e,s,n,r){const i=t._flatColumns;for(const o in r){if(r[o]===void 0)continue;const a=this._resolveOverrideColumn(n,o);a>=0&&i[a].buf.fill(r[o],e,e+s)}}spawn(t,e){const s=this.archGraph.archetypes[t.archetypeId];s.materializesRows&&s.ensureRowCapacity(1);const n=this._allocEntity(),r=this.entityAllocator.lastIndex;if(!s.materializesRows)return this.entityArchetype[r]=t.archetypeId,this.entityRow[r]=h.UNASSIGNED,n;const i=s.length,o=s.enabledCount,a=s.addEntityWithValues(n,t.flatValues,this._tick,this.entityRow);return e!==void 0&&this._applyOverrides(s,a,t,e),this.entityArchetype[r]=t.archetypeId,this.entityRow[r]=a,this._onArchGrow(s,i,o),n}spawnMany(t,e,s){if(e<=0)return[];const n=this.archGraph.archetypes[t.archetypeId];this._ensureEntityIndexCapacity(e),n.ensureRowCapacity(e);const r=new Array(e),i=new Uint32Array(e);for(let f=0;f<e;f++){const p=this._allocEntity();i[f]=p,r[f]=p}const o=this.entityArchetype,a=this.entityRow;if(!n.materializesRows){for(let f=0;f<e;f++){const p=h.getEntityIndex(r[f]);o[p]=t.archetypeId,a[p]=h.UNASSIGNED}return r}const l=n.length,u=n.enabledCount;if(n.disabledCount>0){for(let f=0;f<e;f++){const p=n.addEntityWithValues(r[f],t.flatValues,this._tick,a),y=h.getEntityIndex(r[f]);o[y]=t.archetypeId,a[y]=p,s!==void 0&&this._applyOverrides(n,p,t,s)}return this._onArchGrow(n,l,u),r}const d=n.addEntitiesWithValues(i,e,t.flatValues,this._tick);for(let f=0;f<e;f++){const p=h.getEntityIndex(r[f]);o[p]=t.archetypeId,a[p]=d+f}return s!==void 0&&this._applyOverridesRange(n,d,e,t,s),this._onArchGrow(n,l,u),r}destroyEntity(t){if(!this.isAlive(t))return;if(!this.relationService.hasTargetCleanup){this._destroyOne(t,null);return}const e=[t];for(let s=0;s<e.length;s++){const n=e[s];this.isAlive(n)&&this._destroyOne(n,e)}}_destroyOne(t,e){const s=h.getEntityIndex(t),n=this.entityRow[s];if(n!==h.UNASSIGNED){const r=this.archGet(this.entityArchetype[s]),i=r.length;r.removeRow(n,this.entityRow),this._onArchLenChange(r,i)}this.entityArchetype[s]=h.UNASSIGNED,this.entityRow[s]=h.UNASSIGNED,this.relationService.count>0&&(this.relationService.purgeSource(t),e!==null&&this.relationService.cleanupTarget(t,e)),this.sparseStores.length>0&&this._purgeSparse(s),this._anyDirtyTracked&&this._clearDirtyForIndex(s),this.entityAllocator.recycle(s,h.getEntityGeneration(t))}isAlive(t){if(t<0||t>h.MAX_ENTITY_ID)return!1;const e=h.getEntityGeneration(t);if(e===h.RETIRED_GENERATION)return!1;const s=h.getEntityIndex(t);return this.entityAllocator.isAliveIndex(s,e)}get entityCount(){return this.entityAllocator.aliveCount}_onArchLenChange(t,e){this._rowCountsDirty=!0,e===0!=(t.length===0)&&this._queryDirtyEpoch++}_onArchGrow(t,e,s){this._rowCountsDirty=!0,(e===0||s===0&&t.enabledCount!==0)&&this._queryDirtyEpoch++}_onArchEnabledChange(t,e){this._rowCountsDirty=!0,e===0!=(t.enabledCount===0)&&this._queryDirtyEpoch++}disableEntity(t){if(!this.isAlive(t))return;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[e]);if(s>=n.enabledCount)return;const r=n.enabledCount;n.disableRow(s,this.entityRow),this._onArchEnabledChange(n,r)}enableEntity(t){if(!this.isAlive(t))return;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[e]);if(s<n.enabledCount)return;const r=n.enabledCount;n.enableRow(s,this.entityRow),this._onArchEnabledChange(n,r)}isDisabled(t){if(!this.isAlive(t))return!1;const e=h.getEntityIndex(t),s=this.entityRow[e];if(s===h.UNASSIGNED)return!1;const n=this.archGet(this.entityArchetype[e]);return s>=n.enabledCount}_flushEpoch=0;_flushTouched=[];_settleFlushDirty(){const t=this._flushTouched;if(t.length===0)return;this._rowCountsDirty=!0;let e=!1;for(let s=0;s<t.length;s++){const n=t[s];(n._flushPreLen===0!=(n.length===0)||n._flushPreEnabled===0!=(n.enabledCount===0))&&(e=!0)}e&&this._queryDirtyEpoch++,t.length=0,this._flushEpoch++}destroyEntityDeferred(t){this._deferred.queueDestroy(t)}disableEntityDeferred(t){this._deferred.queueToggle(t,!0)}enableEntityDeferred(t){this._deferred.queueToggle(t,!1)}_flushToggles(){const t=this._deferred.toggleIds,e=this._deferred.toggleDisable,s=t.length;if(!(this._toggleObserverCount>0)){for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(e[i]?this.disableEntity(o):this.enableEntity(o))}t.length=0,e.length=0;return}const r=this._toggleInitial;for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(r.has(o)||r.set(o,this.isDisabled(o)))}for(let i=0;i<s;i++){const o=t[i];this.isAlive(o)&&(e[i]?this.disableEntity(o):this.enableEntity(o))}t.length=0,e.length=0;for(const[i,o]of r){if(!this.isAlive(i))continue;const a=this.isDisabled(i);o!==a&&this._collectToggle(i,a)}r.clear()}_collectToggle(t,e){const s=h.getEntityIndex(t);if(this.entityRow[s]===h.UNASSIGNED)return;const n=this.archGet(this.entityArchetype[s]);this._collectToggleEid=t,n.mask.forEach(e?this._collectDisableBit:this._collectEnableBit)}get pendingToggleCount(){return this._deferred.toggleCount}flushDestroyed(){this._deferred.flushDestroyed()}_drainDestroyed(){const t=this._deferred.destroyIds;if(t.length===0)return;const e=this.entityAllocator,s=this.entityArchetype,n=this.entityRow,r=e.generations,i=this.archGraph.archetypes,o=e.highWater;let a=!1,l=!1;const u=this.sparseStores.length>0,d=this.relationService.count>0,f=d&&this.relationService.hasTargetCleanup,p=this._anyDirtyTracked,y=this._structuralObserverCount>0;for(let g=0;g<t.length;g++){const E=t[g],_=E&h.INDEX_MASK,m=E>>h.INDEX_BITS;if(_>=o||r[_]!==m)continue;const S=n[_];if(S!==h.UNASSIGNED){const v=i[s[_]];y&&(this._collectDestroyEid=E,v.mask.forEach(this._collectDestroyRemoveBit)),v.removeRow(S,n),a=!0,v.length===0&&(l=!0)}d&&this.relationService.purgeSource(E),f&&this.relationService.cleanupTarget(E,t),u&&this._purgeSparse(_),p&&this._clearDirtyForIndex(_),s[_]=h.UNASSIGNED,n[_]=h.UNASSIGNED,e.recycle(_,m)}t.length=0,a&&(this._rowCountsDirty=!0,l&&this._queryDirtyEpoch++)}get pendingDestroyCount(){return this._deferred.destroyCount}addComponentDeferred(t,e,s){this._deferred.queueAdd(t,e,s??h.EMPTY_VALUES)}removeComponentDeferred(t,e){this._deferred.queueRemove(t,e)}flushStructural(){this._deferred.flushStructural()}_flushAdds(){const t=this._deferred.addIds,e=this._deferred.addDefs,s=this._deferred.addValues,n=t.length,r=this.entityArchetype,i=this.entityRow,o=this.entityAllocator.generations,a=this.archGraph.archetypes,l=this.componentMetas,u=this.entityAllocator.highWater,d=this._tick,f=this._flushEpoch,p=this._flushTouched,y=this._structuralObserverCount>0,g=this._obsEvents;for(let E=0;E<n;E++){const _=t[E],m=_&h.INDEX_MASK,S=_>>h.INDEX_BITS;if(m>=u||o[m]!==S)continue;const v=r[m],C=e[E].id,R=a[v],w=l[C];if(R.mask.has(C)){w.fieldNames.length>0&&R.writeFields(i[m],C,s[E],d);continue}const k=this.archResolveAdd(v,C),I=a[k],F=i[m],lt=!I.hasColumns&&!R.hasColumns;F!==h.UNASSIGNED&&R._flushSeenEpoch!==f&&(R._flushSeenEpoch=f,R._flushPreLen=R.length,R._flushPreEnabled=R.enabledCount,p.push(R)),I._flushSeenEpoch!==f&&(I._flushSeenEpoch=f,I._flushPreLen=I.length,I._flushPreEnabled=I.enabledCount,p.push(I));let W;if(F!==h.UNASSIGNED){if(lt)I.moveEntityFromTag(R,F,_,i);else{const Ft=R.getEdge(C);I.moveEntityFrom(R,F,_,Ft.addMap,d,i)}W=A[0]}else W=lt?I.addEntityTag(_,i):I.addEntity(_,i);w.fieldNames.length>0&&I.writeFields(W,C,s[E],d),r[m]=k,i[m]=W,y&&w.obsAdd&&(g.addComp[g.addLen]=C,g.addEid[g.addLen]=_,g.addLen++)}t.length=0,e.length=0,s.length=0,this._settleFlushDirty()}_flushRemoves(){const t=this._deferred.removeIds,e=this._deferred.removeDefs,s=t.length,n=this.entityArchetype,r=this.entityRow,i=this.entityAllocator.generations,o=this.archGraph.archetypes,a=this.entityAllocator.highWater,l=this._tick,u=this._flushEpoch,d=this._flushTouched,f=this.componentMetas,p=this._structuralObserverCount>0,y=this._obsEvents;for(let g=0;g<s;g++){const E=t[g],_=E&h.INDEX_MASK,m=E>>h.INDEX_BITS;if(_>=a||i[_]!==m)continue;const S=n[_],v=e[g].id,C=o[S];if(!C.mask.has(v))continue;const R=this.archResolveRemove(S,v),w=o[R],k=r[_],I=!w.hasColumns&&!C.hasColumns;if(C._flushSeenEpoch!==u&&(C._flushSeenEpoch=u,C._flushPreLen=C.length,C._flushPreEnabled=C.enabledCount,d.push(C)),w._flushSeenEpoch!==u&&(w._flushSeenEpoch=u,w._flushPreLen=w.length,w._flushPreEnabled=w.enabledCount,d.push(w)),I)w.moveEntityFromTag(C,k,E,r);else{const F=C.getEdge(v);w.moveEntityFrom(C,k,E,F.removeMap,l,r)}n[_]=R,r[_]=A[0],p&&f[v].obsRem&&(y.remComp[y.remLen]=v,y.remEid[y.remLen]=E,y.remLen++)}t.length=0,e.length=0,this._settleFlushDirty()}get pendingStructuralCount(){return this._deferred.structuralCount}_configureComponentObservation(t,e,s,n,r,i){const o=this.componentMetas[t];if(o===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`observe(): component ${t} is not registered`);const a=o.obsAdd||o.obsRem;o.obsAdd=e,o.obsRem=s;const l=e||s;a&&!l?this._structuralObserverCount--:!a&&l&&this._structuralObserverCount++;const u=o.obsDisable||o.obsEnable;o.obsDisable=n,o.obsEnable=r;const d=n||r;if(u&&!d?this._toggleObserverCount--:!u&&d&&this._toggleObserverCount++,i&&!o.trackDirty)o.trackDirty=!0,this._dirtyLists[t]===void 0&&(this._dirtyLists[t]=[],this._dirtyMarks[t]=new Uint8Array(Math.max(1,this.entityAllocator.generations.length))),this._dirtyTrackedCids.push(t),this._anyDirtyTracked=!0;else if(!i&&o.trackDirty){o.trackDirty=!1;const f=this._dirtyTrackedCids.indexOf(t);f>=0&&this._dirtyTrackedCids.splice(f,1),this._anyDirtyTracked=this._dirtyTrackedCids.length>0;const p=this._dirtyLists[t],y=this._dirtyMarks[t];if(p!==void 0&&y!==void 0){for(let g=0;g<p.length;g++)y[p[g]&h.INDEX_MASK]=0;p.length=0}}}_noteSet(t,e){const s=t.id,n=this.componentMetas[s];if(n===void 0||!n.trackDirty)return;const r=e&h.INDEX_MASK;let i=this._dirtyMarks[s];r>=i.length&&(i=this._growDirtyMarks(s,r)),i[r]===0&&(i[r]=1,this._dirtyLists[s].push(e))}_growDirtyMarks(t,e){const s=this._dirtyMarks[t];let n=Math.max(1,s.length);for(;n<=e;)n*=2;const r=new Uint8Array(n);return r.set(s),this._dirtyMarks[t]=r,r}_takeDirty(t){const e=this._dirtyLists[t];if(e===void 0||e.length===0)return me;this._dirtyLists[t]=[];const s=this._dirtyMarks[t];for(let n=0;n<e.length;n++)s[e[n]&h.INDEX_MASK]=0;return e}_clearDirtyForIndex(t){const e=this._dirtyTrackedCids;for(let s=0;s<e.length;s++){const n=this._dirtyMarks[e[s]];n!==void 0&&t<n.length&&(n[t]=0)}}_forEachChangedArchetype(t,e,s){const n=this.archGraph.componentIndex[t];if(n===void 0)return;const r=this.archGraph.archetypes;for(let i=0;i<n.length;i++){const o=r[n[i]];o.length>0&&o._changedTick[t]>=e&&s(o)}}_collectEntitiesWithComponent(t){const e=[],s=this.archGraph.componentIndex[t];if(s===void 0)return e;const n=this.archGraph.archetypes;for(let r=0;r<s.length;r++){const i=n[s[r]],o=i.entityIds;for(let a=0;a<i.enabledCount;a++)e.push(h.unsafeCast(o[a]))}return e}registerComponent(t,e){if(this.componentCount>=h.STORE_DESCRIPTOR_COMPONENT_LIMIT)throw new h.ECSError(h.ECS_ERROR.COMPONENT_LIMIT_EXCEEDED,`Cannot register more than ${h.STORE_DESCRIPTOR_COMPONENT_LIMIT} components: the SAB archetype descriptor mask is ${h.STORE_DESCRIPTOR_COMPONENT_LIMIT} bits wide. Widen the descriptor mask (descriptor.ts + abi.zig, a SIM_ABI_VERSION bump) to raise it.`,{componentCount:this.componentCount,limit:h.STORE_DESCRIPTOR_COMPONENT_LIMIT});const s=Object.keys(t),n=new Array(s.length),r=Object.create(null);for(let a=0;a<s.length;a++)r[s[a]]=a,n[a]=t[s[a]];this._rejectNonDeterministicFields(s,n,"component");const i=Rt(this.componentCount++);this.componentMetas.push({name:e,fieldNames:s,fieldIndex:r,fieldTypes:n,obsAdd:!1,obsRem:!1,obsDisable:!1,obsEnable:!1,trackDirty:!1});const o=vt(i);return e!==void 0&&h.setComponentDebugName(o,e),o}componentLabel(t){const e=this.componentMetas[t]?.name;return e!==void 0?`'${e}' (component ${t})`:`component ${t}`}fieldIdOf(t,e){const s=t.id,n=this.componentMetas[s];if(n===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`field_id_of: component ${s} is not registered`);const r=n.fieldIndex[e];if(r===void 0)throw new h.ECSError(h.ECS_ERROR.FIELD_NOT_REGISTERED,`field_id_of: component ${s} has no field "${e}"`);return r}registerSparseComponent(t,e){const s=Object.keys(t),n=new Array(s.length);for(let r=0;r<s.length;r++)n[r]=t[s[r]];return this._rejectNonDeterministicFields(s,n,"sparse component"),this._pushSparseStore(s,n,e)}sparseLabel(t){const e=this.sparseNames[t];return e!==void 0?`'${e}' (sparse component ${t})`:`sparse component ${t}`}_pushSparseStore(t,e,s){const n=this.sparseStores.length;return this.sparseStores.push(new h.SparseComponentStore(t,e)),this.sparseNames.push(s),h.unsafeCast(n)}sparseStoreOf(t){const e=t,s=this.sparseStores[e];if(s===void 0)throw new h.ECSError(h.ECS_ERROR.COMPONENT_NOT_REGISTERED,`sparse component ${e} is not registered`);return s}addSparse(t,e,s){this.isAlive(t)&&this.sparseStoreOf(e).setRow(h.getEntityIndex(t),s??h.EMPTY_VALUES)}removeSparse(t,e){this.isAlive(t)&&this.sparseStoreOf(e).remove(h.getEntityIndex(t))}hasSparse(t,e){return this.isAlive(t)?this.sparseStoreOf(e).has(h.getEntityIndex(t)):!1}getSparseField(t,e,s){const n=this.sparseStoreOf(e),r=n.fieldIndex[s];if(r===void 0)return 0;const i=n.getField(h.getEntityIndex(t),r);return i===void 0?0:i}setSparseField(t,e,s,n){const r=this.sparseStoreOf(e),i=r.fieldIndex[s];i!==void 0&&r.setField(h.getEntityIndex(t),i,n)}_purgeSparse(t){const e=this.sparseStores;for(let s=0;s<e.length;s++)e[s].remove(t)}snapshotSparse(){return this._requireDeterministic("snapshot_sparse()"),this._snapshots.snapshotSparse()}restoreSparse(t){this._requireDeterministic("restore_sparse()"),this._snapshots.restoreSparse(t)}snapshot(){return this._requireDeterministic("snapshot()"),this._snapshots.snapshot()}restoreInto(t){this._requireDeterministic("restoreInto()"),this._snapshots.restoreInto(t)}_mountRestoredDense(t){this._columnStore=t;const e=this.archGraph.archetypes;for(let s=0;s<e.length;s++)e[s].isBufferBacked&&e[s].refreshViews(this._columnStore);this.entityAllocator.setHighWater(t.view.getUint32(t.header.entityIndexOff+h.ENTITY_INDEX_HEADER_OFFSETS.length,!0)),this._handleBufferResized()}_reconstructHostRows(t){const e=this.entityAllocator.highWater,s=this.entityArchetype,n=this.entityRow,r=this.entityAllocator.generations,i=new Map;for(let o=0;o<e;o++){const a=s[o];if(a===h.UNASSIGNED)continue;const l=n[o];if(l===h.UNASSIGNED)continue;let u=i.get(a);u===void 0&&(u=[],i.set(a,u)),u[l]=h.createEntityId(o,r[o])}for(let o=0;o<t.archetypeRows.length;o++){const a=t.archetypeRows[o],l=this.archGet(a.archetypeId),u=i.get(a.archetypeId)??[];l.restoreHostRows(u,a.enabledCount)}}registerRelation(t){return this.relationService.registerRelation(t)}get relationCount(){return this.relationService.count}addRelation(t,e,s){this.relationService.addRelation(t,e,s)}removeRelation(t,e,s){this.relationService.removeRelation(t,e,s)}targetOf(t,e){return this.relationService.targetOf(t,e)}targetsOf(t,e){return this.relationService.targetsOf(t,e)}sourcesOf(t,e){return this.relationService.sourcesOf(t,e)}hasRelation(t,e){return this.relationService.hasRelation(t,e)}pairsOf(t){return this.relationService.pairsOf(t)}sourcesOfAny(t){return this.relationService.sourcesOfAny(t)}relationBackingSparseId(t){return this.relationService.relationBackingSparseId(t)}_forEachRelationTargetMatch(t,e,s,n,r,i,o,a){this.relationService.forEachRelationTargetMatch(t,e,s,n,r,i,o,a)}compactRelations(){return this.relationService.compactRelations()}ancestorsOf(t,e){return this.relationService.ancestorsOf(t,e)}rootOf(t,e){return this.relationService.rootOf(t,e)}cascadeOf(t,e){return this.relationService.cascadeOf(t,e)}_forEachSparseMatch(t,e,s,n,r,i,o,a){const l=this.sparseStores;if(n.length>0){let d=l[n[0]];for(let _=1;_<n.length;_++){const m=l[n[_]];m.size<d.size&&(d=m)}const f=d.indices,p=this.entityAllocator.generations,y=this.entityArchetype,g=this.entityRow,E=this.archGraph.archetypes;for(let _=0;_<f.length;_++){const m=f[_];let S=!0;for(let w=0;w<n.length;w++){const k=l[n[w]];if(k!==d&&!k.has(m)){S=!1;break}}if(!S)continue;for(let w=0;w<r.length;w++)if(l[r[w]].has(m)){S=!1;break}if(!S)continue;const v=y[m];if(v===h.UNASSIGNED)continue;const C=E[v],R=C.mask;if(R.contains(t)&&!(e!==null&&R.overlaps(e))&&!(s!==null&&!R.overlaps(s))){if(!a){const w=g[m];if(w!==h.UNASSIGNED&&w>=C.enabledCount)continue}o(h.createEntityId(m,p[m]))}}return}const u=r.length>0;for(let d=0;d<i.length;d++){const f=i[d],p=f.entityIds,y=a?f.totalCount:f.enabledCount;for(let g=0;g<y;g++){const E=p[g];if(u){const _=h.getEntityIndex(E);let m=!1;for(let S=0;S<r.length;S++)if(l[r[S]].has(_)){m=!0;break}if(m)continue}o(E)}}}_forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){this.relationService.forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u)}addComponent(t,e,s){if(!this.isAlive(t))return;const n=h.getEntityIndex(t),r=this.entityArchetype[n],i=this.archGet(r);if(i.hasComponent(e.id)){i.writeFields(this.entityRow[n],e.id,s,this._tick);return}const o=this.archResolveAdd(r,e.id),a=this.archGet(o),l=this.entityRow[n];let u;if(l!==h.UNASSIGNED){const d=i.length,f=a.length,p=a.enabledCount,y=i.getEdge(e.id);!a.hasColumns&&!i.hasColumns?a.moveEntityFromTag(i,l,t,this.entityRow):a.moveEntityFrom(i,l,t,y.addMap,this._tick,this.entityRow),u=A[0],this._onArchLenChange(i,d),this._onArchGrow(a,f,p)}else{const d=a.length,f=a.enabledCount;u=a.hasColumns?a.addEntity(t,this.entityRow):a.addEntityTag(t,this.entityRow),this._onArchGrow(a,d,f)}a.writeFields(u,e.id,s,this._tick),this.entityArchetype[n]=o,this.entityRow[n]=u}addComponents(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n),i=e.length;let o=i;for(let f=0;f<i;f++){const p=e[f].def.id;if(p>=yt-1||i>we){o=J;break}o=o*yt+(p+1)}if(o!==J){const f=r.getCompositeAddEdge(o);if(f!==void 0){this._addComponentsInto(t,s,r,this.archGet(f.target),f.target,f.map,e);return}}let a=null;for(let f=0;f<i;f++){const p=e[f].def.id;a!==null?a.set(p):r.mask.has(p)||(a=r.mask.copyInto(this._scratchTargetMask),a.set(p))}if(a===null){const f=this.entityRow[s];for(let p=0;p<i;p++)r.writeFields(f,e[p].def.id,e[p].values??h.EMPTY_VALUES,this._tick);return}const l=this.archGetOrCreateFromMask(a),u=this.archGet(l),d=r.getBatchTransitionMap(u);o!==J&&r.cacheCompositeAddEdge(o,l,d),this._addComponentsInto(t,s,r,u,l,d,e)}_addComponentsInto(t,e,s,n,r,i,o){const a=this.entityRow[e];let l;if(a!==h.UNASSIGNED){const u=s.length,d=n.length,f=n.enabledCount;n.moveEntityFrom(s,a,t,i,this._tick,this.entityRow),l=A[0],this._onArchLenChange(s,u),this._onArchGrow(n,d,f)}else{const u=n.length,d=n.enabledCount;l=n.addEntity(t,this.entityRow),this._onArchGrow(n,u,d)}for(let u=0;u<o.length;u++)n.writeFields(l,o[u].def.id,o[u].values??h.EMPTY_VALUES,this._tick);this.entityArchetype[e]=r,this.entityRow[e]=l}removeComponent(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n);if(!r.hasComponent(e.id))return;const i=this.archResolveRemove(n,e.id),o=this.archGet(i),a=this.entityRow[s],l=r.getEdge(e.id),u=!o.hasColumns&&!r.hasColumns,d=r.length,f=o.length,p=o.enabledCount;u?o.moveEntityFromTag(r,a,t,this.entityRow):o.moveEntityFrom(r,a,t,l.removeMap,this._tick,this.entityRow),this.entityArchetype[s]=i,this.entityRow[s]=A[0],this._onArchLenChange(r,d),this._onArchGrow(o,f,p)}removeComponents(t,e){if(!this.isAlive(t))return;const s=h.getEntityIndex(t),n=this.entityArchetype[s],r=this.archGet(n);let i=null;for(let y=0;y<e.length;y++){const g=e[y].id;i!==null?i.clear(g):r.mask.has(g)&&(i=r.mask.copyInto(this._scratchTargetMask),i.clear(g))}if(i===null)return;const o=this.archGetOrCreateFromMask(i),a=this.archGet(o),l=this.entityRow[s],u=r.length,d=a.length,f=a.enabledCount,p=r.getBatchTransitionMap(a);a.moveEntityFrom(r,l,t,p,this._tick,this.entityRow),this.entityArchetype[s]=o,this.entityRow[s]=A[0],this._onArchLenChange(r,u),this._onArchGrow(a,d,f)}hasComponent(t,e){if(!this.isAlive(t))return!1;const s=h.getEntityIndex(t);return this.archGet(this.entityArchetype[s]).hasComponent(e.id)}batchAddComponent(t,e,s){const n=this.archGet(t);if(n.length===0)return;const r=e.id;if(n.mask.has(r))return;const i=this.archResolveAdd(n.id,r),o=this.archGet(i);if(n.disabledCount>0||o.disabledCount>0)throw new h.ECSError(h.ECS_ERROR.PARTITION_BULK_INTO_DISABLED,"batchAddComponent is unsupported on archetypes with disabled entities — enable them first or use per-entity addComponent");const a=n.getEdge(r),l=n.length,u=l,d=o.length,f=o.enabledCount,p=this.entityArchetype,y=this.entityRow,g=o.bulkMoveAllFrom(n,a.addMap,this._tick);for(let _=0;_<l;_++){const m=h.getEntityIndex(o.entityIds[g+_]);p[m]=i,y[m]=g+_}this.componentMetas[r].fieldNames.length>0&&s&&o.bulkWriteFields(g,l,r,s,this._tick),this._onArchLenChange(n,u),this._onArchGrow(o,d,f)}batchRemoveComponent(t,e){const s=this.archGet(t);if(s.length===0)return;const n=e.id;if(!s.mask.has(n))return;const r=this.archResolveRemove(s.id,n),i=this.archGet(r);if(s.disabledCount>0||i.disabledCount>0)throw new h.ECSError(h.ECS_ERROR.PARTITION_BULK_INTO_DISABLED,"batchRemoveComponent is unsupported on archetypes with disabled entities — enable them first or use per-entity removeComponent");const o=s.getEdge(n),a=s.length,l=a,u=this.entityArchetype,d=this.entityRow;if(!i.materializesRows){const g=s.entityIds;for(let E=0;E<a;E++){const _=h.getEntityIndex(g[E]);u[_]=r,d[_]=h.UNASSIGNED}s.clearRows(),this._onArchLenChange(s,l);return}const f=i.length,p=i.enabledCount,y=i.bulkMoveAllFrom(s,o.removeMap,this._tick);for(let g=0;g<a;g++){const E=h.getEntityIndex(i.entityIds[y+g]);u[E]=r,d[E]=y+g}this._onArchLenChange(s,l),this._onArchGrow(i,f,p)}getEntityArchetype(t){return this.archGet(this.entityArchetype[h.getEntityIndex(t)])}getEntityRow(t){return this.entityRow[h.getEntityIndex(t)]}getMatchingArchetypes(t,e,s){const n=t._words;let r=!1;for(let l=0;l<n.length;l++)if(n[l]!==0){r=!0;break}if(!r){const l=this.archGraph.archetypes,u=[];for(let d=0;d<l.length;d++){const f=l[d];(!e||!f.mask.overlaps(e))&&(!s||f.mask.overlaps(s))&&u.push(f)}return u}let i,o=!1;for(let l=0;l<n.length;l++){let u=n[l];if(u===0)continue;const d=l<<T.BITS_PER_WORD_SHIFT;for(;u!==0;){const f=u&-u>>>0,p=d+(T.BITS_PER_WORD_MASK-Math.clz32(f));u^=f;const y=this.archGraph.componentIndex[p];if(y===void 0||y.length===0){o=!0;break}(!i||y.length<i.length)&&(i=y)}if(o)break}if(o||!i)return[];const a=[];for(let l=0;l<i.length;l++){const u=this.archGet(i[l]);u.matches(t)&&(!e||!u.mask.overlaps(e))&&(!s||u.mask.overlaps(s))&&a.push(u)}return a}registerQuery(t,e,s){const n=this.getMatchingArchetypes(t,e,s);return this.registeredQueries.push({includeMask:t.copy(),excludeMask:e?e.copy():null,anyOfMask:s?s.copy():null,result:n,query:null}),n}updateQueryRef(t,e){const s=this.registeredQueries;for(let n=0;n<s.length;n++)if(s[n].result===t){s[n].query=e;return}}get archetypeCount(){return this.archGraph.archetypes.length}registerEvent(t){return this.events.registerEvent(t)}emitEvent(t,e){this.events.emitEvent(t,e)}emitSignal(t){this.events.emitSignal(t)}getEventReader(t){return this.events.getEventReader(t)}clearEvents(){this.events.clearEvents()}_devBufferedEventCount(){return this.events.devBufferedEventCount()}registerEventByKey(t,e){return this.events.registerEventByKey(t,e)}getEventDefByKey(t){return this.events.getEventDefByKey(t)}hasEventKey(t){return this.events.hasEventKey(t)}resources=new qt;registerResource(t,e){this.resources.register(t,e)}getResource(t){return this.resources.get(t)}setResource(t,e){this.resources.set(t,e)}removeResource(t){this.resources.remove(t)}hasResource(t){return this.resources.has(t)}}class Ce{store;constructor(t){this.store=t}register(t){return this.store.registerRelation(t)}get count(){return this.store.relationCount}add(t,e,s){return this.store.addRelation(t,e,s),this}remove(t,e,s){return this.store.removeRelation(t,e,s),this}has(t,e){return this.store.hasRelation(t,e)}targetOf(t,e){return this.store.targetOf(t,e)}targetsOf(t,e){return this.store.targetsOf(t,e)}sourcesOf(t,e){return this.store.sourcesOf(t,e)}pairsOf(t){return this.store.pairsOf(t)}sourcesOfAny(t){return this.store.sourcesOfAny(t)}ancestorsOf(t,e){return this.store.ancestorsOf(t,e)}rootOf(t,e){return this.store.rootOf(t,e)}cascadeOf(t,e){return this.store.cascadeOf(t,e)}compact(){return this.store.compactRelations()}}class Re{store;constructor(t){this.store=t}register(t,e){this.store.registerEventByKey(t,e)}registerSignal(t){this.store.registerEventByKey(t,[])}emit(t,e){const s=this.store.getEventDefByKey(t);e===void 0?this.store.emitSignal(s):this.store.emitEvent(s,e)}read(t){const e=this.store.getEventDefByKey(t);return this.store.getEventReader(e)}}class ve{store;constructor(t){this.store=t}register(t,e){this.store.registerResource(t,e)}get(t){return h.unsafeCast(this.store.getResource(t))}set(t,e){this.store.setResource(t,e)}remove(t){this.store.removeResource(t)}has(t){return this.store.hasResource(t)}}class be{store;constructor(t){this.store=t}get deterministic(){return this.store.deterministic}stateHash(){return this.store.stateHash()}capture(){return this.store.snapshot()}restore(t){this.store.restoreInto(t)}captureSparse(){return this.store.snapshotSparse()}restoreSparse(t){this.store.restoreSparse(t)}}const Et=new WeakMap;function it(c,t){let e=Et.get(c);if(!e){e=Object.create(null);const{fieldNames:n}=c.layout;for(let r=0;r<n.length;r++){const i=c.columns[r];Object.defineProperty(e,n[r],{get(){return i.buf[this._row]},set(o){i.buf[this._row]=o},enumerable:!0,configurable:!1})}Et.set(c,e)}const s=Object.create(e);return s._row=t,s}class Ie{dedup=new Map;andSingle=new Map;notSingle=new Map;anyOfSingle=new Map;changedSingle=new Map;optionalSingle=new Map;withSparseSingle=new Map;withoutSparseSingle=new Map;withRelationSingle=new Map;withoutRelationSingle=new Map;includeDisabledSingle=new Map;hierarchySingle=new Map;findDedup(t,e,s,n){const r=this.dedup.get(t);if(r)for(let i=0;i<r.length;i++){const o=r[i];if(!(!o.includeMask.equals(e)||!(s===null?o.excludeMask===null:o.excludeMask!==null&&o.excludeMask.equals(s))||!(n===null?o.anyOfMask===null:o.anyOfMask!==null&&o.anyOfMask.equals(n))))return o}}addDedup(t,e){Dt(this.dedup,t,e)}}const mt=Object.freeze([]),Ae=Object.freeze([]),wt=Object.freeze([]),ot=Number.POSITIVE_INFINITY;function H(c,t){return(c<<16|t)>>>0}function j(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}function Oe(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}function St(c,t){for(let e=0;e<c.length;e++)if(c[e]===t)return c;return[...c,t]}class kt{_arch;_tick=0;mut(t){return this._arch.columnGroupMut(t,this._tick)}read(t){return this._arch.columnGroupRead(t)}}class D{_archetypes;_defs;_resolver;_include;_exclude;_anyOf;_nonEmptyArchetypes=[];_lastSeenEpoch=-1;_id;_sparseInclude;_sparseExclude;_optional;_includeDisabled;_relationIncludes;_relationExcludes;_hierarchy;constructor(t,e,s,n,r,i,o,a=mt,l=mt,u=Ae,d=!1,f=wt,p=wt,y=null){this._archetypes=t,this._defs=e,this._resolver=s,this._include=n,this._exclude=r,this._anyOf=i,this._id=o,this._sparseInclude=a,this._sparseExclude=l,this._optional=u,this._includeDisabled=d,this._relationIncludes=f,this._relationExcludes=p,this._hierarchy=y}_assertDenseOnly(t){if(this._sparseInclude.length>0||this._sparseExclude.length>0||this._relationIncludes.length>0||this._relationExcludes.length>0||this._hierarchy!==null)throw new h.ECSError(h.ECS_ERROR.SPARSE_QUERY_DENSE_PATH,`Query.${t} ignores sparse / relation-wildcard / hierarchy terms (withSparse / withoutSparse / withRelation / withoutRelation / hierarchy) — it walks only the dense archetype list and would return the wrong result (a hierarchy term has no per-archetype span — its order spans archetypes). Iterate this query with forEachEntity instead.`)}_isDenseOnly(){return this._sparseInclude.length===0&&this._sparseExclude.length===0&&this._relationIncludes.length===0&&this._relationExcludes.length===0&&this._hierarchy===null}firstEntity(){if(this._isDenseOnly()){const e=this._nonEmpty();for(let s=0;s<e.length;s++)if((this._includeDisabled?e[s].totalCount:e[s].enabledCount)>0)return e[s].entityIds[0];return}let t;return this.forEachEntity(e=>{t===void 0&&(t=e)}),t}singleEntity(){return this.firstEntity()}_countViaWalk(){let t=0;return this.forEachEntity(()=>{t++}),t}get archetypeCount(){return this._archetypes.length}get entityCount(){const t=this._nonEmpty();let e=0;if(this._includeDisabled)for(let s=0;s<t.length;s++)e+=t[s].totalCount;else for(let s=0;s<t.length;s++)e+=t[s].enabledCount;return e}get archetypes(){return this._archetypes}_carryNondense(t){return this._optional.length===0&&this._sparseInclude.length===0&&this._sparseExclude.length===0&&!this._includeDisabled&&this._relationIncludes.length===0&&this._relationExcludes.length===0&&this._hierarchy===null?t:new D(t._archetypes,t._defs,this._resolver,t._include,t._exclude,t._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}and(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.andSingle.get(n);return r!==void 0?r:this._andMiss(t[0],s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.and(t[s]);return e}_andMiss(t,e,s){const n=this._include.copy(),r=this._defs.slice();n.has(e)||(n.set(e),r.push(t));const i=this._carryNondense(this._resolver._resolveQuery(n,this._exclude,this._anyOf,r));return this._resolver._caches.andSingle.set(s,i),i}without(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.notSingle.get(n);return r!==void 0?r:this._notMiss(s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.without(t[s]);return e}_notMiss(t,e){const s=this._exclude?this._exclude.copy():new T.BitSet;s.set(t);const n=this._carryNondense(this._resolver._resolveQuery(this._include,s,this._anyOf,this._defs));return this._resolver._caches.notSingle.set(e,n),n}withSparse(...t){if(t.length===1)return this._withSparseOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withSparseOne(t[s]);return e}_withSparseOne(t){const e=H(this._id,t),s=this._resolver._caches.withSparseSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveSparse(j(this._sparseInclude,t),this._sparseExclude);return s.set(e,r),r}withoutSparse(...t){if(t.length===1)return this._withoutSparseOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withoutSparseOne(t[s]);return e}_withoutSparseOne(t){const e=H(this._id,t),s=this._resolver._caches.withoutSparseSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveSparse(this._sparseInclude,j(this._sparseExclude,t));return s.set(e,r),r}_deriveSparse(t,e){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),t,e,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}withRelation(...t){if(t.length===1)return this._withRelationOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withRelationOne(t[s]);return e}_withRelationOne(t){const e=H(this._id,t),s=this._resolver._caches.withRelationSingle,n=s.get(e);if(n!==void 0)return n;const r=this._resolver._relationBackingSparseId(t),i=this._deriveRelation(j(this._sparseInclude,r),this._sparseExclude,St(this._relationIncludes,t),this._relationExcludes);return s.set(e,i),i}withoutRelation(...t){if(t.length===1)return this._withoutRelationOne(t[0]);let e=this;for(let s=0;s<t.length;s++)e=e._withoutRelationOne(t[s]);return e}_withoutRelationOne(t){const e=H(this._id,t),s=this._resolver._caches.withoutRelationSingle,n=s.get(e);if(n!==void 0)return n;const r=this._resolver._relationBackingSparseId(t),i=this._deriveRelation(this._sparseInclude,j(this._sparseExclude,r),this._relationIncludes,St(this._relationExcludes,t));return s.set(e,i),i}_deriveRelation(t,e,s,n){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),t,e,this._optional,this._includeDisabled,s,n,this._hierarchy)}hierarchy(t,e=ot){if(e===ot){const s=H(this._id,t),n=this._resolver._caches.hierarchySingle,r=n.get(s);if(r!==void 0)return r;const i=this._deriveHierarchy({relation:t,maxDepth:e});return n.set(s,i),i}return this._deriveHierarchy({relation:t,maxDepth:e})}_deriveHierarchy(t){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,this._includeDisabled,this._relationIncludes,this._relationExcludes,t)}_checkRelationAccess(){for(let t=0;t<this._relationIncludes.length;t++)h.accessCheck.checkRelationRead(this._relationIncludes[t]);for(let t=0;t<this._relationExcludes.length;t++)h.accessCheck.checkRelationRead(this._relationExcludes[t])}forEachRelatedTo(t,e){this._resolver._forEachRelationTargetMatch(t,this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._includeDisabled,e)}optional(...t){if(t.length===1)return this._optionalOne(t[0].id);let e=this;for(let s=0;s<t.length;s++)e=e._optionalOne(t[s].id);return e}_optionalOne(t){const e=(this._id<<16|t)>>>0,s=this._resolver._caches.optionalSingle,n=s.get(e);if(n!==void 0)return n;const r=this._deriveOptional(Oe(this._optional,t));return s.set(e,r),r}_deriveOptional(t){return new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,t,this._includeDisabled,this._relationIncludes,this._relationExcludes,this._hierarchy)}includeDisabled(){if(this._includeDisabled)return this;const t=this._resolver._caches.includeDisabledSingle,e=t.get(this._id);if(e!==void 0)return e;const s=new D(this._archetypes,this._defs,this._resolver,this._include,this._exclude,this._anyOf,this._resolver._nextQueryId(),this._sparseInclude,this._sparseExclude,this._optional,!0,this._relationIncludes,this._relationExcludes,this._hierarchy);return t.set(this._id,s),s}forEach(t){if(this._includeDisabled){this._forEachIncludeDisabled(t);return}const e=this._nonEmpty();for(let s=0;s<e.length;s++)t(e[s])}_forEachIncludeDisabled(t){const e=x(!0);try{this._forEachInner(t)}finally{x(e)}}eachChunk(t){if(this._includeDisabled){const e=x(!0);try{this._eachChunkInner(t)}finally{x(e)}return}this._eachChunkInner(t)}_eachChunkInner(t){const e=new kt;e._tick=this._resolver._getCurrentTick();const s=this._nonEmpty();for(let n=0;n<s.length;n++)e._arch=s[n],t(e,s[n].entityCount)}forEachUntil(t){if(this._includeDisabled){const e=x(!0);try{return this._forEachUntilInner(t)}finally{x(e)}}return this._forEachUntilInner(t)}_forEachUntilInner(t){const e=this._nonEmpty();for(let s=0;s<e.length;s++)if(t(e[s]))return!0;return!1}_forEachInner(t){const e=this._nonEmpty();for(let s=0;s<e.length;s++)t(e[s])}forEachEntity(t){if(this._hierarchy!==null){this._resolver._forEachHierarchyMatch(this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._nonEmpty(),this._hierarchy.relation,this._hierarchy.maxDepth,this._includeDisabled,t);return}this._resolver._forEachSparseMatch(this._include,this._exclude,this._anyOf,this._sparseInclude,this._sparseExclude,this._nonEmpty(),t,this._includeDisabled)}_nonEmpty(){const t=this._resolver._getQueryDirtyEpoch();return this._lastSeenEpoch!==t&&this._rebuildNonEmpty(t),this._nonEmptyArchetypes}_rebuildNonEmpty(t){const e=this._archetypes,s=[];if(this._includeDisabled)for(let n=0;n<e.length;n++)e[n].totalCount>0&&s.push(e[n]);else for(let n=0;n<e.length;n++)e[n].enabledCount>0&&s.push(e[n]);this._nonEmptyArchetypes=s,this._lastSeenEpoch=t}anyOf(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.anyOfSingle.get(n);return r!==void 0?r:this._anyOfMiss(s,n)}let e=this;for(let s=0;s<t.length;s++)e=e.anyOf(t[s]);return e}_anyOfMiss(t,e){const s=this._anyOf?this._anyOf.copy():new T.BitSet;s.set(t);const n=this._carryNondense(this._resolver._resolveQuery(this._include,this._exclude,s,this._defs));return this._resolver._caches.anyOfSingle.set(e,n),n}changed(...t){if(t.length===1){const s=t[0].id,n=(this._id<<16|s)>>>0,r=this._resolver._caches.changedSingle.get(n);return r!==void 0?r:this._changedMiss(s,n)}const e=new Array(t.length);for(let s=0;s<t.length;s++)e[s]=t[s].id;return new M(this,e)}_changedMiss(t,e){const s=new M(this,[t]);return this._resolver._caches.changedSingle.set(e,s),s}_ctxLastRunTick(){return this._resolver._getLastRunTick()}}class xt{constructor(t){this._resolver=t}with(...t){const e=new T.BitSet;for(let s=0;s<t.length;s++)e.set(t[s].id);return this._resolver._resolveQuery(e,null,null,t)}}class Mt{constructor(t){this.store=t}spawn(...t){const e=this.store.createEntity();for(let s=0;s<t.length;s++){const n=G(t[s]);this.store.addComponentDeferred(e,n,$(t[s]))}return e}add(t,...e){if(e.length===2&&typeof e[0]=="function"&&e[1]!==null&&typeof e[1]=="object"&&typeof e[1].def!="function"){const s=e[0];return this.store.addComponentDeferred(t,s,e[1]),this}for(let s=0;s<e.length;s++){const n=e[s],r=G(n);this.store.addComponentDeferred(t,r,$(n))}return this}remove(t,e){return this.store.removeComponentDeferred(t,e),this}despawn(t){const e=t;return this.store.destroyEntityDeferred(e),this}disable(t){return this.store.disableEntityDeferred(t),this}enable(t){return this.store.enableEntityDeferred(t),this}}class Nt{constructor(t){this.store=t,this.commands=new Mt(t)}lastRunTick=0;commands;get ecsTick(){return this.store._tick}get _trace(){return this.store._trace}isAlive(t){return this.store.isAlive(t)}hasComponent(t,e){return this.store.hasComponent(t,e)}getField(t,e,s){const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}tryGetField(t,e,s){if(!this.store.hasComponent(t,e))return;const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}setField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=r.getColumn(e,s,this.store._tick);o[i]=n,this.store._anyDirtyTracked&&this.store._noteSet(e,t)}updateField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=n(r.readField(i,e.id,s)),a=r.getColumn(e,s,this.store._tick);return a[i]=o,this.store._anyDirtyTracked&&this.store._noteSet(e,t),o}markChanged(t,e){this.store._anyDirtyTracked&&this.store._noteSet(e,t)}ref(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return s._changedTick[t.id]=this.store._tick,it(s.columnGroups[t.id],n)}refRead(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return it(s.columnGroups[t.id],n)}isDisabled(t){return this.store.isDisabled(t)}addSparse(t,e,...s){return this.store.addSparse(t,e,s[0]),this}removeSparse(t,e){return this.store.removeSparse(t,e),this}hasSparse(t,e){return this.store.hasSparse(t,e)}getSparseField(t,e,s){return this.store.getSparseField(t,e,s)}setSparseField(t,e,s,n){this.store.setSparseField(t,e,s,n)}addRelation(t,e,s){return this.store.addRelation(t,e,s),this}removeRelation(t,e,s){return this.store.removeRelation(t,e,s),this}targetOf(t,e){return this.store.targetOf(t,e)}targetsOf(t,e){return this.store.targetsOf(t,e)}sourcesOf(t,e){return this.store.sourcesOf(t,e)}hasRelation(t,e){return this.store.hasRelation(t,e)}flush(){this.store.flushStructural(),this.store.flushDestroyed(),this.store.publishRowCountsToDescriptor()}emit(t,e){const s=this.store.getEventDefByKey(t);e===void 0?this.store.emitSignal(s):this.store.emitEvent(s,e)}read(t){const e=this.store.getEventDefByKey(t);return this.store.getEventReader(e)}getResource(t){return h.unsafeCast(this.store.getResource(t))}setResource(t,e){this.store.setResource(t,e)}removeResource(t){this.store.removeResource(t)}hasResource(t){return this.store.hasResource(t)}}class M{_query;_changedIds;constructor(t,e){this._query=t,this._changedIds=e}and(...t){return new M(this._query.and(...t),this._changedIds)}without(...t){return new M(this._query.without(...t),this._changedIds)}anyOf(...t){return new M(this._query.anyOf(...t),this._changedIds)}optional(...t){return new M(this._query.optional(...t),this._changedIds)}forEach(t){if(this._query._includeDisabled){this._forEachIncludeDisabled(t);return}const e=this._query._ctxLastRunTick(),s=this._query._nonEmpty(),n=this._changedIds;for(let r=0;r<s.length;r++){const i=s[r];for(let o=0;o<n.length;o++)if(i._changedTick[n[o]]>=e){t(i);break}}}_forEachIncludeDisabled(t){const e=x(!0);try{this._forEachInner(t)}finally{x(e)}}_forEachInner(t){const e=this._query._ctxLastRunTick(),s=this._query._nonEmpty(),n=this._changedIds;for(let r=0;r<s.length;r++){const i=s[r];for(let o=0;o<n.length;o++)if(i._changedTick[n[o]]>=e){t(i);break}}}}function Ct(c){if(!(c>0)||!Number.isFinite(c))throw new h.ECSError(h.ECS_ERROR.INVALID_FIXED_TIMESTEP,`fixedTimestep must be a finite number > 0, got ${c}`);return c}function Te(c){if(!Number.isInteger(c)||c<1)throw new h.ECSError(h.ECS_ERROR.INVALID_MAX_FIXED_STEPS,`maxFixedSteps must be an integer >= 1, got ${c}`);return c}class De{store;schedule;ctx;_observers;relations;events;resources;snapshots;systems=new Set;nextSystemId=0;_tick=0;_updating=!1;_fixedTimestep;_accumulator=0;_maxFixedSteps;scratchMask=new T.BitSet;_nextQueryIdCounter=0;_caches=new Ie;_layoutSubscribers=[];_backend=null;_memory;get memoryPlan(){return this._memory}get wasmMemory(){return this._memory.wasmMemory}constructor(t){const e=Object.prototype.hasOwnProperty;if(t!==void 0&&(e.call(t,"initial_capacity")||e.call(t,"buffer_allocator")))throw new h.ECSError(h.ECS_ERROR.INVALID_MEMORY_OPTIONS,"ECSOptions.initial_capacity / buffer_allocator were replaced by ECSOptions.memory: initial_capacity → memory.columnCapacity (or memory.budget); buffer_allocator → memory.wasm (WASM-backed) or memory.allocator (custom in-place).");const s=h.resolveECSMemory(t?.memory);this._memory=s,this.store=new Se({initialCapacity:s.columnCapacity,bufferAllocator:s.allocator,entityIndexCapacity:s.entityIndexCapacity,capContext:{capBytes:s.capBytes,intentLabel:s.intentLabel,budgetEntities:s.budgetEntities},onBufferResized:()=>{const n=this._layoutSubscribers;for(let r=0;r<n.length;r++)n[r].setLayout(0)},regions:t?.regions,bindingsRegionBytes:t?.bindingsRegionBytes,deterministic:t?.deterministic}),this.schedule=new h.Schedule(t?.onWarn),this.relations=new Ce(this.store),this.events=new Re(this.store),this.resources=new ve(this.store),this.snapshots=new be(this.store),this.ctx=new Nt(this.store),this._observers=new Zt(this.store,this.ctx),this.store.setStructuralObserverHook(n=>this._observers.dispatchStructural(n)),this._fixedTimestep=Ct(t?.fixedTimestep??h.DEFAULT_FIXED_TIMESTEP),this._maxFixedSteps=Te(t?.maxFixedSteps??h.DEFAULT_MAX_FIXED_STEPS)}regionHandles(...t){const e=new Array(t.length);let s=null;for(let n=0;n<t.length;n++){const r=this.store.regionHandle(t[n]);r===null?(s??=[]).push(t[n]):e[n]=r}if(s!==null)throw new h.ECSError(h.ECS_ERROR.REGION_NOT_DECLARED,`region_handles: region id(s) [${s.join(", ")}] not declared — pass them via ECSOptions.regions`);return e}onStoreLayoutPublished(t){return this._layoutSubscribers.push(t),t.setLayout(0),()=>{const e=this._layoutSubscribers.indexOf(t);e>=0&&this._layoutSubscribers.splice(e,1)}}attachBackend(t){this._backend=t,this.schedule.setBackend(t);const e=this.onStoreLayoutPublished(t);return()=>{e(),this._backend===t&&(this._backend=null,this.schedule.setBackend(null))}}get fixedTimestep(){return this._fixedTimestep}set fixedTimestep(t){this._fixedTimestep=Ct(t)}get fixedAlpha(){return this._accumulator/this._fixedTimestep}setTrace(t){}registerComponent(t,e,s){if(Array.isArray(t)){const r=typeof e=="string"?e:"f64",i=Object.create(null);for(const o of t)i[o]=r;return this.store.registerComponent(i,s?.name)}const n=typeof e=="object"?e:s;return this.store.registerComponent(t,n?.name)}registerSparseComponent(t,e,s){if(Array.isArray(t)){const r=typeof e=="string"?e:"f64",i=Object.create(null);for(const o of t)i[o]=r;return this.store.registerSparseComponent(i,s?.name)}const n=typeof e=="object"?e:s;return this.store.registerSparseComponent(t,n?.name)}spawn(t,e){return t===void 0?this.store.createEntity():this.store.spawn(t,e)}spawnBundle(...t){const e=this.store.createEntity();for(let s=0;s<t.length;s++){const n=t[s],r=G(n);this.store.addComponent(e,r,$(n))}return e}spawnMany(t,e,s){return this.store.spawnMany(t,e,s)}_assertHostMutationOutsideSystem(t,e){if(this._updating&&h.accessCheck.current()!==null){const s=h.accessCheck.current(),n=s.name??`system_${s.id}`;throw new h.ECSError(h.ECS_ERROR.ACCESS_UNDECLARED,`ecs.${t} called from inside system '${n}' — host ${t} is immediate and unsafe mid-iteration (and invisible to observers); use ${e} instead`,{op:t})}}despawn(t){return this.store.destroyEntity(t),this}disable(t){return this.store.disableEntity(t),this}enable(t){return this.store.enableEntity(t),this}addComponent(t,e,s){const n=G(e);return this.store.addComponent(t,n,s??$(e)),this}addComponents(t,...e){const s=[];for(let n=0;n<e.length;n++){const r=e[n];s.push({def:G(r),values:$(r)})}return this.store.addComponents(t,s),this}removeComponent(t,e){return this.store.removeComponent(t,e),this}removeComponents(t,...e){return this.store.removeComponents(t,e),this}batchAddComponent(t,e,s){return this.store.batchAddComponent(t,e,s),this}batchRemoveComponent(t,e){return this.store.batchRemoveComponent(t,e),this}getField(t,e,s){const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}refRead(t,e){const s=this.store.getEntityArchetype(e),n=this.store.getEntityRow(e);return it(s.columnGroups[t.id],n)}tryGetField(t,e,s){if(!this.store.hasComponent(t,e))return;const n=this.store.getEntityArchetype(t),r=this.store.getEntityRow(t);return n.readField(r,e.id,s)}setField(t,e,s,n){const r=this.store.getEntityArchetype(t),i=this.store.getEntityRow(t),o=r.getColumn(e,s,this.store._tick);o[i]=n,this.store._anyDirtyTracked&&this.store._noteSet(e,t)}updateField(t,e,s,n){const r=n(this.getField(t,e,s));return this.setField(t,e,s,r),r}query(...t){const e=this.scratchMask;e._words.fill(0);for(let s=0;s<t.length;s++)e.set(t[s].id);return this._resolveQuery(e.copy(),null,null,t)}_nextQueryId(){return this._nextQueryIdCounter++}_resolveQuery(t,e,s,n){const r=t.hash(),i=e?e.hash():0,o=s?s.hash():0,a=r^Math.imul(i,h.HASH_GOLDEN_RATIO)^Math.imul(o,h.HASH_SECONDARY_PRIME)|0,l=this._caches.findDedup(a,t,e,s);if(l!==void 0)return l.query;const u=this.store.registerQuery(t,e??void 0,s??void 0),d=new D(u,n,this,t.copy(),e?.copy()??null,s?.copy()??null,this._nextQueryIdCounter++);return this.store.updateQueryRef(u,d),this._caches.addDedup(a,{includeMask:t.copy(),excludeMask:e?.copy()??null,anyOfMask:s?.copy()??null,query:d}),d}registerSystem(t,e){let s;if(typeof t=="function")if(e!==void 0){const i=e(new xt(this)),o=this.ctx,a=t;s={...nt,fn:(l,u)=>a(i,o,u)}}else s={...nt,fn:t};else s=t;const n=bt(this.nextSystemId++),r=Object.freeze({...s,...zt(s),id:n});return this.systems.add(r),r}removeSystem(t){return this.schedule.removeSystem(t),t.onRemoved?.(),this.systems.delete(t),this}get systemCount(){return this.systems.size}startup(){this.prewarmArchetypes();try{for(const t of this.systems.values())if(t.onAdded!==void 0)try{t.onAdded(this.ctx)}finally{}this.schedule.runStartup(this.ctx,this._tick)}finally{}this.store.clearEvents()}prewarmArchetypes(){const t=ke([...this.systems,...this._observers.descriptors()]);t.length!==0&&this.store.archCreateManyFromMasks(t)}update(t){try{if(this.store._tick=this._tick,this.store.publishRowCountsToDescriptor(),this.schedule.hasFixedSystems()){this._accumulator+=t;const s=this._maxFixedSteps*this._fixedTimestep;for(this._accumulator>s&&(this._accumulator=s);this._accumulator>=this._fixedTimestep;)this.schedule.runFixedUpdate(this.ctx,this._fixedTimestep,this._tick),this._accumulator-=this._fixedTimestep}this.schedule.runUpdate(this.ctx,t,this._tick);const e=O?this.store._devBufferedEventCount():0;this._observers.dispatchSet(this._tick),O&&this.store._devBufferedEventCount(),this.store.clearEvents(),this._tick++}finally{}}dispose(){for(const t of this.systems.values())t.dispose?.(),t.onRemoved?.();this.systems.clear(),this.schedule.clear()}template(...t){const e=[];for(let s=0;s<t.length;s++){const n=t[s];e.push({def:G(n),values:$(n)})}return this.store.resolveTemplate(e)}regionOffset(t){return this.store.regionOffset(t)}regionHandle(t){return this.store.regionHandle(t)}fieldId(t,e){return this.store.fieldIdOf(t,e)}entityIdAtRow(t,e){return this.store.entityIdAtRow(t,e)}get columnStore(){return this.store.columnStore}get archetypeCount(){return this.store.archetypeCount}registerTag(){return this.store.registerComponent({})}registerSparseTag(){return this.store.registerSparseComponent({})}isAlive(t){return this.store.isAlive(t)}get entityCount(){return this.store.entityCount}hasComponent(t,e){return this.store.hasComponent(t,e)}isDisabled(t){return this.store.isDisabled(t)}addSparse(t,e,s){return this.store.addSparse(t,e,s),this}removeSparse(t,e){return this.store.removeSparse(t,e),this}hasSparse(t,e){return this.store.hasSparse(t,e)}getSparseField(t,e,s){return this.store.getSparseField(t,e,s)}setSparseField(t,e,s,n){this.store.setSparseField(t,e,s,n)}_getLastRunTick(){return this.ctx.lastRunTick}_getCurrentTick(){return this.store._tick}_getQueryDirtyEpoch(){return this.store._queryDirtyEpoch}_forEachSparseMatch(t,e,s,n,r,i,o,a){this.store._forEachSparseMatch(t,e,s,n,r,i,o,a)}_relationBackingSparseId(t){return this.store.relationBackingSparseId(t)}_forEachRelationTargetMatch(t,e,s,n,r,i,o,a){this.store._forEachRelationTargetMatch(t,e,s,n,r,i,o,a)}_forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u){this.store._forEachHierarchyMatch(t,e,s,n,r,i,o,a,l,u)}addSystems(t,...e){return this.schedule.addSystems(t,...e),this}configureSet(t,e){return this.schedule.configureSet(t,e),this}observe(t,e){return this._observers.register(t,e)}publishArchetypeRowCounts(){this.store.publishRowCountsToDescriptor()}flush(){this.ctx.flush()}}function ke(c){const t=new Map,e=[],s=o=>{const a=o.hash(),l=t.get(a);if(l!==void 0){for(let u=0;u<l.length;u++)if(l[u].equals(o))return;l.push(o)}else t.set(a,[o]);e.push(o)},n=o=>{const a=new T.BitSet;for(let l=0;l<o.length;l++)a.set(o[l].id);return a},r=[];for(const o of c){const a=o.transitions;for(let l=0;l<a.length;l++){const u=a[l];r.push({whenHas:n(u.whenHas),add:u.add,remove:u.remove})}}for(const o of c){const a=o.spawns;for(let l=0;l<a.length;l++)s(n(a[l]))}for(;e.length>0;){const o=e.pop();for(let a=0;a<r.length;a++){const l=r[a];if(!o.contains(l.whenHas))continue;const u=o.copy();if(l.add!==void 0)for(let d=0;d<l.add.length;d++)u.set(l.add[d].id);if(l.remove!==void 0)for(let d=0;d<l.remove.length;d++)u.clear(l.remove[d].id);s(u)}}const i=[];for(const o of t.values())for(let a=0;a<o.length;a++)i.push(o[a]);return i}function xe(c,t){return{name:`runIfResourceEq(${c.description??"?"})`,resourceReads:[c],evaluate:e=>e.getResource(c)===t}}function Me(c,t=0){const e=(t%c+c)%c;return{name:`runEveryNTicks(${c}${e!==0?`, +${e}`:""})`,evaluate:s=>(s.ecsTick-e)%c===0}}function Ne(c){return{name:"runIfAnyMatch",reads:c._defs,evaluate:()=>c.entityCount>0}}function ct(c){const t=[],e=[];for(const s of c)s.reads&&t.push(...s.reads),s.resourceReads&&e.push(...s.resourceReads);return{...t.length>0?{reads:t}:{},...e.length>0?{resourceReads:e}:{}}}function Fe(c){return{name:`not(${c.name})`,...ct([c]),evaluate:t=>!c.evaluate(t)}}function Le(...c){return{name:`allOf(${c.map(t=>t.name).join(", ")})`,...ct(c),evaluate:t=>c.every(e=>e.evaluate(t))}}function Be(...c){return{name:`anyOf(${c.map(t=>t.name).join(", ")})`,...ct(c),evaluate:t=>c.some(e=>e.evaluate(t))}}function Ge(c){return c.kind==="spawn"&&c.onSpawned!==void 0?{kind:"spawn",components:c.components}:c}class $e{seed;_startup=[];_ticks=[];sink=this._startup;constructor(t=0){this.seed=t}openTick(t,e){const s=this._ticks[this._ticks.length-1];if(s!==void 0&&s.tick===t){this.sink=s.commands;return}const n=[];this._ticks.push({tick:t,dt:e,commands:n}),this.sink=n}record=t=>{this.sink.push(Ge(t))};log(){return{seed:this.seed,startup:this._startup,ticks:this._ticks}}snapshotLog(){return{seed:this.seed,startup:this._startup.map(t=>({...t})),ticks:this._ticks.map(t=>({...t,commands:t.commands.map(e=>({...e}))}))}}}const q="__component_def";function Pe(c){return JSON.stringify(c,(t,e)=>{if(typeof e=="function"&&"id"in e)return{[q]:e.id};if(e!==null&&typeof e=="object"&&q in e)throw new h.ECSError(h.ECS_ERROR.COMMAND_LOG_TAG_COLLISION,`Cannot serialize the command log: a value object owns a field named "${q}", the reserved tag the serializer uses for component defs. Rename that component field so the log can round-trip losslessly.`);return e})}function Ue(c){return JSON.parse(c,(t,e)=>e!==null&&typeof e=="object"&&q in e?vt(Rt(e[q])):e)}function He(c,t,e,s){for(const i of e.startup)t.push(i);c.startup();const n=s?.hash??c.snapshots.deterministic,r=[];for(const i of e.ticks){for(const o of i.commands)t.push(o);c.update(i.dt),n&&r.push(c.snapshots.stateHash())}return{startupCommands:e.startup.length,ticks:e.ticks.length,stateHashes:r}}function tt(c){return c.name??`system#${c.id}`}class Ve{_frames=[];_current=null;tickBegin(t,e){const s={tick:t,dt:e,events:[]};this._current=s,this._frames.push(s)}tickEnd(t){this._current=null}systemStart(t,e){this._current?.events.push({kind:"system_start",system:tt(t),phase:e})}systemEnd(t){this._current?.events.push({kind:"system_end",system:tt(t)})}commandQueued(t,e,s){this._current?.events.push({kind:"command_queued",op:t,entity:e,component:s})}flushBegin(t){this._current?.events.push({kind:"flush_begin",phase:t})}flushEnd(t){this._current?.events.push({kind:"flush_end",phase:t})}phaseBoundary(t){}observerFired(t,e,s,n){this._current?.events.push({kind:"observer_fired",op:t,component:e,entity:s,observer:tt(n)})}eventEmitted(t){this._current?.events.push({kind:"event_emitted",key:t})}eventRead(t,e){this._current?.events.push({kind:"event_read",key:t,count:e})}frames(){return this._frames}reset(){this._frames.length=0,this._current=null}}function N(c,t){if(!(t>=0)||!Number.isFinite(t))throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,`${c} must be a finite number >= 0, got ${t}`);return t}function qe(c){if(!Number.isInteger(c)||c<0)throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,`frame count must be an integer >= 0, got ${c}`);return c}class We{ecs;requestFrame;cancelFrame;frameHandle=null;lastTimestampMs=null;running=!1;_fixedDt;_maxDt;constructor(t,e={}){this.ecs=t,this._fixedDt=N("fixedDt",e.fixedDt??1/60),this._maxDt=N("maxDt",e.maxDt??.25);const s=globalThis;this.requestFrame=e.requestFrame??s.requestAnimationFrame?.bind(globalThis),this.cancelFrame=e.cancelFrame??s.cancelAnimationFrame?.bind(globalThis),e.autoStart===!0&&this.play()}get fixedDt(){return this._fixedDt}set fixedDt(t){this._fixedDt=N("fixedDt",t)}get maxDt(){return this._maxDt}set maxDt(t){this._maxDt=N("maxDt",t)}get isRunning(){return this.running}step(t=this._fixedDt){this.ecs.update(N("dt",t))}stepFrames(t,e=this._fixedDt){qe(t);const s=N("dt",e);for(let n=0;n<t;n++)this.ecs.update(s)}play(){if(!this.running){if(this.requestFrame===void 0)throw new h.ECSError(h.ECS_ERROR.INVALID_FRAME_STEP,"FrameStepper.play() requires requestAnimationFrame or a requestFrame option");this.running=!0,this.lastTimestampMs=null,this.scheduleNextFrame()}}pause(){this.running=!1,this.lastTimestampMs=null,this.frameHandle!==null&&this.cancelFrame!==void 0&&this.cancelFrame(this.frameHandle),this.frameHandle=null}toggle(){this.running?this.pause():this.play()}dispose(){this.pause()}scheduleNextFrame(){this.frameHandle=this.requestFrame?.(this.onFrame)??null}onFrame=t=>{if(!this.running)return;const e=this.lastTimestampMs===null?this._fixedDt:(t-this.lastTimestampMs)/1e3;this.lastTimestampMs=t,this.ecs.update(Math.min(N("dt",e),this._maxDt)),this.running&&this.scheduleNextFrame()}}function ze(c,t){return c.relations.register({exclusive:!0,onDeleteTarget:t?.onDeleteTarget??"clear"})}function je(c,t){return c.relations.register({exclusive:!0,onDeleteTarget:t?.onDeleteTarget??"delete"})}function Ye(c){return h.unsafeCast(Symbol(c))}const Ke="0.5.3";exports.ANY_RELATION=h.ANY_RELATION;exports.ECSError=h.ECSError;exports.ECS_ERROR=h.ECS_ERROR;exports.HostCommandQueue=h.HostCommandQueue;exports.SCHEDULE=h.SCHEDULE;exports.SparseRestoreError=h.SparseRestoreError;exports.applyHostCommand=h.applyHostCommand;exports.getEntityIndex=h.getEntityIndex;exports.installHostCommandSeam=h.installHostCommandSeam;exports.isEcsError=h.isEcsError;exports.spawnEntry=h.spawnEntry;exports.systemSet=h.systemSet;exports.uninstallHostCommandSeam=h.uninstallHostCommandSeam;exports.SabUnavailableError=V.SabUnavailableError;exports.ChangedQuery=M;exports.ChunkColumns=kt;exports.Commands=Mt;exports.ECS=De;exports.ECSRestoreError=b;exports.ECS_SNAPSHOT_VERSION=K;exports.FrameStepper=We;exports.FrameTraceRecorder=Ve;exports.HIERARCHY_UNBOUNDED=ot;exports.HostCommandRecorder=$e;exports.Query=D;exports.QueryBuilder=xt;exports.StoreRestoreError=B;exports.SystemContext=Nt;exports.VERSION=Ke;exports.allOf=Le;exports.anyOf=Be;exports.bundle=Lt;exports.deserializeCommandLog=Ue;exports.eventKey=Ut;exports.not=Fe;exports.registerChildOf=je;exports.registerIsA=ze;exports.replayCommandLog=He;exports.resourceKey=Ye;exports.runEveryNTicks=Me;exports.runIfAnyMatch=Ne;exports.runIfResourceEq=xe;exports.serializeCommandLog=Pe;exports.signalKey=Ht;
|
package/dist/index.d.cts
CHANGED
|
@@ -7,7 +7,7 @@
|
|
|
7
7
|
* typed host→ECS write seam.
|
|
8
8
|
*
|
|
9
9
|
* Storage runs over a backing-neutral column store (`ColumnStore`). The default
|
|
10
|
-
* profile is **pure-TS heap** — a plain
|
|
10
|
+
* profile is **pure-TS heap** — a plain fixed `ArrayBuffer`, so no
|
|
11
11
|
* `SharedArrayBuffer` and no cross-origin isolation (COOP/COEP) are required.
|
|
12
12
|
* The opt-in `SharedArrayBuffer` + WASM profile lives at `@oasys/oecs/shared`.
|
|
13
13
|
*
|