UNPKG

agentjs-core

Version:

A comprehensive agent-based modeling framework with built-in p5.js visualization

1 lines 433 kB
(function(C,rt){typeof exports=="object"&&typeof module<"u"?rt(exports,require("@tensorflow/tfjs")):typeof define=="function"&&define.amd?define(["exports","@tensorflow/tfjs"],rt):(C=typeof globalThis<"u"?globalThis:C||self,rt(C.AgentJS={},C.tf))})(this,function(C,rt){"use strict";var ed=Object.defineProperty;var id=(C,rt,Ft)=>rt in C?ed(C,rt,{enumerable:!0,configurable:!0,writable:!0,value:Ft}):C[rt]=Ft;var M=(C,rt,Ft)=>(id(C,typeof rt!="symbol"?rt+"":rt,Ft),Ft);function Ft(s){const t=Object.create(null,{[Symbol.toStringTag]:{value:"Module"}});if(s){for(const e in s)if(e!=="default"){const i=Object.getOwnPropertyDescriptor(s,e);Object.defineProperty(t,e,i.get?i:{enumerable:!0,get:()=>s[e]})}}return t.default=s,Object.freeze(t)}const j=Ft(rt);function dr(s){return s&&s.__esModule&&Object.prototype.hasOwnProperty.call(s,"default")?s.default:s}var kn={exports:{}};(function(s){var t=Object.prototype.hasOwnProperty,e="~";function i(){}Object.create&&(i.prototype=Object.create(null),new i().__proto__||(e=!1));function n(c,l,h){this.fn=c,this.context=l,this.once=h||!1}function o(c,l,h,u,d){if(typeof h!="function")throw new TypeError("The listener must be a function");var f=new n(h,u||c,d),g=e?e+l:l;return c._events[g]?c._events[g].fn?c._events[g]=[c._events[g],f]:c._events[g].push(f):(c._events[g]=f,c._eventsCount++),c}function r(c,l){--c._eventsCount===0?c._events=new i:delete c._events[l]}function a(){this._events=new i,this._eventsCount=0}a.prototype.eventNames=function(){var l=[],h,u;if(this._eventsCount===0)return l;for(u in h=this._events)t.call(h,u)&&l.push(e?u.slice(1):u);return Object.getOwnPropertySymbols?l.concat(Object.getOwnPropertySymbols(h)):l},a.prototype.listeners=function(l){var h=e?e+l:l,u=this._events[h];if(!u)return[];if(u.fn)return[u.fn];for(var d=0,f=u.length,g=new Array(f);d<f;d++)g[d]=u[d].fn;return g},a.prototype.listenerCount=function(l){var h=e?e+l:l,u=this._events[h];return u?u.fn?1:u.length:0},a.prototype.emit=function(l,h,u,d,f,g){var p=e?e+l:l;if(!this._events[p])return!1;var m=this._events[p],y=arguments.length,b,x;if(m.fn){switch(m.once&&this.removeListener(l,m.fn,void 0,!0),y){case 1:return m.fn.call(m.context),!0;case 2:return m.fn.call(m.context,h),!0;case 3:return m.fn.call(m.context,h,u),!0;case 4:return m.fn.call(m.context,h,u,d),!0;case 5:return m.fn.call(m.context,h,u,d,f),!0;case 6:return m.fn.call(m.context,h,u,d,f,g),!0}for(x=1,b=new Array(y-1);x<y;x++)b[x-1]=arguments[x];m.fn.apply(m.context,b)}else{var v=m.length,w;for(x=0;x<v;x++)switch(m[x].once&&this.removeListener(l,m[x].fn,void 0,!0),y){case 1:m[x].fn.call(m[x].context);break;case 2:m[x].fn.call(m[x].context,h);break;case 3:m[x].fn.call(m[x].context,h,u);break;case 4:m[x].fn.call(m[x].context,h,u,d);break;default:if(!b)for(w=1,b=new Array(y-1);w<y;w++)b[w-1]=arguments[w];m[x].fn.apply(m[x].context,b)}}return!0},a.prototype.on=function(l,h,u){return o(this,l,h,u,!1)},a.prototype.once=function(l,h,u){return o(this,l,h,u,!0)},a.prototype.removeListener=function(l,h,u,d){var f=e?e+l:l;if(!this._events[f])return this;if(!h)return r(this,f),this;var g=this._events[f];if(g.fn)g.fn===h&&(!d||g.once)&&(!u||g.context===u)&&r(this,f);else{for(var p=0,m=[],y=g.length;p<y;p++)(g[p].fn!==h||d&&!g[p].once||u&&g[p].context!==u)&&m.push(g[p]);m.length?this._events[f]=m.length===1?m[0]:m:r(this,f)}return this},a.prototype.removeAllListeners=function(l){var h;return l?(h=e?e+l:l,this._events[h]&&r(this,h)):(this._events=new i,this._eventsCount=0),this},a.prototype.off=a.prototype.removeListener,a.prototype.addListener=a.prototype.on,a.prefixed=e,a.EventEmitter=a,s.exports=a})(kn);var fr=kn.exports;const K=dr(fr);let Ve;const gr=new Uint8Array(16);function pr(){if(!Ve&&(Ve=typeof crypto<"u"&&crypto.getRandomValues&&crypto.getRandomValues.bind(crypto),!Ve))throw new Error("crypto.getRandomValues() not supported. See https://github.com/uuidjs/uuid#getrandomvalues-not-supported");return Ve(gr)}const G=[];for(let s=0;s<256;++s)G.push((s+256).toString(16).slice(1));function mr(s,t=0){return G[s[t+0]]+G[s[t+1]]+G[s[t+2]]+G[s[t+3]]+"-"+G[s[t+4]]+G[s[t+5]]+"-"+G[s[t+6]]+G[s[t+7]]+"-"+G[s[t+8]]+G[s[t+9]]+"-"+G[s[t+10]]+G[s[t+11]]+G[s[t+12]]+G[s[t+13]]+G[s[t+14]]+G[s[t+15]]}const In={randomUUID:typeof crypto<"u"&&crypto.randomUUID&&crypto.randomUUID.bind(crypto)};function yr(s,t,e){if(In.randomUUID&&!t&&!s)return In.randomUUID();s=s||{};const i=s.random||(s.rng||pr)();if(i[6]=i[6]&15|64,i[8]=i[8]&63|128,t){e=e||0;for(let n=0;n<16;++n)t[e+n]=i[n];return t}return mr(i)}class Ei extends K{constructor(t=yr(),e={},i={x:0,y:0}){super(),this.state="active",this.id=t,this.properties=new Map(Object.entries(e)),this._position=i,this.createdAt=Date.now(),this.lastUpdated=this.createdAt,this.validateInitialState(),this.emitLifecycleEvent("agentCreated")}getProperty(t){return this.properties.get(t)}setProperty(t,e){this.validateProperty(t,e);const i=this.properties.get(t);this.properties.set(t,e),this.lastUpdated=Date.now(),this.emitPropertyChanged(t,i??null,e)}getProperties(){return Object.fromEntries(this.properties.entries())}getAllProperties(){return Object.fromEntries(this.properties.entries())}hasProperty(t){return this.properties.has(t)}removeProperty(t){const e=this.properties.has(t);if(e){const i=this.properties.get(t);this.properties.delete(t),this.lastUpdated=Date.now(),this.emitPropertyChanged(t,i??null,null)}return e}get position(){return this._position}getPosition(){return this._position}setPosition(t){this.validatePosition(t);const e=this._position;this._position=t,this.lastUpdated=Date.now(),this.emitPositionChanged(e,t)}translate(t,e){const i={x:this._position.x+t,y:this._position.y+e};this.setPosition(i)}get currentState(){return this.state}activate(){this.state!=="active"&&(this.state="active",this.emitLifecycleEvent("agentActivated"))}deactivate(){this.state==="active"&&(this.state="dormant",this.emitLifecycleEvent("agentDeactivated"))}destroy(){this.state!=="destroyed"&&(this.state="destroyed",this.emitLifecycleEvent("agentDestroyed"),this.removeAllListeners())}isActive(){return this.state==="active"}isDestroyed(){return this.state==="destroyed"}toJSON(){return{id:this.id,state:this.state,position:this._position,properties:Object.fromEntries(this.properties.entries()),createdAt:this.createdAt,lastUpdated:this.lastUpdated}}toString(){return`Agent(${this.id}, ${this.state}, ${this._position.x}, ${this._position.y})`}validateProperty(t,e){if(t===""||t===null)throw new Error("Property key cannot be empty or null");if(e!==null&&typeof e=="object"&&!Array.isArray(e))try{JSON.stringify(e)}catch{throw new Error("Property value must be JSON serializable")}}validatePosition(t){if(!isFinite(t.x)||!isFinite(t.y))throw new Error("Position coordinates must be finite numbers")}validateInitialState(){if(!this.id||this.id.length===0)throw new Error("Agent ID cannot be empty")}emitPropertyChanged(t,e,i){const n={type:"propertyChanged",timestamp:Date.now(),agent:this,property:t,oldValue:e,newValue:i};this.emit("propertyChanged",n)}emitPositionChanged(t,e){const i={type:"positionChanged",timestamp:Date.now(),agent:this,oldPosition:t,newPosition:e};this.emit("positionChanged",i)}emitLifecycleEvent(t){const e={type:t,timestamp:Date.now(),agent:this};this.emit(t,e)}}class le extends Ei{constructor(t,e={},i={x:0,y:0}){super(t,e,i)}step(){}moveTo(t){this.setPosition(t)}moveBy(t,e){this.translate(t,e)}setEnergy(t){if(t<0)throw new Error("Energy cannot be negative");this.setProperty("energy",t)}getEnergy(){return this.getProperty("energy")??100}setActivity(t){if(t<0||t>1)throw new Error("Activity must be between 0 and 1");this.setProperty("activity",t)}getActivity(){return this.getProperty("activity")??.5}isAt(t){return this.position.x===t.x&&this.position.y===t.y}distanceTo(t){const e=this.position.x-t.x,i=this.position.y-t.y;return Math.sqrt(e*e+i*i)}distanceToAgent(t){return this.distanceTo(t.position)}isNear(t,e){return this.distanceTo(t)<=e}isNearAgent(t,e){return this.distanceToAgent(t)<=e}}class En extends le{constructor(t,e={},i={x:0,y:0},n={}){super(t,e,i),this.velocity={vx:0,vy:0},this.previousPosition=i,e.x!==void 0&&(i={...i,x:e.x}),e.y!==void 0&&(i={...i,y:e.y}),this.setProperty("x",i.x),this.setProperty("y",i.y),this.movementConfig={maxSpeed:5,acceleration:1,friction:.95,bounceOnBoundary:!0,...n}}step(){this.previousPosition=this.position;const t=this.getProperty("velocityX"),e=this.getProperty("velocityY");t!==void 0&&e!==void 0&&(this.velocity={vx:t,vy:e}),this.velocity=this.applyFriction(this.velocity),this.velocity=this.limitSpeed(this.velocity);const i={x:this.position.x+this.velocity.vx,y:this.position.y+this.velocity.vy};this.setPosition(i),this.setProperty("x",i.x),this.setProperty("y",i.y)}setVelocity(t,e){this.velocity={vx:t,vy:e}}getVelocity(){return{...this.velocity}}addForce(t,e){const i=this.movementConfig.acceleration;this.velocity={vx:this.velocity.vx+t*i,vy:this.velocity.vy+e*i}}applyImpulse(t,e){this.velocity={vx:this.velocity.vx+t,vy:this.velocity.vy+e}}stop(){this.velocity={vx:0,vy:0}}setSpeed(t){const e=this.getSpeed();if(e>0){const i=t/e;this.velocity={vx:this.velocity.vx*i,vy:this.velocity.vy*i}}}getSpeed(){return Math.sqrt(this.velocity.vx*this.velocity.vx+this.velocity.vy*this.velocity.vy)}getDirection(){return Math.atan2(this.velocity.vy,this.velocity.vx)}moveToward(t,e=1){const i=t.x-this.position.x,n=t.y-this.position.y,o=Math.sqrt(i*i+n*n);if(o>0){const r=i/o*e,a=n/o*e;this.addForce(r,a)}}moveAway(t,e=1){const i=this.position.x-t.x,n=this.position.y-t.y,o=Math.sqrt(i*i+n*n);if(o>0){const r=i/o*e,a=n/o*e;this.addForce(r,a)}}wander(t=.5){const e=Math.random()*2*Math.PI,i=Math.cos(e)*t,n=Math.sin(e)*t;this.addForce(i,n)}getMovementConfig(){return{...this.movementConfig}}updateMovementConfig(t){this.movementConfig={...this.movementConfig,...t}}isMoving(){return this.getSpeed()>.001}handleBoundaryCollision(t){let{vx:e,vy:i}=this.velocity;(this.position.x<=0||this.position.x>=t.width)&&(this.movementConfig.bounceOnBoundary?e=-e*.8:e=0),(this.position.y<=0||this.position.y>=t.height)&&(this.movementConfig.bounceOnBoundary?i=-i*.8:i=0),this.velocity={vx:e,vy:i}}applyFriction(t){const e=this.movementConfig.friction;return{vx:t.vx*e,vy:t.vy*e}}limitSpeed(t){const e=Math.sqrt(t.vx*t.vx+t.vy*t.vy),i=this.movementConfig.maxSpeed;if(e>i){const n=i/e;return{vx:t.vx*n,vy:t.vy*n}}return t}}class Lt extends le{constructor(t,e={},i={x:0,y:0}){super(t,e,i),this.connections=new Map,this.incomingConnections=new Set,this.influence=1,this.trustLevels=new Map}step(){this.decayConnections(),this.updateInfluence()}connect(t,e="default",i=1,n={}){if(t.id===this.id)throw new Error("Agent cannot connect to itself");if(i<0||i>1)throw new Error("Connection strength must be between 0 and 1");const o={target:t,type:e,strength:i,createdAt:Date.now(),lastInteraction:Date.now(),metadata:{...n}};this.connections.set(t.id,o),t instanceof Lt&&t.addIncomingConnection(this.id),this.emitConnectionEvent("connectionFormed",t,e,i)}disconnect(t){const e=this.connections.has(t.id);if(e){const i=this.connections.get(t.id);this.connections.delete(t.id),t instanceof Lt&&t.removeIncomingConnection(this.id),this.emitConnectionEvent("connectionBroken",t,i.type,i.strength)}return e}isConnectedTo(t){return this.connections.has(t.id)}getConnection(t){return this.connections.get(t.id)}getAllConnections(){return Array.from(this.connections.values())}getConnectionsByType(t){return Array.from(this.connections.values()).filter(e=>e.type===t)}getConnectionCount(){return this.connections.size}getStrongConnections(){return Array.from(this.connections.values()).filter(t=>t.strength>.7)}getWeakConnections(){return Array.from(this.connections.values()).filter(t=>t.strength<=.3)}updateConnectionStrength(t,e){if(e<0||e>1)throw new Error("Connection strength must be between 0 and 1");const i=this.connections.get(t.id);if(!i)throw new Error(`No connection to agent ${t.id}`);const n={...i,strength:e,lastInteraction:Date.now()};this.connections.set(t.id,n),this.emitConnectionEvent("connectionModified",t,i.type,e)}strengthenConnection(t,e=.1){const i=this.connections.get(t.id);if(i){const n=Math.min(1,i.strength+e);this.updateConnectionStrength(t,n)}}weakenConnection(t,e=.1){const i=this.connections.get(t.id);if(i){const n=Math.max(0,i.strength-e);n===0?this.disconnect(t):this.updateConnectionStrength(t,n)}}setTrust(t,e){if(e<0||e>1)throw new Error("Trust level must be between 0 and 1");this.trustLevels.set(t.id,e)}getTrust(t){return this.trustLevels.get(t.id)??.5}getInfluence(){return this.influence}setInfluence(t){if(t<0)throw new Error("Influence cannot be negative");this.influence=t}getNeighbors(){return Array.from(this.connections.values()).map(t=>t.target)}getTrustedNeighbors(t=.7){return this.getNeighbors().filter(e=>this.getTrust(e)>=t)}getNetworkStats(){const t=Array.from(this.connections.values()),e=t.filter(r=>r.strength>.7),i=t.filter(r=>r.strength<=.3),n=t.length>0?t.reduce((r,a)=>r+a.strength,0)/t.length:0,o=this.calculateClusteringCoefficient();return{connectionCount:t.length,strongConnections:e.length,weakConnections:i.length,averageStrength:n,mostConnectedAgent:this.findMostConnectedNeighbor(),clusteringCoefficient:o}}addIncomingConnection(t){this.incomingConnections.add(t)}removeIncomingConnection(t){this.incomingConnections.delete(t)}getIncomingConnectionCount(){return this.incomingConnections.size}getDegreeCentrality(){return this.connections.size+this.incomingConnections.size}decayConnections(){const e=Date.now(),i=24*60*60*1e3;for(const[n,o]of this.connections.entries()){const r=e-o.lastInteraction;if(r>i){const a=Math.min(.001*r/i,.1),c=Math.max(0,o.strength-a);if(c===0)this.connections.delete(n),this.emitConnectionEvent("connectionBroken",o.target,o.type,0);else{const l={...o,strength:c};this.connections.set(n,l)}}}}updateInfluence(){const t=Array.from(this.connections.values()).reduce((i,n)=>i+n.strength,0),e=this.incomingConnections.size*.5;this.influence=Math.max(.1,1+t*.1+e*.1)}calculateClusteringCoefficient(){const t=this.getNeighbors();if(t.length<2)return 0;let e=0,i=0;for(let n=0;n<t.length;n++)for(let o=n+1;o<t.length;o++){i++;const r=t[n],a=t[o];r instanceof Lt&&a&&r.isConnectedTo(a)&&e++}return i>0?e/i:0}findMostConnectedNeighbor(){let t=-1,e=null;for(const i of this.getNeighbors())if(i instanceof Lt){const n=i.getConnectionCount();n>t&&(t=n,e=i.id)}return e}emitConnectionEvent(t,e,i,n){const o={type:t,timestamp:Date.now(),source:this,target:e,connectionType:i,strength:n};this.emit(t,o)}}class Ri extends K{constructor(t){super(),this.validateDimensions(t),this.dimensions={...t},this.agents=new Set,this.agentPositions=new Map}addAgent(t,e){if(this.agents.has(t))throw new Error(`Agent ${t.id} is already in this environment`);const i=e??t.position;this.validatePosition(i),this.agents.add(t),this.agentPositions.set(t,i),e&&t.setPosition(i),this.onAgentAdded(t,i),this.emit("agentAdded",{agent:t,position:i})}removeAgent(t){return this.agents.has(t)?(this.agents.delete(t),this.agentPositions.delete(t),this.onAgentRemoved(t),this.emit("agentRemoved",{agent:t}),!0):!1}moveAgent(t,e){if(!this.agents.has(t))throw new Error(`Agent ${t.id} is not in this environment`);const i=this.applyBoundaryConditions(e),n=this.agentPositions.get(t);this.agentPositions.set(t,i),t.setPosition(i),this.onAgentMoved(t,n,i),this.emit("agentMoved",{agent:t,oldPosition:n,newPosition:i})}getAgentPosition(t){return this.agentPositions.get(t)}getAllAgents(){return Array.from(this.agents)}getAgentCount(){return this.agents.size}isValidPosition(t){return t.x>=0&&t.x<=this.dimensions.width&&t.y>=0&&t.y<=this.dimensions.height}applyBoundaryConditions(t){switch(this.dimensions.boundaryType){case"periodic":return this.applyPeriodicBoundary(t);case"reflective":return this.applyReflectiveBoundary(t);case"absorbing":return this.applyAbsorbingBoundary(t);default:throw new Error(`Unknown boundary type: ${this.dimensions.boundaryType}`)}}distance(t,e){const i=t.x-e.x,n=t.y-e.y;return Math.sqrt(i*i+n*n)}getDimensions(){return{...this.dimensions}}onAgentAdded(t,e){}onAgentRemoved(t){}onAgentMoved(t,e,i){}validateDimensions(t){if(t.width<=0||t.height<=0)throw new Error("Environment dimensions must be positive");if(!isFinite(t.width)||!isFinite(t.height))throw new Error("Environment dimensions must be finite")}validatePosition(t){if(!isFinite(t.x)||!isFinite(t.y))throw new Error("Position coordinates must be finite numbers")}applyPeriodicBoundary(t){const e=(t.x%this.dimensions.width+this.dimensions.width)%this.dimensions.width,i=(t.y%this.dimensions.height+this.dimensions.height)%this.dimensions.height;return{x:e,y:i}}applyReflectiveBoundary(t){let e=t.x,i=t.y;return e<0&&(e=-e),e>this.dimensions.width&&(e=2*this.dimensions.width-e),i<0&&(i=-i),i>this.dimensions.height&&(i=2*this.dimensions.height-i),{x:e,y:i}}applyAbsorbingBoundary(t){const e=Math.max(0,Math.min(this.dimensions.width,t.x)),i=Math.max(0,Math.min(this.dimensions.height,t.y));return{x:e,y:i}}}class Rn extends Ri{constructor(t,e){let i;typeof t=="number"&&e!==void 0?i={width:t,height:e,boundaryType:"absorbing",enableSpatialIndex:!0,maxObjectsPerNode:10,maxTreeDepth:6}:i=t,super(i),this.config={...i},this.quadtree=null,this.distanceFunction=(n,o)=>{const r=n.x-o.x,a=n.y-o.y;return Math.sqrt(r*r+a*a)},this.initializeQuadtree()}findNeighbors(t,e,i={}){const n=performance.now(),o=i.maxResults??Number.MAX_SAFE_INTEGER,r=i.includeDistance??!1,a=this.config.enableSpatialIndex&&this.quadtree?this.queryQuadtree(t,e):Array.from(this.agents),c=[],l=[];for(const h of a){if(c.length>=o)break;const u=this.agentPositions.get(h);if(!u)continue;const d=this.distanceFunction(t,u);if(d<=e){if(i.filterFn&&!i.filterFn(h))continue;c.push(h),r&&l.push(d)}}if(r&&l.length>0){const h=c.map((u,d)=>({agent:u,distance:l[d]??0}));h.sort((u,d)=>u.distance-d.distance),c.length=0,l.length=0;for(const u of h)c.push(u.agent),l.push(u.distance)}return{items:c,distances:r?l:[],queryTime:performance.now()-n}}getAgentsAt(t){return this.findNeighbors(t,.001).items}setDistanceFunction(t){this.distanceFunction=t}static getManhattanDistance(){return(t,e)=>Math.abs(t.x-e.x)+Math.abs(t.y-e.y)}static getEuclideanDistance(){return(t,e)=>{const i=t.x-e.x,n=t.y-e.y;return Math.sqrt(i*i+n*n)}}static getChebyshevDistance(){return(t,e)=>Math.max(Math.abs(t.x-e.x),Math.abs(t.y-e.y))}getConfig(){return{...this.config}}updateConfig(t){Object.assign(this.config,t),("enableSpatialIndex"in t||"maxObjectsPerNode"in t||"maxTreeDepth"in t)&&this.rebuildQuadtree()}getQuadtreeStats(){return this.quadtree?this.calculateQuadtreeStats(this.quadtree):{nodeCount:0,maxDepth:0,agentCount:0}}rebuildQuadtree(){if(this.config.enableSpatialIndex){this.initializeQuadtree();for(const[t,e]of this.agentPositions.entries())this.insertIntoQuadtree(t,e)}}needsRebalancing(){if(!this.quadtree||!this.config.enableSpatialIndex)return!1;const t=this.getQuadtreeStats(),e=t.agentCount/t.nodeCount;return t.maxDepth>this.config.maxTreeDepth*1.5||e<this.config.maxObjectsPerNode*.2}rebalanceQuadtree(){if(!this.needsRebalancing())return;const t=[];for(const[i,n]of this.agentPositions.entries())t.push({agent:i,position:n});this.initializeQuadtree();const e=this.sortByMortonCode(t);for(const{agent:i,position:n}of e)this.insertIntoQuadtree(i,n)}sortByMortonCode(t){return t.sort((e,i)=>{const n=this.calculateMortonCode(e.position),o=this.calculateMortonCode(i.position);return n-o})}calculateMortonCode(t){const e=Math.floor(t.x/this.dimensions.width*65535),i=Math.floor(t.y/this.dimensions.height*65535);let n=0;for(let o=0;o<16;o++)n|=(e&1<<o)<<o|(i&1<<o)<<o+1;return n}tryMergeNode(t){if(!t.children)return!1;let e=0;for(const i of t.children){if(i.children)return!1;e+=i.agents.length}if(e<=this.config.maxObjectsPerNode){t.agents=[];for(const i of t.children)t.agents.push(...i.agents);return t.children=null,!0}return!1}optimizeQuadtree(){!this.quadtree||!this.config.enableSpatialIndex||this.optimizeNode(this.quadtree)}optimizeNode(t){if(t.children){for(const e of t.children)this.optimizeNode(e);this.tryMergeNode(t)}}onAgentAdded(t,e){this.config.enableSpatialIndex&&this.quadtree&&this.insertIntoQuadtree(t,e)}onAgentRemoved(t){this.config.enableSpatialIndex&&this.quadtree&&this.removeFromQuadtree(t)}onAgentMoved(t,e,i){this.config.enableSpatialIndex&&this.quadtree&&(this.removeFromQuadtree(t),this.insertIntoQuadtree(t,i))}initializeQuadtree(){if(!this.config.enableSpatialIndex){this.quadtree=null;return}this.quadtree={bounds:{x:0,y:0,width:this.dimensions.width,height:this.dimensions.height},agents:[],children:null,level:0}}insertIntoQuadtree(t,e){this.quadtree&&this.insertIntoNode(this.quadtree,t,e)}removeFromQuadtree(t){this.quadtree&&this.removeFromNode(this.quadtree,t)}insertIntoNode(t,e,i){if(this.pointInBounds(i,t.bounds)){if(t.children){for(const n of t.children)this.insertIntoNode(n,e,i);return}t.agents.push(e),t.agents.length>this.config.maxObjectsPerNode&&t.level<this.config.maxTreeDepth&&this.splitNode(t)}}removeFromNode(t,e){const i=t.agents.indexOf(e);if(i>=0)return t.agents.splice(i,1),!0;if(t.children){for(const n of t.children)if(this.removeFromNode(n,e))return!0}return!1}splitNode(t){const{x:e,y:i,width:n,height:o}=t.bounds,r=n/2,a=o/2;t.children=[{bounds:{x:e,y:i,width:r,height:a},agents:[],children:null,level:t.level+1},{bounds:{x:e+r,y:i,width:r,height:a},agents:[],children:null,level:t.level+1},{bounds:{x:e,y:i+a,width:r,height:a},agents:[],children:null,level:t.level+1},{bounds:{x:e+r,y:i+a,width:r,height:a},agents:[],children:null,level:t.level+1}];for(const c of t.agents){const l=this.agentPositions.get(c);if(l){for(const h of t.children)if(this.pointInBounds(l,h.bounds)){this.insertIntoNode(h,c,l);break}}}t.agents=[]}queryQuadtree(t,e){if(!this.quadtree)return[];const i=[];return this.queryNode(this.quadtree,t,e,i),i}queryNode(t,e,i,n){if(this.circleIntersectsBounds(e,i,t.bounds)&&(n.push(...t.agents),t.children))for(const o of t.children)this.queryNode(o,e,i,n)}pointInBounds(t,e){return t.x>=e.x&&t.x<e.x+e.width&&t.y>=e.y&&t.y<e.y+e.height}circleIntersectsBounds(t,e,i){const n=Math.max(i.x,Math.min(t.x,i.x+i.width)),o=Math.max(i.y,Math.min(t.y,i.y+i.height)),r=t.x-n,a=t.y-o;return r*r+a*a<=e*e}calculateQuadtreeStats(t){let e=1,i=t.level,n=t.agents.length;if(t.children)for(const o of t.children){const r=this.calculateQuadtreeStats(o);e+=r.nodeCount,i=Math.max(i,r.maxDepth),n+=r.agentCount}return{nodeCount:e,maxDepth:i,agentCount:n}}}class br extends Ri{constructor(t,e,i){let n;if(typeof t=="number"&&e!==void 0){const o=t,r=i||1;n={width:e*r,height:o*r,boundaryType:"absorbing",rows:o,cols:e,neighborhoodType:"moore",allowMultipleOccupancy:!0}}else n=t;super(n),this.config={...n},this.agentCoordinates=new Map,this.grid=this.initializeGrid(),this.validateConfiguration()}findNeighbors(t,e,i={}){const n=performance.now(),o=i.maxResults??Number.MAX_SAFE_INTEGER,r=this.positionToGrid(t);if(!this.isValidCoordinate(r))return{items:[],distances:[],queryTime:performance.now()-n};const a=[],c=[],l=Math.floor(e);for(let h=-l;h<=l;h++)for(let u=-l;u<=l&&!(a.length>=o);u++){const d={row:r.row+h,col:r.col+u};if(!this.isValidCoordinate(d))continue;const f=this.gridDistance(r,d);if(f>e)continue;const g=this.grid[d.row]?.[d.col];if(g)for(const p of g.agents){if(a.length>=o)break;i.filterFn&&!i.filterFn(p)||(a.push(p),i.includeDistance&&c.push(f))}}if(i.includeDistance&&c.length>0){const h=a.map((u,d)=>({agent:u,distance:c[d]??0}));h.sort((u,d)=>u.distance-d.distance),a.length=0,c.length=0;for(const u of h)a.push(u.agent),c.push(u.distance)}return{items:a,distances:i.includeDistance?c:[],queryTime:performance.now()-n}}getAgentsAt(t){const e=this.positionToGrid(t);if(!this.isValidCoordinate(e))return[];const i=this.grid[e.row]?.[e.col];return i?Array.from(i.agents):[]}getAgentsAtCell(t){if(!this.isValidCoordinate(t))return[];const e=this.grid[t.row]?.[t.col];return e?Array.from(e.agents):[]}getAgentGridCoordinate(t){return this.agentCoordinates.get(t)}getCellNeighbors(t){const e=[];if(this.config.neighborhoodType==="moore")for(let i=-1;i<=1;i++)for(let n=-1;n<=1;n++){if(i===0&&n===0)continue;const o={row:t.row+i,col:t.col+n};this.isValidCoordinate(o)&&e.push(o)}else{const i=[{row:-1,col:0},{row:1,col:0},{row:0,col:-1},{row:0,col:1}];for(const n of i){const o={row:t.row+n.row,col:t.col+n.col};this.isValidCoordinate(o)&&e.push(o)}}return e}canPlaceAgent(t){if(!this.isValidCoordinate(t))return!1;const e=this.grid[t.row]?.[t.col];return e?this.config.allowMultipleOccupancy?e.agents.size<e.maxOccupancy:e.agents.size===0:!1}getEmptyCells(){const t=[];for(let e=0;e<this.config.rows;e++)for(let i=0;i<this.config.cols;i++){const n={row:e,col:i};this.canPlaceAgent(n)&&t.push(n)}return t}getOccupancyStats(){let t=0,e=0,i=0;for(let o=0;o<this.config.rows;o++)for(let r=0;r<this.config.cols;r++){const a=this.grid[o]?.[r];if(!a)continue;const c=a.agents.size;c>0&&(t++,e+=c,i=Math.max(i,c))}const n=this.config.rows*this.config.cols;return{totalCells:n,occupiedCells:t,emptyCells:n-t,averageOccupancy:t>0?e/t:0,maxOccupancy:i}}positionToGrid(t){const e=this.dimensions.width/this.config.cols,i=this.dimensions.height/this.config.rows;return{row:Math.floor(t.y/i),col:Math.floor(t.x/e)}}gridToPosition(t){const e=this.dimensions.width/this.config.cols,i=this.dimensions.height/this.config.rows;return{x:(t.col+.5)*e,y:(t.row+.5)*i}}gridDistance(t,e){return this.config.neighborhoodType==="moore"?Math.max(Math.abs(t.row-e.row),Math.abs(t.col-e.col)):Math.abs(t.row-e.row)+Math.abs(t.col-e.col)}getGridConfig(){return{...this.config}}placeAgentAtCell(t,e){if(!this.canPlaceAgent(e))return!1;this.removeAgentFromGrid(t);const i=this.grid[e.row]?.[e.col];if(!i)return!1;i.agents.add(t),this.agentCoordinates.set(t,e);const n=this.gridToPosition(e);return t.setPosition(n),!0}onAgentAdded(t,e){const i=this.positionToGrid(e);if(this.isValidCoordinate(i)&&this.canPlaceAgent(i)){const n=this.grid[i.row]?.[i.col];if(!n)throw new Error(`Invalid grid cell at ${i.row}, ${i.col}`);n.agents.add(t),this.agentCoordinates.set(t,i);const o=this.gridToPosition(i);t.setPosition(o)}else throw new Error(`Cannot place agent at position ${e.x}, ${e.y} - cell occupied or invalid`)}onAgentRemoved(t){this.removeAgentFromGrid(t)}onAgentMoved(t,e,i){const n=this.positionToGrid(i);if(!this.isValidCoordinate(n))throw new Error(`Invalid grid position: ${n.row}, ${n.col}`);const o=this.agentCoordinates.get(t);if(!o||o.row!==n.row||o.col!==n.col){if(!this.canPlaceAgent(n))throw new Error(`Cannot move agent to occupied cell: ${n.row}, ${n.col}`);if(o&&this.isValidCoordinate(o)){const c=this.grid[o.row]?.[o.col];c&&c.agents.delete(t)}const r=this.grid[n.row]?.[n.col];if(!r)throw new Error(`Invalid grid cell at ${n.row}, ${n.col}`);r.agents.add(t),this.agentCoordinates.set(t,n);const a=this.gridToPosition(n);t.setPosition(a)}}initializeGrid(){const t=[];for(let e=0;e<this.config.rows;e++){t[e]=[];for(let i=0;i<this.config.cols;i++)t[e][i]={coordinate:{row:e,col:i},agents:new Set,maxOccupancy:this.config.allowMultipleOccupancy?10:1}}return t}isValidCoordinate(t){return t.row>=0&&t.row<this.config.rows&&t.col>=0&&t.col<this.config.cols}removeAgentFromGrid(t){const e=this.agentCoordinates.get(t);if(e&&this.isValidCoordinate(e)){const i=this.grid[e.row]?.[e.col];i&&i.agents.delete(t)}this.agentCoordinates.delete(t)}validateConfiguration(){if(this.config.rows<=0||this.config.cols<=0)throw new Error("Grid dimensions must be positive");if(this.dimensions.width/this.config.cols<1||this.dimensions.height/this.config.rows<1)throw new Error("Grid cells are too small for given dimensions")}}class Oi extends K{constructor(t){super(),this.agents=new Set,this.stepNumber=0,this.lastStepTime=0,this.totalSteps=0,this.randomSeed=t,this.randomSeed!==void 0&&this.initializeRandom(this.randomSeed)}addAgent(t){if(this.agents.has(t))throw new Error(`Agent ${t.id} is already scheduled`);this.agents.add(t),this.onAgentAdded(t),this.emit("agentAdded",{agent:t,schedulerSize:this.agents.size})}removeAgent(t){return this.agents.has(t)?(this.agents.delete(t),this.onAgentRemoved(t),this.emit("agentRemoved",{agent:t,schedulerSize:this.agents.size}),!0):!1}getAgents(){return Array.from(this.agents)}getAgentCount(){return this.agents.size}step(){const t=performance.now(),i=this.getActivationOrder().filter(n=>n.isActive());this.emit("stepStarted",{stepNumber:this.stepNumber,agentCount:i.length});for(const n of i)try{n.step()}catch(o){this.emit("agentStepError",{agent:n,error:o,stepNumber:this.stepNumber}),console.warn(`Agent ${n.id} step failed:`,o)}this.stepNumber++,this.totalSteps++,this.lastStepTime=performance.now()-t,this.emit("stepCompleted",{stepNumber:this.stepNumber,executionTime:this.lastStepTime,agentCount:i.length})}reset(){this.stepNumber=0,this.totalSteps=0,this.lastStepTime=0,this.randomSeed!==void 0&&this.initializeRandom(this.randomSeed),this.emit("schedulerReset")}getCurrentStep(){return this.stepNumber}getTotalSteps(){return this.totalSteps}getLastStepTime(){return this.lastStepTime}getStatistics(){const t=this.totalSteps>0?this.lastStepTime/this.totalSteps:0;return{totalAgents:this.agents.size,activeAgents:Array.from(this.agents).filter(e=>e.isActive()).length,currentStep:this.stepNumber,totalSteps:this.totalSteps,lastStepTime:this.lastStepTime,averageStepTime:t,schedulerType:this.getSchedulerType()}}onAgentAdded(t){}onAgentRemoved(t){}initializeRandom(t){let e=t;Math.random=()=>(e=(e*1664525+1013904223)%4294967296,e/4294967296)}}class On extends Oi{constructor(t){super(),this.seed=t,this.rngState=t??Date.now()}getActivationOrder(){return this.schedule(this.getAgents())}getSchedulerType(){return this.getType()}schedule(t){const e=t.filter(n=>n.isActive());if(e.length===0)return[];const i=[...e];return this.shuffleArray(i),i}setSeed(t){this.seed=t,this.rngState=t}getSeed(){return this.seed}resetSeed(){this.rngState=this.seed??Date.now()}getType(){return"random"}getConfiguration(){return{type:this.getType(),seed:this.seed,currentRngState:this.rngState,reproducible:this.seed!==void 0}}shuffleArray(t){for(let e=t.length-1;e>0;e--){const i=Math.floor(this.seededRandom()*(e+1)),n=t[e],o=t[i];n!==void 0&&o!==void 0&&(t[e]=o,t[i]=n)}}seededRandom(){if(this.seed===void 0)return Math.random();const t=1664525,e=1013904223,i=Math.pow(2,32);return this.rngState=(t*this.rngState+e)%i,this.rngState/i}}class xr extends Oi{constructor(t="creation",e,i=!1){super(),this.mode=t,this.orderingFunction=e,this.reversed=i,this.creationOrderCache=new Map}getActivationOrder(){return this.schedule(this.getAgents())}getSchedulerType(){return this.getType()}schedule(t){const e=t.filter(n=>n.isActive());return e.length===0?[]:this.sortAgents([...e])}setMode(t,e){this.mode=t,this.orderingFunction=e}getMode(){return this.mode}setReversed(t){this.reversed=t}isReversed(){return this.reversed}setOrderingFunction(t){this.mode="custom",this.orderingFunction=t}getType(){return"sequential"}getConfiguration(){return{type:this.getType(),mode:this.mode,reversed:this.reversed,hasCustomFunction:this.orderingFunction!==void 0}}cacheCreationOrder(t){for(let e=0;e<t.length;e++){const i=t[e];i&&!this.creationOrderCache.has(i.id)&&this.creationOrderCache.set(i.id,e)}}clearCreationOrderCache(){this.creationOrderCache.clear()}sortAgents(t){let e;switch(this.mode){case"creation":e=(i,n)=>this.compareByCreationOrder(i,n);break;case"id":e=(i,n)=>this.compareById(i,n);break;case"custom":if(!this.orderingFunction)throw new Error("Custom ordering function not provided");e=this.orderingFunction;break;default:throw new Error(`Unknown scheduling mode: ${this.mode}`)}return t.sort(e),this.reversed&&t.reverse(),t}compareByCreationOrder(t,e){const i=this.creationOrderCache.get(t.id)??Number.MAX_SAFE_INTEGER,n=this.creationOrderCache.get(e.id)??Number.MAX_SAFE_INTEGER;if(i!==n)return i-n;const o=t.hasOwnProperty("createdAt")?t.createdAt:0,r=e.hasOwnProperty("createdAt")?e.createdAt:0;return o-r}compareById(t,e){return t.id.localeCompare(e.id)}static createOrderingFunctions(){return{byEnergyDesc:(t,e)=>{const i=t.getProperty("energy")??0;return(e.getProperty("energy")??0)-i},byEnergyAsc:(t,e)=>{const i=t.getProperty("energy")??0,n=e.getProperty("energy")??0;return i-n},byDistanceFromOrigin:(t,e)=>{const i=Math.sqrt(t.position.x*t.position.x+t.position.y*t.position.y),n=Math.sqrt(e.position.x*e.position.x+e.position.y*e.position.y);return i-n},byType:(t,e)=>{const i=t.getProperty("type")??"",n=e.getProperty("type")??"";return i.localeCompare(n)},byCreationTime:(t,e)=>{const i=t.hasOwnProperty("createdAt")?t.createdAt:0,n=e.hasOwnProperty("createdAt")?e.createdAt:0;return i-n},byRandom:()=>Math.random()-.5}}}class Fn extends K{constructor(t={}){super(),this.interactionTypes=new Map,this.interactionCooldowns=new Map,this.config={enableInteractions:!0,maxInteractionsPerStep:1e3,interactionCooldown:100,enableCollisionDetection:!0,collisionRadius:1,...t},this.stats={totalInteractions:0,successfulInteractions:0,failedInteractions:0,lastStepInteractions:0},this.registerBuiltInInteractions()}registerInteraction(t){this.interactionTypes.set(t.id,t),this.emit("interactionRegistered",{interaction:t})}unregisterInteraction(t){const e=this.interactionTypes.delete(t);return e&&this.emit("interactionUnregistered",{interactionId:t}),e}processInteractions(t){if(!this.config.enableInteractions)return;this.stats.lastStepInteractions=0;const i=[...t.getAllAgents()],n=Date.now();this.clearExpiredCooldowns(n);let o=0;for(const r of i){if(!r.isActive()||this.isOnCooldown(r.id,n))continue;const a=t.getAgentPosition(r);if(!a)continue;const c=this.getMaxInteractionRange(),l=t.findNeighbors(a,c,{filterFn:u=>u!==r&&u.isActive()}),h=this.findPotentialInteractions(r,[...l.items],t);for(const u of h){if(o>=this.config.maxInteractionsPerStep)break;this.executeInteraction(u).success?(this.stats.successfulInteractions++,this.setCooldown(r.id,n),o++):this.stats.failedInteractions++,this.stats.totalInteractions++,this.stats.lastStepInteractions++}if(o>=this.config.maxInteractionsPerStep)break}this.config.enableCollisionDetection&&this.processCollisions(t)}getStats(){return{...this.stats}}getConfig(){return{...this.config}}updateConfig(t){this.config={...this.config,...t}}getInteractionTypes(){return Array.from(this.interactionTypes.values())}getInteractionType(t){return this.interactionTypes.get(t)}resetStats(){this.stats={totalInteractions:0,successfulInteractions:0,failedInteractions:0,lastStepInteractions:0}}findPotentialInteractions(t,e,i){const n=[],o=i.getAgentPosition(t);if(!o)return n;for(const r of e){const a=i.getAgentPosition(r);if(!a)continue;const c=i.distance(o,a);for(const l of this.interactionTypes.values())if(c<=l.range&&l.canInitiate(t,r)){const h={environment:i,distance:c,timestamp:Date.now(),metadata:{}};n.push({type:l,initiator:t,target:r,context:h})}}return n.sort((r,a)=>a.type.priority-r.type.priority),n}executeInteraction(t){try{const e=t.type.execute(t.initiator,t.target,t.context);e.success&&this.applyInteractionEffects(e.effects);const i={type:"interaction",timestamp:Date.now(),initiator:t.initiator,target:t.target,interactionType:t.type.id,result:{success:e.success,message:e.message,...e.metadata}};return this.emit("interaction",i),e}catch(e){return{success:!1,effects:[],message:`Interaction failed: ${e instanceof Error?e.message:"Unknown error"}`,metadata:{}}}}applyInteractionEffects(t){for(const e of t)this.applyEffect(e)}applyEffect(t){const{targetAgent:e,property:i,newValue:n,effectType:o}=t;try{switch(o){case"set":e.setProperty(i,n);break;case"add":typeof t.oldValue=="number"&&typeof n=="number"&&e.setProperty(i,t.oldValue+n);break;case"multiply":typeof t.oldValue=="number"&&typeof n=="number"&&e.setProperty(i,t.oldValue*n);break;case"min":typeof t.oldValue=="number"&&typeof n=="number"&&e.setProperty(i,Math.min(t.oldValue,n));break;case"max":typeof t.oldValue=="number"&&typeof n=="number"&&e.setProperty(i,Math.max(t.oldValue,n));break}}catch(r){console.warn(`Failed to apply interaction effect: ${r}`)}}processCollisions(t){const i=[...t.getAllAgents()].filter(n=>n.isActive());for(let n=0;n<i.length;n++)for(let o=n+1;o<i.length;o++){const r=i[n],a=i[o];if(!r||!a)continue;const c=t.getAgentPosition(r),l=t.getAgentPosition(a);if(!c||!l)continue;t.distance(c,l)<this.config.collisionRadius&&this.resolveCollision(r,a,t)}}resolveCollision(t,e,i){this.emit("collision",{type:"collision",timestamp:Date.now(),agent1:t,agent2:e,environment:i})}isOnCooldown(t,e){const i=this.interactionCooldowns.get(t);return i?e<i:!1}setCooldown(t,e){this.interactionCooldowns.set(t,e+this.config.interactionCooldown)}clearExpiredCooldowns(t){for(const[e,i]of this.interactionCooldowns.entries())t>=i&&this.interactionCooldowns.delete(e)}getMaxInteractionRange(){let t=0;for(const e of this.interactionTypes.values())t=Math.max(t,e.range);return t||10}registerBuiltInInteractions(){this.registerInteraction({id:"energy_transfer",name:"Energy Transfer",range:2,priority:5,canInitiate:(t,e)=>{const i=t.getProperty("energy")??0,n=e.getProperty("energy")??0;return i>50&&n<50},execute:(t,e,i)=>{const n=t.getProperty("energy")??0,o=e.getProperty("energy")??0,r=Math.min(20,n-50);return{success:r>0,effects:[{targetAgent:t,property:"energy",oldValue:n,newValue:n-r,effectType:"set"},{targetAgent:e,property:"energy",oldValue:o,newValue:o+r,effectType:"set"}],message:`Transferred ${r} energy`,metadata:{transferAmount:r}}}}),this.registerInteraction({id:"information_share",name:"Information Sharing",range:3,priority:3,canInitiate:(t,e)=>{const i=t.getProperty("information")??0,n=e.getProperty("information")??0;return Math.abs(i-n)>10},execute:(t,e,i)=>{const n=t.getProperty("information")??0,o=e.getProperty("information")??0,r=(n+o)/2;return{success:!0,effects:[{targetAgent:t,property:"information",oldValue:n,newValue:r,effectType:"set"},{targetAgent:e,property:"information",oldValue:o,newValue:r,effectType:"set"}],message:"Shared information",metadata:{averageInfo:r}}}})}}class Ln extends K{constructor(t={}){super(),this.agents=new Map,this.agentsByState=new Map,this._objectPool=[],this.agentsByState.set("active",new Set),this.agentsByState.set("dormant",new Set),this.agentsByState.set("destroyed",new Set),this.config={maxAgents:1e4,enablePerformanceMonitoring:!0,performanceWarningThreshold:100,enableObjectPooling:!1,poolSize:100,...t},this.performanceMetrics={agentCount:0,activeAgents:0,lastStepTime:0,averageStepTime:0,memoryUsage:0,operationsPerSecond:0},this.stepTimes=[],this.lastStepStart=0}addAgent(t){if(this.agents.has(t.id))throw new Error(`Agent with ID ${t.id} already exists`);if(this.agents.size>=this.config.maxAgents)throw new Error(`Maximum agent limit (${this.config.maxAgents}) reached`);this.agents.set(t.id,t),this.addToStateIndex(t),t.on("agentActivated",this.handleAgentStateChange.bind(this)),t.on("agentDeactivated",this.handleAgentStateChange.bind(this)),t.on("agentDestroyed",this.handleAgentStateChange.bind(this)),this.updateMetrics(),this.emit("agentAdded",{agent:t})}removeAgent(t){const e=this.agents.get(t);return e?(this.agents.delete(t),this.removeFromStateIndex(e),e.removeAllListeners(),this.updateMetrics(),this.emit("agentRemoved",{agent:e}),!0):!1}getAgent(t){return this.agents.get(t)}hasAgent(t){return this.agents.has(t)}getAllAgents(){return Array.from(this.agents.values())}getAgentsByState(t){const e=this.agentsByState.get(t);return e?Array.from(e).map(i=>this.agents.get(i)).filter(i=>i!==void 0):[]}getActiveAgents(){return this.getAgentsByState("active")}getAgentCount(){return this.agents.size}getActiveAgentCount(){return this.agentsByState.get("active")?.size??0}queryAgents(t={}){let e=this.getAllAgents();t.state&&(e=this.getAgentsByState(t.state)),t.property!==void 0&&(e=e.filter(o=>{const r=o.getProperty(t.property);return t.propertyValue!==void 0?r===t.propertyValue:r!==void 0}));const i=t.offset??0,n=t.limit??e.length;return e.slice(i,i+n)}addAgents(t){const e={successful:0,failed:0,errors:[]};for(const i of t)try{this.addAgent(i),e.successful++}catch(n){e.failed++,e.errors.push({agentId:i.id,error:n instanceof Error?n.message:"Unknown error"})}return e}removeAgents(t){const e={successful:0,failed:0,errors:[]};for(const i of t)try{this.removeAgent(i)?e.successful++:(e.failed++,e.errors.push({agentId:i,error:"Agent not found"}))}catch(n){e.failed++,e.errors.push({agentId:i,error:n instanceof Error?n.message:"Unknown error"})}return e}stepAll(){this.config.enablePerformanceMonitoring&&(this.lastStepStart=performance.now());const t=this.getActiveAgents();for(const e of t)try{e.step()}catch(i){console.error(`Error stepping agent ${e.id}:`,i)}this.config.enablePerformanceMonitoring&&this.recordStepTime()}clear(){const t=Array.from(this.agents.keys());this.removeAgents(t)}getPerformanceMetrics(){return{...this.performanceMetrics}}getConfig(){return{...this.config}}getObjectPoolSize(){return this._objectPool.length}updateConfig(t){this.config={...this.config,...t}}*iterateAgents(t){const e=t?this.getAgentsByState(t):this.getAllAgents();for(const i of e)yield i}async*iterateAgentsAsync(t,e=100,i=0){const n=t?this.getAgentsByState(t):this.getAllAgents();for(let o=0;o<n.length;o+=e)yield n.slice(o,o+e),i>0&&o+e<n.length&&await new Promise(a=>setTimeout(a,i))}handleAgentStateChange(t){const e=t.agent;this.removeFromStateIndex(e),this.addToStateIndex(e),this.updateMetrics()}addToStateIndex(t){const e=t.currentState,i=this.agentsByState.get(e);i&&i.add(t.id)}removeFromStateIndex(t){for(const e of this.agentsByState.values())e.delete(t.id)}updateMetrics(){this.performanceMetrics={...this.performanceMetrics,agentCount:this.agents.size,activeAgents:this.getActiveAgentCount(),memoryUsage:this.estimateMemoryUsage()}}recordStepTime(){const t=performance.now()-this.lastStepStart;this.stepTimes.push(t),this.stepTimes.length>100&&this.stepTimes.shift();const e=this.stepTimes.reduce((i,n)=>i+n,0)/this.stepTimes.length;this.performanceMetrics={...this.performanceMetrics,lastStepTime:t,averageStepTime:e,operationsPerSecond:t>0?1e3/t:0},t>this.config.performanceWarningThreshold&&this.emitPerformanceWarning("stepTime",t,this.config.performanceWarningThreshold)}estimateMemoryUsage(){return this.agents.size*1024}emitPerformanceWarning(t,e,i){const n={type:"performanceWarning",timestamp:Date.now(),metric:t,value:e,threshold:i,message:`Performance warning: ${t} (${e.toFixed(2)}) exceeded threshold (${i})`};this.emit("performanceWarning",n)}reset(){this.agents.clear();for(const t of this.agentsByState.values())t.clear();this.performanceMetrics={agentCount:0,activeAgents:0,lastStepTime:0,averageStepTime:0,memoryUsage:0,operationsPerSecond:0},this.stepTimes=[],this.lastStepStart=0,this._objectPool=[]}}var nt=(s=>(s.SUPPORTIVE="supportive",s.EXPLOITATIVE="exploitative",s.ECONOMIC="economic",s))(nt||{});class zn extends K{constructor(t={}){super(),this.adjacencyList=new Map,this.connections=new Map,this.incomingConnections=new Map,this.connectionIdCounter=0,this.statsCache=null,this.config={maxConnections:50,connectionDecayRate:.01,minConnectionWeight:.1,enableAutoDecay:!0,proximityRadius:10,similarityThreshold:.5,...t}}addConnection(t,e,i,n=.5,o={}){if(t===e)return null;if((this.adjacencyList.get(t)?.size??0)>=this.config.maxConnections)return this.emit("connectionLimitReached",{agent:t,limit:this.config.maxConnections}),null;if(this.hasConnection(t,e))return null;const a={id:`conn_${++this.connectionIdCounter}`,source:t,target:e,type:i,weight:Math.max(0,Math.min(1,n)),createdAt:Date.now(),lastInteraction:Date.now(),metadata:o};return this.adjacencyList.has(t)||this.adjacencyList.set(t,new Set),this.adjacencyList.get(t).add(a),this.incomingConnections.has(e)||this.incomingConnections.set(e,new Set),this.incomingConnections.get(e).add(a),this.connections.set(a.id,a),this.statsCache=null,this.emit("connectionAdded",{connection:a}),a}removeConnection(t){const e=this.connections.get(t);return e?(this.adjacencyList.get(e.source)?.delete(e),this.incomingConnections.get(e.target)?.delete(e),this.connections.delete(t),this.statsCache=null,this.emit("connectionRemoved",{connection:e}),!0):!1}getConnections(t){return Array.from(this.adjacencyList.get(t)??[])}getIncomingConnections(t){return Array.from(this.incomingConnections.get(t)??[])}hasConnection(t,e){const i=this.adjacencyList.get(t);if(!i)return!1;for(const n of i)if(n.target===e)return!0;return!1}getConnection(t,e){const i=this.adjacencyList.get(t);if(i){for(const n of i)if(n.target===e)return n}}updateConnectionWeight(t,e){const i=this.connections.get(t);if(!i)return!1;const n=i.weight;return i.weight=Math.max(0,Math.min(1,i.weight+e)),i.lastInteraction=Date.now(),i.weight<this.config.minConnectionWeight?(this.removeConnection(t),!0):(this.emit("connectionWeightChanged",{connection:i,oldWeight:n,newWeight:i.weight}),!0)}strengthenConnection(t,e,i=.1){const n=this.getConnection(t,e);return n?this.updateConnectionWeight(n.id,Math.abs(i)):!1}weakenConnection(t,e,i=.1){const n=this.getConnection(t,e);return n?this.updateConnectionWeight(n.id,-Math.abs(i)):!1}applyDecay(){if(!this.config.enableAutoDecay)return;const t=[];for(const[e,i]of this.connections){const o=(Date.now()-i.lastInteraction)/(1e3*60*60),r=this.config.connectionDecayRate*o;i.weight=Math.max(0,i.weight-r),i.weight<this.config.minConnectionWeight&&t.push(e)}for(const e of t)this.removeConnection(e)}getDegree(t){const e=this.adjacencyList.get(t)?.size??0,i=this.incomingConnections.get(t)?.size??0;return{in:i,out:e,total:i+e}}findPath(t,e){if(t===e)return{found:!0,path:[t],distance:0,hops:0};const i=new Set,n=[{agent:t,path:[t],distance:0}];for(;n.length>0;){const o=n.shift();if(i.has(o.agent))continue;i.add(o.agent);const r=this.adjacencyList.get(o.agent)??[];for(const a of r){if(a.target===e){const c=[...o.path,e];return{found:!0,path:c,distance:o.distance+a.weight,hops:c.length-1}}i.has(a.target)||n.push({agent:a.target,path:[...o.path,a.target],distance:o.distance+a.weight})}}return{found:!1,path:[],distance:1/0,hops:-1}}getNetworkAnalysis(){if(this.statsCache)return this.statsCache;const t=new Set;let e=0;for(const[d,f]of this.adjacencyList)t.add(d),e+=f.size;for(const[d]of this.incomingConnections)t.add(d);const i=t.size,n=this.connections.size,o=i>0?e/i:0,r=i*(i-1),a=r>0?n/r:0;let c=0,l=0;for(const d of t){const f=this.getConnections(d).map(p=>p.target),g=f.length;if(g>=2){l+=g*(g-1)/2;for(let p=0;p<f.length;p++)for(let m=p+1;m<f.length;m++)this.hasConnection(f[p],f[m])&&c++}}const h=l>0?3*c/l:0,u=this.countComponents(t);return this.statsCache={nodeCount:i,edgeCount:n,averageDegree:o,density:a,clustering:h,components:u},this.statsCache}getConnectionCount(){return this.connections.size}countComponents(t){const e=new Set;let i=0;for(const n of t)e.has(n)||(i++,this.dfsVisit(n,e));return i}dfsVisit(t,e){e.add(t);const i=this.adjacencyList.get(t)??[];for(const o of i)e.has(o.target)||this.dfsVisit(o.target,e);const n=this.incomingConnections.get(t)??[];for(const o of n)e.has(o.source)||this.dfsVisit(o.source,e)}clear(){this.adjacencyList.clear(),this.connections.clear(),this.incomingConnections.clear(),this.connectionIdCounter=0,this.statsCache=null,this.emit("networkCleared")}getConfig(){return{...this.config}}updateConfig(t){this.config={...this.config,...t},this.emit("configurationChanged",{config:this.config})}getAllConnections(){return Array.from(this.connections.values())}getConnectionById(t){return this.connections.get(t)}}class vr extends K{constructor(t,e={}){super(),this.network=t,this.influenceRules=new Map,this.currentCascade=new Set,this.config={propagationRate:.5,resistanceFactor:.3,connectionTypeWeights:{[nt.SUPPORTIVE]:1,[nt.EXPLOITATIVE]:-.5,[nt.ECONOMIC]:.3},minInfluenceThreshold:.1,maxInfluenceDistance:3,...e},this.stats={totalPropagations:0,successfulInfluences:0,blockedByResistance:0,cascadesTriggered:0}}registerInfluenceRule(t){this.influenceRules.set(t.property,t),this.emit("ruleRegistered",{rule:t})}removeInfluenceRule(t){const e=this.influenceRules.delete(t);return e&&this.emit("ruleRemoved",{property:t}),e}propagateInfluence(t,e,i){const n=`${t.id}-${e}`;if(this.currentCascade.has(n))return 0;this.currentCascade.add(n),this.stats.totalPropagations++;const o=t.getProperty(e);if(o===void 0)return this.currentCascade.delete(n),0;const r=this.network.getConnections(t.id);let a=0;for(const c of r){const l=i.get(c.target);if(!l)continue;this.influenceAgent(t,l,e,o,c)&&(a++,this.stats.successfulInfluences++,this.shouldCascade(e)&&(this.stats.cascadesTriggered++,a+=this.propagateInfluence(l,e,i)))}return this.currentCascade.delete(n),a}propagateAll(t){this.currentCascade.clear();for(const[e]of this.influenceRules)for(const i of t.values())this.propagateInfluence(i,e,t)}calculateAggregateInfluence(t,e,i){const n=this.influenceRules.get(e);if(!n)return null;const o=this.network.getIncomingConnections(t.id);if(o.length===0)return null;const r=[];for(const c of o){const l=i.get(c.source);if(!l)continue;const h=l.getProperty(e);if(h===void 0)continue;const u=this.calculateInfluenceWeight(c);u>this.config.minInfluenceThreshold&&r.push({value:h,weight:u})}if(r.length===0)return null;const a=t.getProperty(e);return a===void 0?null:this.aggregateInfluences(a,r,n)}influenceAgent(t,e,i,n,o){const r=this.influenceRules.get(i);if(!r)return!1;const a=e.getProperty(i);if(a===void 0)return!1;const c=this.calculateInfluenceWeight(o);if(c<this.config.minInfluenceThreshold)return!1;const l=r.resistance??this.config.resistanceFactor;if(Math.random()<l)return this.stats.blockedByResistance++,!1;const h=this.calculateInfluencedValue(a,n,c,r);if(h!==a){e.setProperty(i,h);const u={source:t.id,target:e.id,property:i,oldValue:a,newValue:h,influenceStrength:c,connectionType:o.type};return this.emit("agentInfluenced",u),!0}return!1}calculateInfluenceWeight(t){const e=this.config.connectionTypeWeights[t.type],i=this.calculateTimeFactor(t.lastInteraction);return Math.abs(t.weight*e*this.config.propagationRate*i)}calculateTimeFactor(t){const e=(Date.now()-t)/36e5;