reynard-algorithms
Version:
Algorithm primitives and data structures for Reynard applications
1 lines • 59.1 kB
JavaScript
"use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});class j{constructor(){this.performanceHistory=[],this.selectionStats={totalSelections:0,correctSelections:0,averageConfidence:0,performanceImprovement:0},this.thresholds={naiveVsSpatial:50,spatialVsOptimized:25,memoryThreshold:100}}selectCollisionAlgorithm(t){const e=this.analyzeWorkload(t),s=this.selectOptimalCollisionAlgorithm(e);return this.recordSelection(s,t),s}selectSpatialAlgorithm(t){const e=this.analyzeWorkload(t),s=this.selectOptimalSpatialAlgorithm(e);return this.recordSelection(s,t),s}selectUnionFindAlgorithm(t){const e=this.analyzeWorkload(t),s=this.selectOptimalUnionFindAlgorithm(e);return this.recordSelection(s,t),s}analyzeWorkload(t){const e=this.calculateComplexity(t),s=this.calculateMemoryPressure(t),i=this.getPerformanceProfile(t);return{workload:t,complexity:e,memoryPressure:s,performanceProfile:i,recommendations:this.generateRecommendations(t,e,s)}}calculateComplexity(t){const{objectCount:e,spatialDensity:s,overlapRatio:i}=t,o=e*e,a=e*Math.log(e)+s*e,r=e*Math.log(e)+i*e;return{naive:o,spatial:a,optimized:r,crossoverPoint:this.findCrossoverPoint(o,a),recommendation:this.getComplexityRecommendation(o,a,r)}}calculateMemoryPressure(t){const{objectCount:e,memoryConstraints:s}=t,i={naive:e*16,spatial:e*32+e*Math.log(e)*8,optimized:e*16+1024},o=s?i.optimized/s.maxMemoryUsage:0;return{estimatedUsage:i,pressure:o,recommendation:o>.8?"optimized":"auto"}}getPerformanceProfile(t){const e=this.findSimilarWorkloads(t);if(e.length===0)return{confidence:.5,expectedPerformance:this.getDefaultPerformance(t),historicalData:[]};const s=this.calculateAveragePerformance(e);return{confidence:Math.min(.95,e.length/10),expectedPerformance:s,historicalData:e}}selectOptimalCollisionAlgorithm(t){const{complexity:e,memoryPressure:s,performanceProfile:i}=t,{objectCount:o}=t.workload;return o<this.thresholds.naiveVsSpatial?{algorithm:"naive",confidence:.9,expectedPerformance:{executionTime:e.naive*.001,memoryUsage:o*16},reasoning:["Small object count favors naive approach","PAW findings show naive is optimal for <50 objects","Minimal allocation overhead for small datasets"]}:o<this.thresholds.spatialVsOptimized?{algorithm:"spatial",confidence:.8,expectedPerformance:{executionTime:e.spatial*.001,memoryUsage:o*32},reasoning:["Medium object count benefits from spatial optimization","Spatial hashing reduces collision checks","Memory overhead acceptable for this size"]}:{algorithm:"optimized",confidence:.95,expectedPerformance:{executionTime:e.optimized*.001,memoryUsage:o*16+1024},reasoning:["Large object count requires optimization","Memory pooling eliminates allocation overhead","PAW findings show 99.91% allocation reduction","Best performance for >100 objects"]}}selectOptimalSpatialAlgorithm(t){const{complexity:e,memoryPressure:s}=t,{objectCount:i,spatialDensity:o}=t.workload;return o>.7?{algorithm:"optimized-spatial",confidence:.9,expectedPerformance:{executionTime:e.optimized*.001,memoryUsage:i*32+1024},reasoning:["High spatial density benefits from optimization","Memory pooling reduces allocation overhead","Spatial hashing effective for dense scenarios"]}:{algorithm:"spatial",confidence:.8,expectedPerformance:{executionTime:e.spatial*.001,memoryUsage:i*32},reasoning:["Low spatial density allows standard spatial hashing","Memory overhead acceptable for sparse scenarios","Good balance of performance and memory usage"]}}selectOptimalUnionFindAlgorithm(t){const{complexity:e,memoryPressure:s}=t,{objectCount:i}=t.workload;return i<100?{algorithm:"union-find",confidence:.9,expectedPerformance:{executionTime:i*Math.log(i)*.001,memoryUsage:i*8},reasoning:["Small dataset size optimal for standard Union-Find","Minimal memory overhead","Path compression provides good performance"]}:{algorithm:"batch-union-find",confidence:.9,expectedPerformance:{executionTime:i*Math.log(i)*5e-4,memoryUsage:i*8+512},reasoning:["Large dataset benefits from batch operations","Reduced memory allocation overhead","Better cache locality for batch processing"]}}findCrossoverPoint(t,e){return Math.sqrt(t/e)}getComplexityRecommendation(t,e,s){return t<e&&t<s?"naive":e<s?"spatial":"optimized"}generateRecommendations(t,e,s){const i=[];return t.objectCount>100&&i.push("Consider using optimized algorithms for large datasets"),s.pressure>.8&&i.push("High memory pressure detected - use memory pooling"),t.overlapRatio>.7&&i.push("High overlap ratio - spatial optimization recommended"),t.updateFrequency>10&&i.push("High update frequency - consider incremental updates"),i}findSimilarWorkloads(t){return this.performanceHistory.filter(e=>this.calculateWorkloadSimilarity(t,e.workload)>.8)}calculateWorkloadSimilarity(t,e){const s=1-Math.abs(t.objectCount-e.objectCount)/Math.max(t.objectCount,e.objectCount),i=1-Math.abs(t.spatialDensity-e.spatialDensity),o=1-Math.abs(t.overlapRatio-e.overlapRatio);return(s+i+o)/3}calculateAveragePerformance(t){const e=t.reduce((a,r)=>a+r.performance.executionTime,0)/t.length,s=t.reduce((a,r)=>a+r.performance.memoryUsage,0)/t.length,i=t.reduce((a,r)=>a+r.performance.allocationCount,0)/t.length,o=t.reduce((a,r)=>a+r.performance.cacheHitRate,0)/t.length;return{executionTime:e,memoryUsage:s,allocationCount:i,cacheHitRate:o}}getDefaultPerformance(t){return{executionTime:t.objectCount*.001,memoryUsage:t.objectCount*16,allocationCount:t.objectCount*2,cacheHitRate:.5}}recordSelection(t,e){this.selectionStats.totalSelections++,this.selectionStats.averageConfidence=(this.selectionStats.averageConfidence*(this.selectionStats.totalSelections-1)+t.confidence)/this.selectionStats.totalSelections}updatePerformanceModel(t){this.performanceHistory.push(t),this.performanceHistory.length>1e3&&(this.performanceHistory=this.performanceHistory.slice(-1e3)),this.updateSelectionStats(t)}updateSelectionStats(t){}getSelectionStats(){return{...this.selectionStats}}getPerformanceHistory(){return[...this.performanceHistory]}clearPerformanceHistory(){this.performanceHistory=[],this.selectionStats={totalSelections:0,correctSelections:0,averageConfidence:0,performanceImprovement:0}}}function L(n,t={}){const{targetCellSize:e,maxObjectsPerCell:s=50}=t;let i=e||100;if(n.length>0){const a=n.reduce((l,c)=>l+(c.width||0),0)/n.length,r=n.reduce((l,c)=>l+(c.height||0),0)/n.length;i=Math.max(50,Math.min(200,Math.sqrt(a*r)*2))}const o=new C({cellSize:i,maxObjectsPerCell:s,enableAutoResize:!0});for(const a of n)o.insert(a);return o}function V(n){if(n.length===0)return 100;const t=n.reduce((s,i)=>s+(i.width||0),0)/n.length,e=n.reduce((s,i)=>s+(i.height||0),0)/n.length;return Math.max(50,Math.min(200,Math.sqrt(t*e)*2))}function F(n,t,e){let s=0;return s+=n*50,s+=e*30,s+=t*100,s}let C=class{constructor(t={}){this.cells=new Map,this.objectToCells=new Map,this.stats={queryCount:0,insertCount:0,removeCount:0},this.lastCleanup=Date.now(),this.config={cellSize:100,maxObjectsPerCell:50,enableAutoResize:!0,resizeThreshold:.8,cleanupInterval:6e4,...t}}insert(t){const e=this.getObjectCells(t);for(const s of Array.from(e))this.cells.has(s)||this.cells.set(s,[]),this.cells.get(s).push(t);this.objectToCells.set(t.id,e),this.stats.insertCount++,this.checkAutoResize(),this.checkCleanup()}remove(t){const e=this.objectToCells.get(t);if(!e)return!1;for(const s of Array.from(e)){const i=this.cells.get(s);if(i){const o=i.findIndex(a=>a.id===t);o!==-1&&(i.splice(o,1),i.length===0&&this.cells.delete(s))}}return this.objectToCells.delete(t),this.stats.removeCount++,!0}update(t){return this.remove(t.id)?(this.insert(t),!0):!1}queryRect(t,e,s,i){const o=this.getRectCells(t,e,s,i),a=new Map;for(const r of Array.from(o)){const l=this.cells.get(r);if(l)for(const c of l)this.isObjectInRect(c,t,e,s,i)&&a.set(c.id,c)}return this.stats.queryCount++,Array.from(a.values())}queryRadius(t,e,s){const i=this.getRadiusCells(t,e,s),o=[];for(const a of Array.from(i)){const r=this.cells.get(a);if(r)for(const l of r){const c=this.getDistance(t,e,l.x,l.y);c<=s&&o.push({object:l,distance:c,cellKey:a})}}return this.stats.queryCount++,o.sort((a,r)=>a.distance-r.distance)}findNearest(t,e,s){const i=s||this.config.cellSize*2,o=this.queryRadius(t,e,i);return o.length===0?this.queryRadius(t,e,i*2)[0]||null:o[0]}getAllObjects(){const t=new Map;for(const e of Array.from(this.cells.values()))for(const s of e)t.set(s.id,s);return Array.from(t.values())}clear(){this.cells.clear(),this.objectToCells.clear(),this.stats.queryCount=0,this.stats.insertCount=0,this.stats.removeCount=0}getStats(){let t=0,e=0,s=0;for(const i of Array.from(this.cells.values()))t+=i.length,e=Math.max(e,i.length);return s=this.cells.size===0?0:Array.from(this.cells.values()).filter(i=>i.length===0).length,{totalCells:this.cells.size,totalObjects:t,averageObjectsPerCell:this.cells.size>0?t/this.cells.size:0,maxObjectsInCell:e,emptyCells:s,memoryUsage:F(this.cells.size,t,this.objectToCells.size),queryCount:this.stats.queryCount,insertCount:this.stats.insertCount,removeCount:this.stats.removeCount}}resize(t){if(t===this.config.cellSize)return;const e=this.cells,s=this.objectToCells;this.config.cellSize=t,this.cells=new Map,this.objectToCells=new Map;for(const[i,o]of Array.from(s.entries())){const a=Array.from(o)[0],r=e.get(a)?.find(l=>l.id===i);r&&this.insert(r)}}getObjectCells(t){const e=t.width||0,s=t.height||0;return this.getRectCells(t.x,t.y,e,s)}getRectCells(t,e,s,i){const o=Math.floor(t/this.config.cellSize),a=Math.floor((t+s)/this.config.cellSize),r=Math.floor(e/this.config.cellSize),l=Math.floor((e+i)/this.config.cellSize),c=new Set;for(let h=o;h<=a;h++)for(let u=r;u<=l;u++)c.add(`${h},${u}`);return c}getRadiusCells(t,e,s){const i=Math.floor((t-s)/this.config.cellSize),o=Math.floor((t+s)/this.config.cellSize),a=Math.floor((e-s)/this.config.cellSize),r=Math.floor((e+s)/this.config.cellSize),l=new Set;for(let c=i;c<=o;c++)for(let h=a;h<=r;h++)l.add(`${c},${h}`);return l}isObjectInRect(t,e,s,i,o){const a=t.width||0,r=t.height||0;return t.x<e+i&&t.x+a>e&&t.y<s+o&&t.y+r>s}getDistance(t,e,s,i){const o=s-t,a=i-e;return Math.sqrt(o*o+a*a)}checkAutoResize(){if(!this.config.enableAutoResize)return;if(this.getStats().averageObjectsPerCell/this.config.maxObjectsPerCell>this.config.resizeThreshold){const s=this.config.cellSize*1.5;this.resize(s)}}checkCleanup(){const t=Date.now();t-this.lastCleanup>this.config.cleanupInterval&&(this.cleanup(),this.lastCleanup=t)}cleanup(){for(const[t,e]of Array.from(this.cells.entries()))e.length===0&&this.cells.delete(t)}};class v{constructor(t,e){this.nodes=t,this.stats=e}find(t){return this.nodes[t].parent!==t&&(this.nodes[t].parent=this.find(this.nodes[t].parent),this.stats.compressionCount++),this.nodes[t].parent}getSetSize(t){const e=this.find(t);return this.nodes.filter(s=>this.find(this.nodes.indexOf(s))===e).length}getSetMembers(t){const e=this.find(t);return this.nodes.map((s,i)=>i).filter(s=>this.find(s)===e)}getStats(){const t=new Set;let e=0,s=0;for(let i=0;i<this.nodes.length;i++){const o=this.find(i);t.add(o),e=Math.max(e,this.nodes[o].rank),s+=this.nodes[o].rank}return{totalNodes:this.nodes.length,totalSets:t.size,maxRank:e,averageRank:t.size>0?s/t.size:0,compressionCount:this.stats.compressionCount,unionCount:this.stats.unionCount}}}class g{constructor(t){this.stats={compressionCount:0,unionCount:0},this.nodes=Array.from({length:t},(e,s)=>({parent:s,rank:0})),this.setOps=new v(this.nodes,this.stats)}find(t){return this.setOps.find(t)}union(t,e){const s=this.find(t),i=this.find(e);return s===i?!1:(this.stats.unionCount++,this.nodes[s].rank<this.nodes[i].rank?this.nodes[s].parent=i:this.nodes[s].rank>this.nodes[i].rank?this.nodes[i].parent=s:(this.nodes[i].parent=s,this.nodes[s].rank++),!0)}connected(t,e){return this.find(t)===this.find(e)}getSetSize(t){return this.setOps.getSetSize(t)}getSetMembers(t){return this.setOps.getSetMembers(t)}getStats(){return this.setOps.getStats()}reset(){this.nodes=this.nodes.map((t,e)=>({parent:e,rank:0})),this.stats.compressionCount=0,this.stats.unionCount=0,this.setOps=new v(this.nodes,this.stats)}clone(){const t=new g(this.nodes.length);return t.nodes=this.nodes.map(e=>({...e})),t.stats={...this.stats},t.setOps=new v(t.nodes,t.stats),t}}class R{constructor(t={}){this.spatialHashPool=[],this.unionFindPool=[],this.collisionArrayPool=[],this.processedSetPool=[],this.performanceHistory=[],this.config={spatialHashPoolSize:20,unionFindPoolSize:50,collisionArrayPoolSize:100,processedSetPoolSize:50,enableAutoResize:!0,maxPoolSize:200,cleanupInterval:3e4,enableStatistics:!0,enablePerformanceTracking:!0,...t},this.stats={totalAllocations:0,totalDeallocations:0,poolHits:0,poolMisses:0,memorySaved:0,averageAllocationTime:0,peakPoolUsage:0,currentPoolUsage:0,hitRate:0,allocationReduction:0},this.initializePools(),this.startCleanup()}initializePools(){for(let e=0;e<this.config.spatialHashPoolSize;e++)this.spatialHashPool.push({object:new C({cellSize:100}),isInUse:!1,lastUsed:0,allocationCount:0});const t=[10,25,50,100,200,500];for(const e of t)for(let s=0;s<Math.ceil(this.config.unionFindPoolSize/t.length);s++)this.unionFindPool.push({object:new g(e),isInUse:!1,lastUsed:0,allocationCount:0,size:e});for(let e=0;e<this.config.collisionArrayPoolSize;e++)this.collisionArrayPool.push({object:[],isInUse:!1,lastUsed:0,allocationCount:0});for(let e=0;e<this.config.processedSetPoolSize;e++)this.processedSetPool.push({object:new Set,isInUse:!1,lastUsed:0,allocationCount:0})}getSpatialHash(t){const e=performance.now();let s=this.spatialHashPool.find(i=>!i.isInUse);if(s)return s.isInUse=!0,s.lastUsed=Date.now(),s.allocationCount++,this.stats.poolHits++,s.object.clear(),this.updateStats(e,!0),s.object;{this.stats.poolMisses++;const i=new C(t||{cellSize:100});return this.spatialHashPool.length<this.config.maxPoolSize&&this.spatialHashPool.push({object:i,isInUse:!0,lastUsed:Date.now(),allocationCount:1}),this.updateStats(e,!1),i}}getUnionFind(t){const e=performance.now();let s=this.unionFindPool.find(i=>!i.isInUse&&i.size===t);if(s)return s.isInUse=!0,s.lastUsed=Date.now(),s.allocationCount++,this.stats.poolHits++,s.object=new g(t),this.updateStats(e,!0),s.object;{this.stats.poolMisses++;const i=new g(t);return this.unionFindPool.length<this.config.maxPoolSize&&this.unionFindPool.push({object:i,isInUse:!0,lastUsed:Date.now(),size:t,allocationCount:1}),this.updateStats(e,!1),i}}getCollisionArray(){const t=performance.now();let e=this.collisionArrayPool.find(s=>!s.isInUse);if(e)return e.isInUse=!0,e.lastUsed=Date.now(),e.allocationCount++,this.stats.poolHits++,e.object.length=0,this.updateStats(t,!0),e.object;{this.stats.poolMisses++;const s=[];return this.collisionArrayPool.length<this.config.maxPoolSize&&this.collisionArrayPool.push({object:s,isInUse:!0,lastUsed:Date.now(),allocationCount:1}),this.updateStats(t,!1),s}}getProcessedSet(){const t=performance.now();let e=this.processedSetPool.find(s=>!s.isInUse);if(e)return e.isInUse=!0,e.lastUsed=Date.now(),e.allocationCount++,this.stats.poolHits++,e.object.clear(),this.updateStats(t,!0),e.object;{this.stats.poolMisses++;const s=new Set;return this.processedSetPool.length<this.config.maxPoolSize&&this.processedSetPool.push({object:s,isInUse:!0,lastUsed:Date.now(),allocationCount:1}),this.updateStats(t,!1),s}}returnSpatialHash(t){const e=this.spatialHashPool.find(s=>s.object===t);e&&(e.isInUse=!1,e.lastUsed=Date.now(),this.stats.totalDeallocations++)}returnUnionFind(t){const e=this.unionFindPool.find(s=>s.object===t);e&&(e.isInUse=!1,e.lastUsed=Date.now(),this.stats.totalDeallocations++)}returnCollisionArray(t){const e=this.collisionArrayPool.find(s=>s.object===t);e&&(e.isInUse=!1,e.lastUsed=Date.now(),this.stats.totalDeallocations++)}returnProcessedSet(t){const e=this.processedSetPool.find(s=>s.object===t);e&&(e.isInUse=!1,e.lastUsed=Date.now(),this.stats.totalDeallocations++)}updateStats(t,e){const s=performance.now()-t;this.stats.totalAllocations++,this.stats.averageAllocationTime=(this.stats.averageAllocationTime*(this.stats.totalAllocations-1)+s)/this.stats.totalAllocations,e&&(this.stats.memorySaved+=this.estimateMemorySavings()),this.stats.currentPoolUsage=this.getCurrentPoolUsage(),this.stats.peakPoolUsage=Math.max(this.stats.peakPoolUsage,this.stats.currentPoolUsage);const i=this.stats.poolHits+this.stats.poolMisses;this.stats.hitRate=i>0?this.stats.poolHits/i*100:0,this.stats.allocationReduction=i>0?this.stats.poolHits/i*100:0,this.config.enablePerformanceTracking&&this.recordPerformanceHistory()}estimateMemorySavings(){return 1472}getCurrentPoolUsage(){const t=this.spatialHashPool.filter(o=>o.isInUse).length,e=this.unionFindPool.filter(o=>o.isInUse).length,s=this.collisionArrayPool.filter(o=>o.isInUse).length,i=this.processedSetPool.filter(o=>o.isInUse).length;return t+e+s+i}getPoolInfo(){return{spatialHashPool:{total:this.spatialHashPool.length,inUse:this.spatialHashPool.filter(t=>t.isInUse).length,available:this.spatialHashPool.filter(t=>!t.isInUse).length},unionFindPool:{total:this.unionFindPool.length,inUse:this.unionFindPool.filter(t=>t.isInUse).length,available:this.unionFindPool.filter(t=>!t.isInUse).length},collisionArrayPool:{total:this.collisionArrayPool.length,inUse:this.collisionArrayPool.filter(t=>t.isInUse).length,available:this.collisionArrayPool.filter(t=>!t.isInUse).length},processedSetPool:{total:this.processedSetPool.length,inUse:this.processedSetPool.filter(t=>t.isInUse).length,available:this.processedSetPool.filter(t=>!t.isInUse).length}}}getStatistics(){return{...this.stats}}getOptimizationRecommendations(){const t=[];return this.stats.hitRate<90&&t.push({type:"pool_size",description:"Low pool hit rate detected. Consider increasing pool sizes.",impact:"high",implementation:"Increase spatialHashPoolSize and collisionArrayPoolSize in config"}),this.stats.currentPoolUsage>this.config.maxPoolSize*.8&&t.push({type:"cleanup_interval",description:"High pool usage detected. Consider reducing cleanup interval.",impact:"medium",implementation:"Reduce cleanupInterval in config"}),this.stats.allocationReduction<95&&t.push({type:"object_lifecycle",description:"Allocation reduction below optimal. Check object lifecycle management.",impact:"high",implementation:"Ensure proper returnToPool() calls and object reuse patterns"}),t}recordPerformanceHistory(){this.performanceHistory.push({timestamp:Date.now(),poolUsage:this.stats.currentPoolUsage,hitRate:this.stats.hitRate,memoryUsage:this.estimateMemorySavings()}),this.performanceHistory.length>100&&(this.performanceHistory=this.performanceHistory.slice(-100))}getPerformanceHistory(){return[...this.performanceHistory]}startCleanup(){this.cleanupInterval=window.setInterval(()=>{this.cleanupUnusedPools()},this.config.cleanupInterval)}cleanupUnusedPools(){const t=Date.now(),e=3e5;this.spatialHashPool=this.spatialHashPool.filter(s=>!(!s.isInUse&&t-s.lastUsed>e)),this.unionFindPool=this.unionFindPool.filter(s=>!(!s.isInUse&&t-s.lastUsed>e)),this.collisionArrayPool=this.collisionArrayPool.filter(s=>!(!s.isInUse&&t-s.lastUsed>e)),this.processedSetPool=this.processedSetPool.filter(s=>!(!s.isInUse&&t-s.lastUsed>e))}optimizeForWorkload(t){const{objectCount:e,spatialDensity:s,updateFrequency:i}=t;e>100&&(this.config.spatialHashPoolSize=Math.min(50,this.config.spatialHashPoolSize*1.5),this.config.collisionArrayPoolSize=Math.min(200,this.config.collisionArrayPoolSize*1.5)),s>.7&&(this.config.spatialHashPoolSize=Math.min(100,this.config.spatialHashPoolSize*2)),i>10&&(this.config.cleanupInterval=Math.max(1e4,this.config.cleanupInterval*.5))}destroy(){this.cleanupInterval&&clearInterval(this.cleanupInterval),this.spatialHashPool=[],this.unionFindPool=[],this.collisionArrayPool=[],this.processedSetPool=[],this.performanceHistory=[]}}class I{constructor(t={}){this.performanceHistory=[],this.config={enableMemoryPooling:!0,enableAlgorithmSelection:!0,enablePerformanceMonitoring:!0,algorithmSelectionStrategy:"adaptive",performanceThresholds:{maxExecutionTime:16,maxMemoryUsage:50*1024*1024,minHitRate:90},...t},this.algorithmSelector=new j,this.memoryPool=new R(this.config.memoryPoolConfig),this.stats={totalQueries:0,averageExecutionTime:0,averageMemoryUsage:0,algorithmUsage:{naive:0,spatial:0,optimized:0},memoryPoolStats:this.memoryPool.getStatistics(),performanceHistory:[]}}detectCollisions(t){const e=performance.now(),s=this.getCurrentMemoryUsage();this.stats.totalQueries++;let i,o;if(this.config.enableAlgorithmSelection){const a=this.analyzeWorkload(t);o=this.algorithmSelector.selectCollisionAlgorithm(a).algorithm,i=this.executeAlgorithm(o,t),this.config.enablePerformanceMonitoring&&this.updatePerformanceModel(o,t.length,e,s)}else o=this.config.algorithmSelectionStrategy,i=this.executeAlgorithm(o,t);return this.updateStats(o,e,s),i}analyzeWorkload(t){const e=t.length,s=this.calculateSpatialDensity(t),i=this.calculateOverlapRatio(t),o=this.estimateUpdateFrequency(),a=this.analyzeQueryPattern(t);return{objectCount:e,spatialDensity:s,overlapRatio:i,updateFrequency:o,queryPattern:a}}calculateSpatialDensity(t){if(t.length===0)return 0;let e=1/0,s=1/0,i=-1/0,o=-1/0,a=0;for(const l of t)e=Math.min(e,l.x),s=Math.min(s,l.y),i=Math.max(i,l.x+l.width),o=Math.max(o,l.y+l.height),a+=l.width*l.height;const r=(i-e)*(o-s);return r>0?a/r:0}calculateOverlapRatio(t){if(t.length<2)return 0;let e=0,s=0;const i=Math.min(100,t.length),o=Math.max(1,Math.floor(t.length/i));for(let a=0;a<t.length;a+=o)for(let r=a+o;r<t.length;r+=o)s++,this.checkCollision(t[a],t[r])&&e++;return s>0?e/s:0}estimateUpdateFrequency(){const t=Date.now();return this.performanceHistory.filter(s=>t-s.timestamp<1e3).length}analyzeQueryPattern(t){if(t.length<3)return"random";const e=this.calculateSpatialDensity(t);return e>.7?"clustered":e<.3?"random":"sequential"}executeAlgorithm(t,e){switch(t){case"naive":return this.executeNaiveCollisionDetection(e);case"spatial":return this.executeSpatialCollisionDetection(e);case"optimized":return this.executeOptimizedCollisionDetection(e);default:return this.executeOptimizedCollisionDetection(e)}}executeNaiveCollisionDetection(t){const e=[];for(let s=0;s<t.length;s++)for(let i=s+1;i<t.length;i++)this.checkCollision(t[s],t[i])&&e.push({a:s,b:i,result:this.createCollisionResult(t[s],t[i])});return e}executeSpatialCollisionDetection(t){const e=this.memoryPool.getSpatialHash({cellSize:100}),s=this.memoryPool.getCollisionArray();try{for(let o=0;o<t.length;o++)e.insert({id:o,x:t[o].x,y:t[o].y,width:t[o].width,height:t[o].height,data:{aabb:t[o],index:o}});const i=this.memoryPool.getProcessedSet();try{for(let o=0;o<t.length;o++){if(i.has(o))continue;const a=t[o],r=e.queryRect(a.x-a.width,a.y-a.height,a.width*3,a.height*3);for(const l of r){const c=l.data.index;c<=o||i.has(c)||this.checkCollision(a,l.data.aabb)&&s.push({a:o,b:c,result:this.createCollisionResult(a,l.data.aabb)})}i.add(o)}return[...s]}finally{this.memoryPool.returnProcessedSet(i)}}finally{this.memoryPool.returnSpatialHash(e),this.memoryPool.returnCollisionArray(s)}}executeOptimizedCollisionDetection(t){return this.executeSpatialCollisionDetection(t)}checkCollision(t,e){return!(t.x+t.width<=e.x||e.x+e.width<=t.x||t.y+t.height<=e.y||e.y+e.height<=t.y)}createCollisionResult(t,e){if(!this.checkCollision(t,e))return{colliding:!1,distance:1/0,overlap:null,overlapArea:0};const i=Math.max(0,Math.min(t.x+t.width,e.x+e.width)-Math.max(t.x,e.x)),o=Math.max(0,Math.min(t.y+t.height,e.y+e.height)-Math.max(t.y,e.y)),a={x:t.x+t.width/2,y:t.y+t.height/2},r={x:e.x+e.width/2,y:e.y+e.height/2};return{colliding:!0,distance:Math.sqrt(Math.pow(a.x-r.x,2)+Math.pow(a.y-r.y,2)),overlap:{x:Math.max(t.x,e.x),y:Math.max(t.y,e.y),width:i,height:o},overlapArea:i*o}}updatePerformanceModel(t,e,s,i){const o=performance.now()-s,a=this.getCurrentMemoryUsage()-i,r=this.memoryPool.getStatistics().hitRate,l={timestamp:Date.now(),algorithm:t,objectCount:e,executionTime:o,memoryUsage:a,hitRate:r};this.performanceHistory.push(l),this.performanceHistory.length>1e3&&(this.performanceHistory=this.performanceHistory.slice(-1e3)),this.algorithmSelector.updatePerformanceModel({algorithm:t,workload:this.analyzeWorkload([]),performance:{executionTime:o,memoryUsage:a,allocationCount:0,cacheHitRate:r},timestamp:Date.now()})}updateStats(t,e,s){const i=performance.now()-e,o=this.getCurrentMemoryUsage()-s;this.stats.averageExecutionTime=(this.stats.averageExecutionTime*(this.stats.totalQueries-1)+i)/this.stats.totalQueries,this.stats.averageMemoryUsage=(this.stats.averageMemoryUsage*(this.stats.totalQueries-1)+o)/this.stats.totalQueries,this.stats.algorithmUsage[t]++,this.stats.memoryPoolStats=this.memoryPool.getStatistics()}getCurrentMemoryUsage(){return performance.memory?.usedJSHeapSize||0}getPerformanceStats(){return{...this.stats}}getMemoryPoolStats(){return this.memoryPool.getStatistics()}getOptimizationRecommendations(){return this.memoryPool.getOptimizationRecommendations()}isPerformanceDegraded(){const t=this.getPerformanceStats(),e=this.config.performanceThresholds;return t.averageExecutionTime>e.maxExecutionTime||t.averageMemoryUsage>e.maxMemoryUsage||t.memoryPoolStats.hitRate<e.minHitRate}getPerformanceReport(){const t=this.getPerformanceStats();return{summary:{totalQueries:t.totalQueries,averageExecutionTime:t.averageExecutionTime,averageMemoryUsage:t.averageMemoryUsage,hitRate:t.memoryPoolStats.hitRate,isDegraded:this.isPerformanceDegraded()},algorithmUsage:t.algorithmUsage,memoryPool:t.memoryPoolStats,recommendations:this.getOptimizationRecommendations()}}resetStatistics(){this.stats={totalQueries:0,averageExecutionTime:0,averageMemoryUsage:0,algorithmUsage:{naive:0,spatial:0,optimized:0},memoryPoolStats:this.memoryPool.getStatistics(),performanceHistory:[]},this.performanceHistory=[],this.algorithmSelector.clearPerformanceHistory()}destroy(){this.memoryPool.destroy(),this.performanceHistory=[]}}function T(n,t){return n.x>=t.x&&n.x<=t.x+t.width&&n.y>=t.y&&n.y<=t.y+t.height}function N(n,t){const e=Math.min(n.x,t.x),s=Math.min(n.y,t.y),i=Math.max(n.x+n.width,t.x+t.width),o=Math.max(n.y+n.height,t.y+t.height);return{x:e,y:s,width:i-e,height:o-s}}function G(n,t){const e=Math.max(0,Math.min(n.x+n.width,t.x+t.width)-Math.max(n.x,t.x)),s=Math.max(0,Math.min(n.y+n.height,t.y+t.height)-Math.max(n.y,t.y));return e>0&&s>0?{x:Math.max(n.x,t.x),y:Math.max(n.y,t.y),width:e,height:s}:null}function J(n,t){return{x:n.x-t,y:n.y-t,width:n.width+t*2,height:n.height+t*2}}function Z(n,t){return t.x>=n.x&&t.y>=n.y&&t.x+t.width<=n.x+n.width&&t.y+t.height<=n.y+n.height}function O(n,t){const e=Math.max(0,Math.min(n.x+n.width,t.x+t.width)-Math.max(n.x,t.x)),s=Math.max(0,Math.min(n.y+n.height,t.y+t.height)-Math.max(n.y,t.y)),i=n.x+n.width===t.x||t.x+t.width===n.x,o=n.y+n.height===t.y||t.y+t.height===n.y;return i&&s>0||o&&e>0}function z(n,t){const e=Math.max(0,Math.min(n.x+n.width,t.x+t.width)-Math.max(n.x,t.x)),s=Math.max(0,Math.min(n.y+n.height,t.y+t.height)-Math.max(n.y,t.y)),i=e>0&&s>0,o=e===0&&s>0||s===0&&e>0||e===0&&s===0&&O(n,t),a=t.width===0&&t.height===0&&T({x:t.x,y:t.y},n)||n.width===0&&n.height===0&&T({x:n.x,y:n.y},t),r=i||o||a,l=e*s;let c=null;i&&(c={x:Math.max(n.x,t.x),y:Math.max(n.y,t.y),width:e,height:s});const h=n.x+n.width/2,u=n.y+n.height/2,d=t.x+t.width/2,x=t.y+t.height/2,y=Math.sqrt((d-h)**2+(x-u)**2);return{colliding:r,overlap:c,overlapArea:l,distance:y}}let A={enableMemoryPooling:!0,enableAlgorithmSelection:!0,enablePerformanceMonitoring:!0,algorithmSelectionStrategy:"adaptive",performanceThresholds:{maxExecutionTime:16,maxMemoryUsage:50*1024*1024,minHitRate:90}},S=null;function k(n){A={...A,...n},S&&(S.destroy(),S=new I(A))}function B(){return S||(S=new I(A)),S}function _(n){return B().detectCollisions(n)}function b(n,t){const e=[];for(const s of t)z(n,s.aabb).colliding&&e.push(s);return e}class tt{constructor(){this.adapter=B()}getPerformanceStats(){return this.adapter.getPerformanceStats()}getMemoryPoolStats(){return this.adapter.getMemoryPoolStats()}getOptimizationRecommendations(){return this.adapter.getOptimizationRecommendations()}isPerformanceDegraded(){return this.adapter.isPerformanceDegraded()}getPerformanceReport(){return this.adapter.getPerformanceReport()}resetStatistics(){this.adapter.resetStatistics()}}class et{constructor(t={}){this.config={...A,...t}}update(t){this.config={...this.config,...t},k(this.config)}getConfig(){return{...this.config}}enableMemoryPooling(){this.update({enableMemoryPooling:!0})}disableMemoryPooling(){this.update({enableMemoryPooling:!1})}enableAlgorithmSelection(){this.update({enableAlgorithmSelection:!0})}disableAlgorithmSelection(){this.update({enableAlgorithmSelection:!1})}setAlgorithmStrategy(t){this.update({algorithmSelectionStrategy:t})}setPerformanceThresholds(t){this.update({performanceThresholds:{...this.config.performanceThresholds,...t}})}}function st(){S&&(S.destroy(),S=null)}class q{constructor(t={}){this.spatialHashPool=[],this.unionFindPool=[],this.collisionArrayPool=[],this.config={spatialHashPoolSize:10,unionFindPoolSize:20,collisionArrayPoolSize:50,enablePoolReuse:!0,poolGrowthStrategy:"adaptive",maxPoolSize:100,enableStatistics:!0,...t},this.stats={totalAllocations:0,totalDeallocations:0,poolHits:0,poolMisses:0,memorySaved:0,averageAllocationTime:0,peakPoolUsage:0},this.initializePools(),this.startPoolCleanup()}initializePools(){for(let e=0;e<this.config.spatialHashPoolSize;e++)this.spatialHashPool.push({hash:new C({cellSize:100}),isInUse:!1,lastUsed:0,allocationCount:0});const t=[10,25,50,100,200,500];for(const e of t)for(let s=0;s<Math.ceil(this.config.unionFindPoolSize/t.length);s++)this.unionFindPool.push({unionFind:new g(e),isInUse:!1,lastUsed:0,size:e,allocationCount:0});for(let e=0;e<this.config.collisionArrayPoolSize;e++)this.collisionArrayPool.push({array:[],isInUse:!1,lastUsed:0,allocationCount:0})}getSpatialHash(t){const e=performance.now();let s=this.spatialHashPool.find(i=>!i.isInUse);if(s)return s.isInUse=!0,s.lastUsed=Date.now(),s.allocationCount++,this.stats.poolHits++,s.hash.clear(),this.updateStats(e,!0),s.hash;{this.stats.poolMisses++;const i=new C(t||{cellSize:100});return this.spatialHashPool.length<this.config.maxPoolSize&&this.spatialHashPool.push({hash:i,isInUse:!0,lastUsed:Date.now(),allocationCount:1}),this.updateStats(e,!1),i}}getUnionFind(t){const e=performance.now();let s=this.unionFindPool.find(i=>!i.isInUse&&i.size===t);if(s)return s.isInUse=!0,s.lastUsed=Date.now(),s.allocationCount++,this.stats.poolHits++,s.unionFind=new g(t),this.updateStats(e,!0),s.unionFind;{this.stats.poolMisses++;const i=new g(t);return this.unionFindPool.length<this.config.maxPoolSize&&this.unionFindPool.push({unionFind:i,isInUse:!0,lastUsed:Date.now(),size:t,allocationCount:1}),this.updateStats(e,!1),i}}getCollisionArray(){const t=performance.now();let e=this.collisionArrayPool.find(s=>!s.isInUse);if(e)return e.isInUse=!0,e.lastUsed=Date.now(),e.allocationCount++,this.stats.poolHits++,e.array.length=0,this.updateStats(t,!0),e.array;{this.stats.poolMisses++;const s=[];return this.collisionArrayPool.length<this.config.maxPoolSize&&this.collisionArrayPool.push({array:s,isInUse:!0,lastUsed:Date.now(),allocationCount:1}),this.updateStats(t,!1),s}}returnSpatialHash(t){const e=this.spatialHashPool.find(s=>s.hash===t);e&&(e.isInUse=!1,e.lastUsed=Date.now(),this.stats.totalDeallocations++)}returnUnionFind(t){const e=this.unionFindPool.find(s=>s.unionFind===t);e&&(e.isInUse=!1,e.lastUsed=Date.now(),this.stats.totalDeallocations++)}returnCollisionArray(t){const e=this.collisionArrayPool.find(s=>s.array===t);e&&(e.isInUse=!1,e.lastUsed=Date.now(),this.stats.totalDeallocations++)}updateStats(t,e){const s=performance.now()-t;this.stats.totalAllocations++,this.stats.averageAllocationTime=(this.stats.averageAllocationTime*(this.stats.totalAllocations-1)+s)/this.stats.totalAllocations,e&&(this.stats.memorySaved+=this.estimateMemorySavings()),this.stats.peakPoolUsage=Math.max(this.stats.peakPoolUsage,this.getCurrentPoolUsage())}estimateMemorySavings(){return 1344}getCurrentPoolUsage(){const t=this.spatialHashPool.filter(i=>i.isInUse).length,e=this.unionFindPool.filter(i=>i.isInUse).length,s=this.collisionArrayPool.filter(i=>i.isInUse).length;return t+e+s}getStatistics(){return{...this.stats}}getPoolInfo(){return{spatialHashPool:{total:this.spatialHashPool.length,inUse:this.spatialHashPool.filter(t=>t.isInUse).length,available:this.spatialHashPool.filter(t=>!t.isInUse).length},unionFindPool:{total:this.unionFindPool.length,inUse:this.unionFindPool.filter(t=>t.isInUse).length,available:this.unionFindPool.filter(t=>!t.isInUse).length},collisionArrayPool:{total:this.collisionArrayPool.length,inUse:this.collisionArrayPool.filter(t=>t.isInUse).length,available:this.collisionArrayPool.filter(t=>!t.isInUse).length}}}startPoolCleanup(){this.poolCleanupInterval=window.setInterval(()=>{this.cleanupUnusedPools()},3e4)}cleanupUnusedPools(){const t=Date.now(),e=3e5;this.spatialHashPool=this.spatialHashPool.filter(s=>!(!s.isInUse&&t-s.lastUsed>e)),this.unionFindPool=this.unionFindPool.filter(s=>!(!s.isInUse&&t-s.lastUsed>e)),this.collisionArrayPool=this.collisionArrayPool.filter(s=>!(!s.isInUse&&t-s.lastUsed>e))}destroy(){this.poolCleanupInterval&&clearInterval(this.poolCleanupInterval),this.spatialHashPool=[],this.unionFindPool=[],this.collisionArrayPool=[]}}const X=new q({spatialHashPoolSize:20,unionFindPoolSize:50,collisionArrayPoolSize:100,enablePoolReuse:!0,poolGrowthStrategy:"adaptive",maxPoolSize:200,enableStatistics:!0});class Y{constructor(t={}){this.collisionCache=new Map,this.config={cellSize:100,maxObjectsPerCell:50,enableCaching:!0,cacheSize:1e3,hybridThreshold:100,useMemoryPool:!0,...t},this.memoryPool=this.config.memoryPool||X,this.stats={totalQueries:0,objectsProcessed:0,averageQueryTime:0,memoryPoolHits:0,memoryPoolMisses:0,allocationTimeSaved:0,spatialHashRebuilds:0,cacheHits:0,cacheMisses:0}}detectCollisions(t){const e=performance.now();this.stats.totalQueries++,this.stats.objectsProcessed=t.length;let s;t.length<this.config.hybridThreshold?s=this.optimizedNaiveCollisionDetection(t):s=this.optimizedSpatialCollisionDetection(t);const i=performance.now()-e;return this.updateAverageQueryTime(i),s}optimizedNaiveCollisionDetection(t){const e=this.memoryPool.getCollisionArray();try{for(let s=0;s<t.length;s++)for(let i=s+1;i<t.length;i++){const o=this.checkCollisionWithCache(t[s],t[i]);o.colliding&&e.push({a:s,b:i,result:o})}return[...e]}finally{this.memoryPool.returnCollisionArray(e)}}optimizedSpatialCollisionDetection(t){const e=this.memoryPool.getSpatialHash({cellSize:this.config.cellSize}),s=this.memoryPool.getCollisionArray();try{e.clear(),this.stats.spatialHashRebuilds++,t.forEach((o,a)=>{e.insert({id:a,x:o.x,y:o.y,width:o.width,height:o.height,data:{aabb:o,index:a}})});const i=new Set;for(let o=0;o<t.length;o++){if(i.has(o))continue;const a=t[o],r=e.queryRect(a.x-a.width,a.y-a.height,a.width*3,a.height*3);for(const l of r){const c=l.data.index;if(c<=o||i.has(c))continue;const h=this.checkCollisionWithCache(a,l.data.aabb);h.colliding&&s.push({a:o,b:c,result:h})}i.add(o)}return[...s]}finally{this.memoryPool.returnSpatialHash(e),this.memoryPool.returnCollisionArray(s)}}checkCollisionWithCache(t,e){if(!this.config.enableCaching)return this.checkCollision(t,e);const s=this.generateCacheKey(t,e),i=this.collisionCache.get(s);if(i)return this.stats.cacheHits++,i;this.stats.cacheMisses++;const o=this.checkCollision(t,e);return this.collisionCache.size<this.config.cacheSize&&this.collisionCache.set(s,o),o}checkCollision(t,e){if(!!(t.x+t.width<=e.x||e.x+e.width<=t.x||t.y+t.height<=e.y||e.y+e.height<=t.y))return{colliding:!1,distance:1/0,overlap:null,overlapArea:0};const i=Math.max(0,Math.min(t.x+t.width,e.x+e.width)-Math.max(t.x,e.x)),o=Math.max(0,Math.min(t.y+t.height,e.y+e.height)-Math.max(t.y,e.y)),a={x:t.x+t.width/2,y:t.y+t.height/2},r={x:e.x+e.width/2,y:e.y+e.height/2};return{colliding:!0,distance:Math.sqrt(Math.pow(a.x-r.x,2)+Math.pow(a.y-r.y,2)),overlap:{x:Math.max(t.x,e.x),y:Math.max(t.y,e.y),width:i,height:o},overlapArea:i*o}}generateCacheKey(t,e){const[s,i]=t.x<e.x||t.x===e.x&&t.y<e.y?[t,e]:[e,t];return`${s.x},${s.y},${s.width},${s.height}|${i.x},${i.y},${i.width},${i.height}`}updateAverageQueryTime(t){this.stats.averageQueryTime=(this.stats.averageQueryTime*(this.stats.totalQueries-1)+t)/this.stats.totalQueries}getStatistics(){const t=this.memoryPool.getStatistics();return{...this.stats,memoryPoolHits:t.poolHits,memoryPoolMisses:t.poolMisses,allocationTimeSaved:t.memorySaved}}getMemoryPoolInfo(){return this.memoryPool.getPoolInfo()}clearCache(){this.collisionCache.clear()}resetStatistics(){this.stats={totalQueries:0,objectsProcessed:0,averageQueryTime:0,memoryPoolHits:0,memoryPoolMisses:0,allocationTimeSaved:0,spatialHashRebuilds:0,cacheHits:0,cacheMisses:0}}}function it(n){return new Y(n)}function ot(n){const t=Math.max(...n.flat()),e=new g(t+1);for(const[s,i]of n)if(!e.union(s,i))return!0;return!1}function nt(n){const t=Math.max(...n.flat()),e=new g(t+1);for(const[i,o]of n)e.union(i,o);const s=new Map;for(let i=0;i<=t;i++){const o=e.find(i);s.has(o)||s.set(o,[]),s.get(o).push(i)}return Array.from(s.values())}class at extends g{constructor(t){super(t),this.operationCache=new Map,this.batchStats={batchOperations:0,cacheHits:0,totalOperations:0}}batchUnion(t){const e=[];this.batchStats.batchOperations++,this.batchStats.totalOperations+=t.length;for(const[s,i]of t){const o=this.union(s,i);e.push(o)}return e}batchFind(t){const e=[];this.batchStats.batchOperations++,this.batchStats.totalOperations+=t.length;for(const s of t){const i=this.find(s);e.push(i)}return e}batchConnected(t){const e=[];this.batchStats.batchOperations++,this.batchStats.totalOperations+=t.length;for(const[s,i]of t){const o=this.connected(s,i);e.push(o)}return e}batchOperations(t){const e=[];this.batchStats.batchOperations++,this.batchStats.totalOperations+=t.length;for(const s of t){let i;switch(s.type){case"union":i=this.union(s.args[0],s.args[1]);break;case"find":i=this.find(s.args[0]);break;case"connected":i=this.connected(s.args[0],s.args[1]);break;default:throw new Error(`Unknown operation type: ${s.type}`)}e.push({type:s.type,result:i,args:s.args})}return e}batchUnionOptimized(t){const e=[];this.batchStats.batchOperations++,this.batchStats.totalOperations+=t.length;for(const[s,i]of t){const o=`${s},${i}`;if(this.operationCache.has(o)){const r=this.operationCache.get(o);e.push(r===1),this.batchStats.cacheHits++;continue}const a=this.union(s,i);if(e.push(a),this.operationCache.set(o,a?1:0),this.operationCache.size>1e3){const r=this.operationCache.keys().next().value;this.operationCache.delete(r)}}return e}getBatchStats(){return{...this.batchStats,cacheHitRate:this.batchStats.totalOperations>0?this.batchStats.cacheHits/this.batchStats.totalOperations:0}}clearCache(){this.operationCache.clear()}}class ${constructor(){this.startTime=0,this.endTime=0,this.isRunning=!1}start(){this.startTime=performance.now(),this.isRunning=!0}stop(){if(!this.isRunning)throw new Error("Timer is not running");return this.endTime=performance.now(),this.isRunning=!1,this.endTime-this.startTime}getElapsed(){return this.isRunning?performance.now()-this.startTime:this.endTime-this.startTime}reset(){this.startTime=0,this.endTime=0,this.isRunning=!1}}class Q{constructor(){this.measurements=[]}measure(){if("memory"in performance){const e=performance.memory.usedJSHeapSize;return this.measurements.push({timestamp:Date.now(),usage:e}),e}return 0}getDelta(){if(this.measurements.length<2)return 0;const t=this.measurements[this.measurements.length-1],e=this.measurements[this.measurements.length-2];return t.usage-e.usage}getAverageUsage(){return this.measurements.length===0?0:this.measurements.reduce((e,s)=>e+s.usage,0)/this.measurements.length}clear(){this.measurements=[]}}class rt{constructor(){this.snapshots=[],this.objectCount=0,this.lastSnapshot=0}takeSnapshot(){const t=Date.now(),e=this.getMemoryUsage();this.snapshots.push({timestamp:t,usage:e,count:this.objectCount}),this.snapshots.length>10&&this.snapshots.shift(),this.lastSnapshot=t}detectLeak(){if(this.snapshots.length<3)return{isLeaking:!1,growthRate:0,confidence:0};const t=this.snapshots.slice(-3),e=[];for(let r=1;r<t.length;r++){const l=t[r].timestamp-t[r-1].timestamp,h=(t[r].usage-t[r-1].usage)/l;e.push(h)}const s=e.reduce((r,l)=>r+l,0)/e.length,i=s>1e3,o=e.reduce((r,l)=>r+Math.pow(l-s,2),0)/e.length,a=Math.max(0,1-Math.sqrt(o)/Math.abs(s));return{isLeaking:i,growthRate:s,confidence:a}}getMemoryUsage(){return"memory"in performance?performance.memory.usedJSHeapSize:0}clear(){this.snapshots=[]}}class D{constructor(){this.timer=new $,this.memoryMonitor=new Q}async run(t,e=1,s){const i=[],o=this.memoryMonitor.measure();this.timer.start();for(let y=0;y<e;y++){const P=performance.now();await t();const H=performance.now();i.push(H-P),s&&H-P>s.maxDuration&&console.warn(`Performance budget exceeded: ${H-P}ms > ${s.maxDuration}ms`)}const a=this.timer.stop(),r=this.memoryMonitor.measure(),l=i.sort((y,P)=>y-P),c=i.reduce((y,P)=>y+P,0)/i.length,h=l[0],u=l[l.length-1],d=i.reduce((y,P)=>y+Math.pow(P-c,2),0)/i.length,x=Math.sqrt(d);return{duration:a,memoryBefore:o,memoryAfter:r,memoryDelta:r-o,timestamp:Date.now(),iterations:e,averageTime:c,minTime:h,maxTime:u,standardDeviation:x}}}async function lt(n,t){const s=await new D().run(n,1);return t&&console.log(`Performance measurement for ${t}:`,s),{result:await n(),metrics:s}}async function ct(n,t,e=1){const i=await new D().run(n,e);return t&&console.log(`Performance measurement for ${t}:`,i),{result:n(),metrics:i}}class ht{constructor(){this.frameCount=0,this.lastTime=performance.now(),this.frameTimes=[],this.droppedFrames=0,this.isMonitoring=!1,this.animationFrameId=null}start(){this.isMonitoring||(this.isMonitoring=!0,this.frameCount=0,this.lastTime=performance.now(),this.frameTimes=[],this.droppedFrames=0,this.monitorFrame())}stop(){this.isMonitoring=!1,this.animationFrameId&&(cancelAnimationFrame(this.animationFrameId),this.animationFrameId=null)}monitorFrame(){if(!this.isMonitoring)return;const t=performance.now(),e=t-this.lastTime;this.frameTimes.push(e),this.frameCount++,e>20&&(this.droppedFrames+=Math.floor(e/16.67)-1),this.frameTimes.length>60&&this.frameTimes.shift(),this.lastTime=t,this.animationFrameId=requestAnimationFrame(()=>this.monitorFrame())}getMetrics(){const t=this.frameTimes.length>0?this.frameTimes.reduce((s,i)=>s+i,0)/this.frameTimes.length:0;return{fps:t>0?1e3/t:0,frameTime:t,droppedFrames:this.droppedFrames,averageFrameTime:t,timestamp:Date.now()}}}function ut(n,t,e={}){let s=null,i=0,o=null;const{leading:a=!0,trailing:r=!0,maxWait:l}=e;return((...c)=>{const h=Date.now(),u=h-i;if(s&&(clearTimeout(s),s=null),a&&u>=t)return i=h,n(...c);if(r){o=c;const d=l?Math.min(t,l-u):t;s=window.setTimeout(()=>{o&&(i=Date.now(),n(...o),o=null)},d)}})}function mt(n,t,e={}){let s=null,i=0,o=null;const{leading:a=!1,trailing:r=!0,maxWait:l}=e;return((...c)=>{const h=Date.now(),u=h-i;if(s&&(clearTimeout(s),s=null),a&&u>=t)return i=h,n(...c);if(r){o=c;const d=l?Math.min(t,l-u):t;s=window.setTimeout(()=>{o&&(i=Date.now(),n(...o),o=null)},d)}})}class dt{constructor(){this.budgets=new Map}setBudget(t,e){this.budgets.set(t,e)}checkBudget(t,e){const s=this.budgets.get(t);if(!s)return!0;const i=[];return e.duration>s.maxDuration&&i.push(`Duration: ${e.duration}ms > ${s.maxDuration}ms`),e.memoryDelta>s.maxMemoryUsage&&i.push(`Memory: ${e.memoryDelta} bytes > ${s.maxMemoryUsage} bytes`),e.iterations>s.maxIterations&&i.push(`Iterations: ${e.iterations} > ${s.maxIterations}`),i.length>0?(console.warn(`Performance budget violation for ${t}:`,i.join(", ")),!1):!0}clearBudget(t){this.budgets.delete(t)}clearAllBudgets(){this.budgets.clear()}}class U{constructor(t,e={}){this.pool=[],this.createFn=t,this.config={initialSize:10,maxSize:1e3,growthFactor:1.5,enableStats:!0,...e},this.stats={created:0,acquired:0,released:0,poolSize:0,peakPoolSize:0,hitRate:0},this.initializePool()}initializePool(){for(let t=0;t<this.config.initialSize;t++)this.pool.push(this.createFn()),this.stats.created++;this.stats.poolSize=this.pool.length,this.stats.peakPoolSize=this.pool.length}acquire(){if(this.stats.acquired++,this.pool.length>0){const e=this.pool.pop();return e.reset(),this.stats.poolSize=this.pool.length,this.updateHitRate(),e}const t=this.createFn();return this.stats.created++,this.updateHitRate(),t}release(t){this.pool.length>=this.config.maxSize||(this.pool.push(t),this.stats.released++,this.stats.poolSize=this.pool.length,this.stats.peakPoolSize=Math.max(this.stats.peakPoolSize,this.pool.length))}updateHitRate(){this.stats.acquired>0&&(this.stats.hitRate=(this.stats.acquired-(this.stats.created-this.config.initialSize))/this.stats.acquired)}getStats(){return{...this.stats}}clear(){this.pool.length=0,this.stats.poolSize=0}resize(t){if(t<this.pool.length)this.pool.length=t;else if(t>this.pool.length){const e=t-this.pool.length;for(let s=0;s<e;s++)this.pool.push(this.createFn()),this.stats.created++}this.stats.poolSize=this.pool.length}}function ft(n={}){class t{constructor(){this.id="",this.x=0,this.y=0,this.width=0,this.height=0,this.data=null}reset(){this.id="",this.x=0,this.y=0,this.width=0,this.height=0,this.data=null}}return new U(()=>new t,n)}function gt(n={}){class t{constructor(){this.x=0,this.y=0,this.width=0,this.height=0}reset(){this.x=0,this.y=0,this.width=0,this.height=0}}return new U(()=>new t,n)}function pt(n={}){class t{constructor(){this.x=0,this.y=0}reset(){this.x=0,this.y=0}}return new U(()=>new t,n)}function yt(n={}){class t{constructor(){this.x=0,this.y=0,this.magnitude=0}reset(){this.x=0,this.y=0,this.magnitude=0}}return new U(()=>new t,n)}class W{constructor(){this.pools=new Map}createPool(t,e,s={}){const i=new U(e,s);return this.pools.set(t,i),i}getPool(t){return this.pools.get(t)}removePool(t){return this.pools.delete(t)}getAllStats(){const t={};return this.pools.forEach((e,s)=>{t[s]=e.getStats()}),t}clearAllPools(){this.pools.forEach(t=>{t.clear()})}}const xt=new W;class f{static create(t,e){return{x:t,y:e}}static add(t,e){return{x:t.x+e.x,y:t.y+e.y}}static subtract(t,e){return{x:t.x-e.x,y:t.y-e.y}}static multiply(t,e){return{x:t.x*e,y:t.y*e}}static divide(t,e){if(e===0)throw new Error("Division by zero");return{x:t.x/e,y:t.y/e}}static distance(t,e){const s=e.x-t.x,i=e.y-t.y;return Math.sqrt(s*s+i*i)}static distanceSquared(t,e){const s=e.x-t.x,i=e.y-t.y;return s*s+i*i}static midpoint(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}static lerp(t,e,s){return{x:t.x+(e.x-t.x)*s,y:t.y+(e.y-t.y)*s}}static equals(t,e){return Math.abs(t.x-e.x)<1e-10&&Math.abs(t.y-e.y)<1e-10}static clone(t){return{x:t.x,y:t.y}}}class Pt{static create(t,e){return{x:t,y:e}}static fromPoints(t,e){return{x:e.x-t.x,y:e.y-t.y}}static add(t,e){return{x:t.x+e.x,y:t.y+e.y}}static subtract(t,e){return{x:t.x-e.x,y:t.y-e.y}}static multiply(t,e){return{x:t.x*e,y:t.y*e}}static divide(t,e){if(e===0)throw new Error("Division by zero");return{x:t.x/e,y:t.y/e}}static dot(t,e){return t.x*e.x+t.y*e.y}static cross(t,e){return t.x*e.y-t.y*e.x}static magnitude(t){return Math.sqrt(t.x*t.x+t.y*t.y)}static magnitudeSquared(t){return t.x*t.x+t.y*t.y}static normalize(t){const e=this.magnitude(t);return e===0?{x:0,y:0}:{x:t.x/e,y:t.y/e}}static rotate(t,e){const s=Math.cos(e),i=Math.sin(e);return{x:t.x*s-t.y*i,y:t.x*i+t.y*s}}static angle(t){return Math.atan2(t.y,t.x)}static angleBetween(t,e){const s=this.dot(t,e),i=this.magnitude(t),o=this.magnitude(e);return Math.acos(s/(i*o))}}class St{static create(t,e){return{start:t,end:e}}static getLength(t){return f.distance(t.start,t.end)}static getLengthSquared(t){return f.distanceSquared(t.start,t.end)}static midpoint(t){return f.midpoint(t.start,t.end)}static direction(t){return{x:t.end.x-t.start.x,y:t.end.y-t.start.y}}static normal(t){const e=this.direction(t),s=Math.sqrt(e.x*e.x+e.y*e.y);return s===0?{x:0,y:0}:{x:-e.y/s,y:e.x/s}}static pointAt(t,e){return f.lerp(t.start,t.end,e)}static distanceToPoint(t,e){const s=e.x-t.start.x,i=e.y-t.start.y,o=t.end.x-t.start.x,a=t.end.y-t.start.y,r=s*o+i*a,l=o*o+a*a;if(l===0)return f.distance(t.start,e);const c=r/l;let h,u;c<0?(h=t.start.x,u=t.start.y):c>1?(h=t.end.x,u=t.end.y):(h=t.start.x+c*o,u=t.start.y+c*a);const d=e.x-h,x=e.y-u;return Math.sqrt(d*d+x*x)}static intersects(t,e){const s=t.start.x,i=t.start.y,o=t.end.x,a=t.end.y,r=e.start.x,l=e.start.y,c=e.end.x,h=e.end.y,u=(s-o)*(l-h)-(i-a)*(r-c);if(Math.abs(u)<1e-10)return null;const d=((s-r)*(l-h)-(i-l)*(r-c))/u,x=-((s-o)*(i-l)-(i-a)*(s-r))/u;return d>=0&&d<=1&&x>=0&&x<=1?{x:s+d*(o-s),y:i+d*(a-i)}:null}}class p{static create(t,e,s,i){return{x:t,y:e,width:s,height:i}}static fromPoints(t,e){return{x:t.x,y:t.y,width:e.x-t.x,height:e.y-t.y}}static area(t){return t.width*t.height}static perimeter(t){return 2*(t.width+t.height)}static center(t){return{x:t.x+t.width/2,y:t.y+t.height/2}}static topLeft(t){return{x:t.x,y:t.y}}static topRight(t){return{x:t.x+t.width,y:t.y}}static bottomLeft(t){return{x:t.x,y:t.y+t.height}}static bottomRight(t){return{x:t.x+t.width,y:t.y+t.height}}static containsPoint(t,e){return e.x>=t.x&&e.x<=t.x+t.width&&e.y>=t.y&&e.y<=t.y+t.height}static containsRectangle(t,e){return e.x>=t.x&&e.y>=t.y&&e.x+e.width<=t.x+t.width&&e.y+e.height<=t.y+t.height}}class M{static intersects(t,e){return t.x<e.x+e.width&&t.x+t.width>e.x&&t.y<e.y+e.height&&t.y+t.height>e.y}static intersection(t,e){if(!this.intersects(t,e))return null;const s=Math.max(t.x,e.x),i=Math.max(t.y,e.y),o=Math.min(t.x+t.width,e.x+e.width),a=Math.min(t.y+t.height,e.y+e.height);return{x:s,y:i,width:o-s,height:a-i}}static union(t,e){const s=Math.min(t.x,e.x),i=Math.min(t.y,e.y),o=Math.max(t.x+t.width,e.x+e.width),a=Math.max(t.y+t.height,e.y+e.height);return{x:s,y:i,width:o-s,height:a-i}}static expand(t,e){return{x:t.x-e,y:t.y-e,width:t.width+e*2,height:t.height+e*2}}static shrink(t,e){return{x:t.x+e,y:t.y+e,width:Math.max(0,t.width-e*2),height:Math.max(0,t.height-e*2)}}static translate(t,e){return{x:t.x+e.x,y:t.y+e.y,width:t.width,height:t.height}}static scale(t,e,s){if(s){const i=t.width*e,o=t.height*e,a=s.x-i/2,r=s.y-o/2;return{x:a,