@tscircuit/capacity-autorouter 0.0.329 → 0.0.331

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -1,4 +1,4 @@
1
- var t=Object.create,e=Object.defineProperty,n=Object.getOwnPropertyDescriptor,s=Object.getOwnPropertyNames,o=Object.getPrototypeOf,i=Object.prototype.hasOwnProperty,r=(t,e)=>function(){return e||(0,t[s(t)[0]])((e={exports:{}}).exports,e),e.exports},a=(r,a,c)=>(c=null!=r?t(o(r)):{},((t,o,r,a)=>{if(o&&"object"==typeof o||"function"==typeof o)for(let c of s(o))i.call(t,c)||c===r||e(t,c,{get:()=>o[c],enumerable:!(a=n(o,c))||a.enumerable});return t})(!a&&r&&r.__esModule?c:e(c,"default",{value:r,enumerable:!0}),r)),c=r({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),h=r({"node_modules/kind-of/index.js"(t,e){var n=c(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),l=r({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),d=r({"node_modules/deep-rename-keys/index.js"(t,e){var n=h(),s=l();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),u=r({"node_modules/xml-reader/node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),p=r({"node_modules/xml-lexer/node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),f=r({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=p(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),m=r({"node_modules/xml-reader/dist/reader.js"(t,e){var n=u(),s=f(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}});function g(t,e){return Array.isArray(e)?[t.a*e[0]+t.c*e[1]+t.e,t.b*e[0]+t.d*e[1]+t.f]:{x:t.a*e.x+t.c*e.y+t.e,y:t.b*e.x+t.d*e.y+t.f}}function y(t,e=0){return{a:1,c:0,e:t,b:0,d:1,f:e}}var{cos:x,sin:v,PI:b}=Math,{tan:P}=Math;a(d()),a(m());function S(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var M=(t,e)=>({...t,rects:[...t.rects??[],...e.rects??[]],points:[...t.points??[],...e.points??[]],lines:[...t.lines??[],...e.lines??[]],circles:[...t.circles??[],...e.circles??[]],arrows:[...t.arrows??[],...e.arrows??[]],texts:[...t.texts??[],...e.texts??[]]}),N=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function I(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var _=class extends N{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,s=this.firstIterationOfStage[e.solverName]||0,o=this.iterations,i=e.solverName===this.getCurrentStageName()?o-s:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:i,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(S(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const s=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const s=this[e.solverName],o=s?.visualize();return o?(S(o,n+t),o):null}).filter(Boolean));return 0===s.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(S(n,s.length+t+1),s.push(n)),1===s.length?s[0]:{points:s.flatMap(t=>t.points||[]),rects:s.flatMap(t=>t.rects||[]),lines:s.flatMap(t=>t.lines||[]),circles:s.flatMap(t=>t.circles||[]),texts:s.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},C=class{constructor(){this.ids=[],this.values=[],this.length=0}clear(){this.length=0}push(t,e){let n=this.length++;for(;n>0;){const t=n-1>>1,s=this.values[t];if(e>=s)break;this.ids[n]=this.ids[t],this.values[n]=s,n=t}this.ids[n]=t,this.values[n]=e}pop(){if(0===this.length)return;const t=this.ids,e=this.values,n=t[0],s=--this.length;if(s>0){const n=t[s],o=e[s];let i=0;const r=s>>1;for(;i<r;){const n=1+(i<<1),r=n+1,a=n+(+(r<s)&+(e[r]<e[n]));if(e[a]>=o)break;t[i]=t[a],e[i]=e[a],i=a}t[i]=n,e[i]=o}return n}peek(){return this.length>0?this.ids[0]:void 0}peekValue(){return this.length>0?this.values[0]:void 0}shrink(){this.ids.length=this.values.length=this.length}},T=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],E=class t{static from(e,n=0){if(n%8!=0)throw new Error("byteOffset must be 8-byte aligned.");if(!e||void 0===e.byteLength||e.buffer)throw new Error("Data must be an instance of ArrayBuffer or SharedArrayBuffer.");const[s,o]=new Uint8Array(e,n+0,2);if(251!==s)throw new Error("Data does not appear to be in a Flatbush format.");const i=o>>4;if(3!==i)throw new Error(`Got v${i} data when expected v3.`);const r=T[15&o];if(!r)throw new Error("Unrecognized array type.");const[a]=new Uint16Array(e,n+2,1),[c]=new Uint32Array(e,n+4,1);return new t(c,a,r,void 0,e,n)}constructor(t,e=16,n=Float64Array,s=ArrayBuffer,o,i=0){if(void 0===t)throw new Error("Missing required argument: numItems.");if(isNaN(t)||t<=0)throw new Error(`Unexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+e,2),65535),this.byteOffset=i;let r=t,a=r;this._levelBounds=[4*r];do{r=Math.ceil(r/this.nodeSize),a+=r,this._levelBounds.push(4*a)}while(1!==r);this.ArrayType=n,this.IndexArrayType=a<16384?Uint16Array:Uint32Array;const c=T.indexOf(n),h=4*a*n.BYTES_PER_ELEMENT;if(c<0)throw new Error(`Unexpected typed array class: ${n}.`);if(o)this.data=o,this._boxes=new n(o,i+8,4*a),this._indices=new this.IndexArrayType(o,i+8+h,a),this._pos=4*a,this.minX=this._boxes[this._pos-4],this.minY=this._boxes[this._pos-3],this.maxX=this._boxes[this._pos-2],this.maxY=this._boxes[this._pos-1];else{const o=this.data=new s(8+h+a*this.IndexArrayType.BYTES_PER_ELEMENT);this._boxes=new n(o,8,4*a),this._indices=new this.IndexArrayType(o,8+h,a),this._pos=0,this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,new Uint8Array(o,0,2).set([251,48+c]),new Uint16Array(o,2,1)[0]=e,new Uint32Array(o,4,1)[0]=t}this._queue=new C}add(t,e,n=t,s=e){const o=this._pos>>2,i=this._boxes;return this._indices[o]=o,i[this._pos++]=t,i[this._pos++]=e,i[this._pos++]=n,i[this._pos++]=s,t<this.minX&&(this.minX=t),e<this.minY&&(this.minY=e),n>this.maxX&&(this.maxX=n),s>this.maxY&&(this.maxY=s),o}finish(){if(this._pos>>2!==this.numItems)throw new Error(`Added ${this._pos>>2} items when expected ${this.numItems}.`);const t=this._boxes;if(this.numItems<=this.nodeSize)return t[this._pos++]=this.minX,t[this._pos++]=this.minY,t[this._pos++]=this.maxX,void(t[this._pos++]=this.maxY);const e=this.maxX-this.minX||1,n=this.maxY-this.minY||1,s=new Uint32Array(this.numItems);for(let o=0,i=0;o<this.numItems;o++){const r=t[i++],a=t[i++],c=t[i++],h=t[i++],l=Math.floor(65535*((r+c)/2-this.minX)/e),d=Math.floor(65535*((a+h)/2-this.minY)/n);s[o]=A(l,d)}R(s,t,this._indices,0,this.numItems-1,this.nodeSize);for(let e=0,n=0;e<this._levelBounds.length-1;e++){const s=this._levelBounds[e];for(;n<s;){const e=n;let o=t[n++],i=t[n++],r=t[n++],a=t[n++];for(let e=1;e<this.nodeSize&&n<s;e++)o=Math.min(o,t[n++]),i=Math.min(i,t[n++]),r=Math.max(r,t[n++]),a=Math.max(a,t[n++]);this._indices[this._pos>>2]=e,t[this._pos++]=o,t[this._pos++]=i,t[this._pos++]=r,t[this._pos++]=a}}}search(t,e,n,s,o){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let i=this._boxes.length-4;const r=[],a=[];for(;void 0!==i;){const c=Math.min(i+4*this.nodeSize,w(i,this._levelBounds));for(let h=i;h<c;h+=4){const c=this._boxes[h];if(n<c)continue;const l=this._boxes[h+1];if(s<l)continue;const d=this._boxes[h+2];if(t>d)continue;const u=this._boxes[h+3];if(e>u)continue;const p=0|this._indices[h>>2];i>=4*this.numItems?r.push(p):(void 0===o||o(p,c,l,d,u))&&a.push(p)}i=r.pop()}return a}neighbors(t,e,n=1/0,s=1/0,o){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let i=this._boxes.length-4;const r=this._queue,a=[],c=s*s;t:for(;void 0!==i;){const s=Math.min(i+4*this.nodeSize,w(i,this._levelBounds));for(let n=i;n<s;n+=4){const s=0|this._indices[n>>2],a=this._boxes[n],h=this._boxes[n+1],l=this._boxes[n+2],d=this._boxes[n+3],u=t<a?a-t:t>l?t-l:0,p=e<h?h-e:e>d?e-d:0,f=u*u+p*p;f>c||(i>=4*this.numItems?r.push(s<<1,f):(void 0===o||o(s))&&r.push(1+(s<<1),f))}for(;r.length&&1&r.peek();){if(r.peekValue()>c)break t;if(a.push(r.pop()>>1),a.length===n)break t}i=r.length?r.pop()>>1:void 0}return r.clear(),a}};function w(t,e){let n=0,s=e.length-1;for(;n<s;){const o=n+s>>1;e[o]>t?s=o:n=o+1}return e[n]}function R(t,e,n,s,o,i){if(Math.floor(s/i)>=Math.floor(o/i))return;const r=t[s],a=t[s+o>>1],c=t[o];let h=c;const l=Math.max(r,a);c>l?h=l:l===r?h=Math.max(a,c):l===a&&(h=Math.max(r,c));let d=s-1,u=o+1;for(;;){do{d++}while(t[d]<h);do{u--}while(t[u]>h);if(d>=u)break;O(t,e,n,d,u)}R(t,e,n,s,u,i),R(t,e,n,u+1,o,i)}function O(t,e,n,s,o){const i=t[s];t[s]=t[o],t[o]=i;const r=4*s,a=4*o,c=e[r],h=e[r+1],l=e[r+2],d=e[r+3];e[r]=e[a],e[r+1]=e[a+1],e[r+2]=e[a+2],e[r+3]=e[a+3],e[a]=c,e[a+1]=h,e[a+2]=l,e[a+3]=d;const u=n[s];n[s]=n[o],n[o]=u}function A(t,e){let n=t^e,s=65535^n,o=65535^(t|e),i=t&(65535^e),r=n|s>>1,a=n>>1^n,c=o>>1^s&i>>1^o,h=n&o>>1^i>>1^i;n=r,s=a,o=c,i=h,r=n&n>>2^s&s>>2,a=n&s>>2^s&(n^s)>>2,c^=n&o>>2^s&i>>2,h^=s&o>>2^(n^s)&i>>2,n=r,s=a,o=c,i=h,r=n&n>>4^s&s>>4,a=n&s>>4^s&(n^s)>>4,c^=n&o>>4^s&i>>4,h^=s&o>>4^(n^s)&i>>4,n=r,s=a,o=c,i=h,c^=n&o>>8^s&i>>8,h^=s&o>>8^(n^s)&i>>8,n=c^c>>1,s=h^h>>1;let l=t^e,d=s|65535^(l|n);return l=16711935&(l|l<<8),l=252645135&(l|l<<4),l=858993459&(l|l<<2),l=1431655765&(l|l<<1),d=16711935&(d|d<<8),d=252645135&(d|d<<4),d=858993459&(d|d<<2),d=1431655765&(d|d<<1),(d<<1|l)>>>0}function z(t){const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,maxX:t.center.x+e,minY:t.center.y-n,maxY:t.center.y+n}}function D(t,e,n){return Math.max(e,Math.min(n,t))}function L(t,e,n,s){const o=F(t,e,n),i=F(t,e,s),r=F(n,s,t),a=F(n,s,e);return o!==i&&r!==a||(!(0!==o||!Y(t,n,e))||(!(0!==i||!Y(t,s,e))||(!(0!==r||!Y(n,t,s))||!(0!==a||!Y(n,e,s)))))}function F(t,e,n){const s=(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y);return 0===s?0:s>0?1:2}function Y(t,e,n){return e.x<=Math.max(t.x,n.x)&&e.x>=Math.min(t.x,n.x)&&e.y<=Math.max(t.y,n.y)&&e.y>=Math.min(t.y,n.y)}function X(t,e,n){const s=(n.x-e.x)**2+(n.y-e.y)**2;if(0===s)return k(t,e);let o=((t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y))/s;o=Math.max(0,Math.min(1,o));return k(t,{x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}function k(t,e){const n=t.x-e.x,s=t.y-e.y;return Math.sqrt(n*n+s*s)}function $(t,e,n,s){const o=e.x-t.x,i=e.y-t.y,r=s.x-n.x,a=s.y-n.y,c=t.x-n.x,h=t.y-n.y,l=o*a-i*r;if(Math.abs(l)<1e-10)return null;const d=(h*r-c*a)/l,u=(o*h-i*c)/l,p=1e-9;if(d>=-1e-9&&d<=1+p&&u>=-1e-9&&u<=1+p){return{x:t.x+d*o,y:t.y+d*i}}return null}function B(t,e){const n=e.width/2,s=e.height/2,o=e.center.x-n,i=e.center.x+n,r=e.center.y-s,a=e.center.y+s;if(t.x>=o&&t.x<=i&&t.y>=r&&t.y<=a)return 0;return k(t,{x:D(t.x,o,i),y:D(t.y,r,a)})}function j(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var W=t=>{if("minX"in t)return t;const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,minY:t.center.y-n,maxX:t.center.x+e,maxY:t.center.y+n}},H=t=>[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],U=t=>{const e=[];for(let n=0;n<t.length;n++){const s=t[n],o=t[(n+1)%t.length];e.push([s,o])}return e},V=(t,e,n)=>{const s=(t.y-e.y)*(n.x-e.x)-(t.x-e.x)*(n.y-e.y);if(Math.abs(s)>1e-9)return!1;const o=(t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y);if(o<0)return!1;return!(o>(n.x-e.x)**2+(n.y-e.y)**2)},G=(t,e)=>{if(e.length<3)return!1;const n=U(e);for(const[e,s]of n)if(V(t,e,s))return!0;let s=!1;for(let n=0,o=e.length-1;n<e.length;o=n++){const i=e[n].x,r=e[n].y,a=e[o].x,c=e[o].y;r>t.y!=c>t.y&&t.x<(a-i)*(t.y-r)/(c-r)+i&&(s=!s)}return s},Z=(t,e)=>{const n=H(t),s=[[n[0],n[1]],[n[1],n[2]],[n[2],n[3]],[n[3],n[0]]],o=U(e);for(const[t,e]of o)for(const[n,o]of s)if(L(t,e,n,o))return!0;return!1},q=(t,e)=>((t,e)=>!(e.length<3)&&(!!e.some(e=>((t,e)=>t.x>=e.minX&&t.x<=e.maxX&&t.y>=e.minY&&t.y<=e.maxY)(e,t))||(!!H(t).some(t=>G(t,e))||Z(t,e))))(W(t),e),J=(t,e)=>((t,e)=>!(e.length<3)&&(!!H(t).every(t=>G(t,e))&&!Z(t,e)))(W(t),e);function K(t,e,n,s){if(t.x===e.x&&t.y===e.y)return X(t,n,s);if(n.x===s.x&&n.y===s.y)return X(n,t,e);if(L(t,e,n,s))return 0;const o=[X(t,n,s),X(e,n,s),X(n,t,e),X(s,t,e)];return Math.min(...o)}function Q(t,e,n){const s=n.width/2,o=n.height/2;return function(t,e,n){const s={x:n.minX,y:n.minY},o={x:n.maxX,y:n.minY},i={x:n.minX,y:n.maxY},r={x:n.maxX,y:n.maxY};if(L(t,e,s,o)||L(t,e,o,r)||L(t,e,r,i)||L(t,e,i,s))return 0;if(t.x>=n.minX&&t.x<=n.maxX&&t.y>=n.minY&&t.y<=n.maxY&&e.x>=n.minX&&e.x<=n.maxX&&e.y>=n.minY&&e.y<=n.maxY)return 0;const a=[X(s,t,e),X(o,t,e),X(i,t,e),X(r,t,e)];if(t.x>=n.minX&&t.x<=n.maxX&&t.y>=n.minY&&t.y<=n.maxY)return 0;if(e.x>=n.minX&&e.x<=n.maxX&&e.y>=n.minY&&e.y<=n.maxY)return 0;if(t.x<n.minX||t.x>n.maxX||t.y<n.minY||t.y>n.maxY){const e=D(t.x,n.minX,n.maxX),s=D(t.y,n.minY,n.maxY);a.push(k(t,{x:e,y:s}))}if(e.x<n.minX||e.x>n.maxX||e.y<n.minY||e.y>n.maxY){const t=D(e.x,n.minX,n.maxX),s=D(e.y,n.minY,n.maxY);a.push(k(e,{x:t,y:s}))}return Math.min(...a)}(t,e,{minX:n.center.x-s,maxX:n.center.x+s,minY:n.center.y-o,maxY:n.center.y+o})}function tt(t,e,n){const s=n.x-e.x,o=n.y-e.y,i=s*s+o*o;if(0===i)return{x:e.x,y:e.y};let r=((t.x-e.x)*s+(t.y-e.y)*o)/i;r=Math.max(0,Math.min(1,r));return{x:e.x+r*s,y:e.y+r*o}}function et(t,e,n=0,s=t.length-1,o=st){for(;s>n;){if(s-n>600){const i=s-n+1,r=e-n+1,a=Math.log(i),c=.5*Math.exp(2*a/3),h=.5*Math.sqrt(a*c*(i-c)/i)*(r-i/2<0?-1:1);et(t,e,Math.max(n,Math.floor(e-r*c/i+h)),Math.min(s,Math.floor(e+(i-r)*c/i+h)),o)}const i=t[e];let r=n,a=s;for(nt(t,n,e),o(t[s],i)>0&&nt(t,n,s);r<a;){for(nt(t,r,a),r++,a--;o(t[r],i)<0;)r++;for(;o(t[a],i)>0;)a--}0===o(t[n],i)?nt(t,n,a):(a++,nt(t,a,s)),a<=e&&(n=a+1),e<=a&&(s=a-1)}}function nt(t,e,n){const s=t[e];t[e]=t[n],t[n]=s}function st(t,e){return t<e?-1:t>e?1:0}var ot=class{constructor(t=9){this._maxEntries=Math.max(4,t),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()}all(){return this._all(this.data,[])}search(t){let e=this.data;const n=[];if(!gt(t,e))return n;const s=this.toBBox,o=[];for(;e;){for(let i=0;i<e.children.length;i++){const r=e.children[i],a=e.leaf?s(r):r;gt(t,a)&&(e.leaf?n.push(r):mt(t,a)?this._all(r,n):o.push(r))}e=o.pop()}return n}collides(t){let e=this.data;if(!gt(t,e))return!1;const n=[];for(;e;){for(let s=0;s<e.children.length;s++){const o=e.children[s],i=e.leaf?this.toBBox(o):o;if(gt(t,i)){if(e.leaf||mt(t,i))return!0;n.push(o)}}e=n.pop()}return!1}load(t){if(!t||!t.length)return this;if(t.length<this._minEntries){for(let e=0;e<t.length;e++)this.insert(t[e]);return this}let e=this._build(t.slice(),0,t.length-1,0);if(this.data.children.length)if(this.data.height===e.height)this._splitRoot(this.data,e);else{if(this.data.height<e.height){const t=this.data;this.data=e,e=t}this._insert(e,this.data.height-e.height-1,!0)}else this.data=e;return this}insert(t){return t&&this._insert(t,this.data.height-1),this}clear(){return this.data=yt([]),this}remove(t,e){if(!t)return this;let n=this.data;const s=this.toBBox(t),o=[],i=[];let r,a,c;for(;n||o.length;){if(n||(n=o.pop(),a=o[o.length-1],r=i.pop(),c=!0),n.leaf){const s=it(t,n.children,e);if(-1!==s)return n.children.splice(s,1),o.push(n),this._condense(o),this}c||n.leaf||!mt(n,s)?a?(r++,n=a.children[r],c=!1):n=null:(o.push(n),i.push(r),r=0,a=n,n=n.children[0])}return this}toBBox(t){return t}compareMinX(t,e){return t.minX-e.minX}compareMinY(t,e){return t.minY-e.minY}toJSON(){return this.data}fromJSON(t){return this.data=t,this}_all(t,e){const n=[];for(;t;)t.leaf?e.push(...t.children):n.push(...t.children),t=n.pop();return e}_build(t,e,n,s){const o=n-e+1;let i,r=this._maxEntries;if(o<=r)return i=yt(t.slice(e,n+1)),rt(i,this.toBBox),i;s||(s=Math.ceil(Math.log(o)/Math.log(r)),r=Math.ceil(o/Math.pow(r,s-1))),i=yt([]),i.leaf=!1,i.height=s;const a=Math.ceil(o/r),c=a*Math.ceil(Math.sqrt(r));xt(t,e,n,c,this.compareMinX);for(let o=e;o<=n;o+=c){const e=Math.min(o+c-1,n);xt(t,o,e,a,this.compareMinY);for(let n=o;n<=e;n+=a){const o=Math.min(n+a-1,e);i.children.push(this._build(t,n,o,s-1))}}return rt(i,this.toBBox),i}_chooseSubtree(t,e,n,s){for(;s.push(e),!e.leaf&&s.length-1!==n;){let n,s=1/0,o=1/0;for(let i=0;i<e.children.length;i++){const r=e.children[i],a=dt(r),c=pt(t,r)-a;c<o?(o=c,s=a<s?a:s,n=r):c===o&&a<s&&(s=a,n=r)}e=n||e.children[0]}return e}_insert(t,e,n){const s=n?t:this.toBBox(t),o=[],i=this._chooseSubtree(s,this.data,e,o);for(i.children.push(t),ct(i,s);e>=0&&o[e].children.length>this._maxEntries;)this._split(o,e),e--;this._adjustParentBBoxes(s,o,e)}_split(t,e){const n=t[e],s=n.children.length,o=this._minEntries;this._chooseSplitAxis(n,o,s);const i=this._chooseSplitIndex(n,o,s),r=yt(n.children.splice(i,n.children.length-i));r.height=n.height,r.leaf=n.leaf,rt(n,this.toBBox),rt(r,this.toBBox),e?t[e-1].children.push(r):this._splitRoot(n,r)}_splitRoot(t,e){this.data=yt([t,e]),this.data.height=t.height+1,this.data.leaf=!1,rt(this.data,this.toBBox)}_chooseSplitIndex(t,e,n){let s,o=1/0,i=1/0;for(let r=e;r<=n-e;r++){const e=at(t,0,r,this.toBBox),a=at(t,r,n,this.toBBox),c=ft(e,a),h=dt(e)+dt(a);c<o?(o=c,s=r,i=h<i?h:i):c===o&&h<i&&(i=h,s=r)}return s||n-e}_chooseSplitAxis(t,e,n){const s=t.leaf?this.compareMinX:ht,o=t.leaf?this.compareMinY:lt;this._allDistMargin(t,e,n,s)<this._allDistMargin(t,e,n,o)&&t.children.sort(s)}_allDistMargin(t,e,n,s){t.children.sort(s);const o=this.toBBox,i=at(t,0,e,o),r=at(t,n-e,n,o);let a=ut(i)+ut(r);for(let s=e;s<n-e;s++){const e=t.children[s];ct(i,t.leaf?o(e):e),a+=ut(i)}for(let s=n-e-1;s>=e;s--){const e=t.children[s];ct(r,t.leaf?o(e):e),a+=ut(r)}return a}_adjustParentBBoxes(t,e,n){for(let s=n;s>=0;s--)ct(e[s],t)}_condense(t){for(let e,n=t.length-1;n>=0;n--)0===t[n].children.length?n>0?(e=t[n-1].children,e.splice(e.indexOf(t[n]),1)):this.clear():rt(t[n],this.toBBox)}};function it(t,e,n){if(!n)return e.indexOf(t);for(let s=0;s<e.length;s++)if(n(t,e[s]))return s;return-1}function rt(t,e){at(t,0,t.children.length,e,t)}function at(t,e,n,s,o){o||(o=yt(null)),o.minX=1/0,o.minY=1/0,o.maxX=-1/0,o.maxY=-1/0;for(let i=e;i<n;i++){const e=t.children[i];ct(o,t.leaf?s(e):e)}return o}function ct(t,e){return t.minX=Math.min(t.minX,e.minX),t.minY=Math.min(t.minY,e.minY),t.maxX=Math.max(t.maxX,e.maxX),t.maxY=Math.max(t.maxY,e.maxY),t}function ht(t,e){return t.minX-e.minX}function lt(t,e){return t.minY-e.minY}function dt(t){return(t.maxX-t.minX)*(t.maxY-t.minY)}function ut(t){return t.maxX-t.minX+(t.maxY-t.minY)}function pt(t,e){return(Math.max(e.maxX,t.maxX)-Math.min(e.minX,t.minX))*(Math.max(e.maxY,t.maxY)-Math.min(e.minY,t.minY))}function ft(t,e){const n=Math.max(t.minX,e.minX),s=Math.max(t.minY,e.minY),o=Math.min(t.maxX,e.maxX),i=Math.min(t.maxY,e.maxY);return Math.max(0,o-n)*Math.max(0,i-s)}function mt(t,e){return t.minX<=e.minX&&t.minY<=e.minY&&e.maxX<=t.maxX&&e.maxY<=t.maxY}function gt(t,e){return e.minX<=t.maxX&&e.minY<=t.maxY&&e.maxX>=t.minX&&e.maxY>=t.minY}function yt(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function xt(t,e,n,s,o){const i=[e,n];for(;i.length;){if((n=i.pop())-(e=i.pop())<=s)continue;const r=e+Math.ceil((n-e)/s/2)*s;et(t,r,e,n,o),i.push(e,r,r,n)}}var vt=1e-4;var bt=[{facingDirection:"x-",dx:-1,dy:0,startX:-.5,startY:.5,endX:-.5,endY:-.5},{facingDirection:"x+",dx:1,dy:0,startX:.5,startY:.5,endX:.5,endY:-.5},{facingDirection:"y-",dx:0,dy:-1,startX:-.5,startY:-.5,endX:.5,endY:-.5},{facingDirection:"y+",dx:0,dy:1,startX:.5,startY:.5,endX:-.5,endY:.5}],Pt={"x-":bt.find(t=>"x-"===t.facingDirection),"x+":bt.find(t=>"x+"===t.facingDirection),"y-":bt.find(t=>"y-"===t.facingDirection),"y+":bt.find(t=>"y+"===t.facingDirection)},St={"x-":{x:-1,y:0},"x+":{x:1,y:0},"y-":{x:0,y:-1},"y+":{x:0,y:1}},Mt=(t,e)=>{const{dir:n,amt:s}=e,o=St[n];return t.map(t=>({x:t.x+o.x*s,y:t.y+o.y*s}))},Nt=1e-4,It=class extends N{constructor(t){super(),this.input=t;for(const t of this.input.meshNodes)for(const e of bt){let n={x:t.center.x+t.width*e.startX,y:t.center.y+t.height*e.startY},s={x:t.center.x+t.width*e.endX,y:t.center.y+t.height*e.endY};n.x>s.x&&([n,s]=[s,n]),Math.abs(n.x-s.x)<Nt&&n.y>s.y&&([n,s]=[s,n]);for(const o of t.availableZ)this.unprocessedEdges.push({parent:t,start:n,end:s,facingDirection:e.facingDirection,z:o})}this.allEdges=[...this.unprocessedEdges],this.edgeSpatialIndex=new E(this.allEdges.length);for(const t of this.allEdges)this.edgeSpatialIndex.add(t.start.x,t.start.y,t.end.x,t.end.y);this.edgeSpatialIndex.finish()}allEdges;unprocessedEdges=[];segmentsWithAdjacentEmptySpace=[];edgeSpatialIndex;lastCandidateEdge=null;lastOverlappingEdges=null;lastUncoveredSegments=null;_step(){if(0===this.unprocessedEdges.length)return this.solved=!0,this.lastCandidateEdge=null,this.lastOverlappingEdges=null,void(this.lastUncoveredSegments=null);const t=this.unprocessedEdges.shift();this.lastCandidateEdge=t;const e=this.edgeSpatialIndex.search(t.start.x-Nt,t.start.y-Nt,t.end.x+Nt,t.end.y+Nt).map(t=>this.allEdges[t]).filter(e=>e.z===t.z);this.lastOverlappingEdges=e;const n=function(t,e){const n=Math.abs(t.start.y-t.end.y)<vt,s=Math.abs(t.start.x-t.end.x)<vt;if(!n&&!s)return[];const o=n?"x":"y",i=n?"y":"x",r=t.start[i],a=t.start[o],c=t.end[o],h=Math.min(a,c),l=Math.max(a,c),d=t=>Math.max(h,Math.min(l,t)),u=[];for(const n of e){if(n===t)continue;const e=Math.abs(n.start.y-n.end.y)<vt,s=Math.abs(n.start.x-n.end.x)<vt;if("x"===o&&!e)continue;if("y"===o&&!s)continue;if(Math.abs(n.start[i]-r)>vt)continue;const a=Math.min(n.start[o],n.end[o]),c=Math.max(n.start[o],n.end[o]),h=d(a),l=d(c);l-h>vt&&u.push({s:h,e:l})}if(0===u.length)return[{...t,start:{...t.start},end:{...t.end}}];u.sort((t,e)=>t.s-e.s);const p=[];for(const t of u){const e=p[p.length-1];!e||t.s>e.e+vt?p.push({...t}):e.e=Math.max(e.e,t.e)}const f=[];let m=h;for(const t of p)if(t.s>m+vt&&f.push({s:m,e:t.s}),m=Math.max(m,t.e),m>=l-vt)break;return l>m+vt&&f.push({s:m,e:l}),0===f.length?[]:f.filter(t=>t.e-t.s>vt).map(e=>{const n="x"===o?{x:e.s,y:r}:{x:r,y:e.s},s="x"===o?{x:e.e,y:r}:{x:r,y:e.e};return{parent:t.parent,facingDirection:t.facingDirection,start:n,end:s,z:t.z}})}(t,e);this.lastUncoveredSegments=n,this.segmentsWithAdjacentEmptySpace.push(...n)}getOutput(){return{segmentsWithAdjacentEmptySpace:this.segmentsWithAdjacentEmptySpace}}visualize(){const t={title:"FindSegmentsWithAdjacentEmptySpace",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.input.meshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.1)"});for(const e of this.unprocessedEdges)t.lines.push({points:Mt([e.start,e.end],{dir:e.facingDirection,amt:-.1}),strokeColor:"rgba(0, 0, 255, 0.5)",strokeDash:"5 5"});for(const e of this.segmentsWithAdjacentEmptySpace)t.lines.push({points:[e.start,e.end],strokeColor:"rgba(0,255,0, 0.5)"});if(this.lastCandidateEdge&&t.lines.push({points:[this.lastCandidateEdge.start,this.lastCandidateEdge.end],strokeColor:"blue"}),this.lastOverlappingEdges)for(const e of this.lastOverlappingEdges)t.lines.push({points:Mt([e.start,e.end],{dir:e.facingDirection,amt:.05}),strokeColor:"red",strokeDash:"2 2"});if(this.lastUncoveredSegments)for(const e of this.lastUncoveredSegments)t.lines.push({points:Mt([e.start,e.end],{dir:e.facingDirection,amt:-.05}),strokeColor:"green",strokeDash:"2 2"});return t}},_t=t=>({minX:Math.min(...t.map(t=>t.x)),minY:Math.min(...t.map(t=>t.y)),maxX:Math.max(...t.map(t=>t.x)),maxY:Math.max(...t.map(t=>t.y))}),Ct=1e-4,Tt=class extends N{constructor(t){super(),this.input=t,this.unprocessedSegments=[...this.input.segmentsWithAdjacentEmptySpace],this.rectSpatialIndex=new ot,this.rectSpatialIndex.load(this.input.boardVoid?.boardVoidRects.map((t,e)=>({capacityMeshNodeId:`void-rect-${e}`,center:{x:t.x+t.width/2,y:t.y+t.height/2},width:t.width,height:t.height,availableZ:Array.from({length:this.input.boardVoid?.layerCount||0},(t,e)=>e),layer:"void",minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height}))||[]),this.rectSpatialIndex.load(this.input.inputMeshNodes.map(t=>({...t,minX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxX:t.center.x+t.width/2,maxY:t.center.y+t.height/2})))}unprocessedSegments=[];expandedSegments=[];lastSegment=null;lastSearchBounds=null;lastCollidingNodes=null;lastSearchCorner1=null;lastSearchCorner2=null;lastExpandedSegment=null;rectSpatialIndex;_step(){if(0===this.unprocessedSegments.length)return void(this.solved=!0);const t=this.unprocessedSegments.shift();this.lastSegment=t;const{dx:e,dy:n}=Pt[t.facingDirection],s=t.end.x-t.start.x,o=t.end.y-t.start.y,i=Math.sqrt(s**2+o**2),r=s/i,a=o/i;let c=null,h=1;const l={x:t.start.x+e*Ct+r*Ct*10,y:t.start.y+n*Ct+a*Ct*10},d={x:t.end.x+e*Ct-r*Ct*10,y:t.end.y+n*Ct-a*Ct*10};for(this.lastSearchCorner1=l,this.lastSearchCorner2=d;(!c||0===c.length)&&h<1e3;){const s=_t([l,d,{x:l.x+e*h,y:l.y+n*h},{x:d.x+e*h,y:d.y+n*h}]);this.lastSearchBounds=s,c=this.rectSpatialIndex.search(s).filter(e=>e.availableZ.includes(t.z)).filter(e=>e.capacityMeshNodeId!==t.parent.capacityMeshNodeId),h*=4}if(!c||0===c.length)return;this.lastCollidingNodes=c;let u=1/0;for(const e of c){const n=Q(t.start,t.end,e);n<u&&(u=n)}const p=u,f=_t([t.start,t.end,{x:t.start.x+e*p,y:t.start.y+n*p},{x:t.end.x+e*p,y:t.end.y+n*p}]),m={x:(f.minX+f.maxX)/2,y:(f.minY+f.maxY)/2},g=f.maxX-f.minX,y=f.maxY-f.minY,x={segment:t,newNode:{capacityMeshNodeId:`new-${t.parent.capacityMeshNodeId}-${this.expandedSegments.length}`,center:m,width:g,height:y,availableZ:[t.z],layer:t.parent.layer}};this.lastExpandedSegment=x,g<Ct||y<Ct||(this.expandedSegments.push(x),this.rectSpatialIndex.insert({...x.newNode,...f}))}getOutput(){return{expandedSegments:this.expandedSegments}}visualize(){const t={title:"ExpandEdgesToEmptySpace",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.input.inputMeshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.1)",layer:`z${e.availableZ.join(",")}`,label:[`node ${e.capacityMeshNodeId}`,`z:${e.availableZ.join(",")}`].join("\n")});for(const{newNode:e}of this.expandedSegments)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"green",label:`expandedSegment (z=${e.availableZ.join(",")})`,layer:`z${e.availableZ.join(",")}`});if(this.lastSegment&&t.lines.push({points:[this.lastSegment.start,this.lastSegment.end],strokeColor:"rgba(0, 0, 255, 0.5)"}),this.lastSearchBounds&&t.rects.push({center:{x:(this.lastSearchBounds.minX+this.lastSearchBounds.maxX)/2,y:(this.lastSearchBounds.minY+this.lastSearchBounds.maxY)/2},width:this.lastSearchBounds.maxX-this.lastSearchBounds.minX,height:this.lastSearchBounds.maxY-this.lastSearchBounds.minY,fill:"rgba(0, 0, 255, 0.25)"}),this.lastSearchCorner1&&this.lastSearchCorner2&&(t.points.push({x:this.lastSearchCorner1.x,y:this.lastSearchCorner1.y,color:"rgba(0, 0, 255, 0.5)",label:["searchCorner1",`z=${this.lastSegment?.z}`].join("\n")}),t.points.push({x:this.lastSearchCorner2.x,y:this.lastSearchCorner2.y,color:"rgba(0, 0, 255, 0.5)",label:["searchCorner2",`z=${this.lastSegment?.z}`].join("\n")})),this.lastExpandedSegment&&t.rects.push({center:this.lastExpandedSegment.newNode.center,width:this.lastExpandedSegment.newNode.width,height:this.lastExpandedSegment.newNode.height,fill:"purple",label:`expandedSegment (z=${this.lastExpandedSegment.segment.z})`}),this.lastCollidingNodes)for(const e of this.lastCollidingNodes)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(255, 0, 0, 0.5)"});return t}},Et=class extends _{findSegmentsWithAdjacentEmptySpaceSolver;expandEdgesToEmptySpaceSolver;pipelineDef=[I("findSegmentsWithAdjacentEmptySpaceSolver",It,t=>[{meshNodes:t.inputProblem.meshNodes}],{onSolved:()=>{}}),I("expandEdgesToEmptySpaceSolver",Tt,t=>[{inputMeshNodes:t.inputProblem.meshNodes,segmentsWithAdjacentEmptySpace:t.findSegmentsWithAdjacentEmptySpaceSolver.getOutput().segmentsWithAdjacentEmptySpace,boardVoid:t.inputProblem.boardVoid}],{onSolved:()=>{}})];getOutput(){const t=(this.expandEdgesToEmptySpaceSolver?.getOutput().expandedSegments??[]).map(t=>t.newNode);return{outputNodes:[...this.inputProblem.meshNodes,...t]}}initialVisualize(){const t={title:"GapFillSolverPipeline - Initial",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.inputProblem.meshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.3)",fill:"rgba(100, 100, 100, 0.1)",layer:`z${e.availableZ.join(",")}`,label:[`node ${e.capacityMeshNodeId}`,`z:${e.availableZ.join(",")}`].join("\n")});return t}finalVisualize(){const t={title:"GapFillSolverPipeline - Final",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]},{outputNodes:e}=this.getOutput(),n=this.expandEdgesToEmptySpaceSolver?.getOutput().expandedSegments??[],s=new Set(n.map(t=>t.newNode.capacityMeshNodeId));for(const n of e){const e=s.has(n.capacityMeshNodeId);t.rects.push({center:n.center,width:n.width,height:n.height,stroke:e?"rgba(0, 128, 0, 0.8)":"rgba(0, 0, 0, 0.3)",fill:e?"rgba(0, 200, 0, 0.3)":"rgba(100, 100, 100, 0.1)",layer:`z${n.availableZ.join(",")}`,label:[`${e?"[expanded] ":""}node ${n.capacityMeshNodeId}`,`z:${n.availableZ.join(",")}`].join("\n")})}return t}},wt=1e-9,Rt=(t,e,n)=>Math.max(e,Math.min(n,t)),Ot=(t,e)=>t>e+wt,At=(t,e)=>t>e-wt,zt=(t,e)=>t<e-wt,Dt=(t,e)=>t<e+wt;function Lt(t,e){return!(t.x+t.width<=e.x+wt||e.x+e.width<=t.x+wt||t.y+t.height<=e.y+wt||e.y+e.height<=t.y+wt)}function Ft(t,e){const n=[[e.x,e.y,e.x+e.width,e.y],[e.x+e.width,e.y,e.x+e.width,e.y+e.height],[e.x+e.width,e.y+e.height,e.x,e.y+e.height],[e.x,e.y+e.height,e.x,e.y]];let s=1/0;for(const[e,o,i,r]of n){const n=t.x-e,a=t.y-o,c=i-e,h=r-o,l=c*c+h*h;let d=0!==l?(n*c+a*h)/l:0;d=Rt(d,0,1);const u=e+d*c,p=o+d*h;s=Math.min(s,Math.hypot(t.x-u,t.y-p))}return s}function Yt(t,e){const n=Math.max(t[0],e[0]),s=Math.min(t[1],e[1]);return s>n+wt?[n,s]:null}function Xt(t,e){if(!Lt(t,e))return[t];const n=Yt([t.x,t.x+t.width],[e.x,e.x+e.width]),s=Yt([t.y,t.y+t.height],[e.y,e.y+e.height]);if(!n||!s)return[t];const[o,i]=n,[r,a]=s,c=[];o>t.x+wt&&c.push({x:t.x,y:t.y,width:o-t.x,height:t.height}),t.x+t.width>i+wt&&c.push({x:i,y:t.y,width:t.x+t.width-i,height:t.height});const h=Math.max(0,i-o);return h>wt&&r>t.y+wt&&c.push({x:o,y:t.y,width:h,height:r-t.y}),h>wt&&t.y+t.height>a+wt&&c.push({x:o,y:a,width:h,height:t.y+t.height-a}),c.filter(t=>t.width>wt&&t.height>wt)}function kt(t,e){let n=!1;for(let s=0,o=e.length-1;s<e.length;o=s++){const i=e[s].x,r=e[s].y,a=e[o].x,c=e[o].y;r>t.y!=c>t.y&&t.x<(a-i)*(t.y-r)/(c-r)+i&&(n=!n)}return n}function $t(t,e){if(!e||e.length<3)return[];const n=e.length>100?function(t,e){const n=t=>Math.round(t/e)*e,s=new Set,o=[];for(const e of t){const t=n(e.x),i=n(e.y),r=`${t},${i}`;s.has(r)||(s.add(r),o.push({x:t,y:i}))}return o}(e,Math.max(t.width,t.height)/100):e,s=new Set([t.x,t.x+t.width]),o=new Set([t.y,t.y+t.height]);for(const t of n)s.add(t.x),o.add(t.y);const i=Array.from(s).sort((t,e)=>t-e),r=Array.from(o).sort((t,e)=>t-e),a=[];for(let n=0;n<i.length-1;n++)for(let s=0;s<r.length-1;s++){const o=i[n],c=i[n+1],h=r[s],l=r[s+1],d=(o+c)/2,u=(h+l)/2;d>=t.x&&d<=t.x+t.width&&u>=t.y&&u<=t.y+t.height&&(kt({x:d,y:u},e)||a.push({x:o,y:h,width:c-o,height:l-h}))}const c=[];a.sort((t,e)=>Math.abs(t.y-e.y)>wt?t.y-e.y:t.x-e.x);let h=null;for(const t of a){if(!h){h=t;continue}const e=Math.abs(h.y-t.y)<wt,n=Math.abs(h.height-t.height)<wt,s=Math.abs(h.x+h.width-t.x)<wt;e&&n&&s?h.width+=t.width:(c.push(h),h=t)}h&&c.push(h),c.sort((t,e)=>Math.abs(t.x-e.x)>wt?t.x-e.x:t.y-e.y);const l=[];h=null;for(const t of c){if(!h){h=t;continue}const e=Math.abs(h.x-t.x)<wt,n=Math.abs(h.width-t.width)<wt,s=Math.abs(h.y+h.height-t.y)<wt;e&&n&&s?h.height+=t.height:(l.push(h),h=t)}return h&&l.push(h),l}function Bt(t){const e=t.toLowerCase();if("top"===e)return-1e6;if("bottom"===e)return 1e6;const n=/^inner(\d+)$/i.exec(e);return n?parseInt(n[1],10)||0:100+e.charCodeAt(0)}function jt(t){const e=function(t){return Array.from(new Set(t)).sort((t,e)=>{const n=Bt(t),s=Bt(e);return n!==s?n-s:t.localeCompare(e)})}((t.obstacles??[]).flatMap(t=>t.layers??[])),n=Math.max(1,t.layerCount||e.length||1),s=Array.from({length:n},(t,e)=>0===e?"top":e===n-1?"bottom":`inner${e}`),o=[],i=new Set,r=t=>{const e=t.toLowerCase();i.has(e)||(i.add(e),o.push(t))};s.forEach(r),e.forEach(r);const a=o.slice(0,n),c=new Map;return a.forEach((t,e)=>c.set(t.toLowerCase(),e)),o.slice(a.length).forEach(t=>{const e=t.toLowerCase();c.set(e,(t=>{if(a.length<=1)return 0;if("top"===t)return 0;if("bottom"===t)return a.length-1;const e=/^inner(\d+)$/i.exec(t);if(e){if(a.length<=2)return a.length-1;const t=parseInt(e[1],10),n=a.length-2;return Math.min(n,Math.max(1,Number.isFinite(t)?t:1))}return 0})(e))}),{layerNames:a,zIndexByName:c}}function Wt(t,e){if(t.zLayers?.length)return Array.from(new Set(t.zLayers)).sort((t,e)=>t-e);const n=(t.layers??[]).map(t=>e.get(t.toLowerCase())).filter(t=>"number"==typeof t);return Array.from(new Set(n)).sort((t,e)=>t-e)}function Ht(t){const e=t.width,n=t.height;return"number"!=typeof e||"number"!=typeof n?null:{x:t.center.x-e/2,y:t.center.y-n/2,width:e,height:n}}var Ut=1e-9,Vt=t=>Math.abs(t.rect.x+t.rect.width/2-t.startX)<Ut&&Math.abs(t.rect.y+t.rect.height/2-t.startY)<Ut&&Math.abs(t.rect.width-t.initialW)<Ut&&Math.abs(t.rect.height-t.initialH)<Ut,Gt=({rect:t,bounds:e})=>({x:t.x,y:t.y,width:e.x+e.width-t.x,height:t.height}),Zt=({rect:t,bounds:e})=>({x:t.x,y:t.y,width:t.width,height:e.y+e.height-t.y}),qt=({rect:t,bounds:e})=>({x:e.x,y:t.y,width:t.x-e.x,height:t.height}),Jt=({rect:t,bounds:e})=>({x:t.x,y:e.y,width:t.width,height:t.y-e.y});function Kt(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.x+n.width-e.x;for(const t of s){if(e.y+e.height>t.y+wt&&t.y+t.height>e.y+wt)if(At(t.x,e.x+e.width))i=Math.min(i,t.x-e.x);else if(t.x+t.width>e.x+e.width-wt&&t.x<e.x+e.width+wt)return 0}let r=Math.max(0,i-e.width);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;t>=n&&(r=Math.min(r,o*n-t))}return Math.max(0,r)}function Qt(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.y+n.height-e.y;for(const t of s){if(e.x+e.width>t.x+wt&&t.x+t.width>e.x+wt)if(At(t.y,e.y+e.height))i=Math.min(i,t.y-e.y);else if(t.y+t.height>e.y+e.height-wt&&t.y<e.y+e.height+wt)return 0}let r=Math.max(0,i-e.height);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;n>=t&&(r=Math.min(r,o*t-n))}return Math.max(0,r)}function te(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.x;for(const t of s){if(e.y+e.height>t.y+wt&&t.y+t.height>e.y+wt)if(Dt(t.x+t.width,e.x))i=Math.max(i,t.x+t.width);else if(t.x<e.x+wt&&t.x+t.width>e.x-wt)return 0}let r=Math.max(0,e.x-i);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;t>=n&&(r=Math.min(r,o*n-t))}return Math.max(0,r)}function ee(t){const{r:e,bounds:n,blockers:s,maxAspect:o}=t;let i=n.y;for(const t of s){if(e.x+e.width>t.x+wt&&t.x+t.width>e.x+wt)if(Dt(t.y+t.height,e.y))i=Math.max(i,t.y+t.height);else if(t.y<e.y+wt&&t.y+t.height>e.y-wt)return 0}let r=Math.max(0,e.y-i);if(r<=0)return 0;if(null!=o){const t=e.width,n=e.height;n>=t&&(r=Math.min(r,o*t-n))}return Math.max(0,r)}var ne=t=>({x:t.minX,y:t.minY,width:t.maxX-t.minX,height:t.maxY-t.minY}),se=t=>{const{rect:e,seen:n,blockers:s}=t,o=`${e.x}|${e.y}|${e.width}|${e.height}`;n.has(o)||(n.add(o),s.push(e))};function oe(t){const{startX:e,startY:n,gridSize:s,bounds:o,obsticalIndexByLayer:i,placedIndexByLayer:r,initialCellRatio:a,maxAspectRatio:c,minReq:h}=t,l=Math.max(1e-9,s*a),d=Math.max(l,h.width),u=Math.max(l,h.height),p=[],f=new Set,m=r.length,g=s=>{const a=(t=>{const{bounds:e,rect:n}=t,s=Math.max(e.x,n.x),o=Math.max(e.y,n.y),i=Math.min(e.x+e.width,n.x+n.width),r=Math.min(e.y+e.height,n.y+n.height);return i<=s+wt||r<=o+wt?null:{minX:s,minY:o,maxX:i,maxY:r}})({bounds:o,rect:s});if(a)for(const s of t.zLayers){const t=i[s];if(t)for(const e of t.search(a))se({rect:ne(e),seen:f,blockers:p});const o=r[s];if(o)for(const t of o.search(a)){if(!(t.zLayers.length>=m))continue;const s=ne(t);Vt({rect:s,startX:e,startY:n,initialW:d,initialH:u})||se({rect:s,seen:f,blockers:p})}}},y=[{ox:0,oy:0},{ox:-d,oy:0},{ox:0,oy:-u},{ox:-d,oy:-u},{ox:-d/2,oy:-u/2}];let x=null,v=0;t:for(const t of y){let s={x:e+t.ox,y:n+t.oy,width:d,height:u};if(g(s),zt(s.x,o.x)||zt(s.y,o.y)||Ot(s.x+s.width,o.x+o.width)||Ot(s.y+s.height,o.y+o.height))continue;for(const t of p)if(Lt(s,t))continue t;const i=1e-6,r=1e3;let a=!0,l=0;for(;a&&l<r;){l++,a=!1;const t={bounds:o,blockers:p,maxAspect:c};g(Gt({rect:s,bounds:o}));const e=Kt({...t,r:s});e>i&&(s={...s,width:s.width+e},g(s),a=!0),g(Zt({rect:s,bounds:o}));const n=Qt({...t,r:s});n>i&&(s={...s,height:s.height+n},g(s),a=!0),g(qt({rect:s,bounds:o}));const r=te({...t,r:s});r>i&&(s={x:s.x-r,y:s.y,width:s.width+r,height:s.height},g(s),a=!0),g(Jt({rect:s,bounds:o}));const h=ee({...t,r:s});h>i&&(s={x:s.x,y:s.y-h,width:s.width,height:s.height+h},g(s),a=!0)}if(s.width+wt>=h.width&&s.height+wt>=h.height){const t=s.width*s.height;t>v&&(x=s,v=t)}}return x}function ie(t){const e=Math.max(t.width,t.height);return[e/8,e/16,e/32]}function re(t){const e={minX:t.point.x,minY:t.point.y,maxX:t.point.x,maxY:t.point.y};for(let n=0;n<t.layerCount;n++){const s=t.obstacleIndexByLayer[n],o=!!s&&s.search(e).length>0,i=t.placedIndexByLayer[n],r=!!i&&i.search(e).length>0;if(!o&&!r)return!1}return!0}function ae(t){const{x:e,y:n,z:s,layerCount:o,minSpan:i,maxSpan:r,obstacleIndexByLayer:a,additionalBlockersByLayer:c}=t,h=t=>{const s={minX:e,minY:n,maxX:e,maxY:n},o=a[t];if(o&&o.search(s).length>0)return!1;return!(c?.[t]??[]).some(t=>{return(o={x:e,y:n}).x>=(s=t).x-wt&&o.x<=s.x+s.width+wt&&o.y>=s.y-wt&&o.y<=s.y+s.height+wt;var s,o})};let l=s,d=s;for(;l-1>=0&&h(l-1);)l--;for(;d+1<o&&h(d+1);)d++;if("number"==typeof r){const t=Rt(r,1,o);for(;d-l+1>t;)s-l>d-s?l++:d--}const u=[];for(let t=l;t<=d;t++)u.push(t);return u.length>=i?u:[]}function ce(t){const{lineStart:e,lineEnd:n,coveringIntervals:s,minSegmentLength:o}=t;if(0===s.length){return[{start:e,end:n,center:(e+n)/2}]}const i=[...s].sort((t,e)=>t.start-e.start),r=[];let a={...i[0]};for(let t=1;t<i.length;t++){const e=i[t];e.start<=a.end+wt?a.end=Math.max(a.end,e.end):(r.push(a),a={...e})}r.push(a);const c=[];if(r[0].start>e+wt){const t=e,n=r[0].start;n-t>=o&&c.push({start:t,end:n,center:(t+n)/2})}for(let t=0;t<r.length-1;t++){const e=r[t].end,n=r[t+1].start;n-e>=o&&c.push({start:e,end:n,center:(e+n)/2})}if(r[r.length-1].end<n-wt){const t=r[r.length-1].end,e=n;e-t>=o&&c.push({start:t,end:e,center:(t+e)/2})}return c}function he(t){const{bounds:e,minSize:n,layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,hardPlacedByLayer:r}=t,a=[],c=Math.max(.15*n,3*wt),h=new Set;function l(t){const{x:n,y:c,z:l}=t;if(n<e.x+wt||c<e.y+wt||n>e.x+e.width-wt||c>e.y+e.height-wt)return;if(function(t){return re({layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,point:t})}({x:n,y:c}))return;const d=[...o[l]?.all()??[],...r[l]??[]],u=Math.min(Ft({x:n,y:c},e),...d.length?d.map(t=>Ft({x:n,y:c},t)):[1/0]),p=(t=>`${t.z}|${t.x.toFixed(6)}|${t.y.toFixed(6)}`)({x:n,y:c,z:l});if(h.has(p))return;h.add(p);const f=ae({x:n,y:c,z:l,layerCount:s,minSpan:1,maxSpan:void 0,obstacleIndexByLayer:o,additionalBlockersByLayer:r});a.push({x:n,y:c,z:l,distance:u,zSpanLen:f.length,isEdgeSeed:!0})}for(let t=0;t<s;t++){const s=[...o[t]?.all()??[],...r[t]??[]],i=[{x:e.x+c,y:e.y+c},{x:e.x+e.width-c,y:e.y+c},{x:e.x+c,y:e.y+e.height-c},{x:e.x+e.width-c,y:e.y+e.height-c}];for(const e of i)l({x:e.x,y:e.y,z:t});const a=e.y+c,h=s.filter(t=>t.y<=a&&t.y+t.height>=a).map(t=>({start:Math.max(e.x,t.x),end:Math.min(e.x+e.width,t.x+t.width)})),d=ce({lineStart:e.x+c,lineEnd:e.x+e.width-c,coveringIntervals:h,minSegmentLength:.5*n});for(const e of d){const s=e.end-e.start;s>=n&&(l({x:e.center,y:a,z:t}),s>1.5*n&&(l({x:e.start+.4*n,y:a,z:t}),l({x:e.end-.4*n,y:a,z:t})))}const u=e.y+e.height-c,p=s.filter(t=>t.y<=u&&t.y+t.height>=u).map(t=>({start:Math.max(e.x,t.x),end:Math.min(e.x+e.width,t.x+t.width)})),f=ce({lineStart:e.x+c,lineEnd:e.x+e.width-c,coveringIntervals:p,minSegmentLength:.5*n});for(const e of f){const s=e.end-e.start;s>=n&&(l({x:e.center,y:u,z:t}),s>1.5*n&&(l({x:e.start+.4*n,y:u,z:t}),l({x:e.end-.4*n,y:u,z:t})))}const m=e.x+c,g=s.filter(t=>t.x<=m&&t.x+t.width>=m).map(t=>({start:Math.max(e.y,t.y),end:Math.min(e.y+e.height,t.y+t.height)})),y=ce({lineStart:e.y+c,lineEnd:e.y+e.height-c,coveringIntervals:g,minSegmentLength:.5*n});for(const e of y){const s=e.end-e.start;s>=n&&(l({x:m,y:e.center,z:t}),s>1.5*n&&(l({x:m,y:e.start+.4*n,z:t}),l({x:m,y:e.end-.4*n,z:t})))}const x=e.x+e.width-c,v=s.filter(t=>t.x<=x&&t.x+t.width>=x).map(t=>({start:Math.max(e.y,t.y),end:Math.min(e.y+e.height,t.y+t.height)})),b=ce({lineStart:e.y+c,lineEnd:e.y+e.height-c,coveringIntervals:v,minSegmentLength:.5*n});for(const e of b){const s=e.end-e.start;s>=n&&(l({x:x,y:e.center,z:t}),s>1.5*n&&(l({x:x,y:e.start+.4*n,z:t}),l({x:x,y:e.end-.4*n,z:t})))}for(const o of s){const i=o.x-c;if(i>e.x+wt&&i<e.x+e.width-wt){const e=s.filter(t=>t!==o&&t.x<=i&&t.x+t.width>=i).map(t=>({start:Math.max(o.y,t.y),end:Math.min(o.y+o.height,t.y+t.height)})),r=ce({lineStart:o.y,lineEnd:o.y+o.height,coveringIntervals:e,minSegmentLength:.5*n});for(const e of r)l({x:i,y:e.center,z:t})}const r=o.x+o.width+c;if(r>e.x+wt&&r<e.x+e.width-wt){const e=s.filter(t=>t!==o&&t.x<=r&&t.x+t.width>=r).map(t=>({start:Math.max(o.y,t.y),end:Math.min(o.y+o.height,t.y+t.height)})),i=ce({lineStart:o.y,lineEnd:o.y+o.height,coveringIntervals:e,minSegmentLength:.5*n});for(const e of i)l({x:r,y:e.center,z:t})}const a=o.y-c;if(a>e.y+wt&&a<e.y+e.height-wt){const e=s.filter(t=>t!==o&&t.y<=a&&t.y+t.height>=a).map(t=>({start:Math.max(o.x,t.x),end:Math.min(o.x+o.width,t.x+t.width)})),i=ce({lineStart:o.x,lineEnd:o.x+o.width,coveringIntervals:e,minSegmentLength:.5*n});for(const e of i)l({x:e.center,y:a,z:t})}const h=o.y+o.height+c;if(h>e.y+wt&&h<e.y+e.height-wt){const e=s.filter(t=>t!==o&&t.y<=h&&t.y+t.height>=h).map(t=>({start:Math.max(o.x,t.x),end:Math.min(o.x+o.width,t.x+t.width)})),i=ce({lineStart:o.x,lineEnd:o.x+o.width,coveringIntervals:e,minSegmentLength:.5*n});for(const e of i)l({x:e.center,y:h,z:t})}}}return a.sort((t,e)=>e.zSpanLen-t.zSpanLen||e.distance-t.distance),a}var le=(t,e)=>({...t,minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:e.zLayers});function de(t,e){const n=t.placed[e],{rect:s,zLayers:o}=n,i=t.layerCount,r=[],a=[];for(let n=0;n<t.placed.length;n++){if(n===e)continue;const c=t.placed[n];if(c.zLayers.length>=i)continue;const h=c.zLayers.filter(t=>o.includes(t));if(0===h.length)continue;if(!Lt(c.rect,s))continue;const l=Xt(c.rect,s);r.push(n);const d=c.zLayers.filter(t=>!o.includes(t));d.length>0&&a.push({rect:c.rect,zLayers:d});const u=Math.min(t.options.minSingle.width,t.options.minMulti.width),p=Math.min(t.options.minSingle.height,t.options.minMulti.height);for(const t of l)t.width+wt>=u&&t.height+wt>=p&&a.push({rect:t,zLayers:h.slice()})}const c=(t,e)=>t.minX===e.minX&&t.minY===e.minY&&t.maxX===e.maxX&&t.maxY===e.maxY;r.sort((t,e)=>e-t).forEach(e=>{const n=t.placed.splice(e,1)[0];if(t.placedIndexByLayer)for(const e of n.zLayers){const s=t.placedIndexByLayer[e];s&&s.remove(le(n.rect,{zLayers:n.zLayers}),c)}});for(const e of a){t.placed.push(e);for(const n of e.zLayers)if(t.placedIndexByLayer){const s=t.placedIndexByLayer[n];s&&s.insert(le(e.rect,{zLayers:e.zLayers.slice()}))}}}var ue=t=>{const e=[{fill:"#dbeafe",stroke:"#3b82f6"},{fill:"#fef3c7",stroke:"#f59e0b"},{fill:"#d1fae5",stroke:"#10b981"},{fill:"#e9d5ff",stroke:"#a855f7"},{fill:"#fed7aa",stroke:"#f97316"},{fill:"#fecaca",stroke:"#ef4444"}];return e[Math.min(...t)%e.length]},pe=class extends N{constructor(t){super(),this.input=t}srj;layerNames;layerCount;bounds;options;boardVoidRects;gridIndex;candidates;placed;placedIndexByLayer;expansionIndex;edgeAnalysisDone;totalSeedsThisGrid;consumedSeedsThisGrid;_setup(){const t=this.input.simpleRouteJson,e=this.input.gridOptions??{},{layerNames:n,zIndexByName:s}=jt(t),o=Math.max(1,n.length,t.layerCount||1),i={x:t.bounds.minX,y:t.bounds.minY,width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY},r=Math.max(.01,t.minTraceWidth||.15),a={...{gridSizes:[],initialCellRatio:.2,maxAspectRatio:3,minSingle:{width:2*r,height:2*r},minMulti:{width:4*r,height:4*r,minLayers:Math.min(2,Math.max(1,t.layerCount||1))},preferMultiLayer:!0,maxMultiLayerSpan:void 0},...e,gridSizes:e.gridSizes??ie(i)};this.srj=t,this.layerNames=n,this.layerCount=o,this.bounds=i,this.options=a,this.boardVoidRects=this.input.boardVoidRects,this.gridIndex=0,this.candidates=[],this.placed=[],this.placedIndexByLayer=Array.from({length:o},()=>new ot),this.expansionIndex=0,this.edgeAnalysisDone=!1,this.totalSeedsThisGrid=0,this.consumedSeedsThisGrid=0,this.stats={gridIndex:this.gridIndex}}_step(){this._stepGrid(),this.stats.gridIndex=this.gridIndex,this.stats.placed=this.placed.length}_stepGrid(){const{gridSizes:t,initialCellRatio:e,maxAspectRatio:n,minSingle:s,minMulti:o,preferMultiLayer:i,maxMultiLayerSpan:r}=this.options,a=t[this.gridIndex],c=function(t){const e=Array.from({length:t.layerCount},()=>[]);for(const n of t.placed)if(n.zLayers.length>=t.layerCount)for(const t of n.zLayers)e[t].push(n.rect);return e}({layerCount:this.layerCount,placed:this.placed});if(0===this.candidates.length&&0===this.consumedSeedsThisGrid&&(this.candidates=function(t){const{bounds:e,gridSize:n,layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,hardPlacedByLayer:r}=t,a=new Map;for(let t=e.x;t<e.x+e.width;t+=n)for(let c=e.y;c<e.y+e.height;c+=n){if(Math.abs(t-e.x)<wt||Math.abs(c-e.y)<wt||t>e.x+e.width-n-wt||c>e.y+e.height-n-wt)continue;if(re({layerCount:s,obstacleIndexByLayer:o,placedIndexByLayer:i,point:{x:t,y:c}}))continue;let h=[],l=0;for(let e=0;e<s;e++){const n=ae({x:t,y:c,z:e,layerCount:s,minSpan:1,maxSpan:void 0,obstacleIndexByLayer:o,additionalBlockersByLayer:r});n.length>h.length&&(h=n,l=e)}const d=h.length?h[Math.floor(h.length/2)]:l,u=[...o[d]?.all()??[],...r[d]??[]],p=Math.min(Ft({x:t,y:c},e),...u.length?u.map(e=>Ft({x:t,y:c},e)):[1/0]),f=`${t.toFixed(6)}|${c.toFixed(6)}`,m={x:t,y:c,z:d,distance:p,zSpanLen:h.length},g=a.get(f);(!g||m.zSpanLen>(g.zSpanLen??0)||m.zSpanLen===g.zSpanLen&&m.distance>g.distance)&&a.set(f,m)}const c=Array.from(a.values());return c.sort((t,e)=>e.zSpanLen-t.zSpanLen||e.distance-t.distance),c}({bounds:this.bounds,gridSize:a,layerCount:this.layerCount,hardPlacedByLayer:c,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer}),this.totalSeedsThisGrid=this.candidates.length,this.consumedSeedsThisGrid=0),0===this.candidates.length){if(this.gridIndex+1<t.length)return this.gridIndex+=1,this.totalSeedsThisGrid=0,void(this.consumedSeedsThisGrid=0);if(!this.edgeAnalysisDone){const t=Math.min(s.width,s.height);return this.candidates=he({bounds:this.bounds,minSize:t,layerCount:this.layerCount,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,hardPlacedByLayer:c}),this.edgeAnalysisDone=!0,this.totalSeedsThisGrid=this.candidates.length,void(this.consumedSeedsThisGrid=0)}return this.solved=!0,void(this.expansionIndex=0)}const h=this.candidates.shift();this.consumedSeedsThisGrid+=1;const l=ae({x:h.x,y:h.y,z:h.z,layerCount:this.layerCount,minSpan:o.minLayers,maxSpan:r,obstacleIndexByLayer:this.input.obstacleIndexByLayer,additionalBlockersByLayer:c}),d=[];l.length>=o.minLayers&&d.push({kind:"multi",layers:l,minReq:{width:o.width,height:o.height}}),d.push({kind:"single",layers:[h.z],minReq:{width:s.width,height:s.height}});const u=i?d:d.reverse();for(const t of u){const s=oe({startX:h.x,startY:h.y,gridSize:a,bounds:this.bounds,obsticalIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,initialCellRatio:e,maxAspectRatio:n,minReq:t.minReq,zLayers:t.layers});if(!s)continue;const o={rect:s,zLayers:[...t.layers]},i=this.placed.push(o)-1;for(const e of t.layers){const t=this.placedIndexByLayer[e];t&&t.insert(le(s,{zLayers:o.zLayers}))}return de({layerCount:this.layerCount,placed:this.placed,options:this.options,placedIndexByLayer:this.placedIndexByLayer},i),void(this.candidates=this.candidates.filter(t=>!re({layerCount:this.layerCount,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,point:{x:t.x,y:t.y}})))}}computeProgress(){if(this.solved)return 1;const t=this.options.gridSizes.length,e=this.gridIndex/(t+1),n=Math.max(1,this.totalSeedsThisGrid),s=n?this.consumedSeedsThisGrid/n:1;return Math.min(.999,e+s*(1/(t+1)))}getOutput(){return{srj:this.srj,layerNames:this.layerNames,layerCount:this.layerCount,bounds:this.bounds,options:this.options,boardVoidRects:this.boardVoidRects,gridIndex:this.gridIndex,candidates:this.candidates,placed:this.placed,expansionIndex:this.expansionIndex,edgeAnalysisDone:this.edgeAnalysisDone,totalSeedsThisGrid:this.totalSeedsThisGrid,consumedSeedsThisGrid:this.consumedSeedsThisGrid}}visualize(){const t=[],e=[],n=[],s=this.srj??this.input.simpleRouteJson,o=s.bounds.minX,i=s.bounds.maxX,r=s.bounds.minY,a=s.bounds.maxY;s.outline&&s.outline.length>1?n.push({points:[...s.outline,s.outline[0]],strokeColor:"#111827",strokeWidth:.01,label:"outline"}):t.push({center:{x:(o+i)/2,y:(r+a)/2},width:i-o,height:a-r,fill:"none",stroke:"#111827",label:"board"});for(const e of s.obstacles??[])"rect"!==e.type&&"oval"!==e.type||t.push({center:{x:e.center.x,y:e.center.y},width:e.width,height:e.height,fill:"#fee2e2",stroke:"#ef4444",layer:"obstacle",label:"obstacle"});if(this.boardVoidRects){let e=null;if(s.outline&&s.outline.length>0){const t=s.outline.map(t=>t.x),n=s.outline.map(t=>t.y),o=Math.min(...t),i=Math.min(...n);e={x:o,y:i,width:Math.max(...t)-o,height:Math.max(...n)-i}}for(const n of this.boardVoidRects)e&&!Lt(n,e)||t.push({center:{x:n.x+n.width/2,y:n.y+n.height/2},width:n.width,height:n.height,fill:"rgba(0, 0, 0, 0.5)",stroke:"none",label:"void"})}if(this.candidates?.length)for(const t of this.candidates)e.push({x:t.x,y:t.y,fill:"#9333ea",stroke:"#6b21a8",label:`z:${t.z}`});if(this.placed?.length)for(const e of this.placed){const n=ue(e.zLayers);t.push({center:{x:e.rect.x+e.rect.width/2,y:e.rect.y+e.rect.height/2},width:e.rect.width,height:e.rect.height,fill:n.fill,stroke:n.stroke,layer:`z${e.zLayers.join(",")}`,label:`free\nz:${e.zLayers.join(",")}`})}return{title:"RectDiff Grid",coordinateSystem:"cartesian",rects:t,points:e,lines:n}}};var fe=(t,e)=>t.minX===e.minX&&t.minY===e.minY&&t.maxX===e.maxX&&t.maxY===e.maxY,me=class extends N{constructor(t){super(),this.input=t}placedIndexByLayer=[];_meshNodes=[];_setup(){this.stats={gridIndex:this.input.gridIndex},this.placedIndexByLayer=Array.from({length:this.input.layerCount},()=>new ot);for(const t of this.input.placed)for(const e of t.zLayers){const n=this.placedIndexByLayer[e];n&&n.insert(le(t.rect,{zLayers:t.zLayers}))}}_step(){this.solved||(this._stepExpansion(),this.stats.gridIndex=this.input.gridIndex,this.stats.placed=this.input.placed.length,this.input.expansionIndex>=this.input.placed.length&&this.finalizeIfNeeded())}_stepExpansion(){if(this.input.expansionIndex>=this.input.placed.length)return;const t=this.input.expansionIndex,e=this.input.placed[t],n=this.input.options.gridSizes[this.input.options.gridSizes.length-1],s=e.rect,o=oe({startX:e.rect.x+e.rect.width/2,startY:e.rect.y+e.rect.height/2,gridSize:n,bounds:this.input.bounds,obsticalIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,initialCellRatio:0,maxAspectRatio:null,minReq:{width:e.rect.width,height:e.rect.height},zLayers:e.zLayers});if(o){this.input.placed[t]={rect:o,zLayers:e.zLayers};for(const t of e.zLayers){const n=this.placedIndexByLayer[t];n&&(n.remove(le(s,{zLayers:e.zLayers}),fe),n.insert(le(o,{zLayers:e.zLayers})))}de({layerCount:this.input.layerCount,placed:this.input.placed,options:this.input.options,placedIndexByLayer:this.placedIndexByLayer},t)}this.input.expansionIndex+=1}finalizeIfNeeded(){if(this.solved)return;const t=function(t){const e=t.placed.map(t=>({minX:t.rect.x,minY:t.rect.y,maxX:t.rect.x+t.rect.width,maxY:t.rect.y+t.rect.height,zLayers:[...t.zLayers].sort((t,e)=>t-e)})),{zIndexByName:n}=jt(t.srj),s=new Map;for(const e of t.srj.obstacles??[]){const t=Ht(e);if(!t)continue;const o=e.zLayers?.length&&e.zLayers.length>0?e.zLayers:Wt(e,n),i=`${t.x}:${t.y}:${t.width}:${t.height}`;let r=s.get(i);r||(r={rect:t,layers:new Set},s.set(i,r)),o.forEach(t=>r.layers.add(t))}for(const{rect:t,layers:n}of s.values())e.push({minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:Array.from(n).sort((t,e)=>t-e),isObstacle:!0});return e}({placed:this.input.placed,srj:this.input.srj,boardVoidRects:this.input.boardVoidRects});this._meshNodes=function(t){let e=0;const n=[];for(const s of t){const t=Math.max(0,s.maxX-s.minX),o=Math.max(0,s.maxY-s.minY);t<=0||o<=0||0===s.zLayers.length||n.push({capacityMeshNodeId:"cmn_"+e++,center:{x:(s.minX+s.maxX)/2,y:(s.minY+s.maxY)/2},width:t,height:o,layer:"top",availableZ:s.zLayers.slice(),_containsObstacle:s.isObstacle,_containsTarget:s.isObstacle})}return n}(t),this.solved=!0}computeProgress(){if(this.solved)return 1;const t=this.input.options.gridSizes.length,e=t/(t+1),n=Math.max(1,this.input.placed.length),s=n?this.input.expansionIndex/n:1;return Math.min(.999,e+s*(1/(t+1)))}getOutput(){if(this.solved)return{meshNodes:this._meshNodes};return{meshNodes:this.input.placed.map((t,e)=>({capacityMeshNodeId:`expand-preview-${e}`,center:{x:t.rect.x+t.rect.width/2,y:t.rect.y+t.rect.height/2},width:t.rect.width,height:t.rect.height,availableZ:t.zLayers.slice(),layer:`z${t.zLayers.join(",")}`}))}}visualize(){const t=[];for(const e of this.input.placed??[])t.push({center:{x:e.rect.x+e.rect.width/2,y:e.rect.y+e.rect.height/2},width:e.rect.width,height:e.rect.height,stroke:"rgba(37, 99, 235, 0.9)",fill:"rgba(191, 219, 254, 0.5)",layer:`z${e.zLayers.join(",")}`,label:`expanded\nz:${e.zLayers.join(",")}`});return{title:"RectDiff Expansion",coordinateSystem:"cartesian",rects:t,points:[],lines:[]}}},ge=class extends _{rectDiffSeedingSolver;rectDiffExpansionSolver;obstacleIndexByLayer;constructor(t){super(t);const{obstacleIndexByLayer:e}=(t=>{const{srj:e,boardVoidRects:n}=t,{layerNames:s,zIndexByName:o}=jt(e),i=Math.max(1,s.length,e.layerCount||1),r=(e.bounds.minX,e.bounds.minY,e.bounds.maxX,e.bounds.minX,e.bounds.maxY,e.bounds.minY,Array.from({length:i},()=>new ot)),a=(t,e)=>{const n={...t,minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:[e]};r[e]?.insert(n)};if(e.outline&&e.outline.length>2)for(const t of n??[])for(let e=0;e<i;e++)a(t,e);for(const t of e.obstacles??[]){const e=Ht(t);if(!e)continue;const n=Wt(t,o),s=n.filter(t=>t<0||t>=i);if(s.length)throw new Error(`RectDiff: obstacle uses z-layer indices ${s.join(",")} outside 0-${i-1}`);t.zLayers&&0!==t.zLayers.length||!n.length||(t.zLayers=n);for(const t of n)a(e,t)}return{obstacleIndexByLayer:r}})({srj:t.simpleRouteJson,boardVoidRects:t.boardVoidRects});this.obstacleIndexByLayer=e}pipelineDef=[I("rectDiffSeedingSolver",pe,t=>[{simpleRouteJson:t.inputProblem.simpleRouteJson,gridOptions:t.inputProblem.gridOptions,obstacleIndexByLayer:t.obstacleIndexByLayer,boardVoidRects:t.inputProblem.boardVoidRects}]),I("rectDiffExpansionSolver",me,t=>{const e=t.rectDiffSeedingSolver?.getOutput();if(!e)throw new Error("RectDiffSeedingSolver did not produce output");return[{srj:t.inputProblem.simpleRouteJson,layerNames:e.layerNames??[],boardVoidRects:t.inputProblem.boardVoidRects??[],layerCount:t.inputProblem.simpleRouteJson.layerCount,bounds:e.bounds,candidates:e.candidates,consumedSeedsThisGrid:e.placed.length,totalSeedsThisGrid:e.candidates.length,placed:e.placed,edgeAnalysisDone:e.edgeAnalysisDone,gridIndex:e.gridIndex,expansionIndex:e.expansionIndex,obstacleIndexByLayer:t.obstacleIndexByLayer,options:e.options}]})];getConstructorParams(){return[this.inputProblem]}getOutput(){if(this.rectDiffExpansionSolver)return this.rectDiffExpansionSolver.getOutput();if(this.rectDiffSeedingSolver){return{meshNodes:this.rectDiffSeedingSolver.getOutput().placed.map((t,e)=>({capacityMeshNodeId:`grid-${e}`,center:{x:t.rect.x+t.rect.width/2,y:t.rect.y+t.rect.height/2},width:t.rect.width,height:t.rect.height,availableZ:t.zLayers,layer:`z${t.zLayers.join(",")}`}))}}return{meshNodes:[]}}visualize(){return this.rectDiffExpansionSolver?this.rectDiffExpansionSolver.visualize():this.rectDiffSeedingSolver?this.rectDiffSeedingSolver.visualize():{title:"RectDiff Grid Pipeline",coordinateSystem:"cartesian",rects:[],points:[],lines:[]}}};function ye(t,e="RectDiff"){const n=[],s=[],o=t.bounds.minX,i=t.bounds.maxX,r=t.bounds.minY,a=t.bounds.maxY;t.outline&&t.outline.length>1?s.push({points:[...t.outline,t.outline[0]],strokeColor:"#111827",strokeWidth:.01,label:"outline"}):n.push({center:{x:(o+i)/2,y:(r+a)/2},width:i-o,height:a-r,fill:"none",stroke:"#111827",label:"board"});for(const e of t.obstacles??[])"rect"!==e.type&&"oval"!==e.type||n.push({center:{x:e.center.x,y:e.center.y},width:e.width,height:e.height,fill:"#fee2e2",stroke:"#ef4444",layer:"obstacle",label:"obstacle"});return{title:e,coordinateSystem:"cartesian",rects:n,points:[],lines:s}}var xe=class extends _{rectDiffGridSolverPipeline;gapFillSolver;boardVoidRects;pipelineDef=[I("rectDiffGridSolverPipeline",ge,t=>[{simpleRouteJson:t.inputProblem.simpleRouteJson,gridOptions:t.inputProblem.gridOptions,boardVoidRects:t.boardVoidRects}]),I("gapFillSolver",Et,t=>[{meshNodes:t.rectDiffGridSolverPipeline?.getOutput().meshNodes??[],boardVoid:{boardVoidRects:t.boardVoidRects||[],layerCount:t.inputProblem.simpleRouteJson.layerCount||0}}])];_setup(){this.inputProblem.simpleRouteJson.outline&&(this.boardVoidRects=$t({x:this.inputProblem.simpleRouteJson.bounds.minX,y:this.inputProblem.simpleRouteJson.bounds.minY,width:this.inputProblem.simpleRouteJson.bounds.maxX-this.inputProblem.simpleRouteJson.bounds.minX,height:this.inputProblem.simpleRouteJson.bounds.maxY-this.inputProblem.simpleRouteJson.bounds.minY},this.inputProblem.simpleRouteJson.outline??[]))}getConstructorParams(){return[this.inputProblem]}getOutput(){const t=this.gapFillSolver?.getOutput();return t?{meshNodes:t.outputNodes}:this.rectDiffGridSolverPipeline?this.rectDiffGridSolverPipeline.getOutput():{meshNodes:[]}}initialVisualize(){const t=ye(this.inputProblem.simpleRouteJson,"RectDiffPipeline - Initial"),e=this.rectDiffGridSolverPipeline?.getOutput().meshNodes??[];for(const n of e)t.rects.push({center:n.center,width:n.width,height:n.height,stroke:"rgba(0, 0, 0, 0.3)",fill:"rgba(100, 100, 100, 0.1)",layer:`z${n.availableZ.join(",")}`,label:[`node ${n.capacityMeshNodeId}`,`z:${n.availableZ.join(",")}`].join("\n")});return t}finalVisualize(){const t=ye(this.inputProblem.simpleRouteJson,"RectDiffPipeline - Final"),{meshNodes:e}=this.getOutput(),n=new Set((this.rectDiffGridSolverPipeline?.getOutput().meshNodes??[]).map(t=>t.capacityMeshNodeId));for(const s of e){const e=!n.has(s.capacityMeshNodeId);t.rects.push({center:s.center,width:s.width,height:s.height,stroke:e?"rgba(0, 128, 0, 0.8)":"rgba(0, 0, 0, 0.3)",fill:e?"rgba(0, 200, 0, 0.3)":"rgba(100, 100, 100, 0.1)",layer:`z${s.availableZ.join(",")}`,label:[`${e?"[expanded] ":""}node ${s.capacityMeshNodeId}`,`z:${s.availableZ.join(",")}`].join("\n")})}return t}},ve=class{cacheHitsByPrefix={};cacheMissesByPrefix={};isSyncCache=!0;cacheHits=0;cacheMisses=0;cache=new Map;getCachedSolutionSync(t){const e=this.cache.get(t);if(void 0!==e){this.cacheHits++;const n=t.split(":")[0];return this.cacheHitsByPrefix[n]=(this.cacheHitsByPrefix[n]||0)+1,structuredClone(e)}{this.cacheMisses++;const e=t.split(":")[0];return void(this.cacheMissesByPrefix[e]=(this.cacheMissesByPrefix[e]||0)+1)}}async getCachedSolution(t){return this.getCachedSolutionSync(t)}setCachedSolutionSync(t,e){this.cache.set(t,structuredClone(e))}async setCachedSolution(t,e){this.setCachedSolutionSync(t,e)}clearCache(){this.cache.clear(),this.cacheHits=0,this.cacheMisses=0,this.cacheHitsByPrefix={},this.cacheMissesByPrefix={}}getAllCacheKeys(){return Array.from(this.cache.keys())}},be="tscircuit_autorouter_cache_",Pe=class{isSyncCache=!0;cacheHits=0;cacheMisses=0;cacheHitsByPrefix={};cacheMissesByPrefix={};constructor(){}getKey(t){return`${be}${t}`}getCachedSolutionSync(t){if("undefined"==typeof localStorage)return;const e=this.getKey(t);try{const n=localStorage.getItem(e);if(null!==n){const e=JSON.parse(n);this.cacheHits++;const s=t.split(":")[0];return this.cacheHitsByPrefix[s]=(this.cacheHitsByPrefix[s]||0)+1,e}{this.cacheMisses++;const e=t.split(":")[0];return void(this.cacheMissesByPrefix[e]=(this.cacheMissesByPrefix[e]||0)+1)}}catch(n){console.error(`Error getting cached solution sync for ${e}:`,n),this.cacheMisses++;const s=t.split(":")[0];return void(this.cacheMissesByPrefix[s]=(this.cacheMissesByPrefix[s]||0)+1)}}async getCachedSolution(t){return this.getCachedSolutionSync(t)}setCachedSolutionSync(t,e){if("undefined"==typeof localStorage)return;const n=this.getKey(t);try{const t=JSON.stringify(e);localStorage.setItem(n,t)}catch(t){console.error(`Error setting cached solution sync for ${n}:`,t),t instanceof DOMException&&("QuotaExceededError"===t.name||"NS_ERROR_DOM_QUOTA_REACHED"===t.name)&&console.warn(`LocalStorage quota exceeded. Failed to cache solution for ${n}. Consider clearing the cache.`)}}async setCachedSolution(t,e){this.setCachedSolutionSync(t,e)}clearCache(){if("undefined"!=typeof localStorage)try{const t=[];for(let e=0;e<localStorage.length;e++){const n=localStorage.key(e);n?.startsWith(be)&&t.push(n)}t.forEach(t=>localStorage.removeItem(t)),console.log(`Cleared ${t.length} items from LocalStorage cache.`)}catch(t){console.error("Error clearing LocalStorage cache:",t)}finally{this.cacheHits=0,this.cacheMisses=0,this.cacheHitsByPrefix={},this.cacheMissesByPrefix={}}}getAllCacheKeys(){const t=[];for(let e=0;e<1e4;e++){const n=localStorage.key(e);if(!n)break;n.includes(be)&&t.push(n)}return t}};function Se(){return globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE||Ne(),globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE}function Me(){return globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE||Ne(),globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE}function Ne(){globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE??=new Pe,globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE??=new ve}function Ie(t){const e={minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2};for(const n of t.portPoints)n.x<e.minX&&(e.minX=n.x),n.x>e.maxX&&(e.maxX=n.x),n.y<e.minY&&(e.minY=n.y),n.y>e.maxY&&(e.maxY=n.y);return e}var _e=(t,e)=>t<=e?[t,e]:[e,t],Ce=t=>`${t[0]}|${t[1]}`,Te=({portPointId:t,currentNodeId:e,inputNodes:n})=>{let s;if(t)for(const e of n){const n=e.portPoints.find(e=>e.portPointId===t);if(n?.connectionNodeIds){s=n.connectionNodeIds;break}}if(!s||2!==s.length)return[e,e];const[o,i]=s;return o&&i?_e(o,i):[e,e]},Ee=1e-6,we=(t,e)=>Math.abs(t-e)<=Ee,Re=({nodeAId:t,nodeBId:e,nodeBounds:n})=>{if(t===e)return null;const s=n.get(t),o=n.get(e);if(!s||!o)return null;const i=_e(t,e),r=Ce(i);if(we(s.maxX,o.minX)||we(o.maxX,s.minX)){const n=Math.max(s.minY,o.minY),a=Math.min(s.maxY,o.maxY),c=a-n;if(c>Ee){const h=we(s.maxX,o.minX)?s.maxX:s.minX;return{ownerNodeIds:i,ownerPairKey:r,orientation:"vertical",x1:h,y1:n,x2:h,y2:a,center:{x:h,y:(n+a)/2},length:c,nodeSideByOwnerId:we(s.maxX,o.minX)?{[t]:"right",[e]:"left"}:{[t]:"left",[e]:"right"}}}}if(we(s.maxY,o.minY)||we(o.maxY,s.minY)){const n=Math.max(s.minX,o.minX),a=Math.min(s.maxX,o.maxX),c=a-n;if(c>Ee){const h=we(s.maxY,o.minY)?s.maxY:s.minY;return{ownerNodeIds:i,ownerPairKey:r,orientation:"horizontal",x1:n,y1:h,x2:a,y2:h,center:{x:(n+a)/2,y:h},length:c,nodeSideByOwnerId:we(s.maxY,o.minY)?{[t]:"top",[e]:"bottom"}:{[t]:"bottom",[e]:"top"}}}}return null},Oe=({portPoint:t,ownerNodeIds:e,inputNodes:n})=>{for(const s of e){const e=n.find(t=>t.capacityMeshNodeId===s);if(e?._containsTarget)return!0;const o=e?.portPoints.find(e=>e.portPointId===t.portPointId);if(o?.connectionNodeIds?.some(t=>n.find(e=>e.capacityMeshNodeId===t)?._containsTarget))return!0}return!1},Ae=1e-6,ze=class extends N{constructor(t){super(),this.input=t;for(const e of t.nodeWithPortPoints)this.mapOfNodeIdToBounds.set(e.capacityMeshNodeId,Ie(e));const e=new Map;for(const n of t.nodeWithPortPoints)for(const s of n.portPoints){if(!s.portPointId)continue;const o=Te({portPointId:s.portPointId,currentNodeId:n.capacityMeshNodeId,inputNodes:t.inputNodesWithPortPoints}),i=Ce(o),r=this.mapOfOwnerPairToPortPoints.get(i)??[];r.some(t=>t.portPointId&&t.portPointId===s.portPointId)||r.push({...s,ownerNodeIds:o,ownerPairKey:i}),this.mapOfOwnerPairToPortPoints.set(i,r),e.set(i,o)}this.mapOfOwnerPairToSharedEdge=(({ownerPairs:t,nodeBounds:e})=>{const n=new Map;for(const s of t){const[t,o]=s;if(t===o)continue;const i=Re({nodeAId:t,nodeBId:o,nodeBounds:e});i&&n.set(Ce(s),i)}return n})({ownerPairs:Array.from(e.values()),nodeBounds:this.mapOfNodeIdToBounds}),this.ownerPairsToProcess=Array.from(this.mapOfOwnerPairToSharedEdge.keys()),this.ownerPairsToProcess.sort((t,e)=>{const n=this.mapOfOwnerPairToSharedEdge.get(t),s=this.mapOfOwnerPairToSharedEdge.get(e);return n.center.x-s.center.x||n.center.y-s.center.y})}getSolverName(){return"UniformPortDistributionSolver"}mapOfNodeIdToBounds=new Map;mapOfOwnerPairToPortPoints=new Map;mapOfOwnerPairToSharedEdge=new Map;ownerPairsToProcess=[];currentOwnerPairBeingProcessed=null;redistributedNodes=[];step(){if(0===this.ownerPairsToProcess.length)return this.rebuildNodes(),void(this.solved=!0);this.currentOwnerPairBeingProcessed=this.ownerPairsToProcess.shift();const t=this.currentOwnerPairBeingProcessed,e=this.mapOfOwnerPairToSharedEdge.get(t);if(!e)return;if((({sharedEdge:t,obstacles:e})=>{for(const n of e){const e=n.center.x-n.width/2,s=n.center.x+n.width/2,o=n.center.y-n.height/2,i=n.center.y+n.height/2;if("vertical"!==t.orientation){if(Math.abs(t.y1-o)<Ae||Math.abs(t.y1-i)<Ae){const n=Math.max(t.x1,e);if(Math.min(t.x2,s)-n>Ae)return!0}}else if(Math.abs(t.x1-e)<Ae||Math.abs(t.x1-s)<Ae){const e=Math.max(t.y1,o);if(Math.min(t.y2,i)-e>Ae)return!0}}return!1})({sharedEdge:e,obstacles:this.input.obstacles}))return;const n=this.mapOfOwnerPairToPortPoints.get(t)??[],s=[];for(const t of n)Oe({portPoint:t,ownerNodeIds:t.ownerNodeIds,inputNodes:this.input.inputNodesWithPortPoints})||s.push(t);const o=(({sharedEdge:t,portPoints:e})=>{if(0===e.length)return[];const n=new Map;for(const t of e){const e=t.z??0,s=n.get(e)??[];s.push(t),n.set(e,s)}const s=[],o=Array.from(n.keys()).sort((t,e)=>t-e);for(const e of o){const o=n.get(e),i=o.length;o.sort((e,n)=>"horizontal"===t.orientation?e.x-n.x:e.y-n.y);for(let e=0;e<i;e++){const n=(2*e+1)/(2*i),r="horizontal"===t.orientation?t.x1+t.length*n:t.x1,a="horizontal"===t.orientation?t.y1:t.y1+t.length*n;s.push({...o[e],x:r,y:a})}}return s})({sharedEdge:e,portPoints:s});this.mapOfOwnerPairToPortPoints.set(t,o)}rebuildNodes(){const t=new Map;for(const e of this.mapOfOwnerPairToPortPoints.values())for(const n of e)n.portPointId&&t.set(n.portPointId,{x:n.x,y:n.y});this.redistributedNodes=this.input.nodeWithPortPoints.map(e=>({...e,portPoints:e.portPoints.map(e=>{if(e.portPointId&&t.has(e.portPointId)){const n=t.get(e.portPointId);return{...e,x:n.x,y:n.y}}return e})}))}getOutput=()=>this.redistributedNodes;visualize(){return(({obstacles:t,nodeWithPortPoints:e,mapOfOwnerPairToPortPoints:n,mapOfOwnerPairToSharedEdge:s,ownerPairsToProcess:o,currentOwnerPairBeingProcessed:i,mapOfNodeIdToBounds:r})=>{const a=t.map(t=>({...t,fill:"#ec000070"})),c=[],h=[],l=new Map,d=new Map,u=new Map;for(const t of e)for(const e of t.portPoints)e.portPointId&&(l.set(e.portPointId,{x:e.x,y:e.y}),d.set(e.portPointId,e.z??0));for(const t of n.values())for(const e of t)e.portPointId&&(l.set(e.portPointId,{x:e.x,y:e.y}),d.set(e.portPointId,e.z??0),u.set(e.portPointId,`${e.ownerNodeIds[0]}&${e.ownerNodeIds[1]}`));e.forEach(t=>{const e=r.get(t.capacityMeshNodeId);if(e){const n=(e.minX+e.maxX)/2,s=(e.minY+e.maxY)/2,o=e.maxX-e.minX,i=e.maxY-e.minY;a.push({center:{x:n,y:s},width:o,height:i,fill:"#00000030",label:`${t.capacityMeshNodeId}`})}t.portPoints.forEach(e=>{if(!e.portPointId)return;const n=l.get(e.portPointId),s=d.get(e.portPointId)??0,o=u.get(e.portPointId)??`${t.capacityMeshNodeId}&${t.capacityMeshNodeId}`;c.push({x:n.x,y:n.y,label:`z:${s}\no:${o}`}),t.portPoints.forEach(t=>{if(t.portPointId&&e!==t&&e.connectionName===t.connectionName){const e=l.get(t.portPointId);h.push({points:[n,e],strokeColor:"#fff822c9"})}})})});for(const t of o){const e=s.get(t);e&&h.push({points:[{x:e.x1,y:e.y1},{x:e.x2,y:e.y2}],strokeColor:"orange",strokeWidth:.01})}if(i){const t=s.get(i);t&&(h.push({points:[{x:t.x1,y:t.y1},{x:t.x2,y:t.y2}],strokeColor:"red",strokeWidth:.03}),c.push({x:t.center.x,y:t.center.y,label:t.ownerPairKey}))}for(const t of s.values())h.push({points:[{x:t.x1,y:t.y1},{x:t.x2,y:t.y2}],strokeColor:"#33b5ff80",strokeWidth:.006});return{rects:a,lines:h,points:c}})({obstacles:this.input.obstacles,nodeWithPortPoints:this.input.nodeWithPortPoints,mapOfOwnerPairToPortPoints:this.mapOfOwnerPairToPortPoints,mapOfOwnerPairToSharedEdge:this.mapOfOwnerPairToSharedEdge,ownerPairsToProcess:this.ownerPairsToProcess,currentOwnerPairBeingProcessed:this.currentOwnerPairBeingProcessed,mapOfNodeIdToBounds:this.mapOfNodeIdToBounds})}},De=(t,e)=>{if(1===t&&1===e)return"inner1";if(t<0||t>=e)throw new Error(`Invalid z "${t}" for layer count: ${e}`);return 0===t?"top":t===e-1?"bottom":`inner${t}`},Le=(t,e)=>{const n=[];if(0===t.route.length)return n;let s=[],o=t.route[0].z;for(let i=0;i<t.route.length;i++){const r=t.route[i];if(r.z!==o){const i=De(o,e);for(const e of s)n.push({route_type:"wire",x:e.x,y:e.y,width:t.traceThickness,layer:i});if(t.vias.some(t=>Math.abs(t.x-r.x)<.001&&Math.abs(t.y-r.y)<.001)){const t=De(o,e),s=De(r.z,e);n.push({route_type:"via",x:r.x,y:r.y,from_layer:t,to_layer:s})}s=[r],o=r.z}else s.push(r)}const i=De(o,e);for(const e of s)n.push({route_type:"wire",x:e.x,y:e.y,width:t.traceThickness,layer:i});if(t.jumpers&&t.jumpers.length>0){const s=De(t.route[0]?.z??0,e);for(const e of t.jumpers)n.push({route_type:"jumper",start:e.start,end:e.end,footprint:e.footprint,layer:s})}return n};function Fe(){return Fe=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var s in n)({}).hasOwnProperty.call(n,s)&&(t[s]=n[s])}return t},Fe.apply(null,arguments)}function Ye(t,e){return(Ye=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t})(t,e)}function Xe(t){return(Xe=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function ke(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(ke=function(){return!!t})()}function $e(t){var e="function"==typeof Map?new Map:void 0;return $e=function(t){if(null===t||!function(t){try{return-1!==Function.toString.call(t).indexOf("[native code]")}catch(e){return"function"==typeof t}}(t))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,n)}function n(){return function(t,e,n){if(ke())return Reflect.construct.apply(null,arguments);var s=[null];s.push.apply(s,e);var o=new(t.bind.apply(t,s));return n&&Ye(o,n.prototype),o}(t,arguments,Xe(this).constructor)}return n.prototype=Object.create(t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),Ye(n,t)},$e(t)}var Be={1:"Passed invalid arguments to hsl, please pass multiple numbers e.g. hsl(360, 0.75, 0.4) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75 }).\n\n",2:"Passed invalid arguments to hsla, please pass multiple numbers e.g. hsla(360, 0.75, 0.4, 0.7) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75, alpha: 0.7 }).\n\n",3:"Passed an incorrect argument to a color function, please pass a string representation of a color.\n\n",4:"Couldn't generate valid rgb string from %s, it returned %s.\n\n",5:"Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.\n\n",6:"Passed invalid arguments to rgb, please pass multiple numbers e.g. rgb(255, 205, 100) or an object e.g. rgb({ red: 255, green: 205, blue: 100 }).\n\n",7:"Passed invalid arguments to rgba, please pass multiple numbers e.g. rgb(255, 205, 100, 0.75) or an object e.g. rgb({ red: 255, green: 205, blue: 100, alpha: 0.75 }).\n\n",8:"Passed invalid argument to toColorString, please pass a RgbColor, RgbaColor, HslColor or HslaColor object.\n\n",9:"Please provide a number of steps to the modularScale helper.\n\n",10:"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\n\n",11:'Invalid value passed as base to modularScale, expected number or em string but got "%s"\n\n',12:'Expected a string ending in "px" or a number passed as the first argument to %s(), got "%s" instead.\n\n',13:'Expected a string ending in "px" or a number passed as the second argument to %s(), got "%s" instead.\n\n',14:'Passed invalid pixel value ("%s") to %s(), please pass a value like "12px" or 12.\n\n',15:'Passed invalid base value ("%s") to %s(), please pass a value like "12px" or 12.\n\n',16:"You must provide a template to this method.\n\n",17:"You passed an unsupported selector state to this method.\n\n",18:"minScreen and maxScreen must be provided as stringified numbers with the same units.\n\n",19:"fromSize and toSize must be provided as stringified numbers with the same units.\n\n",20:"expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\n\n",21:"expects the objects in the first argument array to have the properties `prop`, `fromSize`, and `toSize`.\n\n",22:"expects the first argument object to have the properties `prop`, `fromSize`, and `toSize`.\n\n",23:"fontFace expects a name of a font-family.\n\n",24:"fontFace expects either the path to the font file(s) or a name of a local copy.\n\n",25:"fontFace expects localFonts to be an array.\n\n",26:"fontFace expects fileFormats to be an array.\n\n",27:"radialGradient requries at least 2 color-stops to properly render.\n\n",28:"Please supply a filename to retinaImage() as the first argument.\n\n",29:"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\n\n",30:"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n",31:"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation\n\n",32:"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s')\n\n",33:"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation\n\n",34:"borderRadius expects a radius value as a string or number as the second argument.\n\n",35:'borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.\n\n',36:"Property must be a string value.\n\n",37:"Syntax Error at %s.\n\n",38:"Formula contains a function that needs parentheses at %s.\n\n",39:"Formula is missing closing parenthesis at %s.\n\n",40:"Formula has too many closing parentheses at %s.\n\n",41:"All values in a formula must have the same unit or be unitless.\n\n",42:"Please provide a number of steps to the modularScale helper.\n\n",43:"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\n\n",44:"Invalid value passed as base to modularScale, expected number or em/rem string but got %s.\n\n",45:"Passed invalid argument to hslToColorString, please pass a HslColor or HslaColor object.\n\n",46:"Passed invalid argument to rgbToColorString, please pass a RgbColor or RgbaColor object.\n\n",47:"minScreen and maxScreen must be provided as stringified numbers with the same units.\n\n",48:"fromSize and toSize must be provided as stringified numbers with the same units.\n\n",49:"Expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\n\n",50:"Expects the objects in the first argument array to have the properties prop, fromSize, and toSize.\n\n",51:"Expects the first argument object to have the properties prop, fromSize, and toSize.\n\n",52:"fontFace expects either the path to the font file(s) or a name of a local copy.\n\n",53:"fontFace expects localFonts to be an array.\n\n",54:"fontFace expects fileFormats to be an array.\n\n",55:"fontFace expects a name of a font-family.\n\n",56:"linearGradient requries at least 2 color-stops to properly render.\n\n",57:"radialGradient requries at least 2 color-stops to properly render.\n\n",58:"Please supply a filename to retinaImage() as the first argument.\n\n",59:"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\n\n",60:"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n",61:"Property must be a string value.\n\n",62:"borderRadius expects a radius value as a string or number as the second argument.\n\n",63:'borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.\n\n',64:"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation.\n\n",65:"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s').\n\n",66:"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation.\n\n",67:"You must provide a template to this method.\n\n",68:"You passed an unsupported selector state to this method.\n\n",69:'Expected a string ending in "px" or a number passed as the first argument to %s(), got %s instead.\n\n',70:'Expected a string ending in "px" or a number passed as the second argument to %s(), got %s instead.\n\n',71:'Passed invalid pixel value %s to %s(), please pass a value like "12px" or 12.\n\n',72:'Passed invalid base value %s to %s(), please pass a value like "12px" or 12.\n\n',73:"Please provide a valid CSS variable.\n\n",74:"CSS variable not found and no default was provided.\n\n",75:"important requires a valid style object, got a %s instead.\n\n",76:"fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.\n\n",77:'remToPx expects a value in "rem" but you provided it in "%s".\n\n',78:'base must be set in "px" or "%" but you set it in "%s".\n'};function je(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];var s,o=e[0],i=[];for(s=1;s<e.length;s+=1)i.push(e[s]);return i.forEach(function(t){o=o.replace(/%[a-z]/,t)}),o}var We=function(t){var e,n;function s(e){var n;if("production"===process.env.NODE_ENV)n=t.call(this,"An error occurred. See https://github.com/styled-components/polished/blob/main/src/internalHelpers/errors.md#"+e+" for more information.")||this;else{for(var s=arguments.length,o=new Array(s>1?s-1:0),i=1;i<s;i++)o[i-1]=arguments[i];n=t.call(this,je.apply(void 0,[Be[e]].concat(o)))||this}return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(n)}return n=t,(e=s).prototype=Object.create(n.prototype),e.prototype.constructor=e,Ye(e,n),s}($e(Error));function He(t,e){return t.substr(-e.length)===e}var Ue=/^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/;function Ve(t){return"string"!=typeof t?t:t.match(Ue)?parseFloat(t):t}var Ge=function(t){return function(e,n){void 0===n&&(n="16px");var s=e,o=n;if("string"==typeof e){if(!He(e,"px"))throw new We(69,t,e);s=Ve(e)}if("string"==typeof n){if(!He(n,"px"))throw new We(70,t,n);o=Ve(n)}if("string"==typeof s)throw new We(71,e,t);if("string"==typeof o)throw new We(72,n,t);return""+s/o+t}};Ge("em"),Ge("rem");function Ze(t){return Math.round(255*t)}function qe(t,e,n){return Ze(t)+","+Ze(e)+","+Ze(n)}function Je(t,e,n,s){if(void 0===s&&(s=qe),0===e)return s(n,n,n);var o=(t%360+360)%360/60,i=(1-Math.abs(2*n-1))*e,r=i*(1-Math.abs(o%2-1)),a=0,c=0,h=0;o>=0&&o<1?(a=i,c=r):o>=1&&o<2?(a=r,c=i):o>=2&&o<3?(c=i,h=r):o>=3&&o<4?(c=r,h=i):o>=4&&o<5?(a=r,h=i):o>=5&&o<6&&(a=i,h=r);var l=n-i/2;return s(a+l,c+l,h+l)}var Ke={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"00ffff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"0000ff",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"00ffff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"ff00ff",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"639",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"};var Qe=/^#[a-fA-F0-9]{6}$/,tn=/^#[a-fA-F0-9]{8}$/,en=/^#[a-fA-F0-9]{3}$/,nn=/^#[a-fA-F0-9]{4}$/,sn=/^rgb\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*\)$/i,on=/^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i,rn=/^hsl\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i,an=/^hsl(?:a)?\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i;function cn(t){if("string"!=typeof t)throw new We(3);var e=function(t){if("string"!=typeof t)return t;var e=t.toLowerCase();return Ke[e]?"#"+Ke[e]:t}(t);if(e.match(Qe))return{red:parseInt(""+e[1]+e[2],16),green:parseInt(""+e[3]+e[4],16),blue:parseInt(""+e[5]+e[6],16)};if(e.match(tn)){var n=parseFloat((parseInt(""+e[7]+e[8],16)/255).toFixed(2));return{red:parseInt(""+e[1]+e[2],16),green:parseInt(""+e[3]+e[4],16),blue:parseInt(""+e[5]+e[6],16),alpha:n}}if(e.match(en))return{red:parseInt(""+e[1]+e[1],16),green:parseInt(""+e[2]+e[2],16),blue:parseInt(""+e[3]+e[3],16)};if(e.match(nn)){var s=parseFloat((parseInt(""+e[4]+e[4],16)/255).toFixed(2));return{red:parseInt(""+e[1]+e[1],16),green:parseInt(""+e[2]+e[2],16),blue:parseInt(""+e[3]+e[3],16),alpha:s}}var o=sn.exec(e);if(o)return{red:parseInt(""+o[1],10),green:parseInt(""+o[2],10),blue:parseInt(""+o[3],10)};var i=on.exec(e.substring(0,50));if(i)return{red:parseInt(""+i[1],10),green:parseInt(""+i[2],10),blue:parseInt(""+i[3],10),alpha:parseFloat(""+i[4])>1?parseFloat(""+i[4])/100:parseFloat(""+i[4])};var r=rn.exec(e);if(r){var a="rgb("+Je(parseInt(""+r[1],10),parseInt(""+r[2],10)/100,parseInt(""+r[3],10)/100)+")",c=sn.exec(a);if(!c)throw new We(4,e,a);return{red:parseInt(""+c[1],10),green:parseInt(""+c[2],10),blue:parseInt(""+c[3],10)}}var h=an.exec(e.substring(0,50));if(h){var l="rgb("+Je(parseInt(""+h[1],10),parseInt(""+h[2],10)/100,parseInt(""+h[3],10)/100)+")",d=sn.exec(l);if(!d)throw new We(4,e,l);return{red:parseInt(""+d[1],10),green:parseInt(""+d[2],10),blue:parseInt(""+d[3],10),alpha:parseFloat(""+h[4])>1?parseFloat(""+h[4])/100:parseFloat(""+h[4])}}throw new We(5)}function hn(t){return function(t){var e,n=t.red/255,s=t.green/255,o=t.blue/255,i=Math.max(n,s,o),r=Math.min(n,s,o),a=(i+r)/2;if(i===r)return void 0!==t.alpha?{hue:0,saturation:0,lightness:a,alpha:t.alpha}:{hue:0,saturation:0,lightness:a};var c=i-r,h=a>.5?c/(2-i-r):c/(i+r);switch(i){case n:e=(s-o)/c+(s<o?6:0);break;case s:e=(o-n)/c+2;break;default:e=(n-s)/c+4}return e*=60,void 0!==t.alpha?{hue:e,saturation:h,lightness:a,alpha:t.alpha}:{hue:e,saturation:h,lightness:a}}(cn(t))}var ln=function(t){return 7===t.length&&t[1]===t[2]&&t[3]===t[4]&&t[5]===t[6]?"#"+t[1]+t[3]+t[5]:t};function dn(t){var e=t.toString(16);return 1===e.length?"0"+e:e}function un(t){return dn(Math.round(255*t))}function pn(t,e,n){return ln("#"+un(t)+un(e)+un(n))}function fn(t,e,n){return Je(t,e,n,pn)}function mn(t,e,n){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n)return ln("#"+dn(t)+dn(e)+dn(n));if("object"==typeof t&&void 0===e&&void 0===n)return ln("#"+dn(t.red)+dn(t.green)+dn(t.blue));throw new We(6)}function gn(t,e,n,s){if("string"==typeof t&&"number"==typeof e){var o=cn(t);return"rgba("+o.red+","+o.green+","+o.blue+","+e+")"}if("number"==typeof t&&"number"==typeof e&&"number"==typeof n&&"number"==typeof s)return s>=1?mn(t,e,n):"rgba("+t+","+e+","+n+","+s+")";if("object"==typeof t&&void 0===e&&void 0===n&&void 0===s)return t.alpha>=1?mn(t.red,t.green,t.blue):"rgba("+t.red+","+t.green+","+t.blue+","+t.alpha+")";throw new We(7)}function yn(t){if("object"!=typeof t)throw new We(8);if(function(t){return"number"==typeof t.red&&"number"==typeof t.green&&"number"==typeof t.blue&&"number"==typeof t.alpha}(t))return gn(t);if(function(t){return"number"==typeof t.red&&"number"==typeof t.green&&"number"==typeof t.blue&&("number"!=typeof t.alpha||void 0===t.alpha)}(t))return mn(t);if(function(t){return"number"==typeof t.hue&&"number"==typeof t.saturation&&"number"==typeof t.lightness&&"number"==typeof t.alpha}(t))return function(t,e,n,s){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n&&"number"==typeof s)return s>=1?fn(t,e,n):"rgba("+Je(t,e,n)+","+s+")";if("object"==typeof t&&void 0===e&&void 0===n&&void 0===s)return t.alpha>=1?fn(t.hue,t.saturation,t.lightness):"rgba("+Je(t.hue,t.saturation,t.lightness)+","+t.alpha+")";throw new We(2)}(t);if(function(t){return"number"==typeof t.hue&&"number"==typeof t.saturation&&"number"==typeof t.lightness&&("number"!=typeof t.alpha||void 0===t.alpha)}(t))return function(t,e,n){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n)return fn(t,e,n);if("object"==typeof t&&void 0===e&&void 0===n)return fn(t.hue,t.saturation,t.lightness);throw new We(1)}(t);throw new We(8)}function xn(t,e,n){return function(){var s=n.concat(Array.prototype.slice.call(arguments));return s.length>=e?t.apply(this,s):xn(t,e,s)}}function vn(t){return xn(t,t.length,[])}vn(function(t,e){if("transparent"===e)return e;var n=hn(e);return yn(Fe({},n,{hue:n.hue+parseFloat(t)}))});function bn(t,e,n){return Math.max(t,Math.min(e,n))}vn(function(t,e){if("transparent"===e)return e;var n=hn(e);return yn(Fe({},n,{lightness:bn(0,1,n.lightness-parseFloat(t))}))});vn(function(t,e){if("transparent"===e)return e;var n=hn(e);return yn(Fe({},n,{saturation:bn(0,1,n.saturation-parseFloat(t))}))});vn(function(t,e){if("transparent"===e)return e;var n=hn(e);return yn(Fe({},n,{lightness:bn(0,1,n.lightness+parseFloat(t))}))});var Pn=vn(function(t,e,n){if("transparent"===e)return n;if("transparent"===n)return e;if(0===t)return n;var s=cn(e),o=Fe({},s,{alpha:"number"==typeof s.alpha?s.alpha:1}),i=cn(n),r=Fe({},i,{alpha:"number"==typeof i.alpha?i.alpha:1}),a=o.alpha-r.alpha,c=2*parseFloat(t)-1,h=((c*a===-1?c:c+a)/(1+c*a)+1)/2,l=1-h;return gn({red:Math.floor(o.red*h+r.red*l),green:Math.floor(o.green*h+r.green*l),blue:Math.floor(o.blue*h+r.blue*l),alpha:o.alpha*parseFloat(t)+r.alpha*(1-parseFloat(t))})});vn(function(t,e){if("transparent"===e)return e;var n=cn(e);return gn(Fe({},n,{alpha:bn(0,1,(100*("number"==typeof n.alpha?n.alpha:1)+100*parseFloat(t))/100)}))});vn(function(t,e){if("transparent"===e)return e;var n=hn(e);return yn(Fe({},n,{saturation:bn(0,1,n.saturation+parseFloat(t))}))});vn(function(t,e){return"transparent"===e?e:yn(Fe({},hn(e),{hue:parseFloat(t)}))});vn(function(t,e){return"transparent"===e?e:yn(Fe({},hn(e),{lightness:parseFloat(t)}))});vn(function(t,e){return"transparent"===e?e:yn(Fe({},hn(e),{saturation:parseFloat(t)}))});vn(function(t,e){return"transparent"===e?e:Pn(parseFloat(t),"rgb(0, 0, 0)",e)});vn(function(t,e){return"transparent"===e?e:Pn(parseFloat(t),"rgb(255, 255, 255)",e)});var Sn=vn(function(t,e){if("transparent"===e)return e;var n=cn(e);return gn(Fe({},n,{alpha:bn(0,1,+(100*("number"==typeof n.alpha?n.alpha:1)-100*parseFloat(t)).toFixed(2)/100)}))}),Mn=["blue","orange","purple","cyan","magenta","yellowgreen","darkgoldenrod","deeppink"],Nn=(t,e)=>{const n={};for(let s=0;s<t.connections.length;s++){const o=t.connections[s],i=e?.getNetConnectedToId(o.name);i&&!n[i]&&(n[i]=`hsl(${300*s/t.connections.length}, 100%, 50%)`),n[o.name]=(i?n[i]:null)??`hsl(${340*s/t.connections.length}, 100%, 50%)`}return n},In=(t,e)=>{try{return Sn(e,t)}catch(e){return console.error(e),t}},_n=(t,e=1)=>{if(!t)return"rgba(0, 0, 0, 0.5)";const n=300*t.split("").reduce((t,e)=>t+e.charCodeAt(0),0)/t.length;return e<1?`hsla(${n}, 100%, 50%, ${e})`:`hsl(${n}, 100%, 50%)`};function Cn(t){return"layers"in t&&Array.isArray(t.layers)}function Tn(t){return Cn(t)?t.layers[0]:t.layer}function En(t){return Cn(t)?t.layers:[t.layer]}var wn={"0603":{length:1.65,width:.95,padLength:.8,padWidth:.95},1206:{length:3.2,width:1.6,padLength:.6,padWidth:1.6},"1206x4_pair":{length:2.7,width:.5,padLength:.8,padWidth:.5}},Rn=(t,e)=>"top"===t?0:"bottom"===t?e-1:parseInt(t.slice(5)),On=t=>{const e=[],n=[],s=[],o=[],i=Nn(t),r=(t.minViaDiameter??.3)/2;if(t.connections)for(const e of t.connections)for(const t of e.pointsToConnect){const n=En(t);s.push({x:t.x,y:t.y,color:i[e.name],layer:n[0]??("z"in t?De(t.z,2):"top"),label:`${e.name} (${n.join(",")})`})}if(t.traces)for(const s of t.traces){let a=t.minTraceWidth;const c=s.route.filter(t=>"jumper"===t.route_type),h=(t,e)=>{const n=.01;for(const s of c){const o=Math.abs(t.x-s.start.x)<n&&Math.abs(t.y-s.start.y)<n&&Math.abs(e.x-s.end.x)<n&&Math.abs(e.y-s.end.y)<n,i=Math.abs(t.x-s.end.x)<n&&Math.abs(t.y-s.end.y)<n&&Math.abs(e.x-s.start.x)<n&&Math.abs(e.y-s.start.y)<n;if(o||i)return!0}return!1};for(let t=0;t<s.route.length-1;t++){const c=s.route[t],l=s.route[t+1];if("via"===c.route_type)n.push({center:{x:c.x,y:c.y},radius:r,fill:"blue",stroke:"none",layer:"z0,1"});else if("jumper"===c.route_type){const t=i[s.connection_name]??"rgba(255, 165, 0, 0.8)",n=c.footprint,r=wn["1206x4_pair"===n?"1206x4_pair":"0603"]??wn["0603"],a=c.end.x-c.start.x,h=c.end.y-c.start.y,l=Math.abs(a)>Math.abs(h),d=l?r.padLength:r.padWidth,u=l?r.padWidth:r.padLength;o.push({center:c.start,width:d,height:u,fill:In(t,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),o.push({center:c.end,width:d,height:u,fill:In(t,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),e.push({points:[c.start,c.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*r.padWidth,layer:"jumper-body"})}else if("wire"===c.route_type&&"wire"===l.route_type&&l.layer===c.layer){if(h({x:c.x,y:c.y},{x:l.x,y:l.y}))continue;a=c.width;const t=i[s.connection_name],n="top"===c.layer,o=t??{top:"red",bottom:"blue",inner1:"green",inner2:"yellow"}[c.layer];e.push({points:[{x:c.x,y:c.y},{x:l.x,y:l.y}],layer:`z${Rn(c.layer,2)}`,strokeWidth:a,strokeColor:n?o:In(o,.5),...n?{}:{strokeDash:"3 2"}})}}}for(const e of t.obstacles)o.push({center:e.center,width:e.width,height:e.height,fill:"rgba(255,0,0,0.5)",layer:`z${e.layers.map(t=>Rn(t,2)).join(",")}`});if(t.jumpers)for(const e of t.jumpers)for(const t of e.pads)o.push({center:t.center,width:t.width,height:t.height,fill:"rgba(255, 165, 0, 0.3)",stroke:"rgba(255, 165, 0, 0.8)",layer:"jumper"});return{rects:o,circles:n,lines:e,points:s}},An=class{netMap;idToNetMap;constructor(t){this.netMap=t,this.idToNetMap={};for(const[e,n]of Object.entries(t))for(const t of n)this.idToNetMap[t]=e}addConnections(t){for(const e of t){const t=new Set;for(const n of e){const e=this.idToNetMap[n];e&&t.add(e)}let n;if(0===t.size)n=`connectivity_net${Object.keys(this.netMap).length}`,this.netMap[n]=[];else if(1===t.size)n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;else{n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;for(const e of t)if(e!==n){this.netMap[n].push(...this.netMap[e]),this.netMap[e]=this.netMap[n];for(const t of this.netMap[n])this.idToNetMap[t]=n}}for(const t of e)this.netMap[n].includes(t)||this.netMap[n].push(t),this.idToNetMap[t]=n}}getIdsConnectedToNet(t){return this.netMap[t]||[]}getNetConnectedToId(t){return this.idToNetMap[t]}areIdsConnected(t,e){if(t===e)return!0;const n=this.getNetConnectedToId(t);if(!n)return!1;const s=this.getNetConnectedToId(e);return!!s&&(n===s||s===t||s===t)}areAllIdsConnected(t){const e=this.getNetConnectedToId(t[0]);for(const n of t){const t=this.getNetConnectedToId(n);if(void 0===t)return!1;if(t!==e)return!1}return!0}},zn=t=>`${Math.round(100*t.x)},${Math.round(100*t.y)}`,Dn=t=>{const e=new An({});for(const n of t.connections){if(n.rootConnectionName&&e.addConnections([[n.name,n.rootConnectionName]]),n.netConnectionName&&e.addConnections([[n.name,n.netConnectionName]]),n.mergedConnectionNames)for(const t of n.mergedConnectionNames)e.addConnections([[n.name,t]]);for(const s of n.pointsToConnect)e.addConnections([[n.name,`${zn(s)}:${"layers"in s?s.layers.map(e=>Rn(e,t.layerCount)).sort().join("-"):Rn(s.layer,t.layerCount)}`]]),"pcb_port_id"in s&&s.pcb_port_id&&e.addConnections([[n.name,s.pcb_port_id]])}for(const n of t.obstacles){const s=n.offBoardConnectsTo??[],o=Array.from(new Set([n.obstacleId,...n.connectedTo,...s,`${zn(n.center)}:${n.layers.map(e=>Rn(e,t.layerCount)).sort().join("-")}`].filter(Boolean)));o.length>0&&e.addConnections([o])}return e},Ln=class{MAX_ITERATIONS=1e3;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};cacheHit;cacheKey;cacheToSolveSpaceTransform;getSolverName(){return this.constructor.name}step(){if(!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,console.error(this.error),this.failed=!0,t}!this.solved&&this.iterations>this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations (MAX_ITERATIONS=${this.MAX_ITERATIONS})`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function Fn(t){const e=new Map;for(const n of t)for(const t of n.nodeIds)e.set(t,[...e.get(t)??[],n]);return e}var Yn=class extends Ln{getSolverName(){return"AvailableSegmentPointSolver"}nodes;edges;traceWidth;obstacleMargin;minPortSpacing;nodeMap;nodeEdgeMap;sharedEdgeSegments=[];edgeSegmentMap=new Map;portPointMap=new Map;colorMap;shouldReturnCrampedPortPoints;constructor({nodes:t,edges:e,traceWidth:n,obstacleMargin:s,colorMap:o,shouldReturnCrampedPortPoints:i}){super(),this.nodes=t,this.edges=e,this.traceWidth=n,this.obstacleMargin=s??.15,this.shouldReturnCrampedPortPoints=i,this.minPortSpacing=this.traceWidth+this.obstacleMargin,this.colorMap=o??{},this.nodeMap=new Map(t.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Fn(e),this.MAX_ITERATIONS=1}_step(){this.computeAllSharedEdgeSegments(),this.solved=!0}computeAllSharedEdgeSegments(){for(const t of this.edges){const[e,n]=t.nodeIds,s=this.nodeMap.get(e),o=this.nodeMap.get(n);if(!s||!o)continue;const i=this.computeSharedEdgeSegment(t,s,o);if(i){this.sharedEdgeSegments.push(i),this.edgeSegmentMap.set(t.capacityMeshEdgeId,i);for(const t of i.portPoints)this.portPointMap.set(t.segmentPortPointId,t)}}}computeSharedEdgeSegment(t,e,n){const s=this.findOverlappingSegment(e,n);if(!s)return null;const o=e.availableZ.filter(t=>n.availableZ.includes(t));if(0===o.length)return null;const i=Math.sqrt((s.end.x-s.start.x)**2+(s.end.y-s.start.y)**2),r=3*this.minPortSpacing/4,a=Math.max(0,i-2*r);if(a<=0&&!e._containsTarget&&!n._containsTarget){if(!this.shouldReturnCrampedPortPoints)return null;const i=[];for(const r of o)i.push({segmentPortPointId:`${t.capacityMeshEdgeId}_pp0_z${r}_cramped`,x:(s.start.x+s.end.x)/2,y:(s.start.y+s.end.y)/2,availableZ:[r],nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],edgeId:t.capacityMeshEdgeId,connectionName:null,distToCentermostPortOnZ:0,cramped:!0});return{edgeId:t.capacityMeshEdgeId,nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],start:s.start,end:s.end,availableZ:o,portPoints:i}}let c=Math.max(1,Math.floor(a/this.minPortSpacing)+1);if(e._offBoardConnectionId||n._offBoardConnectionId){if(e._offBoardConnectionId&&!n._offBoardConnectionId){if(this.shouldSkipOffBoardPortPoint(e,n))return null}else if(n._offBoardConnectionId&&!e._offBoardConnectionId&&this.shouldSkipOffBoardPortPoint(n,e))return null;c=1}const h=[],l=s.end.x-s.start.x,d=s.end.y-s.start.y,u=(s.start.x+s.end.x)/2,p=(s.start.y+s.end.y)/2;c>5&&(c=5+Math.floor(c/4));const f=[];for(let t=0;t<c;t++){let e;e=0===i||1===c?.5:(r+a*t/(c-1))/i;const n=s.start.x+l*e,o=s.start.y+d*e,h=Math.sqrt((n-u)**2+(o-p)**2);f.push({x:n,y:o,distToCenter:h})}const m=f.reduce((t,e)=>e.distToCenter<t.distToCenter?e:t);for(let s=0;s<c;s++){const{x:i,y:r}=f[s],a=Math.sqrt((i-m.x)**2+(r-m.y)**2);for(const c of o){const o={segmentPortPointId:`${t.capacityMeshEdgeId}_pp${s}_z${c}`,x:i,y:r,availableZ:[c],nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],edgeId:t.capacityMeshEdgeId,connectionName:null,distToCentermostPortOnZ:a,cramped:!1};h.push(o)}}return{edgeId:t.capacityMeshEdgeId,nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],start:s.start,end:s.end,availableZ:o,portPoints:h}}shouldSkipOffBoardPortPoint(t,e){const n=this.nodeEdgeMap.get(e.capacityMeshNodeId)??[];for(const s of n){const n=s.nodeIds[0]===e.capacityMeshNodeId?s.nodeIds[1]:s.nodeIds[0];if(n===t.capacityMeshNodeId)continue;const o=this.nodeMap.get(n);if(o?._offBoardConnectionId!==t._offBoardConnectionId)continue;if(2!==this.nodes.filter(e=>e._offBoardConnectionId===t._offBoardConnectionId).length)continue;const i={x:(t.center.x+o.center.x)/2,y:(t.center.y+o.center.y)/2};if(i.x>=e.center.x-e.width/2&&i.x<=e.center.x+e.width/2&&i.y>=e.center.y-e.height/2&&i.y<=e.center.y+e.height/2)return!0}return!1}findOverlappingSegment(t,e){const n={start:Math.max(t.center.x-t.width/2,e.center.x-e.width/2),end:Math.min(t.center.x+t.width/2,e.center.x+e.width/2)},s={start:Math.max(t.center.y-t.height/2,e.center.y-e.height/2),end:Math.min(t.center.y+t.height/2,e.center.y+e.height/2)},o=n.end-n.start,i=s.end-s.start;if(o<-1e-4||i<-1e-4)return null;if(o<i){const t=(n.start+n.end)/2;return{start:{x:t,y:s.start},end:{x:t,y:s.end}}}{const t=(s.start+s.end)/2;return{start:{x:n.start,y:t},end:{x:n.end,y:t}}}}getAvailablePortPointsBetweenNodes(t,e){const n=this.edges.find(n=>n.nodeIds[0]===t&&n.nodeIds[1]===e||n.nodeIds[0]===e&&n.nodeIds[1]===t);if(!n)return[];const s=this.edgeSegmentMap.get(n.capacityMeshEdgeId);return s?s.portPoints.filter(t=>null===t.connectionName):[]}getPortPointsForEdge(t,e){const n=this.edges.find(n=>n.nodeIds[0]===t&&n.nodeIds[1]===e||n.nodeIds[0]===e&&n.nodeIds[1]===t);if(!n)return[];const s=this.edgeSegmentMap.get(n.capacityMeshEdgeId);return s?.portPoints??[]}assignPortPoint(t,e,n){const s=this.portPointMap.get(t);return!!s&&(null===s.connectionName&&(s.connectionName=e,s.rootConnectionName=n,!0))}releasePortPoint(t){const e=this.portPointMap.get(t);return!!e&&(e.connectionName=null,e.rootConnectionName=void 0,!0)}getAvailablePortCountForEdge(t,e){return this.getAvailablePortPointsBetweenNodes(t,e).length}getOutput(){return this.sharedEdgeSegments}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.sharedEdgeSegments){t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.5)"});for(const n of e.portPoints){const e=n.connectionName?this.colorMap[n.connectionName]??"blue":"rgba(0, 200, 0, 0.7)";n.cramped?t.rects.push({center:{x:n.x,y:n.y},width:.1,height:.1,fill:e,layer:`z${n.availableZ.join(",")}`,label:`cramped ${n.segmentPortPointId}`}):t.circles.push({center:{x:n.x,y:n.y},radius:this.traceWidth/2,fill:e,layer:`z${n.availableZ.join(",")}`,label:[n.segmentPortPointId,n.connectionName,n.availableZ.join(","),`cd: ${n.distToCentermostPortOnZ}`,`connects: ${n.nodeIds.join(",")}`].filter(Boolean).join("\n")})}}return t}};function Xn(t,e){const n=t.center.x-t.width/2,s=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2,r=e.center.x-e.width/2,a=e.center.x+e.width/2,c=e.center.y-e.height/2,h=e.center.y+e.height/2,l=.001,d=(Math.abs(s-r)<l||Math.abs(n-a)<l)&&Math.min(i,h)-Math.max(o,c)>=l,u=(Math.abs(i-c)<l||Math.abs(o-h)<l)&&Math.min(s,a)-Math.max(n,r)>=l;return d||u}var kn=class extends Ln{constructor(t){super(),this.nodes=t,this.edges=[]}getSolverName(){return"CapacityMeshEdgeSolver"}edges;nodeMap;getNextCapacityMeshEdgeId(){return`ce${this.edges.length}`}_step(){this.edges=[];for(let t=0;t<this.nodes.length;t++)for(let e=t+1;e<this.nodes.length;e++){!(this.nodes[t]._strawNode&&this.nodes[e]._strawNode&&this.nodes[t]._strawParentCapacityMeshNodeId===this.nodes[e]._strawParentCapacityMeshNodeId)&&Xn(this.nodes[t],this.nodes[e])&&this.doNodesHaveSharedLayer(this.nodes[t],this.nodes[e])&&this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[this.nodes[t].capacityMeshNodeId,this.nodes[e].capacityMeshNodeId]})}this.handleTargetNodes(),this.solved=!0}handleTargetNodes(){const t=this.nodes.filter(t=>t._containsTarget);for(const e of t){if(this.edges.some(t=>t.nodeIds.includes(e.capacityMeshNodeId)))continue;let t=null,n=1/0;for(const s of this.nodes){if(s._containsObstacle)continue;if(s._containsTarget)continue;const o=k(e.center,s.center);o<n&&(n=o,t=s)}t&&this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[e.capacityMeshNodeId,t.capacityMeshNodeId]})}}doNodesHaveSharedLayer(t,e){return t.availableZ.some(t=>e.availableZ.includes(t))}visualize(){const t=new Map;for(const e of this.edges)for(const n of e.nodeIds)t.set(n,1+(t.get(n)??0));const e={lines:[],points:[],rects:this.nodes.map(e=>{const n=Math.min(...e.availableZ);return{width:Math.max(e.width-2,.8*e.width),height:Math.max(e.height-2,.8*e.height),center:{x:e.center.x+n*e.width*.05,y:e.center.y-n*e.width*.05},fill:e._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[e.availableZ.join(",")]??"rgba(0,200,200,0.1)",label:[e.capacityMeshNodeId,`availableZ: ${e.availableZ.join(",")}`,`target? ${e._containsTarget??!1}`,`obs? ${e._containsObstacle??!1}`,`conn: ${t.get(e.capacityMeshNodeId)??0}`].join("\n"),layer:`z${e.availableZ.join(",")}`}}),circles:[]};if(!this.nodeMap){this.nodeMap=new Map;for(const t of this.nodes)this.nodeMap.set(t.capacityMeshNodeId,t)}for(const t of this.edges){const n=this.nodeMap.get(t.nodeIds[0]),s=this.nodeMap.get(t.nodeIds[1]);if(n?.center&&s?.center){const t=Math.min(...n.availableZ),o=Math.min(...s.availableZ),i={x:n.center.x+t*n.width*.05,y:n.center.y-t*n.width*.05},r={x:s.center.x+o*s.width*.05,y:s.center.y-o*s.width*.05},a=Array.from(new Set([...n.availableZ,...s.availableZ])).sort();e.lines.push({layer:`z${a.join(",")}`,points:[i,r],strokeDash:n.availableZ.join(",")===s.availableZ.join(",")?void 0:"10 5"})}}return e}},$n=class{constructor(t){this.nodes=t,this.buckets=new Map;for(const e of t){const t=e.center.x-e.width/2,n=e.center.y-e.height/2,s=e.center.x+e.width/2,o=e.center.y+e.height/2;for(let i=t;i<=s;i+=this.CELL_SIZE)for(let t=n;t<=o;t+=this.CELL_SIZE){const n=this.getBucketKey(i,t),s=this.buckets.get(n);s?s.push(e):this.buckets.set(n,[e])}}}buckets;CELL_SIZE=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getNodesInArea(t,e,n,s){const o=[],i=new Set,r=e-s/2,a=t+n/2,c=e+s/2;for(let e=t-n/2;e<=a;e+=this.CELL_SIZE)for(let t=r;t<=c;t+=this.CELL_SIZE){const n=this.getBucketKey(e,t),s=this.buckets.get(n)||[];for(const t of s)i.has(t.capacityMeshNodeId)||(i.add(t.capacityMeshNodeId),o.push(t))}return o}},Bn=class extends kn{constructor(t){super(t),this.nodes=t,this.MAX_ITERATIONS=1e7,this.nodeTree=new $n(this.nodes),this.currentNodeIndex=0,this.edgeSet=new Set}getSolverName(){return"CapacityMeshEdgeSolver2_NodeTreeOptimization"}nodeTree;currentNodeIndex;edgeSet;_step(){if(this.currentNodeIndex>=this.nodes.length)return this.handleTargetNodes(),void(this.solved=!0);const t=this.nodes[this.currentNodeIndex],e=this.nodeTree.getNodesInArea(t.center.x,t.center.y,2*t.width,2*t.height);for(const n of e){if(!Xn(t,n))continue;const e=t._strawNode&&n._strawNode&&t._strawParentCapacityMeshNodeId===n._strawParentCapacityMeshNodeId;t.capacityMeshNodeId===n.capacityMeshNodeId||e||!this.doNodesHaveSharedLayer(t,n)||this.edgeSet.has(`${t.capacityMeshNodeId}-${n.capacityMeshNodeId}`)||(this.edgeSet.add(`${t.capacityMeshNodeId}-${n.capacityMeshNodeId}`),this.edgeSet.add(`${n.capacityMeshNodeId}-${t.capacityMeshNodeId}`),this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[t.capacityMeshNodeId,n.capacityMeshNodeId]}))}this.currentNodeIndex++}},jn=(...t)=>{const e={points:[],lines:[],circles:[],rects:[]};return t.forEach((t,n)=>{t&&(t.lines&&(e.lines=[...e.lines||[],...t.lines.map(t=>({...t,step:n}))]),t.points&&(e.points=[...e.points||[],...t.points.map(t=>({...t,step:n}))]),t.circles&&(e.circles=[...e.circles||[],...t.circles.map(t=>({...t,step:n}))]),t.rects&&(e.rects=[...e.rects||[],...t.rects.map(t=>({...t,step:n}))]))}),e};function Wn(t,e,n){const s=[];let o=null;for(let i=0;i<t.length;i++){const r=t[i];o?o.z===r.z?o.points.push({x:r.x,y:r.y}):(s.push(o),o={points:[{x:r.x,y:r.y}],z:r.z,connectionName:e,color:n}):o={points:[{x:r.x,y:r.y}],z:r.z,connectionName:e,color:n},i===t.length-1&&o&&s.push(o)}return s}import Hn from"object-hash";function Un(t){let e=t;for(let t=0;t<10;t++)e=16807*e%2147483647;let n=e;e=(69069*t+1)%2147483647;for(let t=0;t<10;t++)e=48271*e%2147483647;let s=e;return()=>{let t=n;n=s,t^=t<<23,t^=t>>>17,t^=s,t^=s>>>26,s=t;const e=(n+s)/4294967296;return e-Math.floor(e)}}var Vn={1:[[0]],2:[[0,1],[1,0]],3:[[0,1,2],[2,0,1],[1,0,2],[0,2,1],[1,2,0],[2,1,0]],4:[[0,1,2,3],[2,0,1,3],[1,3,2,0],[3,0,1,2],[0,2,1,3],[2,1,3,0],[3,0,2,1],[1,2,0,3],[3,1,0,2],[0,3,2,1],[2,3,0,1],[2,3,1,0],[1,2,3,0],[3,1,2,0],[0,1,3,2],[0,2,3,1],[0,3,1,2],[1,0,2,3],[1,0,3,2],[1,3,0,2],[2,0,3,1],[2,1,0,3],[3,2,0,1],[3,2,1,0]]};function Gn(t,e){if(0===e)return t;if(0===t.length)return t;if(t.length<=4){const n=Vn[t.length];return n[e%n.length].map(e=>t[e])}const n=Un(e),s=t.slice();for(let t=0;t<s.length;t++){const e=Math.floor(n()*s.length),o=Math.floor(n()*(t+1));[s[e],s[o]]=[s[o],s[e]]}return s}var Zn=t=>{let e=1/0;const n=t.portPoints;for(let t=0;t<n.length;t++)for(let s=t+1;s<n.length;s++){const o=n[t],i=n[s];if(o.z!==i.z)continue;if(o.rootConnectionName&&o.rootConnectionName===i.rootConnectionName)continue;const r=Math.sqrt((o.x-i.x)**2+(o.y-i.y)**2);e=Math.min(e,r)}return e===1/0?0:e},qn=class{heap=[];constructor(t){this.heap=[];for(const e of t)this.enqueue(e)}getLeftChildIndex(t){return 2*t+1}getRightChildIndex(t){return 2*t+2}getParentIndex(t){return Math.floor((t-1)/2)}hasLeftChild(t){return this.getLeftChildIndex(t)<this.heap.length}hasRightChild(t){return this.getRightChildIndex(t)<this.heap.length}hasParent(t){return this.getParentIndex(t)>=0}leftChild(t){return this.heap[this.getLeftChildIndex(t)]}rightChild(t){return this.heap[this.getRightChildIndex(t)]}parent(t){return this.heap[this.getParentIndex(t)]}swap(t,e){const n=this.heap[t];this.heap[t]=this.heap[e],this.heap[e]=n}dequeue(){if(0===this.heap.length)return null;const t=this.heap[0];return this.heap[0]=this.heap[this.heap.length-1],this.heap.pop(),this.heapifyDown(),t}peek(){return 0===this.heap.length?null:this.heap[0]}enqueue(t){this.heap.push(t),this.heapifyUp()}heapifyUp(){let t=this.heap.length-1;for(;this.hasParent(t)&&this.parent(t).f>this.heap[t].f;)this.swap(this.getParentIndex(t),t),t=this.getParentIndex(t)}heapifyDown(){let t=0;for(;this.hasLeftChild(t);){let e=this.getLeftChildIndex(t);if(this.hasRightChild(t)&&this.rightChild(t).f<this.leftChild(t).f&&(e=this.getRightChildIndex(t)),this.heap[t].f<this.heap[e].f)break;this.swap(t,e),t=e}}getTopN(t){return[...this.heap].sort((t,e)=>t.f-e.f).slice(0,t)}},Jn=class extends Ln{getSolverName(){return"SingleHighDensityRouteSolver"}obstacleRoutes;bounds;boundsSize;boundsCenter;A;B;straightLineDistance;viaDiameter;traceThickness;obstacleMargin;layerCount;minCellSize=.05;cellStep=.05;GREEDY_MULTIPLER=1.1;numRoutes;VIA_PENALTY_FACTOR=.3;CELL_SIZE_FACTOR;exploredNodes;candidates;connectionName;solvedPath=null;futureConnections;hyperParameters;connMap;obstacleSegments=[];obstacleSegmentIndex=null;obstacleVias=[];obstacleViaIndex=null;debug_exploredNodesOrdered;debug_nodesTooCloseToObstacle;debug_nodePathToParentIntersectsObstacle;debugEnabled=!0;initialNodeGridOffset;constructor(t){super(),this.bounds=t.bounds,this.connMap=t.connMap,this.hyperParameters=t.hyperParameters??{},this.CELL_SIZE_FACTOR=this.hyperParameters.CELL_SIZE_FACTOR??1,this.boundsSize={width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY},this.boundsCenter={x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},this.connectionName=t.connectionName,this.obstacleRoutes=t.obstacleRoutes,this.A=t.A,this.B=t.B,this.viaDiameter=t.viaDiameter??.3,this.traceThickness=t.traceThickness??.15,this.obstacleMargin=t.obstacleMargin??.2,this.layerCount=t.layerCount??2,this.exploredNodes=new Set,this.straightLineDistance=k(this.A,this.B),this.futureConnections=t.futureConnections??[],this.MAX_ITERATIONS=1e4,this.debug_exploredNodesOrdered=[],this.debug_nodesTooCloseToObstacle=new Set,this.debug_nodePathToParentIntersectsObstacle=new Set,this.numRoutes=this.obstacleRoutes.length+this.futureConnections.length,this.buildObstacleIndexes();const e=Math.ceil(5*(this.numRoutes+1));let n=this.boundsSize.width/this.cellStep,s=this.boundsSize.height/this.cellStep;for(;n*s>e**2&&!(2*this.cellStep>t.minDistBetweenEnteringPoints);)this.cellStep*=2,n=this.boundsSize.width/this.cellStep,s=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const o=Math.abs(this.A.x-this.bounds.minX)<.001&&Math.abs(this.B.x-this.bounds.minX)<.001||Math.abs(this.A.x-this.bounds.maxX)<.001&&Math.abs(this.B.x-this.bounds.maxX)<.001||Math.abs(this.A.y-this.bounds.minY)<.001&&Math.abs(this.B.y-this.bounds.minY)<.001||Math.abs(this.A.y-this.bounds.maxY)<.001&&Math.abs(this.B.y-this.bounds.maxY)<.001;this.futureConnections&&0===this.futureConnections.length&&0===this.obstacleRoutes.length&&!o&&this.handleSimpleCases();const i={x:Math.round(t.A.x/(this.cellStep/2))*(this.cellStep/2),y:Math.round(t.A.y/(this.cellStep/2))*(this.cellStep/2)};this.initialNodeGridOffset={x:i.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:i.y-Math.round(t.A.y/this.cellStep)*this.cellStep},this.candidates=new qn([{...t.A,...i,z:t.A.z??0,g:0,h:0,f:0,parent:{...t.A,z:t.A.z??0,g:0,h:0,f:0,parent:null}}])}handleSimpleCases(){this.solved=!0;const{A:t,B:e}=this,n=t.z===e.z?[t,e]:[t,{...this.boundsCenter,z:this.A.z},{...this.boundsCenter,z:e.z},e];this.solvedPath={connectionName:this.connectionName,route:n,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:this.A.z===this.B.z?[]:[this.boundsCenter]}}get viaPenaltyDistance(){return this.cellStep+this.straightLineDistance*this.VIA_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e,n){if(e??=this.obstacleMargin,n&&t.parent){const n=this.getViasInNodePath(t.parent);for(const s of n)if(k(t,s)<this.viaDiameter/2+e)return!0}const s=this.traceThickness+e;if(this.obstacleSegmentIndex){const e=this.obstacleSegmentIndex.search(t.x-s,t.y-s,t.x+s,t.y+s);for(const o of e){const e=this.obstacleSegments[o];if(e&&!e.connectedToCurrentConnection&&((n||e.z===t.z)&&X(t,e.A,e.B)<s))return!0}}const o=this.viaDiameter/2+this.traceThickness/2+e;if(this.obstacleViaIndex){const e=this.obstacleViaIndex.search(t.x-o,t.y-o,t.x+o,t.y+o);for(const n of e){const e=this.obstacleVias[n];if(e&&k(t,e)<o)return!0}}return!1}isNodeTooCloseToEdge(t,e){const n=e?this.viaDiameter/2+this.obstacleMargin/2:this.obstacleMargin/2,s=t.x<this.bounds.minX+n||t.x>this.bounds.maxX-n||t.y<this.bounds.minY+n||t.y>this.bounds.maxY-n;return!(s&&!e&&(k(t,this.B)<2*n||k(t,this.A)<2*n))&&s}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;if(!this.obstacleSegmentIndex)return!1;const n=Math.min(t.x,e.x),s=Math.max(t.x,e.x),o=Math.min(t.y,e.y),i=Math.max(t.y,e.y),r=this.obstacleSegmentIndex.search(n,o,s,i);for(const n of r){const s=this.obstacleSegments[n];if(s&&!s.connectedToCurrentConnection&&(s.z===t.z&&L(t,e,s.A,s.B)))return!0}return!1}buildObstacleIndexes(){if(0===this.obstacleRoutes.length)return this.obstacleSegmentIndex=null,void(this.obstacleViaIndex=null);const t=[],e=[];for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName)??!1;for(const e of Kn(n))t.push({...e,connectedToCurrentConnection:s});for(const t of n.vias)e.push(t)}if(this.obstacleSegments=t,this.obstacleVias=e,t.length>0){const e=new E(t.length);for(const n of t)e.add(Math.min(n.A.x,n.B.x),Math.min(n.A.y,n.B.y),Math.max(n.A.x,n.B.x),Math.max(n.A.y,n.B.y));e.finish(),this.obstacleSegmentIndex=e}else this.obstacleSegmentIndex=null;if(e.length>0){const t=new E(e.length);for(const n of e)t.add(n.x,n.y,n.x,n.y);t.finish(),this.obstacleViaIndex=t}else this.obstacleViaIndex=null}computeH(t){return k(t,this.B)+(t.z!==this.B.z?this.viaPenaltyDistance:0)}computeG(t){return(t.parent?.g??0)+(t.z===t.parent?.z?0:this.viaPenaltyDistance)+k(t,t.parent)}computeF(t,e){return t+e*this.GREEDY_MULTIPLER}getNodeKey(t){return`${Math.round(t.x/this.cellStep)*this.cellStep},${Math.round(t.y/this.cellStep)*this.cellStep},${t.z}`}getNeighbors(t){const e=[],{maxX:n,minX:s,maxY:o,minY:i}=this.bounds;for(let r=-1;r<=1;r++)for(let a=-1;a<=1;a++){if(0===r&&0===a)continue;const c={...t,parent:t,x:Qn(t.x+r*this.cellStep,s,n),y:Qn(t.y+a*this.cellStep,i,o)},h=this.getNodeKey(c);this.exploredNodes.has(h)||(this.isNodeTooCloseToObstacle(c)?(this.debug_nodesTooCloseToObstacle.add(h),this.exploredNodes.add(h)):this.isNodeTooCloseToEdge(c,!1)?this.exploredNodes.add(h):this.doesPathToParentIntersectObstacle(c)?(this.debug_nodePathToParentIntersectsObstacle.add(h),this.exploredNodes.add(h)):(c.g=this.computeG(c),c.h=this.computeH(c),c.f=this.computeF(c.g,c.h),e.push(c)))}for(let n=0;n<this.layerCount;n++){if(n===t.z)continue;const s={...t,parent:t,z:n};this.exploredNodes.has(this.getNodeKey(s))||this.isNodeTooCloseToObstacle(s,this.viaDiameter/2+this.obstacleMargin/2,!0)||this.isNodeTooCloseToEdge(s,!0)||(s.g=this.computeG(s),s.h=this.computeH(s),s.f=this.computeF(s.g,s.h),e.push(s))}return e}getNodePath(t){const e=[];for(;t;)e.push(t),t=t.parent;return e}getViasInNodePath(t){const e=this.getNodePath(t),n=[];for(let t=0;t<e.length-1;t++)e[t].z!==e[t+1].z&&n.push({x:e[t].x,y:e[t].y});return n}setSolvedPath(t){const e=this.getNodePath(t);e.reverse();const n=[];for(let t=0;t<e.length-1;t++)e[t].z!==e[t+1].z&&n.push({x:e[t].x,y:e[t].y});this.solvedPath={connectionName:this.connectionName,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,route:e.map(t=>({x:t.x,y:t.y,z:t.z})).concat([this.B]),vias:n}}computeProgress(t,e,n){n||(e+=this.viaPenaltyDistance);const s=1-e/this.straightLineDistance;return Math.max(this.progress||0,2/Math.PI*Math.atan(.112*s/(1-s)))}_step(){let t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;for(;t&&e&&this.exploredNodes.has(e);)t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;if(!t||!e)return this.failed=!0,void(this.error="Ran out of candidate nodes to explore");this.exploredNodes.add(e),this.debug_exploredNodesOrdered.push(e);const n=k(t,this.B);this.progress=this.computeProgress(t,n,t.z===this.B.z),n<=this.cellStep*Math.SQRT2&&t.z===this.B.z&&!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})&&(this.solved=!0,this.setSolvedPath(t));const s=this.getNeighbors(t);for(const t of s)this.candidates.enqueue(t)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:`Input A\nz: ${this.A.z}`,color:"orange"}),t.points.push({x:this.B.x,y:this.B.y,label:`Input B\nz: ${this.B.z}`,color:"orange"}),t.lines.push({points:[this.A,this.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:"Direct Input Connection"});for(let e=0;e<this.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let s=0;s<n.route.length-1;s++){const o=n.route[s].z;t.lines.push({points:[n.route[s],n.route[s+1]],strokeColor:0===o?"rgba(255, 0, 0, 0.75)":"rgba(255, 128, 0, 0.25)",strokeWidth:n.traceThickness,label:"Obstacle Route",layer:`obstacle${e.toString()}`})}}for(let e=0;e<this.debug_exploredNodesOrdered.length;e++){const n=this.debug_exploredNodesOrdered[e],[s,o,i]=n.split(",").map(Number);this.debug_nodesTooCloseToObstacle.has(n)||(this.debug_nodePathToParentIntersectsObstacle.has(n)||t.rects.push({center:{x:s+this.initialNodeGridOffset.x+i*this.cellStep/20,y:o+this.initialNodeGridOffset.y+i*this.cellStep/20},fill:0===i?`rgba(255,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`:`rgba(0,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`,width:.9*this.cellStep,height:.9*this.cellStep,label:`Explored (z=${i})`}))}if(this.candidates.peek()){const e=this.candidates.peek();t.rects.push({center:{x:e.x+e.z*this.cellStep/20,y:e.y+e.z*this.cellStep/20},fill:"rgba(0, 255, 0, 0.8)",width:.9*this.cellStep,height:.9*this.cellStep,label:`Next (z=${e.z})`})}for(const e of this.obstacleRoutes)for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:this.viaDiameter/2,fill:"rgba(255, 0, 0, 0.5)",label:"Via"});if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:"green",label:"Solved Route"});for(const e of this.solvedPath.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"green",label:"Via"})}return t}};function Kn(t){const e=[];for(let n=0;n<t.route.length-1;n++)t.route[n].z===t.route[n+1].z&&e.push({z:t.route[n].z,A:t.route[n],B:t.route[n+1]});return e}function Qn(t,e,n){return Math.max(e,Math.min(t,n))}var ts=class extends Jn{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR=2;FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR=1;FUTURE_CONNECTION_PROXIMITY_VD=10;MISALIGNED_DIST_PENALTY_FACTOR=5;VIA_PENALTY_FACTOR_2=1;FLIP_TRACE_ALIGNMENT_DIRECTION=!1;constructor(t){super(t);for(const e in t.hyperParameters)this[e]=t.hyperParameters[e];const e=this.boundsSize.width/this.viaDiameter,n=Math.max(1,this.numRoutes);this.VIA_PENALTY_FACTOR=e/n*.3*this.VIA_PENALTY_FACTOR_2}getClosestFutureConnectionPoint(t){let e=1/0,n=null;for(const s of this.futureConnections)for(const o of s.points){const s=k(t,o)+(t.z!==o.z?this.viaPenaltyDistance:0);s<e&&(e=s,n=o)}return n}diminishCloseToGoal(t){const e=k(t,this.B);return 1-Math.exp(-e/this.straightLineDistance*5)}getFutureConnectionPenalty(t,e){let n=0;const s=this.getClosestFutureConnectionPoint(t),o=k(t,this.B);if(s){const i=k(t,s);if(o<=i)return 0;const r=i/(this.viaDiameter*this.FUTURE_CONNECTION_PROXIMITY_VD);n=(e?this.straightLineDistance*this.FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:this.straightLineDistance*this.FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR)*Math.exp(5*-r)}return n}computeH(t){const e=k(t,this.B)**1.6;this.straightLineDistance;return e+(t.z!==this.B.z?this.viaPenaltyDistance:0)+this.getFutureConnectionPenalty(t,t.z!==t.parent?.z)}computeG(t){const e=Math.abs(t.x-t.parent.x),n=Math.abs(t.y-t.parent.y),s=Math.sqrt(e**2+n**2),o=t.z%2==0,i=this.FLIP_TRACE_ALIGNMENT_DIRECTION?o?e:n:o?n:e;return(t.parent?.g??0)+(t.z===t.parent?.z?0:this.viaPenaltyDistance)+s+i*this.MISALIGNED_DIST_PENALTY_FACTOR+this.getFutureConnectionPenalty(t,t.z!==t.parent?.z)}},es=class extends Ln{getSolverName(){return"IntraNodeRouteSolver"}nodeWithPortPoints;colorMap;unsolvedConnections;totalConnections;solvedRoutes;failedSubSolvers;hyperParameters;minDistBetweenEnteringPoints;viaDiameter;traceWidth;activeSubSolver=null;connMap;get failedSolvers(){return this.failedSubSolvers}get activeSolver(){return this.activeSubSolver}constructor(t){const{nodeWithPortPoints:e,colorMap:n}=t;super(),this.nodeWithPortPoints=e,this.colorMap=n??{},this.solvedRoutes=[],this.hyperParameters=t.hyperParameters??{},this.failedSubSolvers=[],this.connMap=t.connMap,this.viaDiameter=t.viaDiameter??.3,this.traceWidth=t.traceWidth??.15;const s=new Map;for(const{connectionName:t,x:n,y:o,z:i}of e.portPoints)s.set(t,[...s.get(t)??[],{x:n,y:o,z:i??0}]);this.unsolvedConnections=Array.from(s.entries().map(([t,e])=>({connectionName:t,points:e}))),this.hyperParameters.SHUFFLE_SEED&&(this.unsolvedConnections=Gn(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=>({...e,points:Gn(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Zn(this.nodeWithPortPoints)}computeProgress(){return(this.solvedRoutes.length+(this.activeSubSolver?.progress||0))/this.totalConnections}_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),this.progress=this.computeProgress(),void(this.activeSubSolver.solved?(this.solvedRoutes.push(this.activeSubSolver.solvedPath),this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSubSolvers.push(this.activeSubSolver),this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=>t.error).join("\n"),this.failed=!0));const t=this.unsolvedConnections.pop();if(this.progress=this.computeProgress(),!t)return void(this.solved=0===this.failedSubSolvers.length);if(1===t.points.length)return;if(2===t.points.length){const[e,n]=t.points,s=Math.abs(e.x-n.x)<1e-6,o=Math.abs(e.y-n.y)<1e-6;if(s&&o&&e.z===n.z)return;if(s&&o&&e.z!==n.z){const s={x:this.nodeWithPortPoints.center.x,y:this.nodeWithPortPoints.center.y},o=[{x:e.x,y:e.y,z:e.z},{...s,z:e.z},{...s,z:n.z},{x:n.x,y:n.y,z:n.z}].filter((t,e,n)=>0===e||Math.abs(t.x-n[e-1].x)>1e-6||Math.abs(t.y-n[e-1].y)>1e-6||t.z!==n[e-1].z);return void this.solvedRoutes.push({connectionName:t.connectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:o,vias:[s]})}}const{connectionName:e,points:n}=t;this.activeSubSolver=new ts({connectionName:e,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:Ie(this.nodeWithPortPoints),A:{x:n[0].x,y:n[0].y,z:n[0].z},B:{x:n[n.length-1].x,y:n[n.length-1].y,z:n[n.length-1].z},obstacleRoutes:this.connMap?this.solvedRoutes.filter(t=>!this.connMap.areIdsConnected(t.connectionName,e)):this.solvedRoutes,futureConnections:this.unsolvedConnections,layerCount:this.nodeWithPortPoints.portPoints.reduce((t,e)=>Math.max(t,(e.z??0)+1),2),hyperParameters:this.hyperParameters,connMap:this.connMap,viaDiameter:this.viaDiameter,traceThickness:this.traceWidth})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:[e.connectionName,`layer: ${e.z}`].join("\n"),color:this.colorMap[e.connectionName]??"blue"});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length>0){const s=this.colorMap[n.connectionName]??"blue";for(let o=0;o<n.route.length-1;o++){const i=n.route[o],r=n.route[o+1];t.lines.push({points:[i,r],strokeColor:0===i.z?In(s,.2):In(s,.8),layer:`route-layer-${i.z}`,step:e,strokeWidth:n.traceThickness})}for(const o of n.vias)t.circles.push({center:{x:o.x,y:o.y},radius:n.viaDiameter/2,fill:In(s,.5),layer:"via",step:e})}}const e=Ie(this.nodeWithPortPoints),{minX:n,minY:s,maxX:o,maxY:i}=e;return t.lines.push({points:[{x:n,y:s},{x:o,y:s},{x:o,y:i},{x:n,y:i},{x:n,y:s}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}},ns=t=>Math.round(200*t)/200,ss=t=>"function"==typeof structuredClone?structuredClone(t):JSON.parse(JSON.stringify(t));Ne();var os=class extends es{getSolverName(){return"CachedIntraNodeRouteSolver"}cacheProvider;cacheHit=!1;hasAttemptedToUseCache=!1;initialUnsolvedConnections;constructor(t){super(t),this.cacheProvider=void 0===t.cacheProvider?Me():t.cacheProvider,this.initialUnsolvedConnections=ss(this.unsolvedConnections),(this.solved||this.failed)&&this.cacheProvider&&!this.cacheHit&&this.saveToCacheSync()}_step(){if(!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync())return;const t=this.solved,e=this.failed;super._step(),!this.cacheProvider||this.cacheHit||!this.solved&&!this.failed||t||e||this.saveToCacheSync()}computeCacheKeyAndTransform(){const t=this.nodeWithPortPoints.center,e=this.initialUnsolvedConnections.map(({connectionName:e,points:n})=>({connectionName:e,points:n.map(n=>({connectionName:e,x:ns(n.x-t.x),y:ns(n.y-t.y),z:n.z??0}))})),n=Object.fromEntries(Object.entries(this.hyperParameters??{}).filter(([,t])=>void 0!==t).sort(([t],[e])=>t.localeCompare(e))),s=this.connMap?this.initialUnsolvedConnections.map(({connectionName:t})=>({connectionName:t,connectedIds:[...new Set(this.connMap.getIdsConnectedToNet(t)??[])].sort()})):void 0,o={node:{width:ns(this.nodeWithPortPoints.width),height:ns(this.nodeWithPortPoints.height),center:{x:ns(this.nodeWithPortPoints.center.x),y:ns(this.nodeWithPortPoints.center.y)},availableZ:this.nodeWithPortPoints.availableZ?[...this.nodeWithPortPoints.availableZ].sort():void 0},normalizedConnections:e,normalizedHyperParameters:n,minDistBetweenEnteringPoints:ns(this.minDistBetweenEnteringPoints),normalizedConnMap:s},i=`intranode-solver:${Hn(o)}`,r={};return this.cacheKey=i,this.cacheToSolveSpaceTransform=r,{cacheKey:i,cacheToSolveSpaceTransform:r}}applyCachedSolution(t){t.success?(this.solvedRoutes=ss(t.solvedRoutes),this.solved=!0,this.failed=!1):(this.solvedRoutes=[],this.failedSubSolvers=[],this.solved=!1,this.failed=!0,this.error=t.error??this.error),this.unsolvedConnections=[],this.activeSubSolver=null,this.cacheHit=!0,this.progress=1}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return!1;if(!this.cacheKey)try{this.computeCacheKeyAndTransform()}catch(t){return console.error("Error computing cache key:",t),!1}if(!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(null!=t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(!this.cacheProvider?.isSyncCache)return;if(!this.cacheKey)try{this.computeCacheKeyAndTransform()}catch(t){return void console.error("Error computing cache key during save:",t)}if(!this.cacheKey)return void console.error("Failed to compute cache key before saving.");const t=this.failed?{success:!1,error:this.error??void 0}:{success:!0,solvedRoutes:ss(this.solvedRoutes)};try{this.cacheProvider.setCachedSolutionSync(this.cacheKey,t)}catch(t){console.error("Error saving solution to cache:",t)}}},is=class extends Ln{getSolverName(){return"HyperParameterSupervisorSolver"}GREEDY_MULTIPLIER=1.2;MIN_SUBSTEPS=1;supervisedSolvers;winningSolver;getHyperParameterDefs(){throw new Error("Not implemented")}getCombinationDefs(){return null}getHyperParameterCombinations(t){t||(t=this.getHyperParameterDefs());const e=[];if(0===t.length)return[{}];const[n,...s]=t,o=this.getHyperParameterCombinations(s);return n.possibleValues.forEach(t=>{o.forEach(n=>{e.push({...n,...t})})}),e}initializeSolvers(){const t=this.getHyperParameterDefs(),e=this.getCombinationDefs()??[t.map(t=>t.name)];this.supervisedSolvers=[];for(const n of e){const e=this.getHyperParameterCombinations(t.filter(t=>n.includes(t.name)));for(const t of e){const e=this.generateSolver(t),n=this.computeG(e);this.supervisedSolvers.push({hyperParameters:t,solver:e,h:0,g:n,f:n})}}}generateSolver(t){throw new Error("Not implemented")}computeG(t){return t.iterations/t.MAX_ITERATIONS}computeH(t){return 1-(t.progress||0)}computeF(t,e){return t+e*this.GREEDY_MULTIPLIER}getSupervisedSolverWithBestFitness(){let t=1/0,e=null;for(const n of this.supervisedSolvers??[]){if(n.solver.solved)return n;if(n.solver.failed)continue;const s=n.f;s<t&&(t=s,e=n)}return e}getFailureMessage(){return`All solvers failed in hyper solver. Example failures: ${this.supervisedSolvers?.sort((t,e)=>e.f-t.f)?.slice(0,5).map(t=>t.solver.error).join(", ")}`}_step(){this.supervisedSolvers||this.initializeSolvers();const t=this.getSupervisedSolverWithBestFitness();if(!t)return this.failed=!0,void(this.error=this.getFailureMessage());for(let e=0;e<this.MIN_SUBSTEPS;e++)t.solver.step();this.activeSubSolver=t.solver,t.g=this.computeG(t.solver),t.h=this.computeH(t.solver),t.f=this.computeF(t.g,t.h),t.solver.solved&&(this.solved=!0,this.winningSolver=t.solver,this.onSolve?.(t))}onSolve(t){}visualize(){const t=this.getSupervisedSolverWithBestFitness();let e={lines:[],circles:[],points:[],rects:[]};return t&&(e=t.solver.visualize()),e}};function rs({A:t,B:e,C:n,D:s,E:o,F:i,radius:r,margin:a,subdivisions:c=0}){const h=(t,e)=>({x:(t.x+e.x)/2,y:(t.y+e.y)/2}),l=(t,e,n)=>{const s=e.x-t.x,o=e.y-t.y,i=Math.sqrt(s*s+o*o),r=s/i,a=o/i,c=-a,h=r;return{midpoint:{x:(t.x+e.x)/2,y:(t.y+e.y)/2},A_Opp:{x:t.x-r*n,y:t.y-a*n},A_Right:{x:t.x+c*n,y:t.y+h*n},A_Left:{x:t.x-c*n,y:t.y-h*n},B_Opp:{x:e.x+r*n,y:e.y+a*n},B_Right:{x:e.x+c*n,y:e.y+h*n},B_Left:{x:e.x-c*n,y:e.y-h*n}}},d=(t,e)=>{const n=k(t,e.start),s=k(t,e.end),o=k(e.start,e.end);return Math.abs(n+s-o)<1e-4},u=(t,e)=>{const{start:n,end:s}=t,{start:o,end:i}=e;if(d(n,e)||d(s,e)||d(o,t)||d(i,t))return!0;const r=s.x-n.x,a=s.y-n.y,c=i.x-o.x,h=i.y-o.y,l=r*h-a*c;if(Math.abs(l)<1e-4)return!1;const u=o.x-n.x,p=o.y-n.y,f=(u*h-p*c)/l,m=(u*a-p*r)/l;return f>0&&f<1&&m>0&&m<1},p=(t,e)=>{const n=[];for(let e=0;e<t.length-1;e++)n.push({start:t[e],end:t[e+1]});const s=[];for(let t=0;t<e.length-1;t++)s.push({start:e[t],end:e[t+1]});for(const t of n)for(const e of s)if(u(t,e))return!0;return!1},f=t=>{let e=0;for(let n=1;n<t.length;n++){const s=t[n].x-t[n-1].x,o=t[n].y-t[n-1].y;e+=Math.sqrt(s*s+o*o)}return e},m=(t,e)=>{const{start:n,end:s}=t,o=s.x-n.x,i=s.y-n.y,r=o*o+i*i;if(0===r)return{...n,t:0};const a=Math.max(0,Math.min(1,((e.x-n.x)*o+(e.y-n.y)*i)/r));return{x:n.x+a*o,y:n.y+a*i,t:a}},g=(e,n,s)=>{const o=m(e,n);if(k(o,n)>=s)return o;const i=o.x-n.x,r=o.y-n.y,a=Math.sqrt(i*i+r*r);if(0===a){const i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=Math.sqrt(i*i+r*r);return{x:n.x+s*i/a,y:n.y+s*r/a,t:o.t,isSpecial:!0,specialType:n===t?"A":"B"}}return{x:n.x+s*i/a,y:n.y+s*r/a,t:o.t,isSpecial:!0,specialType:n===t?"A":"B"}},y=l(t,e,r),x=l(t,e,r+a),v=(t,e,n,s,o)=>{const i=t.points;if(i.length<2)return i;const a=n+s,c=[i[0]];for(let t=0;t<i.length-1;t++){const n={start:i[t],end:i[t+1]};if(X(e,n.start,n.end)<a){const t=m(n,e),s=t.x-e.x,o=t.y-e.y,i=Math.sqrt(s*s+o*o);let h=null;if(i>1e-6)h={x:e.x+a*s/i,y:e.y+a*o/i};else{const t=n.end.x-n.start.x,s=n.end.y-n.start.y,o=Math.sqrt(t*t+s*s);o>1e-6&&(h={x:e.x+a*t/o,y:e.y+a*s/o})}h&&k(n.start,h)>r/10&&c.push(h)}k(c[c.length-1],n.end)>r/10&&c.push(n.end)}if(c.length>1){const t=[c[0]];for(let e=1;e<c.length;e++)k(t[t.length-1],c[e])>r/10&&t.push(c[e]);return t}return c},b=(()=>{const t=[[n,y.B_Left,y.B_Opp,y.B_Right,h(y.midpoint,h(y.B_Right,y.A_Right)),h(y.midpoint,h(y.A_Left,y.B_Left)),y.A_Left,y.A_Opp,y.A_Right,s],[n,y.B_Right,y.B_Opp,y.B_Left,h(y.midpoint,h(y.A_Left,y.B_Left)),h(y.midpoint,h(y.A_Right,y.B_Right)),y.A_Right,y.A_Opp,y.A_Left,s],[s,y.B_Left,y.B_Opp,y.B_Right,h(y.midpoint,h(y.A_Right,y.B_Right)),h(y.midpoint,h(y.A_Left,y.B_Left)),y.A_Left,y.A_Opp,y.A_Right,n],[s,y.B_Right,y.B_Opp,y.B_Left,h(y.midpoint,h(y.A_Left,y.B_Left)),h(y.midpoint,h(y.A_Right,y.B_Right)),y.A_Right,y.A_Opp,y.A_Left,n]],e=[];for(let n=0;n<t.length;n++){const s=t[n],o={start:s[0],end:s[1]},i={start:s[s.length-2],end:s[s.length-1]},r={start:s[3],end:s[4]};u(o,i)||u(o,r)||u(i,r)||e.push({index:n+1,path:s,length:f(s)})}if(0===e.length)return{index:0,path:[]};const o=e.sort((t,e)=>t.length-e.length)[0],i=[...o.path],r=i[0],a=k(r,i[2]),c=k(r,i[3]),l=a<c?2:3;(a<k(r,i[1])||c<k(r,i[1]))&&i.splice(1,l-1);const d=i[i.length-1],p=k(d,i[i.length-3]),m=k(d,i[i.length-4]),g=p<m?i.length-3:i.length-4;return(p<k(d,i[i.length-2])||m<k(d,i[i.length-2]))&&i.splice(g+1,i.length-g-2),{index:o.index,path:i,startsAt:i[0]===n?"C":"D",goesTo:i[i.length-1]===n?"C":"D"}})(),P=c>0?((n,s)=>{if(n.length<2)return n;const o=[n[0]];for(let i=0;i<n.length-1;i++){const a={start:n[i],end:n[i+1]},c={x:(a.start.x+a.end.x)/2,y:(a.start.y+a.end.y)/2},h=k(c,t),l=k(c,e);if((h<=r||l<=r)&&Math.abs(h-l)>1e-4){const n=m(a,t),i=m(a,e),c=k(n,t),h=k(i,e)<r,l=c<r?g(a,t,r):null,d=h?g(a,e,r):null;let u=[];if(k(a.start,a.end)>r/2&&s>0)for(let n=1;n<=s;n++){const o=n/(s+1),i={x:a.start.x+o*(a.end.x-a.start.x),y:a.start.y+o*(a.end.y-a.start.y),t:o,isSpecial:!1},c=k(i,t),h=k(i,e);c<r||h<r||(l&&Math.abs(i.t-l.t)<.1||d&&Math.abs(i.t-d.t)<.1||u.push(i))}if(l&&u.push(l),d&&u.push(d),u.sort((t,e)=>t.t-e.t),u.length>1){const t=[u[0]];for(let e=1;e<u.length;e++){const n=t[t.length-1],s=u[e];k(n,s)>r/10&&t.push(s)}u=t}u.forEach(t=>o.push(t))}o.push(n[i+1])}if(o.length>1){const t=[o[0]];for(let e=1;e<o.length;e++){const n=t[t.length-1],s=o[e];k(n,s)>r/10&&t.push(s)}return t}return o})(b.path,c):b.path;let S=(()=>{if(0===b.path.length)return null;const n=(()=>{const n=h(y.A_Right,y.B_Right),s=h(y.B_Left,y.A_Left);return[{startsAt:"E",goesTo:"B",points:[o,e]},{startsAt:"E",goesTo:"A",points:[o,t]},{startsAt:"F",goesTo:"B",points:[i,e]},{startsAt:"F",goesTo:"A",points:[i,t]},{startsAt:"E",goesTo:"B",points:[o,n,e]},{startsAt:"E",goesTo:"A",points:[o,n,t]},{startsAt:"F",goesTo:"B",points:[i,n,e]},{startsAt:"F",goesTo:"A",points:[i,n,t]},{startsAt:"E",goesTo:"B",points:[o,s,e]},{startsAt:"E",goesTo:"A",points:[o,s,t]},{startsAt:"F",goesTo:"B",points:[i,s,e]},{startsAt:"F",goesTo:"A",points:[i,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Right,n,e]},{startsAt:"F",goesTo:"B",points:[i,x.B_Right,n,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Left,s,t]},{startsAt:"F",goesTo:"A",points:[i,x.A_Left,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Left,s,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Right,n,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Opp,x.A_Right,n,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Opp,x.B_Left,s,t]},{startsAt:"F",goesTo:"B",points:[i,x.A_Opp,x.A_Left,s,e]},{startsAt:"F",goesTo:"A",points:[i,x.B_Opp,x.B_Right,n,t]},{startsAt:"F",goesTo:"A",points:[i,x.B_Opp,x.B_Left,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Opp,x.A_Left,s,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Opp,x.B_Right,n,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Left,x.A_Opp,x.A_Right,n,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Right,x.B_Opp,x.B_Left,s,t]},{startsAt:"F",goesTo:"B",points:[i,x.A_Right,x.A_Opp,x.A_Left,s,e]},{startsAt:"F",goesTo:"A",points:[i,x.B_Left,x.B_Opp,x.B_Right,n,t]},{startsAt:"F",goesTo:"A",points:[i,x.B_Right,x.B_Opp,x.B_Left,s,t]},{startsAt:"E",goesTo:"B",points:[o,x.A_Right,x.A_Opp,x.A_Left,s,e]},{startsAt:"E",goesTo:"A",points:[o,x.B_Left,x.B_Opp,x.B_Right,n,t]}].map((t,e)=>({...t,index:e}))})(),s=n.filter(t=>"E"===t.startsAt),r=n.filter(t=>"F"===t.startsAt),a=[],c=[];for(const t of s)if(!p(t.points,b.path)){a.push(t);break}for(const t of r)if(!p(t.points,b.path)){c.push(t);break}return 0===a.length||0===c.length?null:{line1:a[0],line2:c[0]}})();if(S){const n="A"===S.line1.goesTo?e:t,s="A"===S.line2.goesTo?e:t,o=v(S.line1,n,r,a),i=v(S.line2,s,r,a);S={line1:{...S.line1,points:o},line2:{...S.line2,points:i}}}return{jPair:S,optimalPath:{startsAt:b.startsAt,goesTo:b.goesTo,points:P}}}var as=class extends Ln{getSolverName(){return"TwoCrossingRoutesHighDensitySolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;layerCount=2;debugViaPositions;escapeLayer=1;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.layerCount=t?.layerCount??2,this.debugViaPositions=[],this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),2!==this.routes.length)return this.failed=!0,void(this.error=`Expected 2 routes, but got ${this.routes.length}`);const[e,n]=this.routes;if(!(e.startPort.z===e.endPort.z))return this.failed=!0,void(this.error="Route A must start and end on the same layer");if(!(n.startPort.z===n.endPort.z))return this.failed=!0,void(this.error="Route B must start and end on the same layer");if(!(e.startPort.z===n.startPort.z))return this.failed=!0,void(this.error="Both routes must be on the same layer");0===e.startPort.z?this.escapeLayer=1:this.escapeLayer=0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e)?.push(t)}for(const[e,s]of n.entries())2===s.length&&t.push({startPort:{...s[0],z:s[0].z??0},endPort:{...s[1],z:s[1].z??0},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}doRoutesCross(t,e){return L(t.startPort,t.endPort,e.startPort,e.endPort)}calculateViaPositions(t,e){const n=this.bounds.maxX-this.bounds.minX,s=this.bounds.maxY-this.bounds.minY,o=this.bounds.minX,i=this.bounds.minY,r={width:n-2*this.obstacleMargin-this.viaDiameter,height:s-2*this.obstacleMargin-this.viaDiameter,x:o+this.obstacleMargin+this.viaDiameter/2,y:i+this.obstacleMargin+this.viaDiameter/2},a=this.viaDiameter+this.obstacleMargin,c=e.startPort,h=e.endPort,l=[{x:r.x,y:r.y},{x:r.x+r.width,y:r.y},{x:r.x+r.width,y:r.y+r.height},{x:r.x,y:r.y+r.height}],d=(t,e)=>k(t,e),u=[];l.forEach((t,e)=>{d(t,c)>=a&&d(t,h)>=a&&u.push({...t,type:"corner",index:e})});const p=[{p1:l[0],p2:l[1]},{p1:l[1],p2:l[2]},{p1:l[2],p2:l[3]},{p1:l[3],p2:l[0]}];if([c,h].forEach((t,e)=>{p.forEach((n,s)=>{((t,e)=>{const n=t.x,s=t.y,o=t.r,i=e.p1.x,r=e.p1.y,a=e.p2.x,c=e.p2.y;if(Math.abs(a-i)<.001){const t=i,e=o*o-(t-n)**2;if(e<0)return[];if(Math.abs(e)<.001){const e=s;return e>=Math.min(r,c)&&e<=Math.max(r,c)?[{x:t,y:e}]:[]}const a=s+Math.sqrt(e),h=s-Math.sqrt(e),l=[];return a>=Math.min(r,c)&&a<=Math.max(r,c)&&l.push({x:t,y:a}),h>=Math.min(r,c)&&h<=Math.max(r,c)&&l.push({x:t,y:h}),l}const h=(c-r)/(a-i),l=r-h*i,d=1+h*h,u=2*(h*l-h*s-n),p=u*u-4*d*(n*n+(l-s)*(l-s)-o*o);if(p<0)return[];if(Math.abs(p)<.001){const t=-u/(2*d),e=h*t+l;return t>=Math.min(i,a)&&t<=Math.max(i,a)&&e>=Math.min(r,c)&&e<=Math.max(r,c)?[{x:t,y:e}]:[]}const f=(-u+Math.sqrt(p))/(2*d),m=(-u-Math.sqrt(p))/(2*d),g=h*f+l,y=h*m+l,x=[];return f>=Math.min(i,a)&&f<=Math.max(i,a)&&g>=Math.min(r,c)&&g<=Math.max(r,c)&&x.push({x:f,y:g}),m>=Math.min(i,a)&&m<=Math.max(i,a)&&y>=Math.min(r,c)&&y<=Math.max(r,c)&&x.push({x:m,y:y}),x})({...t,r:a},n).forEach(t=>{d(t,0===e?h:c)>=a&&u.push({...t,type:"intersection",circle:e,edge:s})})})}),u.length<2){const t=.8*a;if(l.forEach((e,n)=>{d(e,c)>=t&&d(e,h)>=t&&!u.some(t=>t.x===e.x&&t.y===e.y)&&u.push({...e,type:"relaxed_corner",index:n})}),u.length<2){const t=[...l].sort((t,e)=>{const n=Math.min(d(t,c),d(t,h));return Math.min(d(e,c),d(e,h))-n});for(const e of t)if(!u.some(t=>t.x===e.x&&t.y===e.y)&&(u.push({...e,type:"forced_corner"}),u.length>=2))break}}if(u.length<2)return null;let f=0,m=[u[0],u[u.length>1?1:0]];for(let t=0;t<u.length;t++)for(let e=t+1;e<u.length;e++){const n=d(u[t],u[e]);n>f&&(f=n,m=[u[t],u[e]])}let g={x:m[0].x,y:m[0].y},y={x:m[1].x,y:m[1].y};const x=k(g,t.startPort);return k(y,t.startPort)<x&&([g,y]=[y,g]),{via1:g,via2:y}}trySolveAOverB(t,e,n=!1){const s=n?this.calculateViaPositions(t,e):this.calculateViaPositions(e,t);if(!s)return!1;this.debugViaPositions.push(s);const{via1:o,via2:i}=this.pushViasFromEndpoints(this.moveViasAsCloseAsPossible(s));this.debugViaPositions.push({via1:o,via2:i});const{jPair:r,optimalPath:a}=rs({A:o,B:i,C:t.startPort,D:t.endPort,E:e.startPort,F:e.endPort,radius:this.viaDiameter/2+this.obstacleMargin+this.traceThickness/2*1.5,margin:2*this.obstacleMargin+this.traceThickness/2*1.5,subdivisions:1});if(!r)return!1;const c={connectionName:t.connectionName,route:a.points.map(e=>({x:e.x,y:e.y,z:t.startPort.z??0})),traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]};r.line2.points.reverse();const h={connectionName:e.connectionName,route:[...r.line1.points.map(t=>({x:t.x,y:t.y,z:e.startPort.z??0})),{...r.line1.points[r.line1.points.length-1],z:this.escapeLayer},{...r.line2.points[0],z:this.escapeLayer},...r.line2.points.map(t=>({x:t.x,y:t.y,z:e.startPort.z??0}))],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[o,i]};return this.solvedRoutes.push(c,h),!0}pushViasFromEndpoints(t){const e={...t.via1},n={...t.via2},s=[this.routes[0].startPort,this.routes[0].endPort,this.routes[1].startPort,this.routes[1].endPort],o=this.getMinDistanceBetweenViaCenters(),i=this.viaDiameter/2+2*this.traceThickness+2*this.obstacleMargin;for(let t=0;t<10;t++){let r=!1,a=!1;const c=.9**t;for(const t of s){const s=k(e,t);if(s<i){const n=(i-s)*c,o=e.x-t.x,a=e.y-t.y,h=Math.sqrt(o*o+a*a);h>1e-6&&(e.x+=o/h*n,e.y+=a/h*n,r=!0)}const o=k(n,t);if(o<i){const e=(i-o)*c,s=n.x-t.x,r=n.y-t.y,h=Math.sqrt(s*s+r*r);h>1e-6&&(n.x+=s/h*e,n.y+=r/h*e,a=!0)}}const h=k(e,n);if(h<o){const t=(o-h)/2,s=n.x-e.x,i=n.y-e.y,c=Math.sqrt(s*s+i*i);c>1e-6?(e.x-=s/c*t,e.y-=i/c*t,n.x+=s/c*t,n.y+=i/c*t,r=!0,a=!0):(e.x-=t,n.x+=t,r=!0,a=!0)}if(!r&&!a)break}const r=k(e,n);if(r<o){const t=(o-r)/2,s=n.x-e.x,i=n.y-e.y,a=Math.sqrt(s*s+i*i);a>1e-6?(e.x-=s/a*t,e.y-=i/a*t,n.x+=s/a*t,n.y+=i/a*t):(e.x-=t,n.x+=t)}return{via1:e,via2:n}}getMinDistanceBetweenViaCenters(){return this.viaDiameter+this.traceThickness+2*this.obstacleMargin}moveViasAsCloseAsPossible(t){const{via1:e,via2:n}=t,s=this.getMinDistanceBetweenViaCenters(),o=k(e,n);if(o<=s)return t;const i=n.x-e.x,r=n.y-e.y,a=Math.sqrt(i*i+r*r),c=i/a,h=r/a,l=(e.x,n.x,e.y,n.y,(o-s)/2);return{via1:{x:e.x+c*l,y:e.y+h*l},via2:{x:n.x-c*l,y:n.y-h*l}}}handleRoutesDontCross(){const[t,e]=this.routes,n={connectionName:t.connectionName,route:[{x:t.startPort.x,y:t.startPort.y,z:t.startPort.z??0},{x:t.endPort.x,y:t.endPort.y,z:t.endPort.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]},s={connectionName:e.connectionName,route:[{x:e.startPort.x,y:e.startPort.y,z:e.startPort.z??0},{x:e.endPort.x,y:e.endPort.y,z:e.endPort.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]};this.solvedRoutes.push(n,s),this.solved=!0}_step(){if(2!==this.routes.length)return void(this.failed=!0);const[t,e]=this.routes;this.doRoutesCross(t,e)?this.trySolveAOverB(t,e)||this.trySolveAOverB(e,t)||this.trySolveAOverB(t,e,!0)||this.trySolveAOverB(e,t,!0)?this.solved=!0:(this.failed=!0,this.error="All crossover strategies failed"):this.handleRoutesDontCross()}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)"});for(const[e,n]of[["Route A",this.routes[0]],["Route B",this.routes[1]]])t.points.push({x:n.startPort.x,y:n.startPort.y,label:`${e}\n${n.connectionName} start`,color:"orange"}),t.points.push({x:n.endPort.x,y:n.endPort.y,label:`${e}\n${n.connectionName} end`,color:"orange"}),t.lines.push({points:[n.startPort,n.endPort],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e}\n${n.connectionName} direct`});for(let e=0;e<this.debugViaPositions.length;e++){const{via1:n,via2:s}=this.debugViaPositions[e],o=["rgba(255, 165, 0, 0.3)","rgba(128, 0, 128, 0.3)"],i=o[e%o.length];t.circles.push({center:n,radius:this.viaDiameter/2,fill:i,stroke:"rgba(0, 0, 0, 0.3)",label:`Computed Via A (attempt ${e+1})`}),t.circles.push({center:s,radius:this.viaDiameter/2,fill:i,stroke:"rgba(0, 0, 0, 0.3)",label:`Computed Via B (attempt ${e+1})`});const r=this.viaDiameter/2+this.obstacleMargin;t.circles.push({center:n,radius:r,stroke:i,fill:"rgba(0, 0, 0, 0)",label:`Debug Via 1 Safety Margin (attempt ${e+1})`}),t.circles.push({center:s,radius:r,stroke:i,fill:"rgba(0, 0, 0, 0)",label:`Debug Via 2 Safety Margin (attempt ${e+1})`}),t.lines.push({points:[this.routes[e%2].startPort,n,s,this.routes[e%2].endPort],strokeColor:`${i.substring(0,i.lastIndexOf(","))}, 0.3)`,strokeDash:[5,5],label:`Potential Route (attempt ${e+1})`})}for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],s=e%2==0?"rgba(0, 255, 0, 0.75)":"rgba(255, 0, 255, 0.75)";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:s,strokeDash:1===o.z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${o.z}`}),o._label&&t.points.push({x:o.x,y:o.y,label:o._label})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Solved Via Margin"})}return t}getSolvedRoutes(){return this.solvedRoutes}},cs=({value:t,min:e,max:n})=>t>=e&&t<=n,hs=({value:t,target:e,epsilon:n})=>Math.abs(t-e)<=n,ls=({point:t,bounds:e,epsilon:n=1e-6})=>{if(![t.x,t.y,e.minX,e.maxX,e.minY,e.maxY].every(t=>(({value:t})=>Number.isFinite(t))({value:t})))return"outside";const s=function(t,e){return t.x>=e.minX&&t.x<=e.maxX&&t.y>=e.minY&&t.y<=e.maxY?0:k(t,{x:D(t.x,e.minX,e.maxX),y:D(t.y,e.minY,e.maxY)})}(t,e);if(s>n)return"outside";const o=hs({value:t.x,target:e.minX,epsilon:n}),i=hs({value:t.x,target:e.maxX,epsilon:n}),r=hs({value:t.y,target:e.minY,epsilon:n}),a=hs({value:t.y,target:e.maxY,epsilon:n}),c=o||i,h=r||a;if(c&&h)return"on-boundary";const l=cs({value:t.y,min:e.minY,max:e.maxY}),d=cs({value:t.x,min:e.minX,max:e.maxX});return c&&l||h&&d?"on-boundary":"inside"};function ds(t,e,n,s,o){const i={x:(t.x+e.x+n.x)/3,y:(t.y+e.y+n.y)/3},r=(t,e)=>Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2),a=i=>{const a=r(i,t),c=r(i,e),h=r(i,n),l=i.x>=o.minX&&i.x<=o.maxX&&i.y>=o.minY&&i.y<=o.maxY;return a>=s&&c>=s&&h>=s&&l};if(a(i))return i;const c=(t,e,n)=>{const s=t.x-e.x,o=t.y-e.y,i=Math.sqrt(s*s+o*o);return i<1e-10?{x:e.x+n,y:e.y}:{x:e.x+s/i*n,y:e.y+o/i*n}},h=(t,e,n)=>{const s=e.x-t.x,o=e.y-t.y,i=Math.sqrt(s*s+o*o);if(i>2*n-1e-10||i<1e-10)return[];const a=i*i/(2*i),c=Math.sqrt(Math.max(0,n*n-a*a)),h=t.x+s*a/i,l=t.y+o*a/i,d={x:h+c*o/i,y:l-c*s/i},u={x:h-c*o/i,y:l+c*s/i},p=[],f=1e-6;return Math.abs(r(d,t)-n)<f&&Math.abs(r(d,e)-n)<f&&p.push(d),Math.abs(r(u,t)-n)<f&&Math.abs(r(u,e)-n)<f&&p.push(u),p},l=[c(i,t,s),c(i,e,s),c(i,n,s),...h(t,e,s),...h(e,n,s),...h(n,t,s)],d=l.filter(a);if(d.length>0){const t=d.filter(t=>!(t=>{const e=1e-6;return Math.abs(t.x-o.minX)<e||Math.abs(t.x-o.maxX)<e||Math.abs(t.y-o.minY)<e||Math.abs(t.y-o.maxY)<e})(t));if(t.length>0)return t.sort((t,e)=>r(t,i)-r(e,i)),t[0]}let u=null,p=1/0;for(let t=o.minX+1;t<o.maxX;t+=5)for(let e=o.minY+1;e<o.maxY;e+=5){const n={x:t,y:e};if(a(n)){const t=r(n,i);t<p&&(p=t,u=n)}}if(null!==u)return u;const f=[];for(let t=0;t<=100;t++){const e=t/100;f.push({x:o.minX+e*(o.maxX-o.minX),y:o.minY}),f.push({x:o.maxX,y:o.minY+e*(o.maxY-o.minY)}),f.push({x:o.maxX-e*(o.maxX-o.minX),y:o.maxY}),f.push({x:o.minX,y:o.maxY-e*(o.maxY-o.minY)})}const m=f.filter(a);if(m.length>0)return m.sort((t,e)=>r(t,i)-r(e,i)),m[0];let g=1/0,y={x:o.minX,y:o.minY};for(const i of[...l,...f])if(i.x>=o.minX&&i.x<=o.maxX&&i.y>=o.minY&&i.y<=o.maxY){const o=Math.max(0,s-r(i,t))+Math.max(0,s-r(i,e))+Math.max(0,s-r(i,n));o<g&&(g=o,y=i)}return y}function us(t,e,n){const s=ps(e,t,n.center,n.radius),o=ps(t,e,n.center,n.radius),i=fs(s,e),r=fs(t,o),a=1e-6;let c;if(i>a&&r>a){c={x:(s.x+o.x)/2,y:(s.y+o.y)/2};const i=fs(s,c),r=fs(o,c);if(Math.abs(i-r)>.5*Math.min(i,r)){const n=fs(t,s),i=fs(e,o),r=n+i;if(r>a){const t=i/r,e=n/r;c={x:s.x*t+o.x*e,y:s.y*t+o.y*e}}}const h=fs(c,n.center);if(h<1.05*n.radius){const t={x:(c.x-n.center.x)/h,y:(c.y-n.center.y)/h};c={x:n.center.x+t.x*n.radius*1.2,y:n.center.y+t.y*n.radius*1.2}}}else{const s={x:(t.x+e.x)/2,y:(t.y+e.y)/2},o=fs(s,n.center);if(o<1.1*n.radius){const t={x:(s.x-n.center.x)/o,y:(s.y-n.center.y)/o};c={x:n.center.x+t.x*n.radius*1.2,y:n.center.y+t.y*n.radius*1.2}}else c=s}return{B:s,D:o,E:c}}function ps(t,e,n,s){const o=[n.x-t.x,n.y-t.y],i=Math.sqrt(o[0]*o[0]+o[1]*o[1]);if(i<=s){if(i<1e-8){const o=[e.x-t.x,e.y-t.y],i=Math.sqrt(o[0]*o[0]+o[1]*o[1]);return i<1e-8?{x:n.x+s,y:n.y}:{x:n.x+o[0]/i*s,y:n.y+o[1]/i*s}}const r=[o[0]/i,o[1]/i];return{x:n.x-r[0]*s,y:n.y-r[1]*s}}const r=[e.x-t.x,e.y-t.y],a=Math.sqrt(i*i-s*s),c=[o[0]/i,o[1]/i],h=[-c[1],c[0]],l=[c[1],-c[0]],d=r[0]*h[0]+r[1]*h[1]>r[0]*l[0]+r[1]*l[1]?h:l,u=s/i,p=a/i,f=[c[0]*p+d[0]*u,c[1]*p+d[1]*u];return{x:t.x+a*f[0],y:t.y+a*f[1]}}function fs(t,e){const n=e.x-t.x,s=e.y-t.y;return Math.sqrt(n*n+s*s)}var ms=1e-9;function gs(t,e,n,s="cw"){const o=ys(t,n),i=ys(e,n);return Math.abs(i-o)<ms?{left:0,top:0,right:0,bottom:0}:function(t,e,n,s){const o=n.maxX-n.minX,i=n.maxY-n.minY;if(o<ms&&i<ms)return{left:0,top:0,right:0,bottom:0};const r=2*(o+i);if(r<ms)return{left:0,top:0,right:0,bottom:0};const a=o/r*(2*Math.PI),c=(o+i)/r*(2*Math.PI),h=(o+o+i)/r*(2*Math.PI),l=2*Math.PI,d=[{name:"top",start:0,end:a,length:o},{name:"right",start:a,end:c,length:i},{name:"bottom",start:c,end:h,length:o},{name:"left",start:h,end:l,length:i}],u={left:0,top:0,right:0,bottom:0},p=(t,e,n,s,o)=>{const i=e>2*Math.PI-ms?2*Math.PI:e;if(i<=t+ms)return 0;if(o){const e=Math.max(t,n),o=Math.min(i,2*Math.PI),r=Math.max(0,o-e),a=Math.max(t,0),c=Math.min(i,s);return r+Math.max(0,c-a)}{const e=Math.max(t,n),o=Math.min(i,s);return Math.max(0,o-e)}};for(const n of d){const o=n.end-n.start;if(o<ms||n.length<ms)continue;let i=0;if("cw"===s){const s=t>e+ms;i=p(n.start,n.end,t,e,s)}else{const s=e>t+ms;i=p(n.start,n.end,e,t,s)}if(i>ms){const t=i/o;u[n.name]+=Math.max(0,Number.isFinite(t)?t:0)}}for(const t in u)u[t]=Math.max(0,Math.min(1,u[t]));return u}(o,i,n,s)}function ys(t,e){const n=e.maxX-e.minX,s=e.maxY-e.minY;if(n<ms&&s<ms)return 0;const o=2*(n+s);if(o<ms)return 0;let i=0;if(Math.abs(t.y-e.maxY)<ms&&t.x>=e.minX-ms&&t.x<=e.maxX+ms)i=Math.max(0,Math.min(n,t.x-e.minX));else if(Math.abs(t.x-e.maxX)<ms&&t.y>=e.minY-ms&&t.y<=e.maxY+ms)i=n+Math.max(0,Math.min(s,e.maxY-t.y));else if(Math.abs(t.y-e.minY)<ms&&t.x>=e.minX-ms&&t.x<=e.maxX+ms)i=n+s+Math.max(0,Math.min(n,e.maxX-t.x));else{if(!(Math.abs(t.x-e.minX)<ms&&t.y>=e.minY-ms&&t.y<=e.maxY+ms))throw new Error(`Point (${t.x}, ${t.y}) does not lie on the boundary defined by ${JSON.stringify(e)}`);i=n+s+n+Math.max(0,Math.min(s,t.y-e.minY))}return i=Math.max(0,Math.min(o,i)),o>ms?i/o*(2*Math.PI):0}function xs(t,e,n,s){return function({angleA:t,angleB:e,angleC:n}){const s=Math.cos(t),o=Math.sin(t),i=Math.cos(e),r=Math.sin(e),a=Math.cos(n);return(i-s)*(Math.sin(n)-o)-(r-o)*(a-s)<0?"ccw":"cw"}({angleA:ys(t,s),angleB:ys(e,s),angleC:ys(n,s)})}var vs=class extends Ln{getSolverName(){return"SingleTransitionCrossingRouteSolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;layerCount=2;debugViaPositions;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.layerCount=t?.layerCount??2,this.debugViaPositions=[],this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),2!==this.routes.length)return this.failed=!0,void(this.error=`Expected 2 routes, but got ${this.routes.length}`);const e=this.routes.flatMap(t=>[t.A,t.B]).map(t=>this.getPortPointBoundsPosition(t));if(e.includes("outside"))return this.failed=!0,void(this.error="Invalid route input: SingleTransitionCrossingRouteSolver received port point(s) outside node bounds");if(e.includes("inside"))return void(this.failed=!0);const[n,s]=this.routes,o=n.A.z!==n.B.z,i=s.A.z!==s.B.z;return o&&i||!o&&!i?(this.failed=!0,void(this.error="Exactly one route must have a layer transition")):void 0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e)?.push(t)}for(const[e,s]of n.entries())2===s.length&&t.push({A:{...s[0],z:s[0].z??0},B:{...s[1],z:s[1].z??0},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}getPortPointBoundsPosition(t,e=1e-6){return ls({point:t,bounds:this.bounds,epsilon:e})}doRoutesCross(t,e){return L(t.A,t.B,e.A,e.B)}calculateViaPosition(t,e){const n=e.A.z,s=t.A.z!==n?t.A:t.B,o=2*this.obstacleMargin+this.viaDiameter/2+this.traceThickness,i=this.obstacleMargin+this.viaDiameter/2,r=e.A,a=s,c=e.B,h=xs(r,a,c,this.bounds),l=function(t,e,n,s,o){const i=gs(t,e,s,o),r=gs(e,n,s,o),a={left:Math.min(1,i.left+r.left),top:Math.min(1,i.top+r.top),right:Math.min(1,i.right+r.right),bottom:Math.min(1,i.bottom+r.bottom)};for(const t in a)Math.abs(a[t])<ms&&(a[t]=0);return a}(r,a,c,this.bounds,h),d={minX:this.bounds.minX+(l.left>.5?o:i),minY:this.bounds.minY+(l.bottom>.5?o:i),maxX:this.bounds.maxX-(l.right>.5?o:i),maxY:this.bounds.maxY-(l.top>.5?o:i)};return d.maxY<d.minY&&(d.minY=(d.minY+d.maxY)/2,d.maxY=d.minY),d.maxX<d.minX&&(d.minX=(d.minX+d.maxX)/2,d.maxX=d.minX),ds(r,a,c,o,d)}createTransitionRoute(t,e,n,s){return{connectionName:s,route:[{x:t.x,y:t.y,z:t.z??0},{x:n.x,y:n.y,z:t.z??0},{x:n.x,y:n.y,z:e.z??0},{x:e.x,y:e.y,z:e.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[n]}}createFlatRoute(t,e,n,s,o,i){s.z,t.z;const r=this.viaDiameter/2+this.traceThickness/2+this.obstacleMargin,a=((t,e,n,s)=>{const o=n.x-t.x,i=n.y-t.y;return((t,e)=>({x:(t.x+e.x)/2,y:(t.y+e.y)/2}))({x:t.x+o*e,y:t.y+i*e},{x:n.x-o*s,y:n.y-i*s})})(n,this.viaDiameter,s.z!==t.z?s:o,this.traceThickness),c={center:{x:n.x,y:n.y},radius:r},h=us(t,a,c).E,l=us(a,e,c).E,d=us(t,h,c).E,u=us(h,a,c).E,p=us(a,l,c).E,f=us(l,e,c).E,m=us(u,p,c).E;return{connectionName:i,route:[{x:t.x,y:t.y,z:t.z??0},{x:d.x,y:d.y,z:t.z??0},{x:h.x,y:h.y,z:t.z??0},{x:u.x,y:u.y,z:t.z??0},{x:m.x,y:m.y,z:t.z??0},{x:p.x,y:p.y,z:t.z??0},{x:l.x,y:l.y,z:t.z??0},{x:f.x,y:f.y,z:t.z??0},{x:e.x,y:e.y,z:e.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]}}trySolve(){const[t,e]=this.routes,n=t.A.z!==t.B.z,s=n?t:e,o=n?e:t,i=this.calculateViaPosition(s,o);if(!i)return!1;this.debugViaPositions.push({via:i});const r=this.createTransitionRoute(s.A,s.B,i,s.connectionName),a=this.createFlatRoute(o.A,o.B,i,s.A,s.B,o.connectionName);return this.solvedRoutes.push(r,a),!0}_step(){if(!this.doRoutesCross(this.routes[0],this.routes[1]))return this.failed=!0,void(this.error="Can only solve routes that have a single transition crossing");this.trySolve()?this.solved=!0:(this.failed=!0,this.error="Failed to find a valid via position and route path")}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)",label:"PCB Bounds"});for(const e of this.routes)t.points.push({x:e.A.x,y:e.A.y,label:`${e.connectionName} start (z=${e.A.z})`,color:"orange"}),t.points.push({x:e.B.x,y:e.B.y,label:`${e.connectionName} end (z=${e.B.z})`,color:"orange"}),t.lines.push({points:[e.A,e.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e.connectionName} direct`});for(let e=0;e<this.debugViaPositions.length;e++){const{via:n}=this.debugViaPositions[e];t.circles.push({center:n,radius:this.viaDiameter/2,fill:"rgba(255, 165, 0, 0.7)",stroke:"rgba(0, 0, 0, 0.5)",label:`Computed Via (attempt ${e+1})`});const s=this.viaDiameter/2+this.obstacleMargin;t.circles.push({center:n,radius:s,stroke:"rgba(255, 165, 0, 0.7)",fill:"rgba(0, 0, 0, 0)",label:"Safety Margin"})}for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],s=e%2==0?"rgba(0, 255, 0, 0.75)":"rgba(255, 0, 255, 0.75)";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:s,strokeDash:o.z!==n.route[0].z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${o.z}`})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Via Margin"})}return t}getSolvedRoutes(){return this.solvedRoutes}},bs=class extends Ln{getSolverName(){return"SingleTransitionIntraNodeSolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),1!==this.routes.length)return this.failed=!0,void(this.error=`Expected 1 route, but got ${this.routes.length}`);const e=this.routes[0];if(void 0===e.A.z||void 0===e.B.z)return this.failed=!0,void(this.error="Route points should have predefined z values");if(e.A.z===e.B.z)return this.failed=!0,void(this.error="Only one route provided, but it has no transition");const n=this.viaDiameter/2+this.obstacleMargin,s={x:D((e.A.x+e.B.x)/2,this.bounds.minX+n,this.bounds.maxX-n),y:D((e.A.y+e.B.y)/2,this.bounds.minY+n,this.bounds.maxY-n)};this.solvedRoutes.push(this.createTransitionRoute(e.A,e.B,s,e.connectionName)),this.solved=!0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e).push(t)}for(const[e,s]of n.entries())2===s.length&&t.push({A:{...s[0]},B:{...s[1]},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}createTransitionRoute(t,e,n,s){return{connectionName:s,route:[{x:t.x,y:t.y,z:t.z},{x:n.x,y:n.y,z:t.z},{x:n.x,y:n.y,z:e.z},{x:e.x,y:e.y,z:e.z}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[n]}}_step(){this.solved=!0}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)",label:"PCB Bounds"}),this.routes.length>0)for(const e of this.routes)t.points.push({x:e.A.x,y:e.A.y,label:`${e.connectionName} start (z=${e.A.z})`,color:"orange"}),t.points.push({x:e.B.x,y:e.B.y,label:`${e.connectionName} end (z=${e.B.z})`,color:"orange"}),t.lines.push({points:[e.A,e.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e.connectionName} direct`});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],s="rgba(0, 255, 0, 0.75)";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:s,strokeDash:o.z!==n.route[0].z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${o.z}`})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Via Margin"})}return t}},Ps=(t,e)=>{const n={};return t.portPoints.forEach((e,s)=>{n[e.connectionName]=`hsl(${360*s/t.portPoints.length}, 100%, 50%)`}),n},Ss=class extends Ln{getSolverName(){return"ViaPossibilitiesSolver2"}bounds;maxViaCount;portPairMap;colorMap;nodeWidth;availableZ;hyperParameters;VIA_INTERSECTION_BUFFER_DISTANCE=.05;PLACEHOLDER_WALL_BUFFER_DISTANCE=.1;NEW_HEAD_WALL_BUFFER_DISTANCE=.05;viaDiameter;unprocessedConnections;completedPaths=new Map;placeholderPaths=new Map;currentHead;currentConnectionName;currentPath;currentViaCount;constructor({nodeWithPortPoints:t,colorMap:e,hyperParameters:n,viaDiameter:s}){super(),this.MAX_ITERATIONS=1e5,this.colorMap=e??Ps(t),this.maxViaCount=5,this.bounds=Ie(t),this.nodeWidth=this.bounds.maxX-this.bounds.minX,this.portPairMap=(t=>{const e=new Map;return t.portPoints.forEach(t=>{e.has(t.connectionName)?e.get(t.connectionName).end=t:e.set(t.connectionName,{start:t,end:null,connectionName:t.connectionName})}),e})(t),this.stats.solutionsFound=0,this.availableZ=t.availableZ??[0,1],this.hyperParameters=n??{SHUFFLE_SEED:0},this.viaDiameter=s??.3,this.unprocessedConnections=Array.from(this.portPairMap.keys()).sort(),n?.SHUFFLE_SEED&&(this.unprocessedConnections=Gn(this.unprocessedConnections,n.SHUFFLE_SEED));for(const[t,{start:e,end:n}]of this.portPairMap.entries())if(e.z===n.z){const s=Math.abs(e.x-n.x)<1e-9,o=Math.abs(e.y-n.y)<1e-9;s||o?this.placeholderPaths.set(t,[e,this._padByPlaceholderWallBuffer(e),this._padByPlaceholderWallBuffer(n),n]):this.placeholderPaths.set(t,[e,n])}else{const s=(e.x+n.x)/2,o=(e.y+n.y)/2,i=this._padByPlaceholderWallBuffer({x:s,y:o,z:e.z}),r=this._padByPlaceholderWallBuffer({x:s,y:o,z:n.z});this.placeholderPaths.set(t,[e,this._padByPlaceholderWallBuffer(e),i,r,this._padByPlaceholderWallBuffer(n),n])}this.currentConnectionName=this.unprocessedConnections.pop();const o=this.portPairMap.get(this.currentConnectionName).start;this.currentHead=this._padByNewHeadWallBuffer(o),this.currentPath=[o,this.currentHead],this.currentViaCount=0,this.placeholderPaths.delete(this.currentConnectionName)}_padByNewHeadWallBuffer(t){return{x:D(t.x,this.bounds.minX+this.NEW_HEAD_WALL_BUFFER_DISTANCE,this.bounds.maxX-this.NEW_HEAD_WALL_BUFFER_DISTANCE),y:D(t.y,this.bounds.minY+this.NEW_HEAD_WALL_BUFFER_DISTANCE,this.bounds.maxY-this.NEW_HEAD_WALL_BUFFER_DISTANCE),z:t.z}}_padByPlaceholderWallBuffer(t){return{x:D(t.x,this.bounds.minX+this.PLACEHOLDER_WALL_BUFFER_DISTANCE,this.bounds.maxX-this.PLACEHOLDER_WALL_BUFFER_DISTANCE),y:D(t.y,this.bounds.minY+this.PLACEHOLDER_WALL_BUFFER_DISTANCE,this.bounds.maxY-this.PLACEHOLDER_WALL_BUFFER_DISTANCE),z:t.z}}_step(){if(this.solved)return;const t=this.portPairMap.get(this.currentConnectionName).end,e=[this.currentHead,t];let n=null,s=null;const o=t=>{for(const o of t.values())for(let t=0;t<o.length-1;t++){const i=[o[t],o[t+1]];if(i[0].x===i[1].x&&i[0].y===i[1].y)continue;if(i[0].z!==this.currentHead.z)continue;const r=$(e[0],e[1],i[0],i[1]);if(r){const t=k(this.currentHead,r);if(t<1e-6)continue;(!n||t<n.dist)&&(n={point:r,dist:t},s=i[0].z)}}};o(this.completedPaths),o(this.placeholderPaths);const i=this.currentHead.z!==t.z;if((n||i)&&(this.currentViaCount++,this.currentViaCount>=this.maxViaCount))return this.failed=!0,void(this.error=`Exceeded max via count of ${this.maxViaCount}`);if(n){let t;const e=n.dist;if(e<=this.VIA_INTERSECTION_BUFFER_DISTANCE+1e-6)t=j(this.currentHead,n.point);else{const s=n.point,o=s.x-this.currentHead.x,i=s.y-this.currentHead.y,r=(e-this.VIA_INTERSECTION_BUFFER_DISTANCE)/e;t={x:this.currentHead.x+o*r,y:this.currentHead.y+i*r}}const o=this.availableZ.find(t=>t!==s);if(void 0===o)return this.error="Could not determine next Z level for via placement!",void(this.failed=!0);const i={...t,z:this.currentHead.z},r={...t,z:o};this.currentPath.push(i,r),this.currentHead=r}else if(i){let e;const n=k(this.currentHead,t);if(n<this.VIA_INTERSECTION_BUFFER_DISTANCE)e=j(this.currentHead,t);else{const s=t.x-this.currentHead.x,o=t.y-this.currentHead.y,i=(n-this.VIA_INTERSECTION_BUFFER_DISTANCE)/n;e={x:this.currentHead.x+s*i,y:this.currentHead.y+o*i}}const s=t.z,o={...e,z:this.currentHead.z},i={...e,z:s};this.currentPath.push(o,i),this.currentHead=i}else if(this.currentPath.push(t),this.completedPaths.set(this.currentConnectionName,this.currentPath),0===this.unprocessedConnections.length)this.solved=!0,this.stats.solutionsFound=1;else{this.currentConnectionName=this.unprocessedConnections.pop();const{start:t}=this.portPairMap.get(this.currentConnectionName);this.currentHead=this._padByNewHeadWallBuffer(t),this.currentPath=[t,this.currentHead],this.currentViaCount=0,this.placeholderPaths.delete(this.currentConnectionName)}}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Via Possibilities Solver State",coordinateSystem:"cartesian"},e=this.colorMap;t.lines.push({points:[{x:this.bounds.minX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.minY}],strokeColor:"gray",strokeWidth:.01});for(const[e,{start:n,end:s}]of this.portPairMap.entries()){const o=this.colorMap[e]??"black";t.points.push({x:n.x,y:n.y,color:o,label:`Port: ${e} Start (z${n.z})`}),t.points.push({x:s.x,y:s.y,color:o,label:`Port: ${e} End (z${s.z})`})}const n=(n,s)=>{for(const[o,i]of n.entries()){const n=e[o]??"black";for(let e=0;e<i.length-1;e++){const r=i[e],a=i[e+1];r.x===a.x&&r.y===a.y&&r.z!==a.z?t.circles.push({center:{x:r.x,y:r.y},radius:this.viaDiameter/2,fill:In(n,.5),label:`${s}: ${o} Via (z${r.z}->z${a.z})`}):t.lines.push({points:[r,a],strokeColor:In(n,.5),strokeDash:0===r.z?void 0:[.1,.1],strokeWidth:.1,label:`${s}: ${o} (z${r.z})`})}}};if(n(this.placeholderPaths,"Placeholder"),n(this.completedPaths,"Completed"),this.currentPath&&this.currentPath.length>0){const n=e[this.currentConnectionName]??"orange";for(let e=0;e<this.currentPath.length-1;e++){const s=this.currentPath[e],o=this.currentPath[e+1];s.x===o.x&&s.y===o.y&&s.z!==o.z?t.circles.push({center:{x:s.x,y:s.y},radius:this.viaDiameter/2,fill:In(n,.5),label:`Current: ${this.currentConnectionName} Via (z${s.z}->z${o.z})`}):t.lines.push({points:[s,o],strokeColor:In(n,.5),strokeWidth:.15,strokeDash:"2,2",label:`Current: ${this.currentConnectionName} (z${s.z})`})}t.points.push({x:this.currentHead.x,y:this.currentHead.y,color:"green",label:`Current Head: ${this.currentConnectionName} (z${this.currentHead.z})`})}return t}},Ms=t=>Math.round(1e4*t),Ns=t=>{let e=0,n=[];const s=[];for(const e of t.portPoints){if(n.some(t=>t.connectionName===e.connectionName))continue;if(s.some(t=>t.connectionName===e.connectionName))continue;const o={connectionName:e.connectionName,z:e.z,points:[{x:Ms(e.x),y:Ms(e.y),z:e.z}]};for(const n of t.portPoints)e.connectionName===n.connectionName&&(e.x===n.x&&e.y===n.y||o.points.push({x:Ms(n.x),y:Ms(n.y),z:n.z}));o.points.some(t=>t.z!==o.z)?s.push(o):n.push(o)}n=n.filter(t=>t.points.length>1);for(let t=0;t<n.length;t++)for(let s=t+1;s<n.length;s++){const o=n[t],i=n[s];o.z===i.z&&L(o.points[0],o.points[1],i.points[0],i.points[1])&&e++}let o=0;for(let t=0;t<s.length;t++)for(let e=t+1;e<s.length;e++){const n=s[t],i=s[e];L(n.points[0],n.points[1],i.points[0],i.points[1])&&o++}return{numSameLayerCrossings:e,numEntryExitLayerChanges:s.length,numTransitionPairCrossings:o}};var Is=t=>{const{start:e,end:n,segmentsPerPolyline:s,viaPositions:o,viaCount:i,availableZ:r}=t,a=function(t,e){const n=new Array(t).fill(0);if(0===e)return n;if(e===t)return n.fill(1);if(e<=t/2){const s=Math.floor(t/e),o=Math.floor((t-(s*(e-1)+1))/2);for(let t=0;t<e;t++)n[o+t*s]=1}else{const s=t-e,o=Math.floor(t/s),i=Math.floor((t-(o*(s-1)+1))/2);n.fill(1);for(let t=0;t<s;t++)n[i+t*o]=0}return n}(s,i),c=a.map(()=>null);let h=0,l=e.z1;const d=r.indexOf(e.z1);for(let t=0;t<a.length;t++)if(1===a[t]){const e=r[(d+h+1)%r.length];c[t]={...o[h],z1:l,z2:e},l=e,h++}let u=e;for(let t=0;t<c.length;t++){if(c[t]){u=c[t];continue}let e=n,s=c.length;for(let n=t+1;n<c.length;n++)if(c[n]){e=c[n],s=n;break}const o=s-t,i=e.x-u.x,r=e.y-u.y;for(let e=1/(o+1),n=0;t+n!==s;e+=1/(o+1),n++)c[t+n]={x:u.x+i*e,y:u.y+r*e,z1:u.z2,z2:u.z2}}return c},_s=1e-9;function Cs(t,e){return Math.abs(t-e)<_s}function Ts(t){return`${Math.round(t.x/_s)}:${Math.round(t.y/_s)}`}function Es(t,e,n,s){return t*s-e*n}function ws(t,e,n,s){const o={x:e.x-t.x,y:e.y-t.y},i={x:s.x-n.x,y:s.y-n.y},r=Es(o.x,o.y,i.x,i.y),a={x:n.x-t.x,y:n.y-t.y};if(Cs(r,0))return null;const c=Es(a.x,a.y,i.x,i.y)/r,h=Es(a.x,a.y,o.x,o.y)/r;return c>=-1e-9&&c<=1+_s&&h>=-1e-9&&h<=1+_s?{x:t.x+c*o.x,y:t.y+c*o.y}:null}function Rs(t,e,n){return Cs(Math.hypot(t.x-e.x,t.y-e.y)+Math.hypot(t.x-n.x,t.y-n.y),Math.hypot(e.x-n.x,e.y-n.y))}function Os(t,e){const n=[],s=new Map;for(const e of t){const t=[e.start,...e.mPoints,e.end];for(let o=0;o<t.length-1;o++){const i=t[o],r=t[o+1],a=i.z2;if(n.push({start:{x:i.x,y:i.y},end:{x:r.x,y:r.y},connectionName:e.connectionName,layer:a}),i.z1!==i.z2){const t=Ts(i);s.has(t)||s.set(t,{point:i,connectionName:e.connectionName})}}const o=t[t.length-1];if(o.z1!==o.z2){const t=Ts(o);s.has(t)||s.set(t,{point:o,connectionName:e.connectionName})}}const o=[{start:{x:e.minX,y:e.minY},end:{x:e.maxX,y:e.minY},connectionName:null,layer:0},{start:{x:e.maxX,y:e.minY},end:{x:e.maxX,y:e.maxY},connectionName:null,layer:0},{start:{x:e.maxX,y:e.maxY},end:{x:e.minX,y:e.maxY},connectionName:null,layer:0},{start:{x:e.minX,y:e.maxY},end:{x:e.minX,y:e.minY},connectionName:null,layer:0}];n.push(...o);const i=new Map;let r=0;function a(t,e){const n=Ts(t);let o=i.get(n);if(!o){const e=s.has(n);o={id:r++,x:t.x,y:t.y,isVia:e,connectionNames:new Set,outgoingEdges:[]},i.set(n,o),e&&s.get(n)&&o.connectionNames.add(s.get(n).connectionName)}return e&&o.connectionNames.add(e),o}for(const t of n)a(t.start,t.connectionName),a(t.end,t.connectionName);const c=new Map;for(const t of n)c.set(t,[]);for(let t=0;t<n.length;t++)for(let e=t+1;e<n.length;e++){if(n[t].layer!==n[e].layer)continue;const s=ws(n[t].start,n[t].end,n[e].start,n[e].end);s&&(a(s),Rs(s,n[t].start,n[t].end)&&c.get(n[t]).push(s),Rs(s,n[e].start,n[e].end)&&c.get(n[e]).push(s))}const h=[];let l=0;for(const t of n){const e=[t.start,...c.get(t),t.end];e.sort((e,n)=>{const s=t.end.x-t.start.x,o=t.end.y-t.start.y;return Math.abs(s)>Math.abs(o)?(e.x-t.start.x)/s-(n.x-t.start.x)/s:Math.abs(o)<_s?0:(e.y-t.start.y)/o-(n.y-t.start.y)/o});const n=[];if(e.length>0){n.push(e[0]);for(let t=1;t<e.length;t++)Cs(e[t].x,e[t-1].x)&&Cs(e[t].y,e[t-1].y)||n.push(e[t])}for(let e=0;e<n.length-1;e++){const s=n[e],o=n[e+1],i=a(s,t.connectionName),r=a(o,t.connectionName);if(i===r)continue;const c={id:l++,origin:i,twin:null,next:null,face:null,connectionName:t.connectionName,layer:t.layer,visited:!1},d={id:l++,origin:r,twin:c,next:null,face:null,connectionName:t.connectionName,layer:t.layer,visited:!1};c.twin=d,h.push(c,d),i.outgoingEdges.push(c),r.outgoingEdges.push(d)}}for(const t of i.values()){t.outgoingEdges.sort((e,n)=>{const s=e.twin.origin,o=n.twin.origin;return Math.atan2(s.y-t.y,s.x-t.x)-Math.atan2(o.y-t.y,o.x-t.x)});const e=t.outgoingEdges.length;for(let n=0;n<e;n++){const s=t.outgoingEdges[n],o=t.outgoingEdges[(n-1+e)%e];s.twin&&(s.twin.next=o)}}const d=[];let u=0,p=null,f=-1/0;for(const t of h){if(t.visited)continue;const e={id:u++,outerComponent:t,innerComponents:[],isOuterFace:!1};d.push(e);let n=t;const s=[],o=[],i=new Set;let r=0;do{if(!n||n.visited){console.warn("Face traversal encountered visited edge or null, breaking loop.",e.id),s.length=0;break}n.visited=!0,n.face=e,s.push(n),o.push(n.origin),null!==n.connectionName&&i.add(n.connectionName);const t=n.origin,a=n.twin.origin;r+=t.x*a.y-a.x*t.y,n=n.next}while(n!==t&&null!==n);if(n===t){if(r=.5*Math.abs(r),r>f&&(f=r,p&&(p.isOuterFace=!1),p=e,e.isOuterFace=!0),!e.isOuterFace&&s.length>0){if([...i].filter(t=>null!==t).length>1){let t=!1;for(const e of o)if(e.isVia){t=!0;break}if(!t)return!0}}}else console.warn(`Face ${e.id} did not close properly.`),d.pop(),u--}return!1}var As=t=>{if(0===t.length)return[[]];const e=[];for(let n=0;n<t.length;n++){const s=t[n],o=[...t.slice(0,n),...t.slice(n+1)],i=As(o);for(const t of i)e.push([s,...t])}return e},zs=1e-9;function Ds(t,e,n=1e-9){return Math.abs(t-e)<n}function Ls(t,e,n,s){return t*s-e*n}function Fs(t,e,n,s){const o={x:e.x-t.x,y:e.y-t.y},i={x:s.x-n.x,y:s.y-n.y},r=Ls(o.x,o.y,i.x,i.y);if(Ds(r,0))return null;const a={x:n.x-t.x,y:n.y-t.y},c=Ls(a.x,a.y,i.x,i.y)/r,h=Ls(a.x,a.y,o.x,o.y)/r;return c<-1e-9||c>1+zs||h<-1e-9||h>1+zs?null:{x:t.x+c*o.x,y:t.y+c*o.y}}function Ys(t){let e=0;for(let n=0,s=t.length;n<s;++n){const o=(n+1)%s;e+=t[n].x*t[o].y-t[o].x*t[n].y}return.5*e}function Xs(t){let e=0,n=0,s=0;for(let o=0,i=t.length;o<i;++o){const r=(o+1)%i,a=t[o].x*t[r].y-t[r].x*t[o].y;e+=a,n+=(t[o].x+t[r].x)*a,s+=(t[o].y+t[r].y)*a}return e*=.5,Ds(e,0)?null:(n/=6*e,s/=6*e,{x:n,y:s})}var ks=class{x;y;out;connectionNames;constructor(t,e){this.x=t,this.y=e,this.out=[],this.connectionNames=new Set}},$s=class{orig;dest;twin;next;visited;constructor(t,e){this.orig=t,this.dest=e,this.twin=null,this.next=null,this.visited=!1}};function Bs(t,e){const n=[...e,...[{start:{x:t.minX,y:t.minY},end:{x:t.maxX,y:t.minY}},{start:{x:t.maxX,y:t.minY},end:{x:t.maxX,y:t.maxY}},{start:{x:t.maxX,y:t.maxY},end:{x:t.minX,y:t.maxY}},{start:{x:t.minX,y:t.maxY},end:{x:t.minX,y:t.minY}}]],s=n.map(()=>[]);for(let t=0;t<n.length;++t){const e=n[t];s[t].push(e.start,e.end)}for(let t=0;t<n.length;++t)for(let e=t+1;e<n.length;++e){const o=Fs(n[t].start,n[t].end,n[e].start,n[e].end);o&&(s[t].push(o),s[e].push(o))}const o=new Map,i=[];function r(t){const e=function(t,e=1e-9){return`${Math.round(t.x/e)}:${Math.round(t.y/e)}`}(t);if(!o.has(e)){const n=i.length;return o.set(e,n),i.push(new ks(t.x,t.y)),n}return o.get(e)}const a=[];for(let t=0;t<n.length;++t){const e=n[t],o=s[t].slice();o.sort((t,n)=>{const s=e.end.x-e.start.x,o=e.end.y-e.start.y;return(Ds(Math.abs(s),0)?(t.y-e.start.y)/o:(t.x-e.start.x)/s)-(Ds(Math.abs(s),0)?(n.y-e.start.y)/o:(n.x-e.start.x)/s)});for(let t=0;t<o.length-1;++t){const n=o[t],s=o[t+1],c=r(n),h=r(s);c!==h&&(a.push([c,h]),e.connectionName&&(i[c].connectionNames.add(e.connectionName),i[h].connectionNames.add(e.connectionName)))}}const c=[];for(const[t,e]of a){const n=new $s(t,e),s=new $s(e,t);n.twin=c.length+1,s.twin=c.length;const o=c.length;c.push(n,s),i[t].out.push(o),i[e].out.push(o+1)}for(let t=0;t<i.length;++t){const e=i[t];e.out.sort((t,n)=>{const s=c[t],o=c[n],r=i[s.dest],a=i[o.dest];return Math.atan2(r.y-e.y,r.x-e.x)-Math.atan2(a.y-e.y,a.x-e.x)});const n=e.out.length;for(let t=0;t<n;++t){const s=e.out[t],o=e.out[(t-1+n)%n],i=c[s];null!==i.twin&&(c[i.twin].next=o)}}const h=[],l=[];for(let t=0;t<c.length;++t){if(c[t].visited)continue;let e=t;const n=[],s=[];do{if(null===e)break;const t=c[e];t.visited=!0,n.push(i[t.orig]),s.push(e),e=t.next}while(null!==e&&e!==t&&!c[e].visited);if(n.length<3)continue;if(Ys(n)>zs){const t=Xs(n);t&&(h.push(t),l.push({vertices:n.map(t=>({x:t.x,y:t.y,connectionNames:t.connectionNames.size>0?t.connectionNames:void 0})),centroid:t}))}}return{centroids:h,faces:l,allVertices:i}}function js(t,e){if(t>e)throw new Error("oneCount cannot be greater than length");if(t<0||e<0)throw new Error("oneCount and length must be non-negative");const n=[];return function t(s,o,i){i!==e?(s[i]=0,t(s,o,i+1),o>0&&(s[i]=1,t(s,o-1,i+1))):0===o&&n.push([...s])}(Array(e).fill(0),t,0),n}var Ws=class extends Ln{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver"}nodeWithPortPoints;colorMap;hyperParameters;connMap;candidates;bounds;solvedRoutes=[];unsolvedConnections=[];SEGMENTS_PER_POLYLINE;cellSize;MAX_CANDIDATES=5e4;viaDiameter=.3;obstacleMargin=.1;traceWidth=.15;availableZ=[];uniqueConnections=0;BOUNDARY_PADDING;lastCandidate=null;maxViaCount;minViaCount;phase="setup";progress=0;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??Ps(t.nodeWithPortPoints),this.hyperParameters=t.hyperParameters??{},this.SEGMENTS_PER_POLYLINE=t.hyperParameters?.SEGMENTS_PER_POLYLINE??3,this.BOUNDARY_PADDING=t.hyperParameters?.BOUNDARY_PADDING??.05,this.connMap=t.connMap,this.viaDiameter=t.viaDiameter??this.viaDiameter,this.cellSize=this.nodeWithPortPoints.width/1024,this.candidates=[],this.availableZ=this.nodeWithPortPoints.availableZ??[0,1],this.bounds={minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2};const e=this.nodeWithPortPoints.width*this.nodeWithPortPoints.height,n=(this.viaDiameter+2*this.obstacleMargin+this.traceWidth/2)**2,s=new Set(this.nodeWithPortPoints.portPoints.map(t=>t.connectionName)).size;this.uniqueConnections=s;const{numSameLayerCrossings:o,numEntryExitLayerChanges:i}=Ns(this.nodeWithPortPoints);if(this.minViaCount=2*o+i,this.maxViaCount=Math.min(Math.floor(e/n),Math.ceil(1.5*s)),this.minViaCount>this.SEGMENTS_PER_POLYLINE*(s/2))return this.failed=!0,void(this.error=`Not possible to solve problem with given SEGMENTS_PER_POLYLINE (${this.SEGMENTS_PER_POLYLINE}), atleast ${this.minViaCount} vias are required`);this.maxViaCount>this.SEGMENTS_PER_POLYLINE&&(this.maxViaCount=this.SEGMENTS_PER_POLYLINE),this.maxViaCount<this.minViaCount&&(this.maxViaCount=this.minViaCount)}computeMinGapBtwPolyLines(t){const e=[],n=[],s=[];for(let e=0;e<t.length;e++){const o=t[e],i=[o.start,...o.mPoints,o.end],r=new Map(this.availableZ.map(t=>[t,[]]));for(let t=0;t<i.length-1;t++){const e=[i[t],i[t+1]],n=e[0].z2;r.has(n)||r.set(n,[]),r.get(n).push(e)}n.push(r),s.push(i.filter(t=>t.z1!==t.z2))}for(let o=0;o<t.length;o++){const i=n[o],r=s[o];for(let a=o+1;a<t.length;a++){if(this.connMap?.areIdsConnected(t[o].connectionName,t[a].connectionName))continue;const c=n[a],h=s[a];let l=1;for(const t of this.availableZ){const e=i.get(t)??[],n=c.get(t)??[];for(const t of e)for(const e of n)l=Math.min(l,K(t[0],t[1],e[0],e[1])-this.traceWidth);for(const t of r)for(const e of n)l=Math.min(l,X(t,e[0],e[1])-this.traceWidth/2-this.viaDiameter/2);for(const t of h)for(const n of e)l=Math.min(l,X(t,n[0],n[1])-this.traceWidth/2-this.viaDiameter/2);for(const t of r)for(const e of h)l=Math.min(l,k(t,e)-this.viaDiameter)}e.push(l)}}return e}insertCandidate(t){let e=0,n=this.candidates.length-1;for(;e<=n;){const s=Math.floor((e+n)/2);this.candidates[s].f<t.f?e=s+1:n=s-1}this.candidates.splice(e,0,t)}setupInitialPolyLines(){const t=new Map;this.nodeWithPortPoints.portPoints.forEach(e=>{t.has(e.connectionName)?t.get(e.connectionName).end={...e,z1:e.z??0,z2:e.z??0}:t.set(e.connectionName,{start:{...e,z1:e.z??0,z2:e.z??0},end:null})});for(const[e,n]of t.entries())null===n.end&&t.delete(e);if(0===t.size)return this.failed=!0,void(this.error="No port pairs found, can't solve");const e=Array.from(t.entries()),n=((t,e,n,s)=>{const o=[];for(const[,n]of t){const t=n.start.z1!==n.end.z1,s=[];for(let n=0;n<=e;n++){const e=n%2!=0;t&&e?s.push(n):t||e||s.push(n)}o.push(s)}if(0===o.length)return[[]];let i=(t=>{if(!t||0===t.length)return[[]];let e=[[]];for(const n of t){const t=[];for(const s of e)for(const e of n)t.push([...s,e]);e=t}return e})(o).filter(t=>{for(let e=0;e<t.length;e++)if(t.reduce((t,e)=>t+e,0)<s)return!1;return!0});return i=i.filter(e=>{for(let n=0;n<t.length;n++){const[,s]=t[n];if(s.start.z1!==s.start.z2&&0===e[n])return!1}return!0}),i=i.filter(e=>{for(let n=0;n<t.length;n++){const[,s]=t[n];if(t[n][1].start.z1===t[n][1].start.z2)for(let o=n+1;o<t.length;o++){if(t[o][1].start.z1!==t[o][1].start.z2)continue;const[,i]=t[o];if(s.start.z1===s.end.z1&&i.start.z1===i.end.z1&&s.start.z1===i.start.z1&&L(s.start,s.end,i.start,i.end)&&e[n]+e[o]<2)return!1}}return!0}),i=i.filter(t=>!(t.reduce((t,e)=>t+e,0)>n)),i})(e,this.SEGMENTS_PER_POLYLINE,this.maxViaCount,this.minViaCount),s=(t=>{const{bounds:e,portPairsEntries:n,viaCountVariants:s}=t,{centroids:o}=Bs(e,n.map(([t,e])=>e)),i=[];for(const t of s){const n=t.reduce((t,e)=>t+e,0);let s=o;if(o.length<n){s=[];const t=Math.ceil(Math.sqrt(n)),o=t;for(let n=0;n<t;n++)for(let i=0;i<o;i++)s.push({x:e.minX+(i+1)/(o+1)*(e.maxX-e.minX),y:e.minY+(n+1)/(t+1)*(e.maxY-e.minY)})}const r=js(n,s.length);for(const e of r){const n=[];for(let t=0;t<e.length;t++)1===e[t]&&n.push(s[t]);i.push({viaPositions:n,viaCountVariant:t})}}return i})({portPairsEntries:e,viaCountVariants:n,bounds:this.bounds}),o=[];for(const{viaCountVariant:t,viaPositions:e}of s){const n=As(e);for(const e of n)o.push({viaCountVariant:t,viaPositions:e})}for(const{viaPositions:t,viaCountVariant:n}of o){const s=[];let o=0;for(let i=0;i<e.length;i++){const[r,a]=e[i],c=n[i],h=t.slice(o,o+c),l=Is({start:a.start,end:a.end,segmentsPerPolyline:this.SEGMENTS_PER_POLYLINE,viaPositions:h,viaCount:c,availableZ:this.availableZ});o+=c,s.push({connectionName:r,start:a.start,end:a.end,mPoints:l})}if(Os(s,this.bounds))continue;const i=this.computeMinGapBtwPolyLines(s),r=this.computeH({minGaps:i,forces:[]}),a={polyLines:s,g:0,h:r,f:r,viaCount:n.reduce((t,e)=>t+e,0),minGaps:i};if(this.checkIfSolved(a))return void(this.candidates=[a]);if(this.candidates.push(a),this.candidates.length>this.MAX_CANDIDATES)return}this.candidates.sort((t,e)=>t.f-e.f)}computeG(t,e){return e.g+5e-6+5e-6*e.viaCount*100}computeH(t){let e=0;for(const n of t.forces??[])for(const t of n)for(const n of t.values())e+=n.fx*n.fx+n.fy*n.fy;return e}getNeighbors(t){const{polyLines:e}=t,n=e.length,s=.02,o=.008,i=1e-6,r=Array.from({length:n},(t,n)=>Array.from({length:e[n].mPoints.length},()=>new Map)),a=(t,n,s,o,i)=>{if(n>0&&n<e[t].mPoints.length+1){const e=n-1,a=r[t][e],c=a.get(s)||{fx:0,fy:0};a.set(s,{fx:c.fx+o,fy:c.fy+i})}};for(let t=0;t<n;t++)for(let o=t+1;o<n;o++){const n=e[t],r=e[o],c=[n.start,...n.mPoints,n.end],h=[r.start,...r.mPoints,r.end],l=[],d=[];for(let t=0;t<c.length-1;t++)l.push({p1:c[t],p2:c[t+1],layer:c[t].z2,p1Idx:t,p2Idx:t+1});c.forEach((t,e)=>{t.z1!==t.z2&&d.push({point:t,layers:[t.z1,t.z2],index:e})});const u=[],p=[];for(let t=0;t<h.length-1;t++)u.push({p1:h[t],p2:h[t+1],layer:h[t].z2,p1Idx:t,p2Idx:t+1});h.forEach((t,e)=>{t.z1!==t.z2&&p.push({point:t,layers:[t.z1,t.z2],index:e})});for(const e of l)for(const n of u)if(e.layer===n.layer){if(K(e.p1,e.p2,n.p1,n.p2)<i)continue;const s={x:(e.p1.x+e.p2.x)/2,y:(e.p1.y+e.p2.y)/2},r={x:(n.p1.x+n.p2.x)/2,y:(n.p1.y+n.p2.y)/2},c=s.x-r.x,h=s.y-r.y,l=c*c+h*h;if(l>i){const s=Math.sqrt(l),r=(Math.exp(-6*s),`seg:${o}:${n.p1Idx}:${n.p2Idx}`),c=`seg:${t}:${e.p1Idx}:${e.p2Idx}`,h=(t,e,n,s,o,r,c)=>{const h=tt(t,n.p1,n.p2),l=t.x-h.x,d=t.y-h.y,u=l*l+d*d;if(u<=i)return;const p=Math.sqrt(u),f=.02*Math.exp(-6*p),m=l/p*f,g=d/p*f;a(s,e,r,m,g),a(o,n.p1Idx,c,-m/2,-g/2),a(o,n.p2Idx,c,-m/2,-g/2)};h(e.p1,e.p1Idx,n,t,o,r,c),h(e.p2,e.p2Idx,n,t,o,r,c),h(n.p1,n.p1Idx,e,o,t,c,r),h(n.p2,n.p2Idx,e,o,t,c,r)}}for(const e of d)for(const n of u)if(e.layers.includes(n.layer)){const r=tt(e.point,n.p1,n.p2),c=e.point.x-r.x,h=e.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p,g=`seg:${o}:${n.p1Idx}:${n.p2Idx}`;a(t,e.index,g,f,m);const y=`via:${t}:${e.index}`;a(o,n.p1Idx,y,-f/2,-m/2),a(o,n.p2Idx,y,-f/2,-m/2)}}for(const e of p)for(const n of l)if(e.layers.includes(n.layer)){const r=tt(e.point,n.p1,n.p2),c=e.point.x-r.x,h=e.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p,g=`seg:${t}:${n.p1Idx}:${n.p2Idx}`;a(o,e.index,g,f,m);const y=`via:${o}:${e.index}`;a(t,n.p1Idx,y,-f/2,-m/2),a(t,n.p2Idx,y,-f/2,-m/2)}}for(const e of d)for(const n of p){if(e.layers.filter(t=>n.layers.includes(t)).length>0){const r=e.point.x-n.point.x,c=e.point.y-n.point.y,h=r*r+c*c;if(h>i){const l=Math.sqrt(h);let d=2,u=l;l<this.viaDiameter?(d*=4,u=Math.max(i,l)):u=Math.max(i,l-this.viaDiameter);const p=d*s*Math.exp(-6*u),f=r/l*p,m=c/l*p,g=`via:${o}:${n.index}`,y=`via:${t}:${e.index}`;a(t,e.index,g,f,m),a(o,n.index,y,-f,-m)}}}}for(let t=0;t<n;t++){const n=e[t],o=[n.start,...n.mPoints,n.end],r=[];if(o.forEach((t,e)=>{t.z1!==t.z2&&r.push({point:t,layers:[t.z1,t.z2],index:e})}),!(r.length<2))for(let e=0;e<r.length;e++)for(let n=e+1;n<r.length;n++){const o=r[e],c=r[n],h=o.point.x-c.point.x,l=o.point.y-c.point.y,d=h*h+l*l;if(d>i){const e=Math.sqrt(d);let n=2,r=e;e<this.viaDiameter?(n*=4,r=Math.max(i,e)):r=Math.max(i,e-this.viaDiameter);const u=n*s*Math.exp(-6*r),p=h/e*u,f=l/e*u,m=`via:${t}:${c.index}`,g=`via:${t}:${o.index}`;a(t,o.index,m,p,f),a(t,c.index,g,-p,-f)}}}const c=e.map(t=>({...t,mPoints:t.mPoints.map(t=>({...t}))}));let h=!1;for(let t=0;t<n;t++)for(let e=0;e<c[t].mPoints.length;e++){const n=c[t].mPoints[e],s=r[t][e],a={fx:0,fy:0};for(const t of s.values())a.fx+=t.fx,a.fy+=t.fy;const l=n.z1!==n.z2;let d=n.x+a.fx,u=n.y+a.fy;if(l){const t=this.viaDiameter/2;let e=0,s=0;const i=this.viaDiameter/2+this.BOUNDARY_PADDING,r=this.bounds.minX+i,c=this.bounds.maxX-i,h=this.bounds.minY+i,l=this.bounds.maxY-i,p=r+t-n.x,f=n.x-(c-t),m=h+t-n.y,g=n.y-(l-t);p>0?e=o*(Math.exp(p/(2*this.obstacleMargin))-1):f>0&&(e=-.008*(Math.exp(f/(2*this.obstacleMargin))-1)),m>0?s=o*(Math.exp(m/(2*this.obstacleMargin))-1):g>0&&(s=-.008*(Math.exp(g/(2*this.obstacleMargin))-1)),a.fx+=e,a.fy+=s,d=n.x+a.fx,u=n.y+a.fy}else{const t=this.traceWidth/2+this.BOUNDARY_PADDING;d=Math.max(this.bounds.minX+t,Math.min(this.bounds.maxX-t,d)),u=Math.max(this.bounds.minY+t,Math.min(this.bounds.maxY-t,u))}Math.abs(a.fx)<i&&Math.abs(a.fy)<i||(Math.abs(n.x-d)>i||Math.abs(n.y-u)>i)&&(n.x=d,n.y=u,h=!0)}if(!h)return[];const l=this.computeMinGapBtwPolyLines(c),d=this.computeG(c,t),u=this.computeH({minGaps:l,forces:r});return[{polyLines:c,g:d,h:u,f:Math.round(5*d)/5+u,minGaps:l,forces:r,viaCount:t.viaCount}]}checkIfSolved(t){const e=t.minGaps.every(t=>t>=this.obstacleMargin),n=t.polyLines.every(t=>t.mPoints.every(t=>{const e=(t.z1!==t.z2?this.viaDiameter/2:this.traceWidth/2)+this.BOUNDARY_PADDING;return((t,e,n=0)=>t.x>=e.minX+n&&t.x<=e.maxX-n&&t.y>=e.minY+n&&t.y<=e.maxY-n)(t,this.bounds,e)}));return e&&n}tryFinalAcceptance(){const t=this.hyperParameters?.MINIMUM_FINAL_ACCEPTANCE_GAP??void 0;if(void 0===t||null===this.lastCandidate||0===this.lastCandidate.minGaps.length)return;return Math.min(...this.lastCandidate.minGaps)>=t?(this.solved=!0,void this._setSolvedRoutes()):void 0}_step(){if("setup"===this.phase)return this.setupInitialPolyLines(),void(this.phase="solving");const t=this.candidates.shift();if(!t){if(this.tryFinalAcceptance(),this.solved)return;return this.failed=!0,void(this.error="No candidates left")}if(this.lastCandidate=t,this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();if(!t)return void(this.failed=!0);const e=this.getNeighbors(t);for(const t of e)this.insertCandidate(t)}visualize(){const t={points:[],lines:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"MultiHeadPolyLineIntraNodeSolver Visualization"};t.lines.push({points:[{x:this.bounds.minX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.minY}],strokeColor:"gray"});const e=this.lastCandidate??this.candidates[0];if(e?.hasClosedSameLayerFace){const e=.1*(this.bounds.maxX-this.bounds.minX),n=.1*(this.bounds.maxY-this.bounds.minY);t.rects.push({center:{x:this.bounds.maxX+.6*e,y:this.bounds.maxY+.6*n},width:e,height:n,fill:"red",label:"HAS CLOSED FACE"})}for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:`${e.connectionName} (Port z=${e.z??0})`,color:this.colorMap[e.connectionName]??"blue"});return e&&e.polyLines.forEach((n,s)=>{const o=this.colorMap[n.connectionName]??"purple",i=[n.start,...n.mPoints,n.end];for(let e=0;e<i.length-1;e++){const s=i[e],r=i[e+1],a=s.z2,c=0===a,h=c?o:In(o,.5);t.lines.push({points:[s,r],strokeColor:h,strokeWidth:this.traceWidth,strokeDash:c?void 0:[.15,.15],label:`${n.connectionName} segment (z=${a})`})}i.forEach((r,a)=>{const c=r.z1!==r.z2,h=r.z1,l=a>0&&a<i.length-1;let d="",u="";if(l){const o=a-1,i=e.forces?.[s]?.[o];if(i&&i.size>0){const s={fx:0,fy:0};i.forEach((i,a)=>{if(s.fx+=i.fx,s.fy+=i.fy,Math.abs(i.fx)>1e-6||Math.abs(i.fy)>1e-6){const s=a.split(":"),c=s[0],h=parseInt(s[1],10),l=e.polyLines[h],d=this.colorMap[l.connectionName]??"gray",u=20,p={x:r.x+i.fx*u,y:r.y+i.fy*u};let f=l.connectionName;if("via"===c){f+=` Via ${parseInt(s[2],10)}`}else if("seg"===c){f+=` Seg ${parseInt(s[2],10)}-${parseInt(s[3],10)}`}t.lines.push({points:[r,p],strokeColor:d,strokeWidth:.02,strokeDash:"2,2",label:`Force by ${f} on ${n.connectionName} mPoint ${o}`})}}),(Math.abs(s.fx)>1e-6||Math.abs(s.fy)>1e-6)&&(u=`\nNet Force: (${s.fx.toFixed(3)}, ${s.fy.toFixed(3)})`)}}if(c)d=`Via (${n.connectionName} z=${r.z1} -> z=${r.z2})${u}`,t.circles.push({center:r,radius:this.viaDiameter/2,fill:In(o,.5),label:d});else if(l){const e=0===h?o:In(o,.5);d=`mPoint (${n.connectionName} z=${h})${u}`,t.circles.push({center:r,radius:this.cellSize/8,fill:e,label:d})}})}),t}_setSolvedRoutes(){if(!this.solved||!this.lastCandidate)return[];const t=[];for(const e of this.lastCandidate.polyLines){const n=[],s=[],o=[e.start,...e.mPoints,e.end];for(let t=0;t<o.length;t++){const e=o[t];n.push({x:e.x,y:e.y,z:e.z1}),e.z1!==e.z2&&(s.push({x:e.x,y:e.y}),n.push({x:e.x,y:e.y,z:e.z2}))}t.push({connectionName:e.connectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:n,vias:s})}this.solvedRoutes=t}},Hs=class extends Ws{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver2"}computeG(t,e){return e.g+5e-6+5e-6*e.viaCount*100}computeH(t){const{minGaps:e}=t;let n=0;for(const t of e)t<0&&(n+=this.obstacleMargin),t<this.obstacleMargin&&(n+=this.obstacleMargin-t);return.011*n}_step(){if("setup"===this.phase)return this.setupInitialPolyLines(),void(this.phase="solving");const t=this.candidates.shift();if(!t){if(this.tryFinalAcceptance(),this.solved)return;return void(this.failed=!0)}if(this.lastCandidate=t,this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();let e=!1,n=0;const s=void 0===t.magForceApplied?1:10;for(let o=0;o<s;o++){const s=this.applyForcesToPolyLines(t.polyLines);if(n+=s.magForceApplied,e=s.lastStepMoved,!s.lastStepMoved)break}if(t.magForceApplied=n,t.minGaps=this.computeMinGapBtwPolyLines(t.polyLines),this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();t.g=this.computeG(t.polyLines,t),t.h=this.computeH(t),t.f=t.g+t.h,e&&this.insertCandidate(t)}applyForcesToPolyLines(t){let e=0;const n=t.length,s=.02,o=.008,i=1e-6,r=Array.from({length:n},(e,n)=>Array.from({length:t[n].mPoints.length},()=>({fx:0,fy:0}))),a=(e,n,s,o)=>{if(n>0&&n<t[e].mPoints.length+1){const t=n-1;r[e][t].fx+=s,r[e][t].fy+=o}},c=(t,e,n,s,o)=>{const r=tt(t,n.p1,n.p2),c=t.x-r.x,h=t.y-r.y,l=c*c+h*h;if(l<=i)return;const d=Math.sqrt(l),u=.02*Math.exp(-6*d),p=c/d*u,f=h/d*u;a(s,e,p,f),a(o,n.p1Idx,-p/2,-f/2),a(o,n.p2Idx,-p/2,-f/2)};for(let e=0;e<n;e++)for(let o=e+1;o<n;o++){const n=t[e],r=t[o],h=[n.start,...n.mPoints,n.end],l=[r.start,...r.mPoints,r.end],d=[],u=[];for(let t=0;t<h.length-1;t++)d.push({p1:h[t],p2:h[t+1],layer:h[t].z2,p1Idx:t,p2Idx:t+1});h.forEach((t,e)=>{t.z1!==t.z2&&u.push({point:t,layers:[t.z1,t.z2],index:e})});const p=[],f=[];for(let t=0;t<l.length-1;t++)p.push({p1:l[t],p2:l[t+1],layer:l[t].z2,p1Idx:t,p2Idx:t+1});l.forEach((t,e)=>{t.z1!==t.z2&&f.push({point:t,layers:[t.z1,t.z2],index:e})});for(const t of d)for(const n of p)if(t.layer===n.layer){K(t.p1,t.p2,n.p1,n.p2);c(t.p1,t.p1Idx,n,e,o),c(t.p2,t.p2Idx,n,e,o),c(n.p1,n.p1Idx,t,o,e),c(n.p2,n.p2Idx,t,o,e)}for(const t of u)for(const n of p)if(t.layers.includes(n.layer)){const r=tt(t.point,n.p1,n.p2),c=t.point.x-r.x,h=t.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p;a(e,t.index,f,m),a(o,n.p1Idx,-f/2,-m/2),a(o,n.p2Idx,-f/2,-m/2)}}for(const t of f)for(const n of d)if(t.layers.includes(n.layer)){const r=tt(t.point,n.p1,n.p2),c=t.point.x-r.x,h=t.point.y-r.y,l=c*c+h*h;if(l>i){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(i,r)):u=Math.max(i,r-this.viaDiameter/2);const p=d*s*Math.exp(-6*u),f=c/r*p,m=h/r*p;a(o,t.index,f,m),a(e,n.p1Idx,-f/2,-m/2),a(e,n.p2Idx,-f/2,-m/2)}}for(const t of u)for(const n of f){if(t.layers.filter(t=>n.layers.includes(t)).length>0){const r=t.point.x-n.point.x,c=t.point.y-n.point.y,h=r*r+c*c;if(h>i){const l=Math.sqrt(h);let d=2,u=l;l<this.viaDiameter?(d*=4,u=Math.max(i,l)):u=Math.max(i,l-this.viaDiameter);const p=d*s*Math.exp(-6*u),f=r/l*p,m=c/l*p;a(e,t.index,f,m),a(o,n.index,-f,-m)}}}}for(let e=0;e<n;e++){const n=t[e],o=[n.start,...n.mPoints,n.end],r=[];if(o.forEach((t,e)=>{t.z1!==t.z2&&r.push({point:t,layers:[t.z1,t.z2],index:e})}),!(r.length<2))for(let t=0;t<r.length;t++)for(let n=t+1;n<r.length;n++){const o=r[t],c=r[n],h=o.point.x-c.point.x,l=o.point.y-c.point.y,d=h*h+l*l;if(d>i){const t=Math.sqrt(d);let n=2,r=t;t<this.viaDiameter?(n*=4,r=Math.max(i,t)):r=Math.max(i,t-this.viaDiameter);const u=n*s*Math.exp(-6*r),p=h/t*u,f=l/t*u;a(e,o.index,p,f),a(e,c.index,-p,-f)}}}let h=!1;for(let s=0;s<n;s++)for(let n=0;n<t[s].mPoints.length;n++){const a=t[s].mPoints[n],c=r[s][n],l=a.z1!==a.z2;let d=c.fx,u=c.fy,p=a.x+d,f=a.y+u;if(l){const t=this.viaDiameter/2;let e=0,n=0;const s=this.viaDiameter/2+this.BOUNDARY_PADDING,i=this.bounds.minX+s,r=this.bounds.maxX-s,c=this.bounds.minY+s,h=this.bounds.maxY-s,l=i+t-a.x,m=a.x-(r-t),g=c+t-a.y,y=a.y-(h-t);l>0?e=o*(Math.exp(l/(2*this.obstacleMargin))-1):m>0&&(e=-.008*(Math.exp(m/(2*this.obstacleMargin))-1)),g>0?n=o*(Math.exp(g/(2*this.obstacleMargin))-1):y>0&&(n=-.008*(Math.exp(y/(2*this.obstacleMargin))-1)),d+=e,u+=n,p=a.x+d,f=a.y+u}else{const t=this.traceWidth/2+this.BOUNDARY_PADDING;p=Math.max(this.bounds.minX+t,Math.min(this.bounds.maxX-t,p)),f=Math.max(this.bounds.minY+t,Math.min(this.bounds.maxY-t,f))}if(Math.abs(d)<i&&Math.abs(u)<i)continue;e+=Math.sqrt(d*d+u*u),(Math.abs(a.x-p)>i||Math.abs(a.y-f)>i)&&(a.x=p,a.y=f,h=!0)}return{lastStepMoved:h,magForceApplied:e}}},Us=t=>t.flatMap(t=>`${t.connectionName}-${t.mPoints.map(t=>`${t.x.toFixed(2)},${t.y.toFixed(2)},${t.z1},${t.z2}`)}`).sort().join("|");var Vs=class extends Hs{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver3"}constructor(t){super(t),this.MAX_ITERATIONS=1e3}createInitialCandidateFromSeed(t){const e=new Ss({nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,hyperParameters:{SHUFFLE_SEED:t},viaDiameter:this.viaDiameter});if(e.solve(),e.failed||!e.solved)return this.failed=!0,this.error=`ViaPossibilitiesSolver2 failed with: ${e.error}`,null;const n=[];let s=0;for(const[t,o]of e.completedPaths.entries()){if(o.length<2){console.warn(`Skipping connection "${t}" due to insufficient points (${o.length}) in ViaPossibilitiesSolver2 path.`);continue}const e=o[0],i=o[o.length-1],r=o.slice(1,-1),a=[];let c=0,h=e.z;for(let t=0;t<r.length;t++){const e=r[t],n=t+1<r.length?r[t+1]:i,s=h,o=t+1<r.length&&e.x===n.x&&e.y===n.y&&e.z!==n.z?n.z:e.z;a.push({x:e.x,y:e.y,z1:s,z2:o}),s!==o?(c++,t++,h=o):h=e.z}s+=c;const l=this.SEGMENTS_PER_POLYLINE;let d=a.length+1;for(;d<l;){let n=-1,s=-1,o=null,r=null;const c=[{...e,z1:e.z,z2:e.z,connectionName:t},...a,{...i,z1:i.z,z2:i.z,connectionName:t}];for(let t=0;t<c.length-1;t++){const e=c[t],i=c[t+1];if(e.x===i.x&&e.y===i.y)continue;const a=k(e,i);a>n&&(n=a,s=t,o=e,r=i)}if(-1===s||!o||!r){console.warn(`Could not find longest segment for ${t} while trying to reach ${l} segments.`);break}const h=(o.x+r.x)/2,u=(o.y+r.y)/2,p=o.z2,f={x:h,y:u,z1:p,z2:p};a.splice(s,0,f),d++}n.push({connectionName:t,start:{...e,z1:e.z,z2:e.z},end:{...i,z1:i.z,z2:i.z},mPoints:a})}if(0===n.length)return this.failed=!0,this.error="No valid polylines generated from ViaPossibilitiesSolver2.",console.error(this.error),null;const o=this.computeMinGapBtwPolyLines(n),i=this.computeH({minGaps:o,forces:[]}),r={polyLines:n,g:0,h:i,f:0+i,viaCount:s,minGaps:o};return r.g=this.computeG(n,r),r.f=r.g+r.h,r}setupInitialPolyLines(){this.candidates=[];const t=Math.min(2e3,function(t){if(!Number.isInteger(t)||t<0)throw new RangeError("n must be a non-negative integer");let e=1;for(let n=2;n<=t;n++)e*=n;return e}(this.uniqueConnections)),e=new Set;for(let n=0;n<t;n++){const t=this.createInitialCandidateFromSeed(n);if(!t)continue;const s=Us(t.polyLines);e.has(s)||(e.add(s),this.candidates.push(t))}this.candidates.sort((t,e)=>t.f-e.f)}};import{HighDensitySolverA01 as Gs,HighDensitySolverA02 as Zs}from"@tscircuit/high-density-a01";var qs=Object.create,Js=Object.defineProperty,Ks=Object.getOwnPropertyDescriptor,Qs=Object.getOwnPropertyNames,to=Object.getPrototypeOf,eo=Object.prototype.hasOwnProperty,no=(t,e)=>function(){return e||(0,t[Qs(t)[0]])((e={exports:{}}).exports,e),e.exports},so=no({"node_modules/binary-search-bounds/search-bounds.js"(t,e){function n(t,e,n,s,o){for(var i=o+1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)>=0?(i=r,o=r-1):s=r+1}return i}function s(t,e,n,s,o){for(var i=o+1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)>0?(i=r,o=r-1):s=r+1}return i}function o(t,e,n,s,o){for(var i=s-1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)<0?(i=r,s=r+1):o=r-1}return i}function i(t,e,n,s,o){for(var i=s-1;s<=o;){var r=s+o>>>1,a=t[r];(void 0!==n?n(a,e):a-e)<=0?(i=r,s=r+1):o=r-1}return i}function r(t,e,n,s,o){for(;s<=o;){var i=s+o>>>1,r=t[i],a=void 0!==n?n(r,e):r-e;if(0===a)return i;a<=0?s=i+1:o=i-1}return-1}function a(t,e,n,s,o,i){return"function"==typeof n?i(t,e,n,void 0===s?0:0|s,void 0===o?t.length-1:0|o):i(t,e,void 0,void 0===n?0:0|n,void 0===s?t.length-1:0|s)}e.exports={ge:function(t,e,s,o,i){return a(t,e,s,o,i,n)},gt:function(t,e,n,o,i){return a(t,e,n,o,i,s)},lt:function(t,e,n,s,i){return a(t,e,n,s,i,o)},le:function(t,e,n,s,o){return a(t,e,n,s,o,i)},eq:function(t,e,n,s,o){return a(t,e,n,s,o,r)}}}}),oo=no({"node_modules/two-product/two-product.js"(t,e){e.exports=function(t,e,s){var o=t*e,i=n*t,r=i-(i-t),a=t-r,c=n*e,h=c-(c-e),l=e-h,d=a*l-(o-r*h-a*h-r*l);if(s)return s[0]=d,s[1]=o,s;return[d,o]};var n=+(Math.pow(2,27)+1)}}),io=no({"node_modules/robust-sum/robust-sum.js"(t,e){e.exports=function(t,e){var n=0|t.length,s=0|e.length;if(1===n&&1===s)return function(t,e){var n=t+e,s=n-t,o=n-s,i=e-s,r=t-o,a=r+i;if(a)return[a,n];return[n]}(t[0],e[0]);var o,i,r=new Array(n+s),a=0,c=0,h=0,l=Math.abs,d=t[c],u=l(d),p=e[h],f=l(p);u<f?(i=d,(c+=1)<n&&(u=l(d=t[c]))):(i=p,(h+=1)<s&&(f=l(p=e[h])));c<n&&u<f||h>=s?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=e[h])));var m,g,y=o+i,x=y-o,v=i-x,b=v,P=y;for(;c<n&&h<s;)u<f?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=e[h]))),(v=(i=b)-(x=(y=o+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m;for(;c<n;)(v=(i=b)-(x=(y=(o=d)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(c+=1)<n&&(d=t[c]);for(;h<s;)(v=(i=b)-(x=(y=(o=p)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(h+=1)<s&&(p=e[h]);b&&(r[a++]=b);P&&(r[a++]=P);a||(r[a++]=0);return r.length=a,r}}}),ro=no({"node_modules/two-sum/two-sum.js"(t,e){e.exports=function(t,e,n){var s=t+e,o=s-t,i=e-o,r=t-(s-o);if(n)return n[0]=r+i,n[1]=s,n;return[r+i,s]}}}),ao=no({"node_modules/robust-scale/robust-scale.js"(t,e){var n=oo(),s=ro();e.exports=function(t,e){var o=t.length;if(1===o){var i=n(t[0],e);return i[0]?i:[i[1]]}var r=new Array(2*o),a=[.1,.1],c=[.1,.1],h=0;n(t[0],e,a),a[0]&&(r[h++]=a[0]);for(var l=1;l<o;++l){n(t[l],e,c);var d=a[1];s(d,c[0],a),a[0]&&(r[h++]=a[0]);var u=c[1],p=a[1],f=u+p,m=p-(f-u);a[1]=f,m&&(r[h++]=m)}a[1]&&(r[h++]=a[1]);0===h&&(r[h++]=0);return r.length=h,r}}}),co=no({"node_modules/robust-subtract/robust-diff.js"(t,e){e.exports=function(t,e){var n=0|t.length,s=0|e.length;if(1===n&&1===s)return function(t,e){var n=t+e,s=n-t,o=n-s,i=e-s,r=t-o,a=r+i;if(a)return[a,n];return[n]}(t[0],-e[0]);var o,i,r=new Array(n+s),a=0,c=0,h=0,l=Math.abs,d=t[c],u=l(d),p=-e[h],f=l(p);u<f?(i=d,(c+=1)<n&&(u=l(d=t[c]))):(i=p,(h+=1)<s&&(f=l(p=-e[h])));c<n&&u<f||h>=s?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=-e[h])));var m,g,y=o+i,x=y-o,v=i-x,b=v,P=y;for(;c<n&&h<s;)u<f?(o=d,(c+=1)<n&&(u=l(d=t[c]))):(o=p,(h+=1)<s&&(f=l(p=-e[h]))),(v=(i=b)-(x=(y=o+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m;for(;c<n;)(v=(i=b)-(x=(y=(o=d)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(c+=1)<n&&(d=t[c]);for(;h<s;)(v=(i=b)-(x=(y=(o=p)+i)-o))&&(r[a++]=v),b=P-((m=P+y)-(g=m-P))+(y-g),P=m,(h+=1)<s&&(p=-e[h]);b&&(r[a++]=b);P&&(r[a++]=P);a||(r[a++]=0);return r.length=a,r}}}),ho=no({"node_modules/robust-orientation/orientation.js"(t,e){var n=oo(),s=io(),o=ao(),i=co();function r(t,e,n,s){return function(n,o,i){var r=t(t(e(o[1],i[0]),e(-i[1],o[0])),t(e(n[1],o[0]),e(-o[1],n[0]))),a=t(e(n[1],i[0]),e(-i[1],n[0])),c=s(r,a);return c[c.length-1]}}function a(t,e,n,s){return function(o,i,r,a){var c=t(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),a[2])))),h=t(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),a[2]))),t(n(t(e(i[1],r[0]),e(-r[1],i[0])),o[2]),t(n(t(e(o[1],r[0]),e(-r[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),r[2])))),l=s(c,h);return l[l.length-1]}}function c(t,e,n,s){return function(o,i,r,a,c){var h=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-a[2]),n(t(e(r[1],a[0]),e(-a[1],r[0])),c[2]))),i[3]),t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-a[2]),n(t(e(i[1],a[0]),e(-a[1],i[0])),c[2]))),-r[3]),n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),c[2]))),a[3]))),t(n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),-c[3]),t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-a[2]),n(t(e(i[1],a[0]),e(-a[1],i[0])),c[2]))),o[3]),n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-a[2]),n(t(e(o[1],a[0]),e(-a[1],o[0])),c[2]))),-i[3])))),t(t(n(t(n(t(e(i[1],c[0]),e(-c[1],i[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),c[2]))),a[3]),t(n(t(n(t(e(i[1],a[0]),e(-a[1],i[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),a[2]))),-c[3]),n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),o[3]))),t(n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),a[2]))),-i[3]),t(n(t(n(t(e(i[1],a[0]),e(-a[1],i[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),a[2]))),r[3]),n(t(n(t(e(i[1],r[0]),e(-r[1],i[0])),o[2]),t(n(t(e(o[1],r[0]),e(-r[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),r[2]))),-a[3]))))),l=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-a[2]),n(t(e(r[1],a[0]),e(-a[1],r[0])),c[2]))),o[3]),n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-a[2]),n(t(e(o[1],a[0]),e(-a[1],o[0])),c[2]))),-r[3])),t(n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),c[2]))),a[3]),n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),o[2]),t(n(t(e(o[1],a[0]),e(-a[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),a[2]))),-c[3]))),t(t(n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),c[2]))),o[3]),n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-r[2]),n(t(e(o[1],r[0]),e(-r[1],o[0])),c[2]))),-i[3])),t(n(t(n(t(e(i[1],c[0]),e(-c[1],i[0])),o[2]),t(n(t(e(o[1],c[0]),e(-c[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),c[2]))),r[3]),n(t(n(t(e(i[1],r[0]),e(-r[1],i[0])),o[2]),t(n(t(e(o[1],r[0]),e(-r[1],o[0])),-i[2]),n(t(e(o[1],i[0]),e(-i[1],o[0])),r[2]))),-c[3])))),d=s(h,l);return d[d.length-1]}}function h(t){return(3===t?r:4===t?a:c)(s,n,o,i)}var l=h(3),d=h(4),u=[function(){return 0},function(){return 0},function(t,e){return e[0]-t[0]},function(t,e,n){var s,o=(t[1]-n[1])*(e[0]-n[0]),i=(t[0]-n[0])*(e[1]-n[1]),r=o-i;if(o>0){if(i<=0)return r;s=o+i}else{if(!(o<0))return r;if(i>=0)return r;s=-(o+i)}var a=33306690738754716e-32*s;return r>=a||r<=-a?r:l(t,e,n)},function(t,e,n,s){var o=t[0]-s[0],i=e[0]-s[0],r=n[0]-s[0],a=t[1]-s[1],c=e[1]-s[1],h=n[1]-s[1],l=t[2]-s[2],u=e[2]-s[2],p=n[2]-s[2],f=i*h,m=r*c,g=r*a,y=o*h,x=o*c,v=i*a,b=l*(f-m)+u*(g-y)+p*(x-v),P=7771561172376103e-31*((Math.abs(f)+Math.abs(m))*Math.abs(l)+(Math.abs(g)+Math.abs(y))*Math.abs(u)+(Math.abs(x)+Math.abs(v))*Math.abs(p));return b>P||-b>P?b:d(t,e,n,s)}];function p(t){var e=u[t.length];return e||(e=u[t.length]=h(t.length)),e.apply(void 0,t)}function f(t,e,n,s,o,i,r){return function(e,n,a,c,h){switch(arguments.length){case 0:case 1:return 0;case 2:return s(e,n);case 3:return o(e,n,a);case 4:return i(e,n,a,c);case 5:return r(e,n,a,c,h)}for(var l=new Array(arguments.length),d=0;d<arguments.length;++d)l[d]=arguments[d];return t(l)}}!function(){for(;u.length<=5;)u.push(h(u.length));e.exports=f.apply(void 0,[p].concat(u));for(var t=0;t<=5;++t)e.exports[t]=u[t]}()}}),lo=no({"node_modules/cdt2d/lib/monotone.js"(t,e){var n=so(),s=ho()[3];function o(t,e,n,s,o){this.a=t,this.b=e,this.idx=n,this.lowerIds=s,this.upperIds=o}function i(t,e,n,s){this.a=t,this.b=e,this.type=n,this.idx=s}function r(t,e){var n=t.a[0]-e.a[0]||t.a[1]-e.a[1]||t.type-e.type;return n||(0!==t.type&&(n=s(t.a,t.b,e.b))?n:t.idx-e.idx)}function a(t,e){return s(t.a,t.b,e)}function c(t,e,o,i,r){for(var c=n.lt(e,i,a),h=n.gt(e,i,a),l=c;l<h;++l){for(var d=e[l],u=d.lowerIds,p=u.length;p>1&&s(o[u[p-2]],o[u[p-1]],i)>0;)t.push([u[p-1],u[p-2],r]),p-=1;u.length=p,u.push(r);var f=d.upperIds;for(p=f.length;p>1&&s(o[f[p-2]],o[f[p-1]],i)<0;)t.push([f[p-2],f[p-1],r]),p-=1;f.length=p,f.push(r)}}function h(t,e){var n;return(n=t.a[0]<e.a[0]?s(t.a,t.b,e.a):s(e.b,e.a,t.a))?n:(n=e.b[0]<t.b[0]?s(t.a,t.b,e.b):s(e.b,e.a,t.b))||t.idx-e.idx}function l(t,e,s){var i=n.le(t,s,h),r=t[i],a=r.upperIds,c=a[a.length-1];r.upperIds=[c],t.splice(i+1,0,new o(s.a,s.b,s.idx,[c],a))}function d(t,e,s){var o=s.a;s.a=s.b,s.b=o;var i=n.eq(t,s,h),r=t[i];t[i-1].upperIds=r.upperIds,t.splice(i,1)}e.exports=function(t,e){for(var n=t.length,s=e.length,a=[],h=0;h<n;++h)a.push(new i(t[h],null,0,h));for(h=0;h<s;++h){var u=e[h],p=t[u[0]],f=t[u[1]];p[0]<f[0]?a.push(new i(p,f,2,h),new i(f,p,1,h)):p[0]>f[0]&&a.push(new i(f,p,2,h),new i(p,f,1,h))}a.sort(r);for(var m=a[0].a[0]-(1+Math.abs(a[0].a[0]))*Math.pow(2,-52),g=[new o([m,1],[m,0],-1,[],[],[],[])],y=[],x=(h=0,a.length);h<x;++h){var v=a[h],b=v.type;0===b?c(y,g,t,v.a,v.idx):2===b?l(g,t,v):d(g,t,v)}return y}}}),uo=no({"node_modules/cdt2d/lib/triangulation.js"(t,e){var n=so();function s(t,e){this.stars=t,this.edges=e}e.exports=function(t,e){for(var n=new Array(t),o=0;o<t;++o)n[o]=[];return new s(n,e)};var o=s.prototype;function i(t,e,n){for(var s=1,o=t.length;s<o;s+=2)if(t[s-1]===e&&t[s]===n)return t[s-1]=t[o-2],t[s]=t[o-1],void(t.length=o-2)}o.isConstraint=function(){var t=[0,0];function e(t,e){return t[0]-e[0]||t[1]-e[1]}return function(s,o){return t[0]=Math.min(s,o),t[1]=Math.max(s,o),n.eq(this.edges,t,e)>=0}}(),o.removeTriangle=function(t,e,n){var s=this.stars;i(s[t],e,n),i(s[e],n,t),i(s[n],t,e)},o.addTriangle=function(t,e,n){var s=this.stars;s[t].push(e,n),s[e].push(n,t),s[n].push(t,e)},o.opposite=function(t,e){for(var n=this.stars[e],s=1,o=n.length;s<o;s+=2)if(n[s]===t)return n[s-1];return-1},o.flip=function(t,e){var n=this.opposite(t,e),s=this.opposite(e,t);this.removeTriangle(t,e,n),this.removeTriangle(e,t,s),this.addTriangle(t,s,n),this.addTriangle(e,n,s)},o.edges=function(){for(var t=this.stars,e=[],n=0,s=t.length;n<s;++n)for(var o=t[n],i=0,r=o.length;i<r;i+=2)e.push([o[i],o[i+1]]);return e},o.cells=function(){for(var t=this.stars,e=[],n=0,s=t.length;n<s;++n)for(var o=t[n],i=0,r=o.length;i<r;i+=2){var a=o[i],c=o[i+1];n<Math.min(a,c)&&e.push([n,a,c])}return e}}}),po=no({"node_modules/robust-in-sphere/in-sphere.js"(t,e){var n=oo(),s=io(),o=co(),i=ao();function r(t){return(3===t?a:4===t?c:5===t?h:l)(s,o,n,i)}function a(t,e,n,s){return function(o,i,r){var a=n(o[0],o[0]),c=s(a,i[0]),h=s(a,r[0]),l=n(i[0],i[0]),d=s(l,o[0]),u=s(l,r[0]),p=n(r[0],r[0]),f=s(p,o[0]),m=s(p,i[0]),g=t(e(m,u),e(d,c)),y=e(f,h),x=e(g,y);return x[x.length-1]}}function c(t,e,n,s){return function(o,i,r,a){var c=t(n(o[0],o[0]),n(o[1],o[1])),h=s(c,i[0]),l=s(c,r[0]),d=s(c,a[0]),u=t(n(i[0],i[0]),n(i[1],i[1])),p=s(u,o[0]),f=s(u,r[0]),m=s(u,a[0]),g=t(n(r[0],r[0]),n(r[1],r[1])),y=s(g,o[0]),x=s(g,i[0]),v=s(g,a[0]),b=t(n(a[0],a[0]),n(a[1],a[1])),P=s(b,o[0]),S=s(b,i[0]),M=s(b,r[0]),N=t(t(s(e(M,v),i[1]),t(s(e(S,m),-r[1]),s(e(x,f),a[1]))),t(s(e(S,m),o[1]),t(s(e(P,d),-i[1]),s(e(p,h),a[1])))),I=t(t(s(e(M,v),o[1]),t(s(e(P,d),-r[1]),s(e(y,l),a[1]))),t(s(e(x,f),o[1]),t(s(e(y,l),-i[1]),s(e(p,h),r[1])))),_=e(N,I);return _[_.length-1]}}function h(t,e,n,s){return function(o,i,r,a,c){var h=t(n(o[0],o[0]),t(n(o[1],o[1]),n(o[2],o[2]))),l=s(h,i[0]),d=s(h,r[0]),u=s(h,a[0]),p=s(h,c[0]),f=t(n(i[0],i[0]),t(n(i[1],i[1]),n(i[2],i[2]))),m=s(f,o[0]),g=s(f,r[0]),y=s(f,a[0]),x=s(f,c[0]),v=t(n(r[0],r[0]),t(n(r[1],r[1]),n(r[2],r[2]))),b=s(v,o[0]),P=s(v,i[0]),S=s(v,a[0]),M=s(v,c[0]),N=t(n(a[0],a[0]),t(n(a[1],a[1]),n(a[2],a[2]))),I=s(N,o[0]),_=s(N,i[0]),C=s(N,r[0]),T=s(N,c[0]),E=t(n(c[0],c[0]),t(n(c[1],c[1]),n(c[2],c[2]))),w=s(E,o[0]),R=s(E,i[0]),O=s(E,r[0]),A=s(E,a[0]),z=t(t(t(s(t(s(e(A,T),r[1]),t(s(e(O,M),-a[1]),s(e(C,S),c[1]))),i[2]),t(s(t(s(e(A,T),i[1]),t(s(e(R,x),-a[1]),s(e(_,y),c[1]))),-r[2]),s(t(s(e(O,M),i[1]),t(s(e(R,x),-r[1]),s(e(P,g),c[1]))),a[2]))),t(s(t(s(e(C,S),i[1]),t(s(e(_,y),-r[1]),s(e(P,g),a[1]))),-c[2]),t(s(t(s(e(A,T),i[1]),t(s(e(R,x),-a[1]),s(e(_,y),c[1]))),o[2]),s(t(s(e(A,T),o[1]),t(s(e(w,p),-a[1]),s(e(I,u),c[1]))),-i[2])))),t(t(s(t(s(e(R,x),o[1]),t(s(e(w,p),-i[1]),s(e(m,l),c[1]))),a[2]),t(s(t(s(e(_,y),o[1]),t(s(e(I,u),-i[1]),s(e(m,l),a[1]))),-c[2]),s(t(s(e(C,S),i[1]),t(s(e(_,y),-r[1]),s(e(P,g),a[1]))),o[2]))),t(s(t(s(e(C,S),o[1]),t(s(e(I,u),-r[1]),s(e(b,d),a[1]))),-i[2]),t(s(t(s(e(_,y),o[1]),t(s(e(I,u),-i[1]),s(e(m,l),a[1]))),r[2]),s(t(s(e(P,g),o[1]),t(s(e(b,d),-i[1]),s(e(m,l),r[1]))),-a[2]))))),D=t(t(t(s(t(s(e(A,T),r[1]),t(s(e(O,M),-a[1]),s(e(C,S),c[1]))),o[2]),s(t(s(e(A,T),o[1]),t(s(e(w,p),-a[1]),s(e(I,u),c[1]))),-r[2])),t(s(t(s(e(O,M),o[1]),t(s(e(w,p),-r[1]),s(e(b,d),c[1]))),a[2]),s(t(s(e(C,S),o[1]),t(s(e(I,u),-r[1]),s(e(b,d),a[1]))),-c[2]))),t(t(s(t(s(e(O,M),i[1]),t(s(e(R,x),-r[1]),s(e(P,g),c[1]))),o[2]),s(t(s(e(O,M),o[1]),t(s(e(w,p),-r[1]),s(e(b,d),c[1]))),-i[2])),t(s(t(s(e(R,x),o[1]),t(s(e(w,p),-i[1]),s(e(m,l),c[1]))),r[2]),s(t(s(e(P,g),o[1]),t(s(e(b,d),-i[1]),s(e(m,l),r[1]))),-c[2])))),L=e(z,D);return L[L.length-1]}}function l(t,e,n,s){return function(o,i,r,a,c,h){var l=t(t(n(o[0],o[0]),n(o[1],o[1])),t(n(o[2],o[2]),n(o[3],o[3]))),d=s(l,i[0]),u=s(l,r[0]),p=s(l,a[0]),f=s(l,c[0]),m=s(l,h[0]),g=t(t(n(i[0],i[0]),n(i[1],i[1])),t(n(i[2],i[2]),n(i[3],i[3]))),y=s(g,o[0]),x=s(g,r[0]),v=s(g,a[0]),b=s(g,c[0]),P=s(g,h[0]),S=t(t(n(r[0],r[0]),n(r[1],r[1])),t(n(r[2],r[2]),n(r[3],r[3]))),M=s(S,o[0]),N=s(S,i[0]),I=s(S,a[0]),_=s(S,c[0]),C=s(S,h[0]),T=t(t(n(a[0],a[0]),n(a[1],a[1])),t(n(a[2],a[2]),n(a[3],a[3]))),E=s(T,o[0]),w=s(T,i[0]),R=s(T,r[0]),O=s(T,c[0]),A=s(T,h[0]),z=t(t(n(c[0],c[0]),n(c[1],c[1])),t(n(c[2],c[2]),n(c[3],c[3]))),D=s(z,o[0]),L=s(z,i[0]),F=s(z,r[0]),Y=s(z,a[0]),X=s(z,h[0]),k=t(t(n(h[0],h[0]),n(h[1],h[1])),t(n(h[2],h[2]),n(h[3],h[3]))),$=s(k,o[0]),B=s(k,i[0]),j=s(k,r[0]),W=s(k,a[0]),H=s(k,c[0]),U=t(t(t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),r[2]),s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),-a[2])),t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),c[2]),s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),-h[2]))),i[3]),t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),-a[2])),t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),c[2]),s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),-h[2]))),-r[3]),s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),c[2]),s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),-h[2]))),a[3]))),t(t(s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),i[2]),s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-h[2]))),-c[3]),s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),i[2]),s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),-r[2])),t(s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-c[2]))),h[3])),t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),-a[2])),t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),c[2]),s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),-h[2]))),o[3]),s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-a[2])),t(s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),c[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-h[2]))),-i[3])))),t(t(t(s(t(t(s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),c[2]),s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),-h[2]))),a[3]),s(t(t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-h[2]))),-c[3])),t(s(t(t(s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-i[2])),t(s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-c[2]))),h[3]),s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),i[2]),s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-h[2]))),o[3]))),t(t(s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-h[2]))),-i[3]),s(t(t(s(t(s(e(W,A),i[1]),t(s(e(B,P),-a[1]),s(e(w,v),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-h[2]))),r[3])),t(s(t(t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),o[2]),s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-h[2]))),-a[3]),s(t(t(s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),o[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-i[2])),t(s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-a[2]))),h[3]))))),V=t(t(t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),r[2]),s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),-a[2])),t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),c[2]),s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),-h[2]))),o[3]),t(s(t(t(s(t(s(e(H,X),a[1]),t(s(e(W,A),-c[1]),s(e(Y,O),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-a[2])),t(s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),c[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-h[2]))),-r[3]),s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),c[2]),s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),-h[2]))),a[3]))),t(t(s(t(t(s(t(s(e(W,A),r[1]),t(s(e(j,C),-a[1]),s(e(R,I),h[1]))),o[2]),s(t(s(e(W,A),o[1]),t(s(e($,m),-a[1]),s(e(E,p),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-h[2]))),-c[3]),s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-r[2])),t(s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-c[2]))),h[3])),t(s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),i[2]),s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),-r[2])),t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),c[2]),s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),-h[2]))),o[3]),s(t(t(s(t(s(e(H,X),r[1]),t(s(e(j,C),-c[1]),s(e(F,_),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-r[2])),t(s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),c[2]),s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),-h[2]))),-i[3])))),t(t(t(s(t(t(s(t(s(e(H,X),i[1]),t(s(e(B,P),-c[1]),s(e(L,b),h[1]))),o[2]),s(t(s(e(H,X),o[1]),t(s(e($,m),-c[1]),s(e(D,f),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),c[2]),s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),-h[2]))),r[3]),s(t(t(s(t(s(e(j,C),i[1]),t(s(e(B,P),-r[1]),s(e(N,x),h[1]))),o[2]),s(t(s(e(j,C),o[1]),t(s(e($,m),-r[1]),s(e(M,u),h[1]))),-i[2])),t(s(t(s(e(B,P),o[1]),t(s(e($,m),-i[1]),s(e(y,d),h[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-h[2]))),-c[3])),t(s(t(t(s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),o[2]),s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),-i[2])),t(s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-c[2]))),h[3]),s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),i[2]),s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),-r[2])),t(s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),a[2]),s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),-c[2]))),o[3]))),t(t(s(t(t(s(t(s(e(Y,O),r[1]),t(s(e(F,_),-a[1]),s(e(R,I),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-r[2])),t(s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),a[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-c[2]))),-i[3]),s(t(t(s(t(s(e(Y,O),i[1]),t(s(e(L,b),-a[1]),s(e(w,v),c[1]))),o[2]),s(t(s(e(Y,O),o[1]),t(s(e(D,f),-a[1]),s(e(E,p),c[1]))),-i[2])),t(s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),a[2]),s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),-c[2]))),r[3])),t(s(t(t(s(t(s(e(F,_),i[1]),t(s(e(L,b),-r[1]),s(e(N,x),c[1]))),o[2]),s(t(s(e(F,_),o[1]),t(s(e(D,f),-r[1]),s(e(M,u),c[1]))),-i[2])),t(s(t(s(e(L,b),o[1]),t(s(e(D,f),-i[1]),s(e(y,d),c[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-c[2]))),-a[3]),s(t(t(s(t(s(e(R,I),i[1]),t(s(e(w,v),-r[1]),s(e(N,x),a[1]))),o[2]),s(t(s(e(R,I),o[1]),t(s(e(E,p),-r[1]),s(e(M,u),a[1]))),-i[2])),t(s(t(s(e(w,v),o[1]),t(s(e(E,p),-i[1]),s(e(y,d),a[1]))),r[2]),s(t(s(e(N,x),o[1]),t(s(e(M,u),-i[1]),s(e(y,d),r[1]))),-a[2]))),c[3]))))),G=e(U,V);return G[G.length-1]}}var d=[function(){return 0},function(){return 0},function(){return 0}];function u(t){var e=d[t.length];return e||(e=d[t.length]=r(t.length)),e.apply(void 0,t)}function p(t,e,n,s,o,i,r,a){return function(e,n,c,h,l,d){switch(arguments.length){case 0:case 1:return 0;case 2:return s(e,n);case 3:return o(e,n,c);case 4:return i(e,n,c,h);case 5:return r(e,n,c,h,l);case 6:return a(e,n,c,h,l,d)}for(var u=new Array(arguments.length),p=0;p<arguments.length;++p)u[p]=arguments[p];return t(u)}}!function(){for(;d.length<=6;)d.push(r(d.length));e.exports=p.apply(void 0,[u].concat(d));for(var t=0;t<=6;++t)e.exports[t]=d[t]}()}}),fo=no({"node_modules/cdt2d/lib/delaunay.js"(t,e){var n=po()[4];so();function s(t,e,s,o,i,r){var a=e.opposite(o,i);if(!(a<0)){if(i<o){var c=o;o=i,i=c,c=r,r=a,a=c}e.isConstraint(o,i)||n(t[o],t[i],t[r],t[a])<0&&s.push(o,i)}}e.exports=function(t,e){for(var o=[],i=t.length,r=e.stars,a=0;a<i;++a)for(var c=r[a],h=1;h<c.length;h+=2){if(!((p=c[h])<a)&&!e.isConstraint(a,p)){for(var l=c[h-1],d=-1,u=1;u<c.length;u+=2)if(c[u-1]===p){d=c[u];break}d<0||n(t[a],t[p],t[l],t[d])<0&&o.push(a,p)}}for(;o.length>0;){for(var p=o.pop(),f=(l=-1,d=-1,c=r[a=o.pop()],1);f<c.length;f+=2){var m=c[f-1],g=c[f];m===p?d=g:g===p&&(l=m)}l<0||d<0||(n(t[a],t[p],t[l],t[d])>=0||(e.flip(a,p),s(t,e,o,l,a,d),s(t,e,o,a,d,l),s(t,e,o,d,p,l),s(t,e,o,p,l,d)))}}}}),mo=no({"node_modules/cdt2d/lib/filter.js"(t,e){var n=so();function s(t,e,n,s,o,i,r){this.cells=t,this.neighbor=e,this.flags=s,this.constraint=n,this.active=o,this.next=i,this.boundary=r}function o(t,e){return t[0]-e[0]||t[1]-e[1]||t[2]-e[2]}e.exports=function(t,e,n){var i=function(t,e){for(var n=t.cells(),i=n.length,r=0;r<i;++r){var a=(y=n[r])[0],c=y[1],h=y[2];c<h?c<a&&(y[0]=c,y[1]=h,y[2]=a):h<a&&(y[0]=h,y[1]=a,y[2]=c)}n.sort(o);var l=new Array(i);for(r=0;r<l.length;++r)l[r]=0;var d=[],u=[],p=new Array(3*i),f=new Array(3*i),m=null;e&&(m=[]);var g=new s(n,p,f,l,d,u,m);for(r=0;r<i;++r)for(var y=n[r],x=0;x<3;++x){a=y[x],c=y[(x+1)%3];var v=p[3*r+x]=g.locate(c,a,t.opposite(c,a)),b=f[3*r+x]=t.isConstraint(a,c);v<0&&(b?u.push(r):(d.push(r),l[r]=1),e&&m.push([c,a,-1]))}return g}(t,n);if(0===e)return n?i.cells.concat(i.boundary):i.cells;var r=1,a=i.active,c=i.next,h=i.flags,l=i.cells,d=i.constraint,u=i.neighbor;for(;a.length>0||c.length>0;){for(;a.length>0;){var p=a.pop();if(h[p]!==-r){h[p]=r;l[p];for(var f=0;f<3;++f){var m=u[3*p+f];m>=0&&0===h[m]&&(d[3*p+f]?c.push(m):(a.push(m),h[m]=r))}}}var g=c;c=a,a=g,c.length=0,r=-r}var y=function(t,e,n){for(var s=0,o=0;o<t.length;++o)e[o]===n&&(t[s++]=t[o]);return t.length=s,t}(l,h,e);if(n)return y.concat(i.boundary);return y},s.prototype.locate=function(){var t=[0,0,0];return function(e,s,i){var r=e,a=s,c=i;return s<i?s<e&&(r=s,a=i,c=e):i<e&&(r=i,a=e,c=s),r<0?-1:(t[0]=r,t[1]=a,t[2]=c,n.eq(this.cells,t,o))}}()}}),go=no({"node_modules/cdt2d/cdt2d.js"(t,e){var n=lo(),s=uo(),o=fo(),i=mo();function r(t){return[Math.min(t[0],t[1]),Math.max(t[0],t[1])]}function a(t,e){return t[0]-e[0]||t[1]-e[1]}function c(t,e,n){return e in t?t[e]:n}e.exports=function(t,e,h){Array.isArray(e)?(h=h||{},e=e||[]):(h=e||{},e=[]);var l=!!c(h,"delaunay",!0),d=!!c(h,"interior",!0),u=!!c(h,"exterior",!0),p=!!c(h,"infinity",!1);if(!d&&!u||0===t.length)return[];var f=n(t,e);if(l||d!==u||p){for(var m=s(t.length,function(t){return t.map(r).sort(a)}(e)),g=0;g<f.length;++g){var y=f[g];m.addTriangle(y[0],y[1],y[2])}return l&&o(t,m),u?d?p?i(m,0,p):m.cells():i(m,1,p):i(m,-1)}return f}}}),yo=class{heap=[];maxSize;constructor(t=[],e=1e4){if(this.maxSize=e,t.length>0){this.heap=[...t].sort((t,e)=>t.f-e.f).slice(0,this.maxSize);for(let t=Math.floor(this.heap.length/2)-1;t>=0;t--)this._siftDown(t)}}get size(){return this.heap.length}isEmpty(){return 0===this.heap.length}peek(){return this.isEmpty()?null:this.heap[0]??null}peekMany(t){return[...this.heap].sort((t,e)=>t.f-e.f).slice(0,t)}dequeue(){if(this.isEmpty())return null;const t=this.heap[0],e=this.heap.pop();return 0===this.heap.length&&void 0!==e||void 0!==e&&(this.heap[0]=e,this._siftDown(0)),t}enqueue(t){this.heap.length>=this.maxSize||(this.heap.push(t),this._siftUp(this.heap.length-1))}_siftUp(t){let e=t;for(;e>0;){const t=this._parentIndex(e);if(this.heap[t].f<=this.heap[e].f)break;this._swap(e,t),e=t}}_siftDown(t){let e=t;const n=this.heap.length;for(;;){const t=this._leftChildIndex(e),s=this._rightChildIndex(e);let o=e;if(t<n&&this.heap[t].f<this.heap[o].f&&(o=t),s<n&&this.heap[s].f<this.heap[o].f&&(o=s),o===e)break;this._swap(e,o),e=o}}_swap(t,e){[this.heap[t],this.heap[e]]=[this.heap[e],this.heap[t]]}_parentIndex(t){return Math.floor((t-1)/2)}_leftChildIndex(t){return 2*t+1}_rightChildIndex(t){return 2*t+2}},xo=class extends N{constructor(t){super(),this.input=t,this.graph=(t=>{if(t.ports.length>0&&"region1"in t.ports[0]&&"object"==typeof t.ports[0].region1)return t;const e=new Map,n=new Map;for(const e of t.regions){const{assignments:t,...s}=e;n.set(e.regionId,{...s,ports:[],assignments:void 0})}for(const s of t.ports){const t=n.get(s.region1Id??s.region1?.regionId),o=n.get(s.region2Id??s.region2?.regionId),i={portId:s.portId,region1:t,region2:o,d:s.d};e.set(s.portId,i),t.ports.push(i),o.ports.push(i)}return{ports:Array.from(e.values()),regions:Array.from(n.values())}})(t.inputGraph);for(const t of this.graph.regions)t.assignments=[];this.connections=((t,e)=>{const n=[];for(const s of t)"startRegionId"in s?n.push({connectionId:s.connectionId,mutuallyConnectedNetworkId:s.connectionId,startRegion:e.regions.find(t=>t.regionId===s.startRegionId),endRegion:e.regions.find(t=>t.regionId===s.endRegionId)}):n.push(s);return n})(t.inputConnections,this.graph),void 0!==t.greedyMultiplier&&(this.greedyMultiplier=t.greedyMultiplier),void 0!==t.rippingEnabled&&(this.rippingEnabled=t.rippingEnabled),void 0!==t.ripCost&&(this.ripCost=t.ripCost),this.unprocessedConnections=[...this.connections],this.candidateQueue=new yo,this.beginNewConnection()}getSolverName(){return"HyperGraphSolver"}graph;connections;candidateQueue;unprocessedConnections;solvedRoutes=[];currentConnection=null;currentEndRegion=null;greedyMultiplier=1;rippingEnabled=!1;ripCost=0;lastCandidate=null;visitedPointsForCurrentConnection=new Map;getConstructorParams(){return{inputGraph:(e=this.graph,{ports:e.ports.map(t=>({portId:t.portId,region1Id:t.region1.regionId,region2Id:t.region2.regionId,d:t.d})),regions:e.regions.map(t=>({regionId:t.regionId,pointIds:t.ports.map(t=>t.portId),d:t.d}))}),inputConnections:(t=this.connections,t.map(t=>({connectionId:t.connectionId,startRegionId:t.startRegion.regionId,endRegionId:t.endRegion.regionId}))),greedyMultiplier:this.greedyMultiplier,rippingEnabled:this.rippingEnabled,ripCost:this.ripCost};var t,e}computeH(t){return this.estimateCostToEnd(t.port)}estimateCostToEnd(t){return 0}getPortUsagePenalty(t){return 0}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){return 0}getRipsRequiredForPortUsage(t,e,n){return[]}isRipRequiredForPortUsage(t,e,n){return!1}isTransitionAllowed(t,e,n){return!0}computeG(t){return t.parent.g+this.computeIncreasedRegionCostIfPortsAreUsed(t.lastRegion,t.lastPort,t.port)+(t.ripRequired?this.ripCost:0)+this.getPortUsagePenalty(t.port)}selectCandidatesForEnteringRegion(t){return t}computeRoutesToRip(t){const e=this.computeCrossingRoutes(t),n=this.computePortOverlapRoutes(t);return new Set([...e,...n])}computePortOverlapRoutes(t){const e=new Set;for(const n of t.path)n.port.assignment&&n.port.assignment.connection.mutuallyConnectedNetworkId!==t.connection.mutuallyConnectedNetworkId&&e.add(n.port.assignment.solvedRoute);return e}computeCrossingRoutes(t){const e=new Set;for(const n of t.path){if(!n.lastPort||!n.lastRegion)continue;const t=this.getRipsRequiredForPortUsage(n.lastRegion,n.lastPort,n.port);for(const n of t)e.add(n.solvedRoute)}return e}getNextCandidates(t){const e=t.nextRegion,n=t.port,s={};for(const o of e.ports){if(o===t.port)continue;if(!this.isTransitionAllowed(e,n,o))continue;const i=o.assignment&&o.assignment.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId||this.isRipRequiredForPortUsage(e,n,o),r={port:o,hops:t.hops+1,parent:t,lastRegion:e,nextRegion:o.region1===e?o.region2:o.region1,lastPort:n,ripRequired:i};!this.rippingEnabled&&r.ripRequired||(s[r.nextRegion.regionId]??=[],s[r.nextRegion.regionId].push(r))}const o=[];for(const t in s){const e=s[t];o.push(...this.selectCandidatesForEnteringRegion(e))}for(const t of o)t.g=this.computeG(t),t.h=this.computeH(t),t.f=t.g+t.h*this.greedyMultiplier;return o}processSolvedRoute(t){const e={path:[],connection:this.currentConnection,requiredRip:!1};let n=t,s=!1;for(;n;)s||=!!n.ripRequired,e.path.unshift(n),n=n.parent;s&&(e.requiredRip=!0);const o=this.computeRoutesToRip(e);if(o.size>0){e.requiredRip=!0;for(const t of o)this.ripSolvedRoute(t)}for(const t of e.path){if(t.port.assignment={solvedRoute:e,connection:this.currentConnection},!t.lastPort)continue;const n={regionPort1:t.lastPort,regionPort2:t.port,region:t.lastRegion,connection:this.currentConnection,solvedRoute:e};t.lastRegion.assignments?.push(n)}this.solvedRoutes.push(e),this.routeSolvedHook(e)}routeSolvedHook(t){}routeStartedHook(t){}ripSolvedRoute(t){for(const e of t.path.map(t=>t.port))e.ripCount=(e.ripCount??0)+1,e.region1.assignments=e.region1.assignments?.filter(t=>t.regionPort1!==e&&t.regionPort2!==e),e.region2.assignments=e.region2.assignments?.filter(t=>t.regionPort1!==e&&t.regionPort2!==e),e.assignment=void 0;this.solvedRoutes=this.solvedRoutes.filter(e=>e!==t),this.unprocessedConnections.push(t.connection)}beginNewConnection(){this.currentConnection=this.unprocessedConnections.shift(),this.currentEndRegion=this.currentConnection.endRegion,this.candidateQueue=new yo,this.visitedPointsForCurrentConnection.clear(),this.routeStartedHook(this.currentConnection);for(const t of this.currentConnection.startRegion.ports)this.candidateQueue.enqueue({port:t,g:0,h:0,f:0,hops:0,ripRequired:!1,nextRegion:t.region1===this.currentConnection.startRegion?t.region2:t.region1})}_step(){let t=this.candidateQueue.dequeue();if(!t)return this.failed=!0,void(this.error="Ran out of candidates");let e=this.visitedPointsForCurrentConnection.get(t.port.portId);for(;t&&void 0!==e&&!(t.g<e)&&(t=this.candidateQueue.dequeue(),t);)e=this.visitedPointsForCurrentConnection.get(t.port.portId);if(!t)return this.failed=!0,void(this.error="Ran out of candidates");if(this.lastCandidate=t,this.visitedPointsForCurrentConnection.set(t.port.portId,t.g),t.nextRegion===this.currentEndRegion)return this.processSolvedRoute(t),0===this.unprocessedConnections.length?void(this.solved=!0):void this.beginNewConnection();const n=this.getNextCandidates(t);for(const t of n)this.candidateQueue.enqueue(t)}};function vo(t,e){return Array.isArray(e)?[t.a*e[0]+t.c*e[1]+t.e,t.b*e[0]+t.d*e[1]+t.f]:{x:t.a*e.x+t.c*e.y+t.e,y:t.b*e.x+t.d*e.y+t.f}}function bo(t){return void 0===t}function Po(t,e=0){return{a:1,c:0,e:t,b:0,d:1,f:e}}function So(...t){const e=(t,e)=>({a:t.a*e.a+t.c*e.b,c:t.a*e.c+t.c*e.d,e:t.a*e.e+t.c*e.f+t.e,b:t.b*e.a+t.d*e.b,d:t.b*e.c+t.d*e.d,f:t.b*e.e+t.d*e.f+t.f});switch((t=Array.isArray(t[0])?t[0]:t).length){case 0:throw new Error("no matrices provided");case 1:return t[0];case 2:return e(t[0],t[1]);default:{const[n,s,...o]=t;return So(e(n,s),...o)}}}var{cos:Mo,sin:No,PI:Io}=Math;var{tan:_o}=Math,Co=t=>{let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(const i of t){const{bounds:t}=i.d;e=Math.min(e,t.minX),n=Math.max(n,t.maxX),s=Math.min(s,t.minY),o=Math.max(o,t.maxY)}return{minX:e,maxX:n,minY:s,maxY:o}},To=t=>({x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}),Eo=(t,e)=>{const n=t.regions.map(t=>{const{bounds:n,center:s,...o}=t.d,i=[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.minX,y:n.maxY},{x:n.maxX,y:n.maxY}].map(t=>vo(e,t)),r={minX:Math.min(...i.map(t=>t.x)),maxX:Math.max(...i.map(t=>t.x)),minY:Math.min(...i.map(t=>t.y)),maxY:Math.max(...i.map(t=>t.y))},a=vo(e,s);return{...t,ports:[],d:{...o,bounds:r,center:a}}}),s=new Map;for(let e=0;e<t.regions.length;e++)s.set(t.regions[e],n[e]);const o=t.ports.map(t=>{const n=vo(e,t.d),o=s.get(t.region1),i=s.get(t.region2),r={...t,region1:o,region2:i,d:n};return o.ports.push(r),i.ports.push(r),r}),i=t.jumperLocations?.map(t=>{const n=vo(e,t.center),o=t.padRegions.map(t=>s.get(t)),i=vo(e,{x:1,y:0}),r=vo(e,{x:0,y:0}),a=i.x-r.x,c=i.y-r.y;return{center:n,orientation:Math.abs(c)>Math.abs(a)?"horizontal"===t.orientation?"vertical":"horizontal":t.orientation,padRegions:o}});return{regions:n,ports:o,...i&&{jumperLocations:i}}};function wo(t,e){const n=t.x-e.x,s=t.y-e.y;return n*n+s*s}function Ro(t,e,n,s,o){const i=n-e,r=o-s,a=1e-6;if(Math.abs(t.y-o)<a)return t.x-e;if(Math.abs(t.x-n)<a)return i+(o-t.y);if(Math.abs(t.y-s)<a)return i+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*i+r+(t.y-s);const c=Math.abs(t.y-o),h=Math.abs(t.x-n),l=Math.abs(t.y-s),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(i,t.x-e)):u===h?i+Math.max(0,Math.min(r,o-t.y)):u===l?i+r+Math.max(0,Math.min(i,n-t.x)):2*i+r+Math.max(0,Math.min(r,t.y-s))}function Oo(t,e,n){const s=n.x-e.x,o=n.y-e.y,i=t.x-e.x,r=t.y-e.y,a=s*s+o*o,c=a>0?(h=(i*s+r*o)/a,l=0,d=1,Math.max(l,Math.min(d,h))):0;var h,l,d;return{u:c,d2:wo(t,{x:e.x+c*s,y:e.y+c*o})}}function Ao(t){const e=t.d.polygon;if(!e||e.length<3)return null;const n=t.d.polygonPerimeterCache;if(n)return n;const s=function(t){const e=t.length,n=new Array(e),s=new Array(e+1);s[0]=0;for(let o=0;o<e;o++){const i=t[o],r=t[(o+1)%e],a=Math.hypot(r.x-i.x,r.y-i.y);n[o]=a,s[o+1]=s[o]+a}return{edgeLengths:n,cumulative:s,perimeter:s[e]}}(e);return t.d.polygonPerimeterCache=s,s}function zo(t){const e=Ao(t);if(e)return e.perimeter;const{minX:n,maxX:s,minY:o,maxY:i}=t.d.bounds;return 2*(s-n)+2*(i-o)}function Do(t,e){if(t.region1===e){if("number"==typeof t.region1T)return t.region1T;const n=Lo(t.d,e);return t.region1T=n,n}if(t.region2===e){if("number"==typeof t.region2T)return t.region2T;const n=Lo(t.d,e);return t.region2T=n,n}return Lo(t.d,e)}function Lo(t,e){const n=e.d.polygon;if(n&&n.length>=3){const s=Ao(e);if(s)return function(t,e,n,s=1e-6){let o=0,i=0,r=Number.POSITIVE_INFINITY;const a=s*s;for(let n=0;n<e.length;n++){const s=Oo(t,e[n],e[(n+1)%e.length]);if(s.d2<=a){o=n,i=s.u,r=s.d2;break}s.d2<r&&(o=n,i=s.u,r=s.d2)}return n.cumulative[o]+i*n.edgeLengths[o]}(t,n,s)}const{minX:s,maxX:o,minY:i,maxY:r}=e.d.bounds;return Ro(t,s,o,i,r)}function Fo(t,e,n=1e-6){return Math.abs(t-e)<n}function Yo(t,e){return(t%e+e)%e}function Xo(t,e,n,s){const o=Math.abs(Yo(t-e,n));return o<s||n-o<s}function ko(t,e,n,s,o){const i=Yo(t,s),r=Yo(e,s),a=Yo(n,s);return!(Math.abs(r-a)<o)&&(r<a?r<i&&i<a:i>r||i<a)}function $o(t,e,n){if("number"==typeof n&&n>0){let[s,o]=t,[i,r]=e;if(s=Yo(s,n),o=Yo(o,n),i=Yo(i,n),r=Yo(r,n),Xo(s,i,n,1e-6)||Xo(s,r,n,1e-6)||Xo(o,i,n,1e-6)||Xo(o,r,n,1e-6))return!1;return ko(i,s,o,n,1e-12)!==ko(r,s,o,n,1e-12)}const[s,o]=t[0]<t[1]?t:[t[1],t[0]],[i,r]=e[0]<e[1]?e:[e[1],e[0]];return!(Fo(s,i)||Fo(s,r)||Fo(o,i)||Fo(o,r))&&(s<i&&i<o&&o<r||i<s&&s<r&&r<o)}function Bo(t,e){if(e.length<2)return 0;let n=1/0,s=-1/0,o=1/0,i=-1/0;for(const e of t.regions){const t=e;t.d?.bounds?(n=Math.min(n,t.d.bounds.minX),s=Math.max(s,t.d.bounds.maxX),o=Math.min(o,t.d.bounds.minY),i=Math.max(i,t.d.bounds.maxY)):t.d?.center&&(n=Math.min(n,t.d.center.x),s=Math.max(s,t.d.center.x),o=Math.min(o,t.d.center.y),i=Math.max(i,t.d.center.y))}const r=new Map;for(const e of t.regions){const t=e;t.d?.center&&r.set(e.regionId,t.d.center)}const a=[],c=2*(s-n)+2*(i-o);for(const t of e){let e,c;if("startRegion"in t&&t.startRegion){const n=t.startRegion,s=t.endRegion;e=n.d?.center,c=s.d?.center}else"startRegionId"in t&&(e=r.get(t.startRegionId),c=r.get(t.endRegionId));if(!e||!c)continue;const h=Ro(e,n,s,o,i),l=Ro(c,n,s,o,i);a.push([h,l])}let h=0;for(let t=0;t<a.length;t++)for(let e=t+1;e<a.length;e++)$o(a[t],a[e],c)&&h++;return h}var jo=(t,e)=>{const n={arrows:[],circles:[],title:"Jumper Graph",lines:[],points:[],rects:[],texts:[],polygons:[],coordinateSystem:"cartesian"};for(const e of t.regions){const{bounds:t,isPad:s,isThroughJumper:o,isConnectionRegion:i,polygon:r}=e.d,a=(t.minX+t.maxX)/2,c=(t.minY+t.maxY)/2,h=t.maxX-t.minX,l=t.maxY-t.minY;let d;if(d=i?"rgba(255, 100, 255, 0.6)":o?"rgba(100, 200, 100, 0.5)":s?"rgba(255, 200, 100, 0.5)":"rgba(200, 200, 255, 0.1)",r&&r.length>=3){const t=r;n.polygons.push({points:t,fill:d})}else n.rects.push({center:{x:a,y:c},width:h-.1,height:l-.1,fill:d})}if(!e?.hidePortPoints)for(const e of t.ports){const t=e.region1.regionId.split(":").pop()??e.region1.regionId,s=e.region2.regionId.split(":").pop()??e.region2.regionId;n.circles.push({center:{x:e.d.x,y:e.d.y},radius:.05,fill:"rgba(128, 128, 128, 0.5)",label:`${t}-${s}`})}if(!e?.hideRegionPortLines)for(const e of t.ports){const t={x:(e.region1.d.bounds.minX+e.region1.d.bounds.maxX)/2,y:(e.region1.d.bounds.minY+e.region1.d.bounds.maxY)/2},s={x:(e.region2.d.bounds.minX+e.region2.d.bounds.maxX)/2,y:(e.region2.d.bounds.minY+e.region2.d.bounds.maxY)/2};n.lines.push({points:[t,{x:e.d.x,y:e.d.y},s],strokeColor:"rgba(100, 100, 100, 0.3)"})}if(e?.connections&&!e?.hideConnectionLines)for(const t of e.connections){const e=t.startRegion,s=t.endRegion,o={x:(e.d.bounds.minX+e.d.bounds.maxX)/2,y:(e.d.bounds.minY+e.d.bounds.maxY)/2},i={x:(s.d.bounds.minX+s.d.bounds.maxX)/2,y:(s.d.bounds.minY+s.d.bounds.maxY)/2},r=(o.x+i.x)/2,a=(o.y+i.y)/2;n.lines.push({points:[o,i],strokeColor:"rgba(255, 50, 150, 0.8)",strokeDash:"3 3"}),n.points.push({x:r,y:a,color:"rgba(200, 0, 100, 1)",label:t.connectionId})}return n},Wo=(t,e=.8)=>{let n=0;for(let e=0;e<t.length;e++)n=17777*t.charCodeAt(e)+((n<<5)-n);return`hsla(${Math.abs(n)%360}, 70%, 50%, ${e})`},Ho=.034685181009478865,Uo=0,Vo=4.072520483177124,Go=0,Zo=35.38577539020022,qo=.5518001238069296,Jo=class extends xo{getSolverName(){return"JumperGraphSolver"}UNIT_OF_COST="hops";portUsagePenalty=Ho;portUsagePenaltySq=Uo;crossingPenalty=Vo;crossingPenaltySq=Go;ripCost=Zo;baseMaxIterations=4e3;additionalMaxIterationsPerConnection=2e3;additionalMaxIterationsPerCrossing=2e3;constructor(t){super({greedyMultiplier:qo,rippingEnabled:!0,...t}),this.ripCost=t.ripCost??this.ripCost,this.portUsagePenalty=t.portUsagePenalty??this.portUsagePenalty,this.crossingPenalty=t.crossingPenalty??this.crossingPenalty,this.baseMaxIterations=t.baseMaxIterations??this.baseMaxIterations,this.additionalMaxIterationsPerConnection=t.additionalMaxIterationsPerConnection??this.additionalMaxIterationsPerConnection;const e=Bo(this.graph,t.inputConnections);this.MAX_ITERATIONS=this.baseMaxIterations+t.inputConnections.length*this.additionalMaxIterationsPerConnection+e*this.additionalMaxIterationsPerCrossing,this.populateDistanceToEndMaps()}populateDistanceToEndMaps(){const t=new Set(this.connections.map(t=>t.endRegion));for(const e of t){const t=new Map,n=[];for(t.set(e.regionId,0),n.push({region:e,distance:0});n.length>0;){const{region:e,distance:s}=n.shift();for(const o of e.ports){const i=o.region1===e?o.region2:o.region1;t.has(i.regionId)||(t.set(i.regionId,s+1),n.push({region:i,distance:s+1}))}}for(const n of this.graph.ports){n.distanceToEndMap||(n.distanceToEndMap={});const s=t.get(n.region1.regionId)??1/0,o=t.get(n.region2.regionId)??1/0;n.distanceToEndMap[e.regionId]=Math.min(s,o)}}}estimateCostToEnd(t){const e=this.currentEndRegion.regionId;return t.distanceToEndMap[e]}getPortUsagePenalty(t){const e=t.ripCount??0;return e*this.portUsagePenalty+e*this.portUsagePenaltySq}isTransitionAllowed(t,e,n){if(!t.d.isPad)return!0;const s=e=>{const n=e.region1===t?e.region2:e.region1;return Boolean(n.d.isThroughJumper)};return s(e)||s(n)}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){if(t.d.isPad){const e=(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId).length;return e>0?e*this.crossingPenalty+e*this.crossingPenaltySq:0}const s=function(t,e,n){const s=zo(t),o=[Do(e,t),Do(n,t)];let i=0;const r=t.assignments??[];for(const e of r)$o(o,[Do(e.regionPort1,t),Do(e.regionPort2,t)],s)&&i++;return i}(t,e,n);return s*this.crossingPenalty+s*this.crossingPenaltySq}getRipsRequiredForPortUsage(t,e,n){if(t.d.isPad){return(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}const s=function(t,e,n){const s=zo(t),o=[Do(e,t),Do(n,t)],i=[],r=t.assignments??[];for(const e of r)$o(o,[Do(e.regionPort1,t),Do(e.regionPort2,t)],s)&&i.push(e);return i}(t,e,n),o=s.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId);if(!t.d.isThroughJumper)return o;for(const e of t.assignments??[])e.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId&&o.push(e);return o}isRipRequiredForPortUsage(t,e,n){if(!t.d.isThroughJumper&&!t.d.isPad)return!1;for(const e of t.assignments??[])if(e.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)return!0;return!1}routeSolvedHook(t){}routeStartedHook(t){}visualize(){return(t=>{const e={regions:t.graph.regions,ports:t.graph.ports},n=jo(e,{connections:t.connections,...t.iterations>0?{hideRegionPortLines:!0,hideConnectionLines:!0,hidePortPoints:!0}:{}});if(0===t.iterations)for(const t of n.polygons)t.stroke="rgba(128, 128, 128, 0.5)",t.strokeWidth=.03;if(t.currentConnection&&!t.solved){const e=Wo(t.currentConnection.connectionId),s=t.currentConnection.startRegion,o=t.currentConnection.endRegion,i={x:(s.d.bounds.minX+s.d.bounds.maxX)/2,y:(s.d.bounds.minY+s.d.bounds.maxY)/2},r={x:(o.d.bounds.minX+o.d.bounds.maxX)/2,y:(o.d.bounds.minY+o.d.bounds.maxY)/2};n.lines.push({points:[i,r],strokeColor:e,strokeDash:"10 5"}),n.points.push({x:i.x-.1,y:i.y+.1,color:e,label:[t.currentConnection.connectionId,"start"].join("\n")}),n.points.push({x:r.x-.1,y:r.y+.1,color:e,label:[t.currentConnection.connectionId,"end"].join("\n")})}for(const e of t.solvedRoutes){const t=Wo(e.connection.connectionId),s=[];for(const t of e.path){const e=t.port;s.push({x:e.d.x,y:e.d.y})}s.length>0&&n.lines.push({points:s,strokeColor:t})}const s=t.candidateQueue.peekMany(10);for(let t=0;t<s.length;t++){const e=s[t],o=e.port,i=0===t;n.points.push({x:o.d.x,y:o.d.y,color:i?"green":"rgba(128, 128, 128, 0.25)",label:[e.port.portId,`g: ${e.g.toFixed(2)}`,`h: ${e.h.toFixed(2)}`,`f: ${e.f.toFixed(2)}`].join("\n")})}const o=s[0];if(!t.solved&&o&&t.currentConnection){const e=Wo(t.currentConnection.connectionId),s=[];let i=o;for(;i;){const t=i.port;s.unshift({x:t.d.x,y:t.d.y}),i=i.parent}s.length>1&&n.lines.push({points:s,strokeColor:e})}return n})(this)}},Ko=(t,e,n,s)=>{const o={portId:t,region1:e,region2:n,d:{x:s.x,y:s.y}};return e.ports.push(o),n.ports.push(o),o},Qo=(t,e,n)=>{const s=.2;return{regionId:t,ports:[],d:{bounds:{minX:e-s,maxX:e+s,minY:n-s,maxY:n+s},center:{x:e,y:n},isPad:!1,isConnectionRegion:!0}}},ti=.01,ei=(t,e,n)=>Math.max(e,Math.min(n,t)),ni=(t,e,n)=>"left"===e?Math.abs(t.x-n.minX)<ti:"right"===e?Math.abs(t.x-n.maxX)<ti:"top"===e?Math.abs(t.y-n.maxY)<ti:Math.abs(t.y-n.minY)<ti,si=(t,e,n,s)=>{const o=s.x-n.x,i=s.y-n.y,r=t-n.x,a=e-n.y,c=o*o+i*i,h=c>0?ei((r*o+a*i)/c,0,1):0,l=n.x+h*o,d=n.y+h*i,u=t-l,p=e-d;return{x:l,y:d,d2:u*u+p*p}},oi=(t,e,n,s,o)=>{const i=n.d.polygon;if(i&&i.length>=3){const n=new Set(o);let r=null;for(let a=0;a<i.length;a++){const c=i[a],h=i[(a+1)%i.length];if(o.length>0){if(!o.some(t=>ni(c,t,s)&&ni(h,t,s)&&n.has(t)))continue}const l=si(t,e,c,h);(!r||l.d2<r.d2)&&(r=l)}if(r)return r}const r=n.d.bounds,a=[];if(o.length>0)for(const n of o)"left"===n?a.push({side:n,x:r.minX,y:ei(e,r.minY,r.maxY)}):"right"===n?a.push({side:n,x:r.maxX,y:ei(e,r.minY,r.maxY)}):"top"===n?a.push({side:n,x:ei(t,r.minX,r.maxX),y:r.maxY}):a.push({side:n,x:ei(t,r.minX,r.maxX),y:r.minY});0===a.length&&a.push({side:"left",x:r.minX,y:ei(e,r.minY,r.maxY)},{side:"right",x:r.maxX,y:ei(e,r.minY,r.maxY)},{side:"top",x:ei(t,r.minX,r.maxX),y:r.maxY},{side:"bottom",x:ei(t,r.minX,r.maxX),y:r.minY});let c=null;for(const n of a){if(o.length>0&&!o.includes(n.side))continue;const s=t-n.x,i=e-n.y,r=s*s+i*i;(!c||r<c.d2)&&(c={x:n.x,y:n.y,d2:r})}return c},ii=(t,e,n,s)=>{const o=((t,e,n)=>{const s=[];return Math.abs(t-n.minX)<ti&&s.push("left"),Math.abs(t-n.maxX)<ti&&s.push("right"),Math.abs(e-n.maxY)<ti&&s.push("top"),Math.abs(e-n.minY)<ti&&s.push("bottom"),s})(t,e,s);let i=null,r=Number.POSITIVE_INFINITY,a={x:t,y:e};for(const c of n){if(c.d.isPad||c.d.isThroughJumper)continue;const n=c.d.bounds;if(!(Math.abs(n.minX-s.minX)<.01||Math.abs(n.maxX-s.maxX)<.01||Math.abs(n.minY-s.minY)<.01||Math.abs(n.maxY-s.maxY)<.01))continue;const h=oi(t,e,c,s,o);if(!h)continue;const l=Math.sqrt(h.d2);l<r&&(r=l,i=c,a={x:h.x,y:h.y})}return i?{region:i,portPosition:a}:null},ri={padWidth:.8,outerPadHeight:.5,innerPadHeight:.4,leftPadCenterX:-.9,rightPadCenterX:.9,row1CenterY:-1.2,row2CenterY:-.4,row3CenterY:.4,row4CenterY:1.2},ai=({cols:t,rows:e,marginX:n,marginY:s,innerColChannelPointCount:o=1,innerRowChannelPointCount:i=1,regionsBetweenPads:r=!1,outerPaddingX:a=.5,outerPaddingY:c=.5,outerChannelXPointCount:h,outerChannelYPointCount:l,orientation:d="vertical",center:u,bounds:p,parallelTracesUnderJumperCount:f=2})=>{const m=[],g=[],{padWidth:y,outerPadHeight:x,innerPadHeight:v,leftPadCenterX:b,rightPadCenterX:P,row1CenterY:S,row2CenterY:M,row3CenterY:N,row4CenterY:I}=ri,_=y/2,C=x/2,T=v/2,E=P-b+y,w=E+n,R=I-S+x,O=R+s;let A=a,z=c;if(p){const o=t*E+(t-1)*n,i=e*R+(e-1)*s;A=(("horizontal"===d?p.maxY-p.minY:p.maxX-p.minX)-o)/2,z=(("horizontal"===d?p.maxX-p.minX:p.maxY-p.minY)-i)/2}const D=h??Math.max(1,Math.floor(A/.4)),L=l??Math.max(1,Math.floor(z/.4)),F=[],Y=[],X=(t,e,n,s)=>({regionId:t,ports:[],d:{bounds:e,center:To(e),isPad:n,isThroughJumper:s}}),k=(t,e,n)=>{const s=e.d.bounds,o=n.d.bounds;let i,r;Math.abs(s.maxX-o.minX)<.001?(i=s.maxX,r=(Math.max(s.minY,o.minY)+Math.min(s.maxY,o.maxY))/2):Math.abs(s.minX-o.maxX)<.001?(i=s.minX,r=(Math.max(s.minY,o.minY)+Math.min(s.maxY,o.maxY))/2):Math.abs(s.maxY-o.minY)<.001?(i=(Math.max(s.minX,o.minX)+Math.min(s.maxX,o.maxX))/2,r=s.maxY):(i=(Math.max(s.minX,o.minX)+Math.min(s.maxX,o.maxX))/2,r=s.minY);const a={portId:t,region1:e,region2:n,d:{x:i,y:r}};return e.ports.push(a),n.ports.push(a),a},$=(t,e,n,s)=>{if(s<=0)return[];if(1===s)return[k(t,e,n)];const o=e.d.bounds,i=n.d.bounds,r=[];let a,c,h,l;Math.abs(o.maxX-i.minX)<.001?(a=!0,c=o.maxX,h=Math.max(o.minY,i.minY),l=Math.min(o.maxY,i.maxY)):Math.abs(o.minX-i.maxX)<.001?(a=!0,c=o.minX,h=Math.max(o.minY,i.minY),l=Math.min(o.maxY,i.maxY)):Math.abs(o.maxY-i.minY)<.001?(a=!1,c=o.maxY,h=Math.max(o.minX,i.minX),l=Math.min(o.maxX,i.maxX)):(a=!1,c=o.minY,h=Math.max(o.minX,i.minX),l=Math.min(o.maxX,i.maxX));for(let o=0;o<s;o++){const i=h+(o+.5)/s*(l-h),d={portId:`${t}:${o}`,region1:e,region2:n,d:{x:a?c:i,y:a?i:c}};e.ports.push(d),n.ports.push(d),r.push(d)}return r};for(let n=0;n<e;n++){F[n]=[];for(let a=0;a<t;a++){const c=`cell_${n}_${a}`,h=a*w,l=-n*O,d=h+b,u=l+S,p=h+b,y=l+M,x=h+b,v=l+N,E=h+b,R=l+I,B=h+P,j=l+I,W=h+P,H=l+N,U=h+P,V=l+M,G=h+P,Z=l+S,q=(t,e,n)=>({minX:t-_,maxX:t+_,minY:e-n,maxY:e+n}),J=q(d,u,C),K=q(p,y,T),Q=q(x,v,T),tt=q(E,R,C),et=q(B,j,C),nt=q(W,H,T),st=q(U,V,T),ot=q(G,Z,C),it={minX:J.maxX,maxX:ot.minX,minY:J.minY,maxY:tt.maxY},rt=.3,at={minX:d,maxX:G,minY:u-rt/2,maxY:u+rt/2},ct={minX:p,maxX:U,minY:y-rt/2,maxY:y+rt/2},ht={minX:x,maxX:W,minY:v-rt/2,maxY:v+rt/2},lt={minX:E,maxX:B,minY:R-rt/2,maxY:R+rt/2},dt=J.minX,ut=ot.maxX,pt=J.minY,ft=tt.maxY,mt=X(`${c}:pad1`,J,!0),gt=X(`${c}:pad2`,K,!0),yt=X(`${c}:pad3`,Q,!0),xt=X(`${c}:pad4`,tt,!0),vt=X(`${c}:pad5`,et,!0),bt=X(`${c}:pad6`,nt,!0),Pt=X(`${c}:pad7`,st,!0),St=X(`${c}:pad8`,ot,!0),Mt=X(`${c}:underjumper`,it,!1),Nt=X(`${c}:throughjumper1`,at,!1,!0),It=X(`${c}:throughjumper2`,ct,!1,!0),_t=X(`${c}:throughjumper3`,ht,!1,!0),Ct=X(`${c}:throughjumper4`,lt,!1,!0);m.push(mt,gt,yt,xt,vt,bt,Pt,St,Mt,Nt,It,_t,Ct);const Tt=(d+G)/2,Et=(u+R)/2;Y.push({center:{x:Tt,y:Et},orientation:"vertical",padRegions:[mt,gt,yt,xt,vt,bt,Pt,St]});let wt=null,Rt=null,Ot=null,At=null,zt=null,Dt=null;r&&(wt=X(`${c}:L-BP12`,{minX:J.minX,maxX:J.maxX,minY:J.maxY,maxY:K.minY},!1),Rt=X(`${c}:L-BP23`,{minX:K.minX,maxX:K.maxX,minY:K.maxY,maxY:Q.minY},!1),Ot=X(`${c}:L-BP34`,{minX:Q.minX,maxX:Q.maxX,minY:Q.maxY,maxY:tt.minY},!1),At=X(`${c}:R-BP87`,{minX:ot.minX,maxX:ot.maxX,minY:ot.maxY,maxY:st.minY},!1),zt=X(`${c}:R-BP76`,{minX:st.minX,maxX:st.maxX,minY:st.maxY,maxY:nt.minY},!1),Dt=X(`${c}:R-BP65`,{minX:nt.minX,maxX:nt.maxX,minY:nt.maxY,maxY:et.minY},!1),m.push(wt,Rt,Ot,At,zt,Dt));const Lt=0===a,Ft=n===e-1,Yt=a===t-1;let Xt;if(Yt)Xt=ut+A;else{Xt=(a+1)*w+b-_}let kt=null;0===n&&(kt=X(`${c}:T`,{minX:Lt?dt-A:dt,maxX:Xt,minY:ft,maxY:ft+z},!1),m.push(kt));let $t=null;$t=X(`${c}:B`,{minX:Lt?dt-A:dt,maxX:Xt,minY:pt-(Ft?z:s),maxY:pt},!1),m.push($t);let Bt=null;Lt&&(Bt=X(`${c}:L`,{minX:dt-A,maxX:dt,minY:pt,maxY:ft},!1),m.push(Bt));const jt=X(`${c}:R`,{minX:ut,maxX:Xt,minY:pt,maxY:ft},!1);if(m.push(jt),F[n][a]={pad1:mt,pad2:gt,pad3:yt,pad4:xt,pad5:vt,pad6:bt,pad7:Pt,pad8:St,underjumper:Mt,throughjumper1:Nt,throughjumper2:It,throughjumper3:_t,throughjumper4:Ct,top:kt,bottom:$t,left:Bt,right:jt,leftBP12:wt,leftBP23:Rt,leftBP34:Ot,rightBP87:At,rightBP76:zt,rightBP65:Dt},kt)if(Bt&&g.push(...$(`${c}:T-L`,kt,Bt,D)),g.push(...$(`${c}:T-R`,kt,jt,Yt?D:o)),g.push(k(`${c}:T-P4`,kt,xt)),g.push(k(`${c}:T-P5`,kt,vt)),r){const t=Mt.d.bounds,e=(t.maxX-t.minX)/(f+1);for(let n=1;n<=f;n++){const s={portId:`${c}:T-UJ${n}`,region1:kt,region2:Mt,d:{x:t.minX+e*n,y:t.maxY}};kt.ports.push(s),Mt.ports.push(s),g.push(s)}}else g.push(k(`${c}:T-UJ`,kt,Mt));if($t)if(Bt&&g.push(...$(`${c}:B-L`,$t,Bt,D)),g.push(...$(`${c}:B-R`,$t,jt,Yt?D:o)),g.push(k(`${c}:B-P1`,$t,mt)),g.push(k(`${c}:B-P8`,$t,St)),r){const t=Mt.d.bounds,e=(t.maxX-t.minX)/(f+1);for(let n=1;n<=f;n++){const s={portId:`${c}:B-UJ${n}`,region1:$t,region2:Mt,d:{x:t.minX+e*n,y:t.minY}};$t.ports.push(s),Mt.ports.push(s),g.push(s)}}else g.push(k(`${c}:B-UJ`,$t,Mt));Bt&&(g.push(k(`${c}:L-P1`,Bt,mt)),g.push(k(`${c}:L-P2`,Bt,gt)),g.push(k(`${c}:L-P3`,Bt,yt)),g.push(k(`${c}:L-P4`,Bt,xt))),g.push(k(`${c}:R-P5`,jt,vt)),g.push(k(`${c}:R-P6`,jt,bt)),g.push(k(`${c}:R-P7`,jt,Pt)),g.push(k(`${c}:R-P8`,jt,St)),r&&(Bt&&(g.push(k(`${c}:L-BP12`,Bt,wt)),g.push(k(`${c}:L-BP23`,Bt,Rt)),g.push(k(`${c}:L-BP34`,Bt,Ot))),g.push(k(`${c}:UJ-LBP12`,wt,Mt)),g.push(k(`${c}:UJ-LBP23`,Rt,Mt)),g.push(k(`${c}:UJ-LBP34`,Ot,Mt)),g.push(k(`${c}:R-BP87`,jt,At)),g.push(k(`${c}:R-BP76`,jt,zt)),g.push(k(`${c}:R-BP65`,jt,Dt)),g.push(k(`${c}:UJ-RBP87`,At,Mt)),g.push(k(`${c}:UJ-RBP76`,zt,Mt)),g.push(k(`${c}:UJ-RBP65`,Dt,Mt)));const Wt={portId:`${c}:TJ1-P1`,region1:Nt,region2:mt,d:{x:d,y:u}};Nt.ports.push(Wt),mt.ports.push(Wt),g.push(Wt);const Ht={portId:`${c}:TJ1-P8`,region1:Nt,region2:St,d:{x:G,y:Z}};Nt.ports.push(Ht),St.ports.push(Ht),g.push(Ht);const Ut={portId:`${c}:TJ2-P2`,region1:It,region2:gt,d:{x:p,y:y}};It.ports.push(Ut),gt.ports.push(Ut),g.push(Ut);const Vt={portId:`${c}:TJ2-P7`,region1:It,region2:Pt,d:{x:U,y:V}};It.ports.push(Vt),Pt.ports.push(Vt),g.push(Vt);const Gt={portId:`${c}:TJ3-P3`,region1:_t,region2:yt,d:{x:x,y:v}};_t.ports.push(Gt),yt.ports.push(Gt),g.push(Gt);const Zt={portId:`${c}:TJ3-P6`,region1:_t,region2:bt,d:{x:W,y:H}};_t.ports.push(Zt),bt.ports.push(Zt),g.push(Zt);const qt={portId:`${c}:TJ4-P4`,region1:Ct,region2:xt,d:{x:E,y:R}};Ct.ports.push(qt),xt.ports.push(qt),g.push(qt);const Jt={portId:`${c}:TJ4-P5`,region1:Ct,region2:vt,d:{x:B,y:j}};if(Ct.ports.push(Jt),vt.ports.push(Jt),g.push(Jt),a>0){const t=F[n][a-1];g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P1`,t.right,mt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P2`,t.right,gt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P3`,t.right,yt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P4`,t.right,xt)),r&&(g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP12`,t.right,wt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP23`,t.right,Rt)),g.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP34`,t.right,Ot))),kt&&t.top&&g.push(...$(`cell_${n}_${a-1}->cell_${n}_${a}:T-T`,t.top,kt,L)),$t&&t.bottom&&g.push(...$(`cell_${n}_${a-1}->cell_${n}_${a}:B-B`,t.bottom,$t,Ft?L:i))}if(n>0){const t=F[n-1][a];if(Bt&&g.push(...$(`cell_${n-1}_${a}->cell_${n}_${a}:B-L`,t.bottom,Bt,D)),g.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-P4`,t.bottom,xt)),r){const e=Mt.d.bounds,s=(e.maxX-e.minX)/(f+1);for(let o=1;o<=f;o++){const i=e.minX+s*o,r={portId:`cell_${n-1}_${a}->cell_${n}_${a}:B-UJ${o}`,region1:t.bottom,region2:Mt,d:{x:i,y:e.maxY}};t.bottom.ports.push(r),Mt.ports.push(r),g.push(r)}}else g.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-UJ`,t.bottom,Mt));g.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-P5`,t.bottom,vt)),g.push(...$(`cell_${n-1}_${a}->cell_${n}_${a}:B-R`,t.bottom,jt,Yt?D:o))}}}let B={regions:m,ports:g,jumperLocations:Y};const j="horizontal"===d;if(j||void 0!==u||void 0!==p){const t=Co(B.regions),e=To(t),n=[];let s;s=u||(p?To(p):e),n.push(Po(s.x,s.y)),j&&n.push(function(t,e,n){const s=Mo(t),o=No(t),i={a:s,c:-o,e:0,b:o,d:s,f:0};return bo(e)||bo(n)?i:So([Po(e,n),i,Po(-e,-n)])}(-Math.PI/2)),n.push(Po(-e.x,-e.y));const o=function(...t){return So(...t)}(...n);B=Eo(B,o)}return B},ci={viasByNet:{net1:[{viaId:"14ee4bf1-e7e7-4351-ad16-ba1a8aac0af3",diameter:.3,position:{x:.815244,y:-.055081}},{viaId:"8a898812-db2b-4b81-899d-f953b3222f9a",diameter:.3,position:{x:-.528763,y:.676055}}],net3:[{viaId:"13cd75da-d582-4eed-bc2c-fee6fa78bc6a",diameter:.3,position:{x:-.808222,y:-.726499}},{viaId:"9f188f9d-bce8-46c7-b9e8-542b8599d48d",diameter:.3,position:{x:.901143,y:.437488}}],net4:[{viaId:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",diameter:.3,position:{x:-.029,y:.691542}},{viaId:"37a70467-7553-415f-8ad7-8b88a5e56ca8",diameter:.3,position:{x:-.824388,y:.272808}},{viaId:"6d182b7d-a260-427b-8c43-a09409422252",diameter:.3,position:{x:.083422,y:-.705274}}],net5:[{viaId:"346c301a-f2b4-44d7-b975-5438ddaa0bde",diameter:.3,position:{x:.517145,y:-.456503}},{viaId:"c54b4b94-90e0-4240-97ef-883cf097d79d",diameter:.3,position:{x:.471002,y:.692404}},{viaId:"f3cb916e-b0fd-4c5e-b14b-3779f4f9bd01",diameter:.3,position:{x:-.833162,y:-.227118}}]},routeSegments:[{routeId:"net1:route_0",fromPort:"14ee4bf1-e7e7-4351-ad16-ba1a8aac0af3",toPort:"8a898812-db2b-4b81-899d-f953b3222f9a",layer:"bottom",segments:[{x:.815244,y:-.055081},{x:1.01282,y:-.252657},{x:1.01282,y:-.563283},{x:.444829,y:-1.131274},{x:-.093033,y:-1.131274},{x:-.382222,y:-.842085},{x:-.382222,y:.433097},{x:-.528763,y:.579638},{x:-.528763,y:.676055}]},{routeId:"net3:route_0",fromPort:"13cd75da-d582-4eed-bc2c-fee6fa78bc6a",toPort:"9f188f9d-bce8-46c7-b9e8-542b8599d48d",layer:"bottom",segments:[{x:-.808222,y:-.726499},{x:-.808222,y:-.912474},{x:-.238422,y:-1.482274},{x:.590217,y:-1.482274},{x:1.36382,y:-.708672},{x:1.36382,y:-.001202},{x:.92513,y:.437488},{x:.901143,y:.437488}]},{routeId:"net4:route_0",fromPort:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",toPort:"6d182b7d-a260-427b-8c43-a09409422252",layer:"bottom",segments:[{x:-.029,y:.691542},{x:-.029,y:-.592852},{x:.083422,y:-.705274}]},{routeId:"net4:route_1",fromPort:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",toPort:"37a70467-7553-415f-8ad7-8b88a5e56ca8",layer:"bottom",segments:[{x:-.029,y:.691542},{x:-.029,y:.778747},{x:-.352308,y:1.102055},{x:-.705218,y:1.102055},{x:-.954763,y:.85251},{x:-.954763,y:.403183},{x:-.824388,y:.272808}]},{routeId:"net5:route_0",fromPort:"346c301a-f2b4-44d7-b975-5438ddaa0bde",toPort:"c54b4b94-90e0-4240-97ef-883cf097d79d",layer:"bottom",segments:[{x:.517145,y:-.456503},{x:.389244,y:-.328602},{x:.389244,y:.610646},{x:.471002,y:.692404}]},{routeId:"net5:route_1",fromPort:"c54b4b94-90e0-4240-97ef-883cf097d79d",toPort:"f3cb916e-b0fd-4c5e-b14b-3779f4f9bd01",layer:"bottom",segments:[{x:.471002,y:.692404},{x:.471002,y:1.111132},{x:.129079,y:1.453055},{x:-.850606,y:1.453055},{x:-1.305763,y:.997899},{x:-1.305763,y:.151728},{x:-.926917,y:-.227118},{x:-.833162,y:-.227118}]}],tileWidth:2.9695829999999996,tileHeight:3.2353289999999997};function hi(t,e,n,s,o,i,r){return!!$o(t,e,n)||function(t,e,n,s,o=1e-9){const i=(t,e)=>Math.abs(t.x-e.x)<o&&Math.abs(t.y-e.y)<o;if(i(t,n)||i(t,s)||i(e,n)||i(e,s))return!1;const r=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),a=r(n,s,t),c=r(n,s,e),h=r(t,e,n),l=r(t,e,s);if(a*c<0&&h*l<0)return!0;const d=(t,e,n,s)=>{if(Math.abs(s)>o)return!1;const i=Math.min(e.x,n.x)-o,r=Math.max(e.x,n.x)+o,a=Math.min(e.y,n.y)-o,c=Math.max(e.y,n.y)+o;return t.x>=i&&t.x<=r&&t.y>=a&&t.y<=c};return!((!d(t,n,s,a)||i(t,n)||i(t,s))&&(!d(e,n,s,c)||i(e,n)||i(e,s))&&(!d(n,t,e,h)||i(n,t)||i(n,e))&&(!d(s,t,e,l)||i(s,t)||i(s,e)))}(s.d,o.d,i.d,r.d)}var li=1e-6;function di(t,e){return Math.abs(t.x-e.x)<=li&&Math.abs(t.y-e.y)<=li}function ui(t,e){const n=t[t.length-1];n&&di(n,e)||t.push(e)}function pi(t,e){let n=null,s=1/0;for(const o of t){const t=o.position.x-e.x,i=o.position.y-e.y,r=Math.hypot(t,i);r<s&&(s=r,n=o)}return n}function fi(t,e){const n=new Set(e.map(t=>t.viaId));return t.routeSegments.filter(t=>"bottom"===t.layer&&n.has(t.fromPort)&&n.has(t.toPort)&&t.segments.length>=2)}function mi(t,e){const n=function(t){const e=t.lastIndexOf(":v:");if(-1!==e)return t.slice(e+3);const n=t.lastIndexOf(":");return-1===n?t:t.slice(n+1)}(e.regionId);if(!n)return[];const s=t.viasByNet[n];if(!s||0===s.length)return[];const o=function(t){const e=t.lastIndexOf(":v:");return e<=0?null:t.slice(0,e)}(e.regionId);if(!o)return s;const i=s.filter(t=>t.viaId.startsWith(`${o}:`));return i.length>0?i:s}function gi(t,e,n){const s=function(t){const e=[];for(const n of t)ui(e,n);return e}(e);if(s.length<2)return;const o=t[t.length-1];if(!o||o.layer!==n)return void t.push({points:s,layer:n});const i=o.points[o.points.length-1],r=s[0];if(!i||!r||!di(i,r))return void t.push({points:s,layer:n});const a=s.slice(1);for(const t of a)ui(o.points,t)}function yi(t,e){if(0===t.path.length)return[];const n=t.path,s=[],o=new Set;for(let t=1;t<n.length;t++){const i=n[t-1],r=n[t],a={x:i.port.d.x,y:i.port.d.y},c={x:r.port.d.x,y:r.port.d.y},h=r.lastRegion;if(!(!!e&&!!h?.d?.isViaRegion)){gi(s,[a,c],"top");continue}const l=mi(e,h);if(0===l.length)continue;const d=pi(l,a),u=pi(l,c);d&&gi(s,[a,d.position],"top");const p=fi(e,l);if(p.length>0&&!o.has(h.regionId)){o.add(h.regionId);for(const t of p)gi(s,t.segments,"bottom")}u&&gi(s,[u.position,c],"top")}return s}function xi(t,e){return function(t){const e=[];for(const n of t)for(const t of n.points)ui(e,t);return e}(yi(t,e))}var vi=(t,e=.8)=>{let n=0;for(let e=0;e<t.length;e++)n=17777*t.charCodeAt(e)+((n<<5)-n);return`hsla(${Math.abs(n)%360}, 70%, 50%, ${e})`},bi=["rgba(231, 76, 60, 0.35)","rgba(46, 204, 113, 0.35)","rgba(52, 152, 219, 0.35)","rgba(243, 156, 18, 0.35)","rgba(155, 89, 182, 0.35)","rgba(26, 188, 156, 0.35)","rgba(241, 196, 15, 0.35)","rgba(230, 126, 34, 0.35)"],Pi=.034685181009478865,Si=0,Mi=4.072520483177124,Ni=0,Ii=35.38577539020022,_i=.5518001238069296,Ci=class extends xo{getSolverName(){return"ViaGraphSolver"}UNIT_OF_COST="hops";viaTile;portUsagePenalty=Pi;portUsagePenaltySq=Si;crossingPenalty=Mi;crossingPenaltySq=Ni;ripCost=Ii;baseMaxIterations=9e5;additionalMaxIterationsPerConnection=2e3;additionalMaxIterationsPerCrossing=2e3;constructor(t){super({greedyMultiplier:_i,rippingEnabled:!0,...t}),this.viaTile=t.viaTile,this.ripCost=t.ripCost??this.ripCost,this.portUsagePenalty=t.portUsagePenalty??this.portUsagePenalty,this.crossingPenalty=t.crossingPenalty??this.crossingPenalty,this.baseMaxIterations=t.baseMaxIterations??this.baseMaxIterations,this.additionalMaxIterationsPerConnection=t.additionalMaxIterationsPerConnection??this.additionalMaxIterationsPerConnection;const e=Bo(this.graph,t.inputConnections);this.MAX_ITERATIONS=this.baseMaxIterations+t.inputConnections.length*this.additionalMaxIterationsPerConnection+e*this.additionalMaxIterationsPerCrossing,this.populateDistanceToEndMaps()}populateDistanceToEndMaps(){const t=new Set(this.connections.map(t=>t.endRegion));for(const e of t){const t=new Map,n=[];for(t.set(e.regionId,0),n.push({region:e,distance:0});n.length>0;){const{region:e,distance:s}=n.shift();for(const o of e.ports){const i=o.region1===e?o.region2:o.region1;t.has(i.regionId)||(t.set(i.regionId,s+1),n.push({region:i,distance:s+1}))}}for(const n of this.graph.ports){n.distanceToEndMap||(n.distanceToEndMap={});const s=t.get(n.region1.regionId)??1/0,o=t.get(n.region2.regionId)??1/0;n.distanceToEndMap[e.regionId]=Math.min(s,o)}}}estimateCostToEnd(t){const e=this.currentEndRegion.regionId;return t.distanceToEndMap[e]}getPortUsagePenalty(t){const e=t.ripCount??0;return e*this.portUsagePenalty+e*this.portUsagePenaltySq}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){if(t.d.isViaRegion){const e=(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId).length;return e>0?e*this.crossingPenalty+e*this.crossingPenaltySq:0}const s=function(t,e,n){const s=t.d.polygon;if(!s||s.length<3)return 0;const o=zo(t),i=[Do(e,t),Do(n,t)];let r=0;const a=t.assignments??[];for(const s of a){const a=s.regionPort1,c=s.regionPort2;hi(i,[Do(a,t),Do(c,t)],o,e,n,a,c)&&r++}return r}(t,e,n);return s*this.crossingPenalty+s*this.crossingPenaltySq}isRipRequiredForPortUsage(t,e,n){if(t.d.isViaRegion){return(t.assignments??[]).some(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}return!1}getRipsRequiredForPortUsage(t,e,n){if(t.d.isViaRegion){return(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}const s=function(t,e,n){const s=t.d.polygon;if(!s||s.length<3)return[];const o=zo(t),i=[Do(e,t),Do(n,t)],r=[],a=t.assignments??[];for(const s of a){const a=s.regionPort1,c=s.regionPort2;hi(i,[Do(a,t),Do(c,t)],o,e,n,a,c)&&r.push(s)}return r}(t,e,n);return s.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}routeSolvedHook(t){}getSolvedRoutePoints(t){return xi(t,this.viaTile)}getSolvedRouteLineSegments(t){return yi(t,this.viaTile)}routeStartedHook(t){}visualize(){return(t=>{const e={regions:t.graph.regions,ports:t.graph.ports},n=jo(e,{connections:t.connections,...t.iterations>0?{hideRegionPortLines:!0,hideConnectionLines:!0,hidePortPoints:!0}:{}});if(0===t.iterations)for(const t of n.polygons)t.stroke="rgba(128, 128, 128, 0.5)",t.strokeWidth=.03;const s=new Set(["T","B","L","R"]);let o=0;const i=new Map;let r=0;for(const t of e.regions){const e=t;if(!(e.d.polygon&&e.d.polygon.length>=3))continue;const a=e.regionId.split(":").pop()??"";s.has(a)||e.d.isConnectionRegion||(i.has(a)||(i.set(a,bi[o%bi.length]),o++),n.polygons[r]&&(n.polygons[r].fill=i.get(a))),r++}if(t.currentConnection&&!t.solved){const e=vi(t.currentConnection.connectionId),s=t.currentConnection.startRegion,o=t.currentConnection.endRegion,i={x:(s.d.bounds.minX+s.d.bounds.maxX)/2,y:(s.d.bounds.minY+s.d.bounds.maxY)/2},r={x:(o.d.bounds.minX+o.d.bounds.maxX)/2,y:(o.d.bounds.minY+o.d.bounds.maxY)/2};n.lines.push({points:[i,r],strokeColor:e,strokeDash:"10 5"}),n.points.push({x:i.x-.1,y:i.y+.1,color:e,label:[t.currentConnection.connectionId,"start"].join("\n")}),n.points.push({x:r.x-.1,y:r.y+.1,color:e,label:[t.currentConnection.connectionId,"end"].join("\n")})}for(const e of t.solvedRoutes){const s=vi(e.connection.connectionId),o=t.getSolvedRouteLineSegments(e);for(const t of o){const e="bottom"===t.layer;n.lines.push({points:t.points,strokeColor:e?"rgba(52, 152, 219, 0.95)":s,...e?{strokeDash:"3 2"}:{}})}}const a=t.candidateQueue.peekMany(10);for(let t=0;t<a.length;t++){const e=a[t],s=e.port,o=0===t;n.points.push({x:s.d.x,y:s.d.y,color:o?"green":"rgba(128, 128, 128, 0.25)",label:[e.port.portId,`g: ${e.g.toFixed(2)}`,`h: ${e.h.toFixed(2)}`,`f: ${e.f.toFixed(2)}`].join("\n")})}const c=a[0];if(!t.solved&&c&&t.currentConnection){const e=vi(t.currentConnection.connectionId),s=[];let o=c;for(;o;){const t=o.port;s.unshift({x:t.d.x,y:t.d.y}),o=o.parent}s.length>1&&n.lines.push({points:s,strokeColor:e})}if(t.viaTile){n.circles||(n.circles=[]);for(const[e,s]of Object.entries(t.viaTile.viasByNet)){const t=i.get(e),o=t?t.replace("0.35","0.5"):"rgba(255, 0, 0, 0.3)";for(const t of s)n.circles.push({center:t.position,radius:t.diameter/2,fill:o,label:e})}}return n})(this)}};function Ti(t,e){let n=1/0,s={x:t.x,y:t.y};for(let o=0;o<e.length;o++){const i=e[o],r=e[(o+1)%e.length],a=r.x-i.x,c=r.y-i.y,h=a*a+c*c;if(h<1e-10)continue;const l=Math.max(0,Math.min(1,((t.x-i.x)*a+(t.y-i.y)*c)/h)),d=i.x+l*a,u=i.y+l*c,p=Math.sqrt((t.x-d)**2+(t.y-u)**2);p<n&&(n=p,s={x:d,y:u})}return{...s,dist:n}}var Ei=t=>{const{x:e,y:n,regions:s}=t,o=s.some(t=>t.regionId.startsWith("filler:"));let i=null,r=1/0,a={x:e,y:n};for(const t of s){if(t.d.isPad||t.d.isThroughJumper||t.d.isConnectionRegion)continue;if(o&&!t.regionId.startsWith("filler:"))continue;const s=t.d.polygon;if(!s||s.length<3)continue;const c=Ti({x:e,y:n},s);c.dist<r&&(r=c.dist,i=t,a={x:c.x,y:c.y})}return i?{region:i,portPosition:a}:null},wi=!0,Ri={CCW:-1,CW:1,NOT_ORIENTABLE:0},Oi=2*Math.PI,Ai=Object.freeze({__proto__:null,BOUNDARY:2,CCW:wi,CONTAINS:3,CW:!1,END_VERTEX:2,INSIDE:1,INTERLACE:4,NOT_VERTEX:0,ORIENTATION:Ri,OUTSIDE:0,OVERLAP_OPPOSITE:2,OVERLAP_SAME:1,PIx2:Oi,START_VERTEX:1}),zi=1e-6;function Di(t){zi=t}function Li(){return zi}function Fi(t){return t<zi&&t>-zi}function Yi(t,e){return t-e<zi&&t-e>-zi}function Xi(t,e){return t-e>zi}function ki(t,e){return t-e<-zi}var $i={Utils:Object.freeze({__proto__:null,DECIMALS:3,EQ:Yi,EQ_0:Fi,GE:function(t,e){return t-e>-zi},GT:Xi,LE:function(t,e){return t-e<zi},LT:ki,getTolerance:Li,setTolerance:Di}),Errors:void 0,Matrix:void 0,Planar_set:void 0,Point:void 0,Vector:void 0,Line:void 0,Circle:void 0,Segment:void 0,Arc:void 0,Box:void 0,Edge:void 0,Face:void 0,Ray:void 0,Ray_shooting:void 0,Multiline:void 0,Polygon:void 0,Distance:void 0,Inversion:void 0};for(let t in Ai)$i[t]=Ai[t];Object.defineProperty($i,"DP_TOL",{get:function(){return Li()},set:function(t){Di(t)}});var Bi=class{static get ILLEGAL_PARAMETERS(){return new ReferenceError("Illegal Parameters")}static get ZERO_DIVISION(){return new Error("Zero division")}static get UNRESOLVED_BOUNDARY_CONFLICT(){return new Error("Unresolved boundary conflict in boolean operation")}static get INFINITE_LOOP(){return new Error("Infinite loop")}static get CANNOT_COMPLETE_BOOLEAN_OPERATION(){return new Error("Cannot complete boolean operation")}static get CANNOT_INVOKE_ABSTRACT_METHOD(){return new Error("Abstract method cannot be invoked")}static get OPERATION_IS_NOT_SUPPORTED(){return new Error("Operation is not supported")}static get UNSUPPORTED_SHAPE_TYPE(){return new Error("Unsupported shape type")}};$i.Errors=Bi;var ji=class{constructor(t,e){this.first=t,this.last=e||this.first}[Symbol.iterator](){let t;return{next:()=>(t=t?t.next:this.first,{value:t,done:void 0===t})}}get size(){let t=0;for(let e of this)t++;return t}toArray(t=void 0,e=void 0){let n=[],s=t||this.first,o=e||this.last,i=s;if(void 0===i)return n;do{n.push(i),i=i.next}while(i!==o.next);return n}append(t){return this.isEmpty()?this.first=t:(t.prev=this.last,this.last.next=t),this.last=t,this.last.next=void 0,this.first.prev=void 0,this}insert(t,e){if(this.isEmpty())this.first=t,this.last=t;else if(null==e)t.next=this.first,this.first.prev=t,this.first=t;else{let n=e.next;e.next=t,n&&(n.prev=t),t.prev=e,t.next=n,this.last===e&&(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first&&t===this.last?(this.first=void 0,this.last=void 0):(t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t===this.first&&(this.first=t.next),t===this.last&&(this.last=t.prev)),this}isEmpty(){return void 0===this.first}static testInfiniteLoop(t){let e=t,n=t;do{if(e!=t&&e===n)throw Bi.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}},Wi={stroke:"black"},Hi=class{constructor(t=Wi){for(const e in t)this[e]=t[e];this.stroke=t.stroke??Wi.stroke}toAttributesString(){return Object.keys(this).reduce((t,e)=>t+(void 0!==this[e]?this.toAttrString(e,this[e]):""),"")}toAttrString(t,e){const n="className"===t?"class":this.convertCamelToKebabCase(t);return null===e?`${n} `:`${n}="${e.toString()}" `}convertCamelToKebabCase(t){return t.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).join("-").toLowerCase()}};function Ui(t){return new Hi(t).toAttributesString()}function Vi(t,e){let n=[],[s,o,i]=t.standard,[r,a,c]=e.standard,h=s*a-o*r,l=i*a-o*c,d=s*c-i*r;if(!$i.Utils.EQ_0(h)){let t,e;0===o?(t=i/s,e=d/h):0===a?(t=c/r,e=d/h):0===s?(t=l/h,e=i/o):0===r?(t=l/h,e=c/a):(t=l/h,e=d/h),n.push(new $i.Point(t,e))}return n}function Gi(t,e){let n=[],s=e.pc.projectionOn(t),o=e.pc.distanceTo(s)[0];if($i.Utils.EQ(o,e.r))n.push(s);else if($i.Utils.LT(o,e.r)){let i,r,a=Math.sqrt(e.r*e.r-o*o);i=t.norm.rotate90CCW().multiply(a),r=s.translate(i),n.push(r),i=t.norm.rotate90CW().multiply(a),r=s.translate(i),n.push(r)}return n}function Zi(t,e){let n=[];for(let s of e.toSegments()){let e=Ji(s,t);for(let t of e)mr(t,n)||n.push(t)}return n}function qi(t,e){let n=[];if(0===Zi(t,e.box).length)return n;let s=Gi(t,new $i.Circle(e.pc,e.r));for(let t of s)t.on(e)&&n.push(t);return n}function Ji(t,e){let n=[];return t.ps.on(e)&&n.push(t.ps),t.pe.on(e)&&!t.isZeroLength()&&n.push(t.pe),n.length>0||t.isZeroLength()||t.ps.leftTo(e)&&t.pe.leftTo(e)||!t.ps.leftTo(e)&&!t.pe.leftTo(e)?n:Vi(new $i.Line(t.ps,t.pe),e)}function Ki(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)&&n.push(t.ps),n;if(e.isZeroLength())return e.ps.on(t)&&n.push(e.ps),n;let s=new $i.Line(t.ps,t.pe),o=new $i.Line(e.ps,e.pe);if(s.incidentTo(o))t.ps.on(e)&&n.push(t.ps),t.pe.on(e)&&n.push(t.pe),!e.ps.on(t)||e.ps.equalTo(t.ps)||e.ps.equalTo(t.pe)||n.push(e.ps),!e.pe.on(t)||e.pe.equalTo(t.ps)||e.pe.equalTo(t.pe)||n.push(e.pe);else{let i=Vi(s,o);i.length>0&&Qi(i[0],t)&&Qi(i[0],e)&&n.push(i[0])}return n}function Qi(t,e){const n=e.box;return $i.Utils.LE(t.x,n.xmax)&&$i.Utils.GE(t.x,n.xmin)&&$i.Utils.LE(t.y,n.ymax)&&$i.Utils.GE(t.y,n.ymin)}function tr(t,e){let n=[];if(t.isZeroLength()){let[s,o]=t.ps.distanceTo(e.pc);return $i.Utils.EQ(s,e.r)&&n.push(t.ps),n}let s=Gi(new $i.Line(t.ps,t.pe),e);for(let e of s)e.on(t)&&n.push(e);return n}function er(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)&&n.push(t.ps),n;let s=Gi(new $i.Line(t.ps,t.pe),new $i.Circle(e.pc,e.r));for(let o of s)o.on(t)&&o.on(e)&&n.push(o);return n}function nr(t,e){let n=[],s=new $i.Vector(t.pc,e.pc),o=t.r,i=e.r;if($i.Utils.EQ_0(o)||$i.Utils.EQ_0(i))return n;if($i.Utils.EQ_0(s.x)&&$i.Utils.EQ_0(s.y)&&$i.Utils.EQ(o,i))return n.push(t.pc.translate(-o,0)),n;let r,a=t.pc.distanceTo(e.pc)[0];if($i.Utils.GT(a,o+i))return n;if($i.Utils.LT(a,Math.abs(o-i)))return n;if(s.x/=a,s.y/=a,$i.Utils.EQ(a,o+i)||$i.Utils.EQ(a,Math.abs(o-i)))return r=t.pc.translate(o*s.x,o*s.y),n.push(r),n;let c=o*o/(2*a)-i*i/(2*a)+a/2,h=t.pc.translate(c*s.x,c*s.y),l=Math.sqrt(o*o-c*c);return r=h.translate(s.rotate90CCW().multiply(l)),n.push(r),r=h.translate(s.rotate90CW().multiply(l)),n.push(r),n}function sr(t,e){let n=[];if(t.pc.equalTo(e.pc)&&$i.Utils.EQ(t.r,e.r)){let s;return s=t.start,s.on(e)&&n.push(s),s=t.end,s.on(e)&&n.push(s),s=e.start,s.on(t)&&n.push(s),s=e.end,s.on(t)&&n.push(s),n}let s=new $i.Circle(t.pc,t.r),o=new $i.Circle(e.pc,e.r),i=s.intersect(o);for(let s of i)s.on(t)&&s.on(e)&&n.push(s);return n}function or(t,e){let n=[];if(e.pc.equalTo(t.pc)&&$i.Utils.EQ(e.r,t.r))return n.push(t.start),n.push(t.end),n;let s=nr(e,new $i.Circle(t.pc,t.r));for(let e of s)e.on(t)&&n.push(e);return n}function ir(t,e){return t.isSegment?Ki(t.shape,e):er(e,t.shape)}function rr(t,e){return t.isSegment?er(t.shape,e):sr(t.shape,e)}function ar(t,e){return t.isSegment?Ji(t.shape,e):qi(e,t.shape)}function cr(t,e){return t.isSegment?tr(t.shape,e):or(t.shape,e)}function hr(t,e){let n=[];for(let s of e.edges)for(let e of ir(s,t))n.push(e);return n}function lr(t,e){let n=[];for(let s of e.edges)for(let e of rr(s,t))n.push(e);return n}function dr(t,e){let n=[];if(e.isEmpty())return n;for(let s of e.edges)for(let e of ar(s,t))mr(e,n)||n.push(e);return t.sortPoints(n)}function ur(t,e){let n=[];if(e.isEmpty())return n;for(let s of e.edges)for(let e of cr(s,t))n.push(e);return n}function pr(t,e){return t.isSegment?ir(e,t.shape):t.isArc?rr(e,t.shape):t.isLine?ar(e,t.shape):t.isRay?(n=e,s=t.shape,n.isSegment?yr(s,n.shape):xr(s,n.shape)):[];var n,s}function fr(t,e){let n=[];if(e.isEmpty()||t.shape.box.not_intersect(e.box))return n;let s=e.edges.search(t.shape.box);for(let e of s)n=[...n,...pr(t,e)];return n}function mr(t,e){return e.some(e=>e.equalTo(t))}function gr(t){return new $i.Line(t.start,t.norm)}function yr(t,e){return Ji(e,gr(t)).filter(e=>t.contains(e))}function xr(t,e){return qi(gr(t),e).filter(e=>t.contains(e))}function vr(t,e){return Gi(gr(t),e).filter(e=>t.contains(e))}function br(t,e){return Vi(gr(t),e).filter(e=>t.contains(e))}function Pr(t,e){return dr(gr(t),e).filter(e=>t.contains(e))}function Sr(t,e){if(t.intersect&&t.intersect instanceof Function)return t.intersect(e);throw Bi.UNSUPPORTED_SHAPE_TYPE}function Mr(t,e){let n=[];for(let s of e)n=[...n,...Sr(t,s.shape)];return n}var Nr=class t extends ji{constructor(...t){if(super(),this.isInfinite=!1,1===t.length&&t[0]instanceof Array&&t[0].length>0){const e=t[0],n=e.length,s=t=>t instanceof $i.Segment||t instanceof $i.Arc||t instanceof $i.Ray,o=t=>t instanceof $i.Segment||t instanceof $i.Arc;if(!(1===n&&(t=>t instanceof $i.Segment||t instanceof $i.Arc||t instanceof $i.Ray||t instanceof $i.Line)(e[0])||n>1&&s(e[0])&&s(e[n-1])&&e.slice(1,n-1).every(o)))throw $i.Errors.ILLEGAL_PARAMETERS;this.isInfinite=e.some(t=>t instanceof $i.Ray||t instanceof $i.Line);for(let t of e){let e=new $i.Edge(t);this.append(e)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=>t.merge(e.box),new $i.Box)}get vertices(){let t=this.edges.map(t=>t.start);return t.push(this.last.end),t}get length(){if(this.isEmpty())return 0;if(this.isInfinite)return Number.POSITIVE_INFINITY;let t=0;for(let e of this)t+=e.length;return t}clone(){return new t(this.toShapes())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t)}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}pointAtLength(t){if(t>this.length||t<0)return null;if(this.isInfinite)return null;let e=null;for(let n of this)if(t>=n.arc_length&&(n===this.last||t<n.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}addVertex(t,e){let n=e.shape.split(t);if(null===n[0])return e.prev;if(null===n[1])return e;let s=new $i.Edge(n[0]),o=e.prev;return this.insert(s,o),e.shape=n[1],s}getChain(t,e){let n=[];for(let s=t;s!==e.next;s=s.next)n.push(s);return n}split(t){for(let e of t){let t=this.findEdgeByPoint(e);this.addVertex(e,t)}return this}findEdgeByPoint(t){let e;for(let n of this)if(n.shape.contains(t)){e=n;break}return e}distanceTo(t){if(t instanceof Point){const[e,n]=$i.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof $i.Line){const[e,n]=$i.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof $i.Circle){const[e,n]=$i.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof $i.Segment){const[e,n]=$i.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof $i.Arc){const[e,n]=$i.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof $i.Multiline)return $i.Distance.multiline2multiline(this,t);throw $i.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof $i.Multiline?function(t,e){let n=[];for(let s of t)for(let t of e)n=[...n,...Sr(s.shape,t.shape)];return n}(this,t):Mr(t,this)}contains(t){if(t instanceof $i.Point)return this.edges.some(e=>e.shape.contains(t));throw $i.Errors.UNSUPPORTED_SHAPE_TYPE}translate(e){return new t(this.edges.map(t=>t.shape.translate(e)))}rotate(e=0,n=new $i.Point){return new t(this.edges.map(t=>t.shape.rotate(e,n)))}transform(e=new $i.Matrix){return new t(this.edges.map(t=>t.shape.transform(e)))}toShapes(){return this.edges.map(t=>t.shape.clone())}toJSON(){return this.edges.map(t=>t.toJSON())}svgPoints(){return this.vertices.map(t=>`${t.x},${t.y}`).join(" ")}dpath(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let e of this)t+=e.svg();return t}svg(t={}){let e=`\n<path ${Ui({fill:"none",...t})} d="`;e+=`\nM${this.first.start.x},${this.first.start.y}`;for(let t of this)e+=t.svg();return e+='" >\n</path>',e}};$i.Multiline=Nr;function Ir(t,e,n){let s=n.length,o=t.shape.split(e);if(0===o.length)return;let i=0;i=null===o[0]?0:null===o[1]?t.shape.length:o[0].length;let r,a=0;Yi(i,0)&&(a|=1),Yi(i,t.shape.length)&&(a|=2),r=i===1/0?o[0].coord(e):2&a&&t.next&&0===t.next.arc_length?0:t.arc_length+i,n.push({id:s,pt:e,arc_length:r,edge_before:t,edge_after:void 0,face:t.face,is_vertex:a})}function _r(t){t.int_points1_sorted=Cr(t.int_points1),t.int_points2_sorted=Cr(t.int_points2)}function Cr(t){let e=new Map,n=0;for(let s of t)e.has(s.face)||(e.set(s.face,n),n++);for(let n of t)n.faceId=e.get(n.face);return t.slice().sort(Tr)}function Tr(t,e){return t.faceId<e.faceId?-1:t.faceId>e.faceId?1:t.arc_length<e.arc_length?-1:t.arc_length>e.arc_length?1:0}function Er(t){if(t.int_points1.length<2)return;let e,n,s,o,i=!1;for(let r=0;r<t.int_points1_sorted.length;r++)if(-1!==t.int_points1_sorted[r].id){e=t.int_points1_sorted[r],n=t.int_points2[e.id];for(let a=r+1;a<t.int_points1_sorted.length&&(s=t.int_points1_sorted[a],Yi(s.arc_length,e.arc_length));a++)-1!==s.id&&(o=t.int_points2[s.id],-1!==o.id&&s.edge_before===e.edge_before&&s.edge_after===e.edge_after&&o.edge_before===n.edge_before&&o.edge_after===n.edge_after&&(s.id=-1,o.id=-1,i=!0))}n=t.int_points2_sorted[0],e=t.int_points1[n.id];for(let s=1;s<t.int_points2_sorted.length;s++){let o=t.int_points2_sorted[s];if(-1===o.id)continue;if(-1===n.id||!Yi(o.arc_length,n.arc_length)){n=o,e=t.int_points1[n.id];continue}let r=t.int_points1[o.id];r.edge_before===e.edge_before&&r.edge_after===e.edge_after&&o.edge_before===n.edge_before&&o.edge_after===n.edge_after&&(r.id=-1,o.id=-1,i=!0)}i&&(t.int_points1=t.int_points1.filter(t=>t.id>=0),t.int_points2=t.int_points2.filter(t=>t.id>=0),t.int_points1.forEach((t,e)=>t.id=e),t.int_points2.forEach((t,e)=>t.id=e))}function wr(t){for(let e of t)e.edge_before&&(e.edge_before.bvStart=void 0,e.edge_before.bvEnd=void 0,e.edge_before.bv=void 0,e.edge_before.overlap=void 0),e.edge_after&&(e.edge_after.bvStart=void 0,e.edge_after.bvEnd=void 0,e.edge_after.bv=void 0,e.edge_after.overlap=void 0);for(let e of t)e.edge_before&&(e.edge_before.bvEnd=2),e.edge_after&&(e.edge_after.bvStart=2)}function Rr(t,e){for(let n of t)n.edge_before&&n.edge_before.setInclusion(e),n.edge_after&&n.edge_after.setInclusion(e)}function Or(t,e,n){let s,o,i=1;if(1===t.length)return 1;s=t[e];for(let r=e+1;r<t.length&&s.face===n&&(o=t[r],o.pt.equalTo(s.pt)&&o.edge_before===s.edge_before&&o.edge_after===s.edge_after);r++)i++;return i}function Ar(t,e){if(e){for(let n of e){let e=n.edge_before;if(n.is_vertex=0,e.shape.start&&e.shape.start.equalTo(n.pt)&&(n.is_vertex|=1),e.shape.end&&e.shape.end.equalTo(n.pt)&&(n.is_vertex|=2),1&n.is_vertex){n.edge_before=e.prev,e.prev&&(n.is_vertex=2);continue}if(2&n.is_vertex)continue;let s=t.addVertex(n.pt,e);n.edge_before=s}for(let n of e)n.edge_before?n.edge_after=n.edge_before.next:t instanceof Nr&&1&n.is_vertex&&(n.edge_after=t.first)}}function zr(t,e,n){const s=t.edge_before,o=e.edge_after,i=n.length;s.next=n[0],n[0].prev=s,n[i-1].next=o,o.prev=n[i-1]}$i.multiline=(...t)=>new $i.Multiline(...t);var{INSIDE:Dr,OUTSIDE:Lr,BOUNDARY:Fr,OVERLAP_SAME:Yr,OVERLAP_OPPOSITE:Xr}=Ai,{NOT_VERTEX:kr,START_VERTEX:$r,END_VERTEX:Br}=Ai;function jr(t,e){let n=e.clone().reverse(),[s,o]=Zr(t,n,3,!0);return s}function Wr(t,e){let[n,s]=Zr(t,e,2,!0);return n}function Hr(t,e){let[n,s]=Zr(t,e,2,!1),o=[];for(let t of n.faces)o=[...o,...[...t.edges].map(t=>t.shape)];let i=[];for(let t of s.faces)i=[...i,...[...t.edges].map(t=>t.shape)];return[o,i]}function Ur(t,e){let[n,s]=Zr(t,e,3,!1),o=[];for(let t of n.faces)o=[...o,...[...t.edges].map(t=>t.shape)];return o}function Vr(t,e){let n=t.clone(),s=e.clone(),o=qr(n,s);return _r(o),Ar(n,o.int_points1_sorted),Ar(s,o.int_points2_sorted),Er(o),_r(o),[o.int_points1_sorted.map(t=>t.pt),o.int_points2_sorted.map(t=>t.pt)]}function Gr(t,e,n,s){let o=Jr(t,n.int_points1),i=Jr(e,n.int_points2);for(Kr(o,e),Kr(i,t),wr(n.int_points1),wr(n.int_points2),Rr(n.int_points1,e),Rr(n.int_points2,t);Qr(t,e,n.int_points1,n.int_points1_sorted,n.int_points2,n););!function(t){let e,n,s,o=t.int_points1.length;for(let i=0;i<o;i++){let r=t.int_points1_sorted[i];r.face!==e&&(n=i,e=r.face);let a,c=i,h=Or(t.int_points1_sorted,i,e);a=c+h<o&&t.int_points1_sorted[c+h].face===e?c+h:n;let l=Or(t.int_points1_sorted,a,e);s=null;for(let n=a;n<a+l;n++){let o=t.int_points1_sorted[n];if(o.face===e&&t.int_points2[o.id].face===t.int_points2[r.id].face){s=o;break}}if(null===s)continue;let d=r.edge_after,u=s.edge_before;if(2!==d.bv||2!==u.bv)continue;if(d!==u)continue;let p=t.int_points2[r.id],f=t.int_points2[s.id],m=p.edge_after,g=f.edge_before;2===m.bv&&2===g.bv&&m===g||(p=t.int_points2[s.id],f=t.int_points2[r.id],m=p.edge_after,g=f.edge_before),2===m.bv&&2===g.bv&&m===g&&d.setOverlap(m)}}(n),ta(t,s,n.int_points1_sorted,!0),ta(e,s,n.int_points2_sorted,!1),sa(t,o,s,!0),sa(e,i,s,!1)}function Zr(t,e,n,s){let o=t.clone(),i=e.clone(),r=qr(o,i);return _r(r),Ar(o,r.int_points1_sorted),Ar(i,r.int_points2_sorted),Er(r),_r(r),Gr(o,i,r,n),s&&function(t,e,n){!function(t,e,n,s){for(let n of e.faces){for(let e of n)t.edges.add(e);void 0===s.find(t=>t.face===n)&&t.addFace(n.first,n.last)}}(t,e,0,n.int_points2),function(t,e,n){if(0!==n.int_points1.length)for(let t=0;t<n.int_points1.length;t++){let e=n.int_points1[t],s=n.int_points2[t];if(void 0!==e.edge_before&&void 0===e.edge_after&&void 0===s.edge_before&&void 0!==s.edge_after&&(e.edge_before.next=s.edge_after,s.edge_after.prev=e.edge_before,e.edge_after=s.edge_after,s.edge_before=e.edge_before),void 0!==s.edge_before&&void 0===s.edge_after&&void 0===e.edge_before&&void 0!==e.edge_after&&(s.edge_before.next=e.edge_after,e.edge_after.prev=s.edge_before,s.edge_after=e.edge_after,e.edge_before=s.edge_before),void 0!==e.edge_before&&void 0===e.edge_after)for(let t of n.int_points1_sorted)t!==e&&void 0===t.edge_before&&void 0!==t.edge_after&&t.pt.equalTo(e.pt)&&(e.edge_before.next=t.edge_after,t.edge_after.prev=e.edge_before,e.edge_after=t.edge_after,t.edge_before=e.edge_before);if(void 0!==s.edge_before&&void 0===s.edge_after)for(let t of n.int_points2_sorted)t!==s&&void 0===t.edge_before&&void 0!==t.edge_after&&t.pt.equalTo(s.pt)&&(s.edge_before.next=t.edge_after,t.edge_after.prev=s.edge_before,s.edge_after=t.edge_after,t.edge_before=s.edge_before)}}(0,0,n),ea(t,n.int_points1),ea(e,n.int_points2),na(t,n.int_points1,n.int_points2),na(t,n.int_points2,n.int_points1)}(o,i,r),[o,i]}function qr(t,e){let n={int_points1:[],int_points2:[]};for(let s of t.edges){let t=e.edges.search(s.box);for(let e of t){let t=s.shape.intersect(e.shape);for(let o of t)Ir(s,o,n.int_points1),Ir(e,o,n.int_points2)}}return n}function Jr(t,e){let n=[];for(let s of t.faces)e.find(t=>t.face===s)||n.push(s);return n}function Kr(t,e){for(let n of t)n.first.bv=n.first.bvStart=n.first.bvEnd=void 0,n.first.setInclusion(e)}function Qr(t,e,n,s,o,i){let r,a,c,h=s.length,l=!1;for(let d=0;d<h;d++){let u=s[d];u.face!==r&&(a=d,r=u.face);let p,f=d,m=Or(s,d,r);p=f+m<h&&s[f+m].face===r?f+m:a;let g=Or(s,p,r);c=null;for(let t=p;t<p+g;t++){let e=s[t];if(e.face===r&&o[e.id].face===o[u.id].face){c=e;break}}if(null===c)continue;let y=u.edge_after,x=c.edge_before;if(y.bv!==Fr||x.bv==Fr)if(y.bv==Fr||x.bv!==Fr){if(y.bv===Fr&&x.bv===Fr&&y!=x||y.bv===Dr&&x.bv===Lr||y.bv===Lr&&x.bv===Dr){let t=y.next;for(;t!=x;)t.bvStart=void 0,t.bvEnd=void 0,t.bv=void 0,t.setInclusion(e),t=t.next}if(y.bv===Fr&&x.bv===Fr&&y!=x){let t,e=y.next;for(;e!=x;){if(e.bv!=Fr)if(void 0===t)t=e.bv;else if(e.bv!=t)throw Bi.UNRESOLVED_BOUNDARY_CONFLICT;e=e.next}null!=t&&(y.bv=t,x.bv=t);continue}if(y.bv===Dr&&x.bv===Lr||y.bv===Lr&&x.bv===Dr){let s=y;for(;s!=x;){if(s.bvStart===y.bv&&s.bvEnd===x.bv){let[r,a]=s.shape.distanceTo(e);if(r<10*$i.DP_TOL){Ir(s,a.ps,n);let r=n[n.length-1];if(r.is_vertex&$r)r.edge_after=s,r.edge_before=s.prev,s.bvStart=Fr,s.bv=void 0,s.setInclusion(e);else if(r.is_vertex&Br)r.edge_after=s.next,s.bvEnd=Fr,s.bv=void 0,s.setInclusion(e);else{let t=e.addVertex(r.pt,s);r.edge_before=t,r.edge_after=t.next,t.setInclusion(e),t.next.bvStart=Fr,t.next.bvEnd=void 0,t.next.bv=void 0,t.next.setInclusion(e)}let c=e.findEdgeByPoint(a.pe);Ir(c,a.pe,o);let h=o[o.length-1];if(h.is_vertex&$r)h.edge_after=c,h.edge_before=c.prev;else if(h.is_vertex&Br)h.edge_after=c.next;else{let n=o.find(t=>t.edge_after===c),s=e.addVertex(h.pt,c);h.edge_before=s,h.edge_after=s.next,n&&(n.edge_after=s),s.bvStart=void 0,s.bvEnd=Fr,s.bv=void 0,s.setInclusion(t),s.next.bvStart=Fr,s.next.bvEnd=void 0,s.next.bv=void 0,s.next.setInclusion(t)}_r(i),l=!0;break}}s=s.next}if(l)break;throw Bi.UNRESOLVED_BOUNDARY_CONFLICT}}else x.bv=y.bv;else y.bv=x.bv}return l}function ta(t,e,n,s){if(!n)return;let o,i,r,a;for(let c=0;c<n.length;c++){if(r=n[c],r.face!==o&&(i=c,o=r.face),o.isEmpty())continue;let h,l=c,d=Or(n,c,o);h=l+d<n.length&&n[l+d].face===r.face?l+d:i,a=n[h];let u=h,p=Or(n,u,o),f=r.edge_after,m=a.edge_before;if(f.bv===Dr&&m.bv===Dr&&1===e||f.bv===Lr&&m.bv===Lr&&2===e||(f.bv===Lr||m.bv===Lr)&&3===e&&!s||(f.bv===Dr||m.bv===Dr)&&3===e&&s||f.bv===Fr&&m.bv===Fr&&f.overlap&Yr&&s||f.bv===Fr&&m.bv===Fr&&f.overlap&Xr){t.removeChain(o,f,m);for(let t=l;t<l+d;t++)n[t].edge_after=void 0;for(let t=u;t<u+p;t++)n[t].edge_before=void 0}c+=d-1}}function ea(t,e){for(let n of e)t.faces.delete(n.face),n.face=void 0,n.edge_before&&(n.edge_before.face=void 0),n.edge_after&&(n.edge_after.face=void 0)}function na(t,e,n){for(let s of e){if(void 0===s.edge_before||void 0===s.edge_after)continue;if(s.face)continue;if(s.edge_after.face||s.edge_before.face)continue;let o=s.edge_after,i=s.edge_before;try{ji.testInfiniteLoop(o)}catch(t){throw Bi.CANNOT_COMPLETE_BOOLEAN_OPERATION}let r=t.addFace(o,i);for(let t of e)t.edge_before&&t.edge_after&&t.edge_before.face===r&&t.edge_after.face===r&&(t.face=r);for(let t of n)t.edge_before&&t.edge_after&&t.edge_before.face===r&&t.edge_after.face===r&&(t.face=r)}}function sa(t,e,n,s){for(let o of e){let e=o.first.bv;(1===n&&e===Dr||3===n&&e===Dr&&s||3===n&&e===Lr&&!s||2===n&&e===Lr)&&t.deleteFace(o)}}var oa=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:2,BOOLEAN_SUBTRACT:3,BOOLEAN_UNION:1,calculateIntersections:Vr,innerClip:Hr,intersect:Wr,outerClip:Ur,removeNotRelevantChains:ta,removeOldFaces:ea,restoreFaces:na,subtract:jr,unify:function(t,e){let[n,s]=Zr(t,e,1,!0);return n}}),ia=RegExp("T.F..FFF.|T.F...F.."),ra=RegExp("T........|.T.......|...T.....|....T...."),aa=RegExp("FT.......|F..T.....|F...T...."),ca=RegExp("T.F..F..."),ha=RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF..."),la=class{constructor(){this.m=new Array(9).fill(void 0)}get I2I(){return this.m[0]}set I2I(t){this.m[0]=t}get I2B(){return this.m[1]}set I2B(t){this.m[1]=t}get I2E(){return this.m[2]}set I2E(t){this.m[2]=t}get B2I(){return this.m[3]}set B2I(t){this.m[3]=t}get B2B(){return this.m[4]}set B2B(t){this.m[4]=t}get B2E(){return this.m[5]}set B2E(t){this.m[5]=t}get E2I(){return this.m[6]}set E2I(t){this.m[6]=t}get E2B(){return this.m[7]}set E2B(t){this.m[7]=t}get E2E(){return this.m[8]}set E2E(t){this.m[8]=t}toString(){return this.m.map(t=>t instanceof Array&&t.length>0?"T":t instanceof Array&&0===t.length?"F":"*").join("")}equal(){return ia.test(this.toString())}intersect(){return ra.test(this.toString())}touch(){return aa.test(this.toString())}inside(){return ca.test(this.toString())}covered(){return ha.test(this.toString())}};function da(t,e){let n,s=new $i.Ray(e),o=new $i.Line(s.pt,s.norm);const i=new $i.Box(s.box.xmin-$i.DP_TOL,s.box.ymin-$i.DP_TOL,s.box.xmax+$i.DP_TOL,s.box.ymax+$i.DP_TOL);if(t.box.not_intersect(i))return $i.OUTSIDE;let r=t.edges.search(i);if(0===r.length)return $i.OUTSIDE;for(let t of r)if(t.shape.contains(e))return $i.BOUNDARY;let a=[...t.faces],c=[];for(let t of r)for(let n of s.intersect(t.shape)){if(n.equalTo(e))return $i.BOUNDARY;c.push({pt:n,edge:t,face_index:a.indexOf(t.face)})}c.sort((t,e)=>ki(t.pt.x,e.pt.x)?-1:Xi(t.pt.x,e.pt.x)?1:t.face_index<e.face_index?-1:t.face_index>e.face_index?1:t.edge.arc_length<e.edge.arc_length?-1:t.edge.arc_length>e.edge.arc_length?1:0);let h=0;for(let t=0;t<c.length;t++){let e=c[t];if(e.pt.equalTo(e.edge.shape.start)){if(t>0&&e.pt.equalTo(c[t-1].pt)&&e.face_index===c[t-1].face_index&&e.edge.prev===c[t-1].edge)continue;let n=e.edge.prev;for(;Fi(n.length);)n=n.prev;let s=n.shape.tangentInEnd(),i=e.pt.translate(s),r=e.edge.shape.tangentInStart(),a=e.pt.translate(r),l=i.leftTo(o),d=a.leftTo(o);(l&&!d||!l&&d)&&h++}else if(e.pt.equalTo(e.edge.shape.end)){if(t>0&&e.pt.equalTo(c[t-1].pt)&&e.face_index===c[t-1].face_index&&e.edge.next===c[t-1].edge)continue;let n=e.edge.next;for(;Fi(n.length);)n=n.next;let s=n.shape.tangentInStart(),i=e.pt.translate(s),r=e.edge.shape.tangentInEnd(),a=e.pt.translate(r),l=i.leftTo(o),d=a.leftTo(o);(l&&!d||!l&&d)&&h++}else if(e.edge.shape instanceof $i.Segment)h++;else{let t=e.edge.shape.box;Yi(e.pt.y,t.ymin)||Yi(e.pt.y,t.ymax)||h++}}return n=h%2==1?1:0,n}function ua(t,e){return ga(t,e).intersect()}function pa(t,e){return ga(t,e).inside()}function fa(t,e){return ga(t,e).covered()}function ma(t,e){return fa(e,t)}function ga(t,e){return t instanceof $i.Line&&e instanceof $i.Line?function(t,e){let n=new la,s=Vi(t,e);0===s.length?t.contains(e.pt)&&e.contains(t.pt)?(n.I2I=[t],n.I2E=[],n.E2I=[]):(n.I2I=[],n.I2E=[t],n.E2I=[e]):(n.I2I=s,n.I2E=t.split(s),n.E2I=e.split(s));return n}(t,e):t instanceof $i.Line&&e instanceof $i.Circle?function(t,e){let n=new la,s=Gi(t,e);if(0===s.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===s.length)n.I2I=[],n.I2B=s,n.I2E=t.split(s),n.E2I=[e];else{let o=new Nr([t]),i=t.sortPoints(s);o.split(i);let r=o.toShapes();n.I2I=[r[1]],n.I2B=i,n.I2E=[r[0],r[2]],n.E2I=new $i.Polygon([e.toArc()]).cutWithLine(t)}return n}(t,e):t instanceof $i.Line&&e instanceof $i.Box?function(t,e){let n=new la,s=Zi(t,e);if(0===s.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===s.length)n.I2I=[],n.I2B=s,n.I2E=t.split(s),n.E2I=[e];else{let o=new Nr([t]),i=t.sortPoints(s);o.split(i);let r=o.toShapes();e.toSegments().some(t=>t.contains(s[0])&&t.contains(s[1]))?(n.I2I=[],n.I2B=[r[1]],n.I2E=[r[0],r[2]],n.E2I=[e]):(n.I2I=[r[1]],n.I2B=i,n.I2E=[r[0],r[2]],n.E2I=new $i.Polygon(e.toSegments()).cutWithLine(t))}return n}(t,e):t instanceof $i.Line&&e instanceof $i.Polygon?function(t,e){let n=new la,s=dr(t,e),o=new Nr([t]),i=s.length>0?s.slice():t.sortPoints(s);return o.split(i),[...o].forEach(t=>t.setInclusion(e)),n.I2I=[...o].filter(t=>t.bv===$i.INSIDE).map(t=>t.shape),n.I2B=[...o].slice(1).map(t=>t.bv===$i.BOUNDARY?t.shape:t.shape.start),n.I2E=[...o].filter(t=>t.bv===$i.OUTSIDE).map(t=>t.shape),n.E2I=e.cutWithLine(t),n}(t,e):(t instanceof $i.Segment||t instanceof $i.Arc)&&e instanceof $i.Polygon?ya(t,e):(t instanceof $i.Segment||t instanceof $i.Arc)&&(e instanceof $i.Circle||e instanceof $i.Box)?ya(t,new $i.Polygon(e)):t instanceof $i.Polygon&&e instanceof $i.Polygon?xa(t,e):(t instanceof $i.Circle||t instanceof $i.Box)&&(e instanceof $i.Circle||e instanceof $i.Box)?xa(new $i.Polygon(t),new $i.Polygon(e)):(t instanceof $i.Circle||t instanceof $i.Box)&&e instanceof $i.Polygon?xa(new $i.Polygon(t),e):t instanceof $i.Polygon&&(e instanceof $i.Circle||e instanceof $i.Box)?xa(t,new $i.Polygon(e)):void 0}function ya(t,e){let n=new la,s=function(t,e){return t instanceof $i.Line?dr(t,e):t instanceof $i.Segment?hr(t,e):t instanceof $i.Arc?lr(t,e):[]}(t,e),o=s.length>0?s.slice():t.sortPoints(s),i=new Nr([t]);i.split(o),[...i].forEach(t=>t.setInclusion(e)),n.I2I=[...i].filter(t=>t.bv===$i.INSIDE).map(t=>t.shape),n.I2B=[...i].slice(1).map(t=>t.bv===$i.BOUNDARY?t.shape:t.shape.start),n.I2E=[...i].filter(t=>t.bv===$i.OUTSIDE).map(t=>t.shape),n.B2I=[],n.B2B=[],n.B2E=[];for(let s of[t.start,t.end])switch(da(e,s)){case $i.INSIDE:n.B2I.push(s);break;case $i.BOUNDARY:n.B2B.push(s);break;case $i.OUTSIDE:n.B2E.push(s)}return n}function xa(t,e){let n=new la,[s,o]=Vr(t,e),i=Wr(t,e),r=jr(t,e),a=jr(e,t),[c,h]=Hr(t,e),l=Ur(t,e),d=Ur(e,t);return n.I2I=i.isEmpty()?[]:[i],n.I2B=h,n.I2E=r.isEmpty()?[]:[r],n.B2I=c,n.B2B=s,n.B2E=l,n.E2I=a.isEmpty()?[]:[a],n.E2B=d,n}var va=Object.freeze({__proto__:null,contain:function(t,e){return pa(e,t)},cover:ma,covered:fa,disjoint:function(t,e){return!ua(t,e)},equal:function(t,e){return ga(t,e).equal()},inside:pa,intersect:ua,relate:ga,touch:function(t,e){return ga(t,e).touch()}}),ba=class t{constructor(t=1,e=0,n=0,s=1,o=0,i=0){this.a=t,this.b=e,this.c=n,this.d=s,this.tx=o,this.ty=i}fromMatrix3x3(e){const[n,s,o]=e[0],[i,r,a]=e[1];return new t(n,i,s,r,o,a)}toMatrix3x3(){return[[this.a,this.c,this.tx],[this.b,this.d,this.ty],[0,0,1]]}clone(){return new t(this.a,this.b,this.c,this.d,this.tx,this.ty)}transform(t){return[t[0]*this.a+t[1]*this.c+this.tx,t[0]*this.b+t[1]*this.d+this.ty]}multiply(e){return new t(this.a*e.a+this.c*e.b,this.b*e.a+this.d*e.b,this.a*e.c+this.c*e.d,this.b*e.c+this.d*e.d,this.a*e.tx+this.c*e.ty+this.tx,this.b*e.tx+this.d*e.ty+this.ty)}translate(...e){let n,s;if(1!=e.length||isNaN(e[0].x)||isNaN(e[0].y)){if(2!==e.length||"number"!=typeof e[0]||"number"!=typeof e[1])throw Bi.ILLEGAL_PARAMETERS;n=e[0],s=e[1]}else n=e[0].x,s=e[0].y;return this.multiply(new t(1,0,0,1,n,s))}rotate(e,n=0,s=0){let o=Math.cos(e),i=Math.sin(e);return this.translate(n,s).multiply(new t(o,i,-i,o,0,0)).translate(-n,-s)}scale(e,n){return this.multiply(new t(e,0,0,n,0,0))}equalTo(t){return!!$i.Utils.EQ(this.tx,t.tx)&&(!!$i.Utils.EQ(this.ty,t.ty)&&(!!$i.Utils.EQ(this.a,t.a)&&(!!$i.Utils.EQ(this.b,t.b)&&(!!$i.Utils.EQ(this.c,t.c)&&!!$i.Utils.EQ(this.d,t.d)))))}};$i.Matrix=ba;$i.matrix=(...t)=>new $i.Matrix(...t);var Pa=class{constructor(t,e){this.low=t,this.high=e}get max(){return this.clone()}less_than(t){return this.low<t.low||this.low===t.low&&this.high<t.high}equal_to(t){return this.low===t.low&&this.high===t.high}intersect(t){return!this.not_intersect(t)}not_intersect(t){return this.high<t.low||t.high<this.low}merge(t){const e=void 0===this.low?t.low:this.low<t.low?this.low:t.low,n=void 0===this.high?t.high:this.high>t.high?this.high:t.high,s=this.clone();return s.low=e,s.high=n,s}output(){return[this.low,this.high]}comparable_less_than(t,e){return t<e}},Sa=class t extends Pa{clone(){return new t(this.low,this.high)}},Ma=class{constructor(t,e,n=null,s=null,o=null,i=0){if(this.left=n,this.right=s,this.parent=o,this.color=i,this.item={key:void 0,values:[]},void 0!==e&&this.item.values.push(e),void 0!==t)if(Array.isArray(t)){const[e,n]=t;if(!Number.isNaN(e)&&!Number.isNaN(n)){let t=e,s=n;t>s&&([t,s]=[s,t]),this.item.key=new Sa(t,s)}}else this.item.key=t;this.max=this.item.key?this.item.key.max:void 0}isNil(){return void 0===this.item.key&&0===this.item.values.length&&null===this.left&&null===this.right&&0===this.color}requireKey(){if(!this.item.key)throw new Error("Node key is undefined (nil/sentinel). Operation is not applicable.");return this.item.key}less_than(t){const e=this.requireKey(),n=t.requireKey();return e.less_than(n)}_value_equal(t){const e=this.item.values[0],n=t.item.values[0];return e&&n&&e.equal_to?e.equal_to(n):e===n}equal_to(t){const e=this.requireKey(),n=t.requireKey();return e.equal_to(n)}intersect(t){const e=this.requireKey(),n=t.requireKey();return e.intersect(n)}copy_data(t){this.item.key=t.item.key,this.item.values=t.item.values.slice()}update_max(){this.max=this.item.key?this.item.key.max:void 0,this.right&&this.right.max&&(this.max=this.max?this.max.merge(this.right.max):this.right.max),this.left&&this.left.max&&(this.max=this.max?this.max.merge(this.left.max):this.left.max)}not_intersect_left_subtree(t){if(!this.left)return!0;const e=this.left.max?this.left.max.high:this.left.item.key.high,n=this.requireKey(),s=t.requireKey();return n.comparable_less_than(e,s.low)}not_intersect_right_subtree(t){if(!this.right)return!0;const e=this.right.max?this.right.max.low:this.right.item.key.low,n=this.requireKey(),s=t.requireKey();return n.comparable_less_than(s.high,e)}},Na=class t{constructor(){this.root=null,this.nil_node=new Ma}get size(){let t=0;return this.tree_walk(this.root,e=>t+=e.item.values.length),t}get keys(){const t=[];return this.tree_walk(this.root,e=>t.push(e.item.key.output())),t}get values(){const t=[];return this.tree_walk(this.root,e=>{for(const n of e.item.values)t.push(n)}),t}get items(){const t=[];return this.tree_walk(this.root,e=>{const n=e.item.key.output();for(const s of e.item.values)t.push({key:n,value:s})}),t}isEmpty(){return null==this.root||this.root===this.nil_node}clear(){this.root=null}insert(t,e=t){if(void 0===t)return;const n=this.tree_search(this.root,new Ma(t));if(n)return n.item.values.push(e),n;const s=new Ma(t,e,this.nil_node,this.nil_node,null,1);return this.tree_insert(s),this.recalc_max(s),s}exist(t,e=t){const n=this.tree_search(this.root,new Ma(t));return!!n&&(arguments.length<2||e===t||n.item.values.some(t=>t&&t.equal_to?t.equal_to(e):t===e))}remove(t,e=t){const n=this.tree_search(this.root,new Ma(t));if(!n)return;if(arguments.length<2)return this.tree_delete(n),n;const s=n.item.values.findIndex(t=>t&&t.equal_to?t.equal_to(e):t===e);return s>=0?(n.item.values.splice(s,1),0===n.item.values.length&&this.tree_delete(n),n):void 0}search(t,e=(t,e)=>t===e?e.output():t){const n=new Ma(t),s=[];this.tree_search_interval(this.root,n,s);const o=[];for(const t of s)for(const n of t.item.values)o.push(e(n,t.item.key));return o}intersect_any(t){const e=new Ma(t);return this.tree_find_any_interval(this.root,e)}forEach(t){this.tree_walk(this.root,e=>{for(const n of e.item.values)t(e.item.key,n)})}map(e){const n=new t;return this.tree_walk(this.root,t=>{for(const s of t.item.values)n.insert(t.item.key,e(s,t.item.key))}),n}*iterate(t,e=(t,e)=>t===e?e.output():t){let n=null;for(t?n=this.tree_search_nearest_forward(this.root,new Ma(t)):this.root&&(n=this.local_minimum(this.root));n;){for(const t of n.item.values)yield e(t,n.item.key);n=this.tree_successor(n)}}recalc_max(t){let e=t;for(;null!=e.parent;)e.parent.update_max(),e=e.parent}tree_insert(t){let e=this.root,n=null;if(null==this.root||this.root===this.nil_node)this.root=t;else{for(;e!==this.nil_node;)n=e,e=t.less_than(e)?e.left:e.right;t.parent=n,t.less_than(n)?n.left=t:n.right=t}this.insert_fixup(t)}insert_fixup(t){let e,n;for(e=t;e!==this.root&&1===e.parent.color;)e.parent===e.parent.parent.left?(n=e.parent.parent.right,1===n.color?(e.parent.color=0,n.color=0,e.parent.parent.color=1,e=e.parent.parent):(e===e.parent.right&&(e=e.parent,this.rotate_left(e)),e.parent.color=0,e.parent.parent.color=1,this.rotate_right(e.parent.parent))):(n=e.parent.parent.left,1===n.color?(e.parent.color=0,n.color=0,e.parent.parent.color=1,e=e.parent.parent):(e===e.parent.left&&(e=e.parent,this.rotate_right(e)),e.parent.color=0,e.parent.parent.color=1,this.rotate_left(e.parent.parent)));this.root.color=0}tree_delete(t){let e,n;e=t.left===this.nil_node||t.right===this.nil_node?t:this.tree_successor(t),n=e.left!==this.nil_node?e.left:e.right,n.parent=e.parent,e===this.root?this.root=n:(e===e.parent.left?e.parent.left=n:e.parent.right=n,e.parent.update_max()),this.recalc_max(n),e!==t&&(t.copy_data(e),t.update_max(),this.recalc_max(t)),0===e.color&&this.delete_fixup(n)}delete_fixup(t){let e,n=t;for(;n!==this.root&&null!=n.parent&&0===n.color;)n===n.parent.left?(e=n.parent.right,1===e.color&&(e.color=0,n.parent.color=1,this.rotate_left(n.parent),e=n.parent.right),0===e.left.color&&0===e.right.color?(e.color=1,n=n.parent):(0===e.right.color&&(e.color=1,e.left.color=0,this.rotate_right(e),e=n.parent.right),e.color=n.parent.color,n.parent.color=0,e.right.color=0,this.rotate_left(n.parent),n=this.root)):(e=n.parent.left,1===e.color&&(e.color=0,n.parent.color=1,this.rotate_right(n.parent),e=n.parent.left),0===e.left.color&&0===e.right.color?(e.color=1,n=n.parent):(0===e.left.color&&(e.color=1,e.right.color=0,this.rotate_left(e),e=n.parent.left),e.color=n.parent.color,n.parent.color=0,e.left.color=0,this.rotate_right(n.parent),n=this.root));n.color=0}tree_search(t,e){if(null!=t&&t!==this.nil_node)return e.equal_to(t)?t:e.less_than(t)?this.tree_search(t.left,e):this.tree_search(t.right,e)}tree_search_nearest_forward(t,e){let n=null,s=t;for(;s&&s!==this.nil_node;)s.less_than(e)?s.intersect(e)?(n=s,s=s.left):s=s.right:(n&&!s.less_than(n)||(n=s),s=s.left);return n||null}tree_search_interval(t,e,n){null!=t&&t!==this.nil_node&&(t.left===this.nil_node||t.not_intersect_left_subtree(e)||this.tree_search_interval(t.left,e,n),t.intersect(e)&&n.push(t),t.right===this.nil_node||t.not_intersect_right_subtree(e)||this.tree_search_interval(t.right,e,n))}tree_find_any_interval(t,e){let n=!1;return null!=t&&t!==this.nil_node&&(t.left===this.nil_node||t.not_intersect_left_subtree(e)||(n=this.tree_find_any_interval(t.left,e)),n||(n=t.intersect(e)),n||t.right===this.nil_node||t.not_intersect_right_subtree(e)||(n=this.tree_find_any_interval(t.right,e))),n}local_minimum(t){let e=t;for(;null!=e.left&&e.left!==this.nil_node;)e=e.left;return e}local_maximum(t){let e=t;for(;null!=e.right&&e.right!==this.nil_node;)e=e.right;return e}tree_successor(t){let e,n,s;if(t.right!==this.nil_node)e=this.local_minimum(t.right);else{for(n=t,s=t.parent;null!=s&&s.right===n;)n=s,s=s.parent;e=s}return e}rotate_left(t){const e=t.right;t.right=e.left,e.left!==this.nil_node&&(e.left.parent=t),e.parent=t.parent,t===this.root?this.root=e:t===t.parent.left?t.parent.left=e:t.parent.right=e,e.left=t,t.parent=e,null!==t&&t!==this.nil_node&&t.update_max(),null!=e&&e!==this.nil_node&&e.update_max()}rotate_right(t){const e=t.left;t.left=e.right,e.right!==this.nil_node&&(e.right.parent=t),e.parent=t.parent,t===this.root?this.root=e:t===t.parent.left?t.parent.left=e:t.parent.right=e,e.right=t,t.parent=e,null!==t&&t!==this.nil_node&&t.update_max(),null!=e&&e!==this.nil_node&&e.update_max()}tree_walk(t,e){null!=t&&t!==this.nil_node&&(this.tree_walk(t.left,e),e(t),this.tree_walk(t.right,e))}testRedBlackProperty(){let t=!0;return this.tree_walk(this.root,function(e){1===e.color&&(0===e.left.color&&0===e.right.color||(t=!1))}),t}testBlackHeightProperty(t){let e=0,n=0,s=0;if(0===t.color&&e++,n=t.left!==this.nil_node?this.testBlackHeightProperty(t.left):1,s=t.right!==this.nil_node?this.testBlackHeightProperty(t.right):1,n!==s)throw new Error("Red-black height property violated");return e+=n,e}},Ia=class extends Set{constructor(t){super(t),this.index=new Na,this.forEach(t=>this.index.insert(t))}add(t){let e=this.size;const{key:n,value:s}=t,o=n||t.box,i=s||t;return super.add(i),this.size>e&&this.index.insert(o,i),this}delete(t){const{key:e,value:n}=t,s=e||t.box,o=n||t;let i=super.delete(o);return i&&this.index.remove(s,o),i}clear(){super.clear(),this.index=new Na}search(t){return this.index.search(t)}hit(t){let e=new $i.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(e).filter(e=>t.on(e))}svg(){return[...this].reduce((t,e)=>t+e.svg(),"")}};$i.PlanarSet=Ia;var _a=class{get name(){throw Bi.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw Bi.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw Bi.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform((new ba).translate(...t))}rotate(t,e=new $i.Point){return this.transform((new ba).rotate(t,e.x,e.y))}scale(t,e){return this.transform((new ba).scale(t,e))}transform(...t){throw Bi.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw Bi.CANNOT_INVOKE_ABSTRACT_METHOD}};$i.Point=class t extends _a{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length&&t[0]instanceof Array&&2===t[0].length){let e=t[0];if("number"==typeof e[0]&&"number"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length&&t[0]instanceof Object&&"point"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1])return this.x=t[0],void(this.y=t[1]);throw Bi.ILLEGAL_PARAMETERS}}get box(){return new $i.Box(this.x,this.y,this.x,this.y)}clone(){return new $i.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return $i.Utils.EQ(this.x,t.x)&&$i.Utils.EQ(this.y,t.y)}lessThan(t){return!!$i.Utils.LT(this.y,t.y)||!(!$i.Utils.EQ(this.y,t.y)||!$i.Utils.LT(this.x,t.x))}transform(t){return new $i.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new $i.Vector(this,t.pt);if($i.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),s=t.norm.multiply(n);return this.translate(s)}leftTo(t){let e=new $i.Vector(t.pt,this);return $i.Utils.GT(e.dot(t.norm),0)}distanceTo(e){if(e instanceof t){let t=e.x-this.x,n=e.y-this.y;return[Math.sqrt(t*t+n*n),new $i.Segment(this,e)]}return e instanceof $i.Line?$i.Distance.point2line(this,e):e instanceof $i.Circle?$i.Distance.point2circle(this,e):e instanceof $i.Segment?$i.Distance.point2segment(this,e):e instanceof $i.Arc?$i.Distance.point2arc(this,e):e instanceof $i.Polygon?$i.Distance.point2polygon(this,e):e instanceof $i.PlanarSet?$i.Distance.shape2planarSet(this,e):e instanceof $i.Multiline?$i.Distance.shape2multiline(this,e):void 0}on(t){if(t instanceof $i.Point)return this.equalTo(t);if(t.contains&&t.contains instanceof Function)return t.contains(this);throw $i.Errors.UNSUPPORTED_SHAPE_TYPE}get name(){return"point"}svg(t={}){const e=t.r??3;return`\n<circle cx="${this.x}" cy="${this.y}" r="${e}"\n ${Ui({fill:"red",...t})} />`}};var Ca=(...t)=>new $i.Point(...t);$i.point=Ca;$i.Vector=class extends _a{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length&&t[0]instanceof Array&&2===t[0].length){let e=t[0];if("number"==typeof e[0]&&"number"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length&&t[0]instanceof Object&&"vector"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(1===t.length&&t[0]instanceof Object&&"segment"===t[0].name){let{start:e,end:n}=t[0];return this.x=n.x-e.x,void(this.y=n.y-e.y)}if(2===t.length){let e=t[0],n=t[1];if("number"==typeof e&&"number"==typeof n)return this.x=e,void(this.y=n);if(e instanceof $i.Point&&n instanceof $i.Point)return this.x=n.x-e.x,void(this.y=n.y-e.y)}throw Bi.ILLEGAL_PARAMETERS}}clone(){return new $i.Vector(this.x,this.y)}get slope(){let t=Math.atan2(this.y,this.x);return t<0&&(t=2*Math.PI+t),t}get length(){return Math.sqrt(this.dot(this))}isZeroLength(){return $i.Utils.EQ_0(this.length)}equalTo(t){return $i.Utils.EQ(this.x,t.x)&&$i.Utils.EQ(this.y,t.y)}multiply(t){return new $i.Vector(t*this.x,t*this.y)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}normalize(){if(this.isZeroLength())throw Bi.ZERO_DIVISION;return new $i.Vector(this.x/this.length,this.y/this.length)}rotate(t,e=new $i.Point){if(0===e.x&&0===e.y)return this.transform((new ba).rotate(t));throw Bi.OPERATION_IS_NOT_SUPPORTED}transform(t){return new $i.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new $i.Vector(-this.y,this.x)}rotate90CW(){return new $i.Vector(this.y,-this.x)}invert(){return new $i.Vector(-this.x,-this.y)}add(t){return new $i.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new $i.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),s=Math.atan2(e.cross(n),e.dot(n));return s<0&&(s+=2*Math.PI),s}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return"vector"}};var Ta=(...t)=>new $i.Vector(...t);$i.vector=Ta;$i.Segment=class t extends _a{constructor(...t){if(super(),this.ps=new $i.Point,this.pe=new $i.Point,0!==t.length){if(1===t.length&&t[0]instanceof Array&&4===t[0].length){let e=t[0];return this.ps=new $i.Point(e[0],e[1]),void(this.pe=new $i.Point(e[2],e[3]))}if(1===t.length&&t[0]instanceof Object&&"segment"===t[0].name){let{ps:e,pe:n}=t[0];return this.ps=new $i.Point(e.x,e.y),void(this.pe=new $i.Point(n.x,n.y))}if(!(1===t.length&&t[0]instanceof $i.Point)){if(2===t.length&&t[0]instanceof $i.Point&&t[1]instanceof $i.Point)return this.ps=t[0].clone(),void(this.pe=t[1].clone());if(4===t.length)return this.ps=new $i.Point(t[0],t[1]),void(this.pe=new $i.Point(t[2],t[3]));throw Bi.ILLEGAL_PARAMETERS}this.ps=t[0].clone()}}clone(){return new $i.Segment(this.start,this.end)}get start(){return this.ps}get end(){return this.pe}get vertices(){return[this.ps.clone(),this.pe.clone()]}get length(){return this.start.distanceTo(this.end)[0]}get slope(){return new $i.Vector(this.start,this.end).slope}get box(){return new $i.Box(Math.min(this.start.x,this.end.x),Math.min(this.start.y,this.end.y),Math.max(this.start.x,this.end.x),Math.max(this.start.y,this.end.y))}equalTo(t){return this.ps.equalTo(t.ps)&&this.pe.equalTo(t.pe)}contains(t){return $i.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){return t instanceof $i.Point?this.contains(t)?[t]:[]:t instanceof $i.Line?Ji(this,t):t instanceof $i.Ray?yr(t,this):t instanceof $i.Segment?Ki(this,t):t instanceof $i.Circle?tr(this,t):t instanceof $i.Box?function(t,e){let n=[];for(let s of e.toSegments()){let e=Ki(s,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof $i.Arc?er(this,t):t instanceof $i.Polygon?hr(this,t):t instanceof $i.Multiline?Mr(this,t):void 0}distanceTo(t){if(t instanceof $i.Point){let[e,n]=$i.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof $i.Circle){let[e,n]=$i.Distance.segment2circle(this,t);return[e,n]}if(t instanceof $i.Line){let[e,n]=$i.Distance.segment2line(this,t);return[e,n]}if(t instanceof $i.Segment){let[e,n]=$i.Distance.segment2segment(this,t);return[e,n]}if(t instanceof $i.Arc){let[e,n]=$i.Distance.segment2arc(this,t);return[e,n]}if(t instanceof $i.Polygon){let[e,n]=$i.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof $i.PlanarSet){let[e,n]=$i.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof $i.Multiline)return $i.Distance.shape2multiline(this,t)}tangentInStart(){return new $i.Vector(this.start,this.end).normalize()}tangentInEnd(){return new $i.Vector(this.end,this.start).normalize()}reverse(){return new t(this.end,this.start)}split(t){return this.start.equalTo(t)?[null,this.clone()]:this.end.equalTo(t)?[this.clone(),null]:[new $i.Segment(this.start,t),new $i.Segment(t,this.end)]}middle(){return new $i.Point((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)}pointAtLength(t){if(t>this.length||t<0)return null;if(0==t)return this.start;if(t==this.length)return this.end;let e=t/this.length;return new $i.Point((this.end.x-this.start.x)*e+this.start.x,(this.end.y-this.start.y)*e+this.start.y)}distanceToPoint(t){let[e,...n]=$i.Distance.point2segment(t,this);return e}definiteIntegral(t=0){return(this.end.x-this.start.x)*(this.start.y-t+(this.end.y-t))/2}transform(e=new $i.Matrix){return new t(this.ps.transform(e),this.pe.transform(e))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new $i.Line(this.start,this.end).sortPoints(t)}get name(){return"segment"}svg(t={}){return`\n<line x1="${this.start.x}" y1="${this.start.y}" x2="${this.end.x}" y2="${this.end.y}" ${Ui(t)} />`}};var Ea=(...t)=>new $i.Segment(...t);$i.segment=Ea;var{vector:wa}=$i;$i.Line=class t extends _a{constructor(...e){if(super(),this.pt=new $i.Point,this.norm=new $i.Vector(0,1),0!==e.length){if(1===e.length&&e[0]instanceof Object&&"line"===e[0].name){let{pt:t,norm:n}=e[0];return this.pt=new $i.Point(t),void(this.norm=new $i.Vector(n))}if(2===e.length){let n=e[0],s=e[1];if(n instanceof $i.Point&&s instanceof $i.Point)return this.pt=n,this.norm=t.points2norm(n,s),void(this.norm.dot(wa(this.pt.x,this.pt.y))>=0&&this.norm.invert());if(n instanceof $i.Point&&s instanceof $i.Vector){if($i.Utils.EQ_0(s.x)&&$i.Utils.EQ_0(s.y))throw Bi.ILLEGAL_PARAMETERS;return this.pt=n.clone(),this.norm=s.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(wa(this.pt.x,this.pt.y))>=0&&this.norm.invert())}if(n instanceof $i.Vector&&s instanceof $i.Point){if($i.Utils.EQ_0(n.x)&&$i.Utils.EQ_0(n.y))throw Bi.ILLEGAL_PARAMETERS;return this.pt=s.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(wa(this.pt.x,this.pt.y))>=0&&this.norm.invert())}}throw Bi.ILLEGAL_PARAMETERS}}clone(){return new $i.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new $i.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new $i.Vector(this.norm.y,-this.norm.x).slope}get standard(){return[this.norm.x,this.norm.y,this.norm.dot(wa(this.pt.x,this.pt.y))]}parallelTo(t){return $i.Utils.EQ_0(this.norm.cross(t.norm))}incidentTo(t){return this.parallelTo(t)&&this.pt.on(t)}contains(t){if(this.pt.equalTo(t))return!0;let e=new $i.Vector(this.pt,t);return $i.Utils.EQ_0(this.norm.dot(e))}coord(t){return wa(t.x,t.y).cross(this.norm)}intersect(t){return t instanceof $i.Point?this.contains(t)?[t]:[]:t instanceof $i.Line?Vi(this,t):t instanceof $i.Ray?br(t,this):t instanceof $i.Circle?Gi(this,t):t instanceof $i.Box?Zi(this,t):t instanceof $i.Segment?Ji(t,this):t instanceof $i.Arc?qi(this,t):t instanceof $i.Polygon?dr(this,t):t instanceof $i.Multiline?Mr(this,t):void 0}distanceTo(t){if(t instanceof $i.Point){let[e,n]=$i.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof $i.Circle){let[e,n]=$i.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof $i.Segment){let[e,n]=$i.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof $i.Arc){let[e,n]=$i.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof $i.Polygon){let[e,n]=$i.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof $i.Point)return[new $i.Ray(t,this.norm),new $i.Ray(t,this.norm)];{let e=new $i.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new $i.Point){return new $i.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new $i.Line(this.pt.transform(t),this.norm.clone())}sortPoints(t){return t.slice().sort((t,e)=>this.coord(t)<this.coord(e)?-1:this.coord(t)>this.coord(e)?1:0)}get name(){return"line"}svg(t,e={}){let n=Zi(this,t);if(0===n.length)return"";let s=n[0],o=2===n.length?n[1]:n.find(t=>!t.equalTo(s));return void 0===o&&(o=s),new $i.Segment(s,o).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw Bi.ILLEGAL_PARAMETERS;return new $i.Vector(t,e).normalize().rotate90CCW()}};var Ra=(...t)=>new $i.Line(...t);$i.line=Ra;$i.Circle=class extends _a{constructor(...t){if(super(),this.pc=new $i.Point,this.r=1,1===t.length&&t[0]instanceof Object&&"circle"===t[0].name){let{pc:e,r:n}=t[0];this.pc=new $i.Point(e),this.r=n}else{let[e,n]=[...t];e&&e instanceof $i.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n)}}clone(){return new $i.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new $i.Box(this.pc.x-this.r,this.pc.y-this.r,this.pc.x+this.r,this.pc.y+this.r)}contains(t){return t instanceof $i.Point?$i.Utils.LE(t.distanceTo(this.center)[0],this.r):t instanceof $i.Segment?$i.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&$i.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof $i.Arc?0===this.intersect(t).length&&$i.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&$i.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof $i.Circle?0===this.intersect(t).length&&$i.Utils.LE(t.r,this.r)&&$i.Utils.LE(t.center.distanceTo(this.center)[0],this.r):void 0}toArc(t=!0){return new $i.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e)throw Bi.OPERATION_IS_NOT_SUPPORTED;if(0!==this.pc.x||0!==this.pc.y)throw Bi.OPERATION_IS_NOT_SUPPORTED;return new $i.Circle(this.pc,this.r*t)}transform(t=new $i.Matrix){return new $i.Circle(this.pc.transform(t),this.r)}intersect(t){return t instanceof $i.Point?this.contains(t)?[t]:[]:t instanceof $i.Line?Gi(t,this):t instanceof $i.Ray?vr(t,this):t instanceof $i.Segment?tr(t,this):t instanceof $i.Circle?nr(t,this):t instanceof $i.Box?function(t,e){let n=[];for(let s of e.toSegments()){let e=tr(s,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof $i.Arc?or(t,this):t instanceof $i.Polygon?ur(this,t):t instanceof $i.Multiline?Mr(this,t):void 0}distanceTo(t){if(t instanceof $i.Point){let[e,n]=$i.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof $i.Circle){let[e,n]=$i.Distance.circle2circle(this,t);return[e,n]}if(t instanceof $i.Line){let[e,n]=$i.Distance.circle2line(this,t);return[e,n]}if(t instanceof $i.Segment){let[e,n]=$i.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof $i.Arc){let[e,n]=$i.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof $i.Polygon){let[e,n]=$i.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof $i.PlanarSet){let[e,n]=$i.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof $i.Multiline){let[e,n]=$i.Distance.shape2multiline(this,t);return[e,n]}}get name(){return"circle"}svg(t={}){return`\n<circle cx="${this.pc.x}" cy="${this.pc.y}" r="${this.r}"\n ${Ui({fill:"none",...t})} />`}};$i.circle=(...t)=>new $i.Circle(...t);$i.Arc=class extends _a{constructor(...t){if(super(),this.pc=new $i.Point,this.r=1,this.startAngle=0,this.endAngle=2*Math.PI,this.counterClockwise=!0,0!==t.length)if(1===t.length&&t[0]instanceof Object&&"arc"===t[0].name){let{pc:e,r:n,startAngle:s,endAngle:o,counterClockwise:i}=t[0];this.pc=new $i.Point(e.x,e.y),this.r=n,this.startAngle=s,this.endAngle=o,this.counterClockwise=i}else{let[e,n,s,o,i]=[...t];e&&e instanceof $i.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n),void 0!==s&&(this.startAngle=s),void 0!==o&&(this.endAngle=o),void 0!==i&&(this.counterClockwise=i)}}clone(){return new $i.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){let t=this.startAngle,e=this.endAngle;if($i.Utils.EQ(Math.abs(t-e),$i.PIx2))return $i.PIx2;Math.abs(t)>$i.PIx2&&(t-=Math.trunc(t/$i.PIx2)*$i.PIx2),t<0&&(t+=$i.PIx2),Math.abs(e)>$i.PIx2&&(e-=Math.trunc(e/$i.PIx2)*$i.PIx2),e<0&&(e+=$i.PIx2);let n=this.counterClockwise?e-t:t-e;return n<0&&(n+=$i.PIx2),n}get start(){return new $i.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new $i.Point(this.pc.x+this.r,this.pc.y).rotate(this.endAngle,this.pc)}get center(){return this.pc.clone()}get vertices(){return[this.start.clone(),this.end.clone()]}get length(){return Math.abs(this.sweep*this.r)}get box(){let t=this.breakToFunctional().reduce((t,e)=>t.merge(e.start.box),new $i.Box);return t=t.merge(this.end.box),t}contains(t){if(!$i.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let e=new $i.Vector(this.pc,t).slope,n=new $i.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise);return $i.Utils.LE(n.length,this.length)}split(t){if(this.start.equalTo(t))return[null,this.clone()];if(this.end.equalTo(t))return[this.clone(),null];let e=new $i.Vector(this.pc,t).slope;return[new $i.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise),new $i.Arc(this.pc,this.r,e,this.endAngle,this.counterClockwise)]}middle(){let t=this.counterClockwise?this.startAngle+this.sweep/2:this.startAngle-this.sweep/2;return new $i.Arc(this.pc,this.r,this.startAngle,t,this.counterClockwise).end}pointAtLength(t){if(t>this.length||t<0)return null;if(0===t)return this.start;if(t===this.length)return this.end;let e=t/this.length,n=this.counterClockwise?this.startAngle+this.sweep*e:this.startAngle-this.sweep*e;return new $i.Arc(this.pc,this.r,this.startAngle,n,this.counterClockwise).end}chordHeight(){return(1-Math.cos(Math.abs(this.sweep/2)))*this.r}intersect(t){return t instanceof $i.Point?this.contains(t)?[t]:[]:t instanceof $i.Line?qi(t,this):t instanceof $i.Ray?xr(t,this):t instanceof $i.Circle?or(this,t):t instanceof $i.Segment?er(t,this):t instanceof $i.Box?function(t,e){let n=[];for(let s of e.toSegments()){let e=er(s,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof $i.Arc?sr(this,t):t instanceof $i.Polygon?lr(this,t):t instanceof $i.Multiline?Mr(this,t):void 0}distanceTo(t){if(t instanceof $i.Point){let[e,n]=$i.Distance.point2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof $i.Circle){let[e,n]=$i.Distance.arc2circle(this,t);return[e,n]}if(t instanceof $i.Line){let[e,n]=$i.Distance.arc2line(this,t);return[e,n]}if(t instanceof $i.Segment){let[e,n]=$i.Distance.segment2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof $i.Arc){let[e,n]=$i.Distance.arc2arc(this,t);return[e,n]}if(t instanceof $i.Polygon){let[e,n]=$i.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof $i.PlanarSet){let[e,n]=$i.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof $i.Multiline)return $i.Distance.shape2multiline(this,t)}breakToFunctional(){let t=[],e=[0,Math.PI/2,Math.PI,3*Math.PI/2],n=this.startAngle,s=this.endAngle;$i.Utils.EQ(Math.abs(n-s),$i.PIx2)&&(s=n),Math.abs(n)>$i.PIx2&&(n-=Math.trunc(n/$i.PIx2)*$i.PIx2),n<0&&(n+=$i.PIx2),Math.abs(s)>$i.PIx2&&(s-=Math.trunc(s/$i.PIx2)*$i.PIx2),s<0&&(s+=$i.PIx2);let o,i,r,a=n;this.counterClockwise?(i=Math.ceil(n/(Math.PI/2))%4,r=1):(i=Math.floor(n/(Math.PI/2))%4,r=-1);for(let s=0,c=i;s<4;s++,c=(c+r+4)%4){if(o=e[c],o===a)continue;let s=this.counterClockwise?o-n:n-o;if(s<0&&(s+=$i.PIx2),s>this.sweep)break;t.push(new $i.Arc(this.pc,this.r,a,o,this.counterClockwise)),a=o}return 0===t.length?(t.push(this),t):(o=s,a!==o&&t.push(new $i.Arc(this.pc,this.r,a,o,this.counterClockwise)),t)}tangentInStart(){let t=new $i.Vector(this.pc,this.start),e=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(e).normalize()}tangentInEnd(){let t=new $i.Vector(this.pc,this.end),e=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(e).normalize()}reverse(){return new $i.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new $i.Matrix){let e=this.start.transform(t),n=this.end.transform(t),s=this.pc.transform(t),o=this.counterClockwise;return t.a*t.d<0&&(o=!o),$i.Arc.arcSE(s,e,n,o)}static arcSE(t,e,n,s){let{vector:o}=$i,i=o(t,e).slope,r=o(t,n).slope;$i.Utils.EQ(i,r)&&(r+=2*Math.PI,s=!0);let a=o(t,e).length;return new $i.Arc(t,a,i,r,s)}definiteIntegral(t=0){return this.breakToFunctional().reduce((e,n)=>e+n.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let e=new $i.Segment(this.start,this.end).definiteIntegral(t),n=$i.Utils.EQ(this.sweep,$i.PIx2)?0:this.circularSegmentArea();return this.counterClockwise?e-n:e+n}circularSegmentArea(){return.5*this.r*this.r*(this.sweep-Math.sin(this.sweep))}sortPoints(t){let{vector:e}=$i;return t.slice().sort((t,n)=>{let s=e(this.pc,t).slope,o=e(this.pc,n).slope;return s<o?-1:s>o?1:0})}get name(){return"arc"}svg(t={}){let e=this.sweep<=Math.PI?"0":"1",n=this.counterClockwise?"1":"0";if($i.Utils.EQ(this.sweep,2*Math.PI)){return new $i.Circle(this.pc,this.r).svg(t)}return`\n<path d="M${this.start.x},${this.start.y}\n A${this.r},${this.r} 0 ${e},${n} ${this.end.x},${this.end.y}"\n ${Ui({fill:"none",...t})} />`}};$i.arc=(...t)=>new $i.Arc(...t);$i.Box=class t extends _a{constructor(t=void 0,e=void 0,n=void 0,s=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=s}clone(){return new t(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new $i.Point(this.xmin,this.ymin)}get high(){return new $i.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new $i.Point((this.xmin+this.xmax)/2,(this.ymin+this.ymax)/2)}get width(){return Math.abs(this.xmax-this.xmin)}get height(){return Math.abs(this.ymax-this.ymin)}get box(){return this.clone()}not_intersect(t){return this.xmax<t.xmin||this.xmin>t.xmax||this.ymax<t.ymin||this.ymin>t.ymax}intersect(t){return!this.not_intersect(t)}merge(e){return new t(void 0===this.xmin?e.xmin:Math.min(this.xmin,e.xmin),void 0===this.ymin?e.ymin:Math.min(this.ymin,e.ymin),void 0===this.xmax?e.xmax:Math.max(this.xmax,e.xmax),void 0===this.ymax?e.ymax:Math.max(this.ymax,e.ymax))}less_than(t){return!!this.low.lessThan(t.low)||!(!this.low.equalTo(t.low)||!this.high.lessThan(t.high))}equal_to(t){return this.low.equalTo(t.low)&&this.high.equalTo(t.high)}output(){return this.clone()}comparable_less_than(t,e){return t.lessThan(e)}set(t,e,n,s){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=s}extend(e){return e<=0?this.clone():new t(this.xmin-e,this.ymin-e,this.xmax+e,this.ymax+e)}toPoints(){return[new $i.Point(this.xmin,this.ymin),new $i.Point(this.xmax,this.ymin),new $i.Point(this.xmax,this.ymax),new $i.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new $i.Segment(t[0],t[1]),new $i.Segment(t[1],t[2]),new $i.Segment(t[2],t[3]),new $i.Segment(t[3],t[0])]}rotate(t,e=new $i.Point){throw Bi.OPERATION_IS_NOT_SUPPORTED}transform(e=new $i.Matrix){return this.toPoints().map(t=>t.transform(e)).reduce((t,e)=>t.merge(e.box),new t)}contains(t){return t instanceof $i.Point?t.x>=this.xmin&&t.x<=this.xmax&&t.y>=this.ymin&&t.y<=this.ymax:t instanceof $i.Segment?t.vertices.every(t=>this.contains(t)):t instanceof $i.Box?t.toSegments().every(t=>this.contains(t)):t instanceof $i.Circle?this.contains(t.box):t instanceof $i.Arc?t.vertices.every(t=>this.contains(t))&&this.toSegments().every(e=>0===er(e,t).length):!(t instanceof $i.Line||t instanceof $i.Ray)&&(t instanceof $i.Multiline?t.toShapes().every(t=>this.contains(t)):t instanceof $i.Polygon?this.contains(t.box):void 0)}distanceTo(t){const e=this.toSegments().map(e=>e.distanceTo(t));let n=[Number.MAX_SAFE_INTEGER,null];return e.forEach(t=>{t[0]<n[0]&&(n=t)}),n}get name(){return"box"}svg(t={}){const e=this.xmax-this.xmin,n=this.ymax-this.ymin;return`\n<rect x="${this.xmin}" y="${this.ymin}" width="${e}" height="${n}"\n ${Ui({fill:"none",...t})} />`}};$i.box=(...t)=>new $i.Box(...t);$i.Edge=class{constructor(t){this.shape=t,this.next=void 0,this.prev=void 0,this.face=void 0,this.arc_length=0,this.bvStart=void 0,this.bvEnd=void 0,this.bv=void 0,this.overlap=void 0}get start(){return this.shape.start}get end(){return this.shape.end}get length(){return this.shape.length}get box(){return this.shape.box}get isSegment(){return this.shape instanceof $i.Segment}get isArc(){return this.shape instanceof $i.Arc}get isLine(){return this.shape instanceof $i.Line}get isRay(){return this.shape instanceof $i.Ray}middle(){return this.shape.middle()}pointAtLength(t){return this.shape.pointAtLength(t)}contains(t){return this.shape.contains(t)}setInclusion(t){if(void 0!==this.bv)return this.bv;if(this.shape instanceof $i.Line||this.shape instanceof $i.Ray)return this.bv=$i.OUTSIDE,this.bv;if(void 0===this.bvStart&&(this.bvStart=da(t,this.start)),void 0===this.bvEnd&&(this.bvEnd=da(t,this.end)),this.bvStart===$i.OUTSIDE||this.bvEnd==$i.OUTSIDE)this.bv=$i.OUTSIDE;else if(this.bvStart===$i.INSIDE||this.bvEnd==$i.INSIDE)this.bv=$i.INSIDE;else{let e=da(t,this.middle());this.bv=e}return this.bv}setOverlap(t){let e,n=this.shape,s=t.shape;n instanceof $i.Segment&&s instanceof $i.Segment?n.start.equalTo(s.start)&&n.end.equalTo(s.end)?e=$i.OVERLAP_SAME:n.start.equalTo(s.end)&&n.end.equalTo(s.start)&&(e=$i.OVERLAP_OPPOSITE):(n instanceof $i.Arc&&s instanceof $i.Arc||n instanceof $i.Segment&&s instanceof $i.Arc||n instanceof $i.Arc&&s instanceof $i.Segment)&&(n.start.equalTo(s.start)&&n.end.equalTo(s.end)&&n.middle().equalTo(s.middle())?e=$i.OVERLAP_SAME:n.start.equalTo(s.end)&&n.end.equalTo(s.start)&&n.middle().equalTo(s.middle())&&(e=$i.OVERLAP_OPPOSITE)),void 0===this.overlap&&(this.overlap=e),void 0===t.overlap&&(t.overlap=e)}svg(){if(this.shape instanceof $i.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof $i.Arc){let t,e=this.shape,n=e.counterClockwise?"1":"0";if($i.Utils.EQ(e.sweep,2*Math.PI)){let s=e.counterClockwise?1:-1,o=new $i.Arc(e.pc,e.r,e.startAngle,e.startAngle+s*Math.PI,e.counterClockwise),i=new $i.Arc(e.pc,e.r,e.startAngle+s*Math.PI,e.endAngle,e.counterClockwise);return t="0",` A${o.r},${o.r} 0 ${t},${n} ${o.end.x},${o.end.y}\n A${i.r},${i.r} 0 ${t},${n} ${i.end.x},${i.end.y}`}return t=e.sweep<=Math.PI?"0":"1",` A${e.r},${e.r} 0 ${t},${n} ${e.end.x},${e.end.y}`}}toJSON(){return this.shape.toJSON()}};var Oa=class extends ji{constructor(t,e){super(t,e),this.setCircularLinks()}setCircularLinks(){this.isEmpty()||(this.last.next=this.first,this.first.prev=this.last)}[Symbol.iterator](){let t;return{next:()=>{let e=t||this.first,n=!this.first||!!t&&t===this.first;return t=e?e.next:void 0,{value:e,done:n}}}}append(t){return super.append(t),this.setCircularLinks(),this}insert(t,e){return super.insert(t,e),this.setCircularLinks(),this}remove(t){return super.remove(t),this}};$i.Face=class t extends Oa{constructor(e,...n){if(super(),this._box=void 0,this._orientation=void 0,0!==n.length){if(1===n.length)if(n[0]instanceof Array){let s=n[0];if(0===s.length)return;if(s.every(t=>t instanceof $i.Point)){let n=t.points2segments(s);this.shapes2face(e.edges,n)}else if(s.every(t=>t instanceof Array&&2===t.length)){let n=s.map(t=>new $i.Point(t[0],t[1])),o=t.points2segments(n);this.shapes2face(e.edges,o)}else if(s.every(t=>t instanceof $i.Segment||t instanceof $i.Arc))this.shapes2face(e.edges,s);else if(s.every(t=>"segment"===t.name||"arc"===t.name)){let t=[];for(let e of s){let n;n="segment"===e.name?new $i.Segment(e):new $i.Arc(e),t.push(n)}this.shapes2face(e.edges,t)}}else if(n[0]instanceof t){let t=n[0];this.first=t.first,this.last=t.last;for(let n of t)e.edges.add(n)}else if(n[0]instanceof $i.Circle)this.shapes2face(e.edges,[n[0].toArc(wi)]);else if(n[0]instanceof $i.Box){let t=n[0];this.shapes2face(e.edges,[new $i.Segment(new $i.Point(t.xmin,t.ymin),new $i.Point(t.xmax,t.ymin)),new $i.Segment(new $i.Point(t.xmax,t.ymin),new $i.Point(t.xmax,t.ymax)),new $i.Segment(new $i.Point(t.xmax,t.ymax),new $i.Point(t.xmin,t.ymax)),new $i.Segment(new $i.Point(t.xmin,t.ymax),new $i.Point(t.xmin,t.ymin))])}2===n.length&&n[0]instanceof $i.Edge&&n[1]instanceof $i.Edge&&(this.first=n[0],this.last=n[1],this.last.next=this.first,this.first.prev=this.last,this.setArcLength())}}get edges(){return this.toArray()}get vertices(){return this.edges.map(t=>t.shape.start.clone())}get shapes(){return this.edges.map(t=>t.shape.clone())}get box(){if(void 0===this._box){let t=new $i.Box;for(let e of this)t=t.merge(e.box);this._box=t}return this._box}get perimeter(){return this.last.arc_length+this.last.length}pointAtLength(t){if(t>this.perimeter||t<0)return null;let e=null;for(let n of this)if(t>=n.arc_length&&(n===this.last||t<n.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}static points2segments(t){let e=[];for(let n=0;n<t.length;n++)t[n].equalTo(t[(n+1)%t.length])||e.push(new $i.Segment(t[n],t[(n+1)%t.length]));return e}shapes2face(t,e){for(let n of e){let e=new $i.Edge(n);this.append(e),t.add(e)}}append(t){return super.append(t),this.setOneEdgeArcLength(t),t.face=this,this}insert(t,e){return super.insert(t,e),this.setOneEdgeArcLength(t),t.face=this,this}remove(t){return super.remove(t),this.setArcLength(),this}merge_with_next_edge(t){return t.shape.end.x=t.next.shape.end.x,t.shape.end.y=t.next.shape.end.y,this.remove(t.next),this}reverse(){let t=[],e=this.last;do{e.shape=e.shape.reverse(),t.push(e),e=e.prev}while(e!==this.last);this.first=void 0,this.last=void 0;for(let e of t)void 0===this.first?(e.prev=e,e.next=e,this.first=e,this.last=e):(e.prev=this.last,this.last.next=e,this.last=e,this.last.next=this.first,this.first.prev=this.last),this.setOneEdgeArcLength(e);void 0!==this._orientation&&(this._orientation=void 0,this._orientation=this.orientation())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t),t.face=this}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}area(){return Math.abs(this.signedArea())}signedArea(){let t=0,e=this.box.ymin;for(let n of this)t+=n.shape.definiteIntegral(e);return t}orientation(){if(void 0===this._orientation){let t=this.signedArea();$i.Utils.EQ_0(t)?this._orientation=Ri.NOT_ORIENTABLE:$i.Utils.LT(t,0)?this._orientation=Ri.CCW:this._orientation=Ri.CW}return this._orientation}isSimple(e){return 0===t.getSelfIntersections(this,e,!0).length}static getSelfIntersections(t,e,n=!1){let s=[];for(let o of t){let i=e.search(o.box);for(let e of i){if(o===e)continue;if(e.face!==t)continue;if(o.shape instanceof $i.Segment&&e.shape instanceof $i.Segment&&(o.next===e||o.prev===e))continue;let i=o.shape.intersect(e.shape);for(let t of i)if((!t.equalTo(o.start)||!t.equalTo(e.end)||e!==o.prev)&&(!t.equalTo(o.end)||!t.equalTo(e.start)||e!==o.next)&&(s.push(t),n))break;if(s.length>0&&n)break}if(s.length>0&&n)break}return s}findEdgeByPoint(t){let e;for(let n of this)if(!t.equalTo(n.shape.start)&&(t.equalTo(n.shape.end)||n.shape.contains(t))){e=n;break}return e}toPolygon(){return new $i.Polygon(this.shapes)}toJSON(){return this.edges.map(t=>t.toJSON())}svg(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let e of this)t+=e.svg();return t+=" z",t}};$i.Ray=class t extends _a{constructor(...t){if(super(),this.pt=new $i.Point,this.norm=new $i.Vector(0,1),0!==t.length&&(t.length>=1&&t[0]instanceof $i.Point&&(this.pt=t[0].clone()),1!==t.length)){if(!(2===t.length&&t[1]instanceof $i.Vector))throw Bi.ILLEGAL_PARAMETERS;this.norm=t[1].clone()}}clone(){return new t(this.pt,this.norm)}get slope(){return new $i.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new $i.Box(t>Math.PI/2&&t<3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t>=0&&t<=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t>=Math.PI/2&&t<=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t>=Math.PI&&t<=2*Math.PI||0===t?this.pt.y:Number.POSITIVE_INFINITY)}get start(){return this.pt}get end(){}get length(){return Number.POSITIVE_INFINITY}contains(t){if(this.pt.equalTo(t))return!0;let e=new $i.Vector(this.pt,t);return $i.Utils.EQ_0(this.norm.dot(e))&&$i.Utils.GE(e.cross(this.norm),0)}coord(t){return Ta(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new $i.Segment(this.pt,t),new $i.Ray(t,this.norm)]:[]}intersect(t){return t instanceof $i.Point?this.contains(t)?[t]:[]:t instanceof $i.Segment?yr(this,t):t instanceof $i.Arc?xr(this,t):t instanceof $i.Line?br(this,t):t instanceof $i.Ray?(n=t,Vi(gr(e=this),gr(n)).filter(t=>e.contains(t)).filter(t=>n.contains(t))):t instanceof $i.Circle?vr(this,t):t instanceof $i.Box?function(t,e){return Zi(gr(t),e).filter(e=>t.contains(e))}(this,t):t instanceof $i.Polygon?Pr(this,t):t instanceof $i.Multiline?Mr(this,t):void 0;var e,n}rotate(t,e=new $i.Point){return new $i.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new $i.Ray(this.pt.transform(t),this.norm.clone())}get name(){return"ray"}svg(t,e={}){let n=Zi(new $i.Line(this.pt,this.norm),t);return n=n.filter(t=>this.contains(t)),0===n.length||2===n.length?"":new $i.Segment(this.pt,n[0]).svg(e)}};$i.ray=(...t)=>new $i.Ray(...t);var Aa=class t{constructor(){this.faces=new $i.PlanarSet,this.edges=new $i.PlanarSet;let t=[...arguments];if(1===t.length&&(t[0]instanceof Array&&t[0].length>0||t[0]instanceof $i.Circle||t[0]instanceof $i.Box)){let e=t[0];if(t[0]instanceof Array&&t[0].every(t=>t instanceof Array))if(e.every(t=>t instanceof Array&&2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1]))this.faces.add(new $i.Face(this,e));else for(let t of e)if(t instanceof Array&&t[0]instanceof Array&&t[0].every(t=>t instanceof Array&&2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1]))for(let e of t)this.faces.add(new $i.Face(this,e));else this.faces.add(new $i.Face(this,t));else this.faces.add(new $i.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=>t.merge(e.box),new $i.Box)}get vertices(){return[...this.faces].flatMap(t=>t.vertices)}clone(){let e=new t;for(let t of this.faces)e.addFace(t.shapes);return e}createFromArray(e){const n=new t;return e.forEach(t=>[...t.faces].forEach(t=>n.addFace(t.shapes))),n}isEmpty(){return 0===this.edges.size||0===this.faces.size}isValid(){let t=!0;for(let e of this.faces)if(!e.isSimple(this.edges)){t=!1;break}return t}area(){let t=[...this.faces].reduce((t,e)=>t+e.signedArea(),0);return Math.abs(t)}addFace(...t){let e=new $i.Face(this,...t);return this.faces.add(e),e}deleteFace(t){for(let e of t)this.edges.delete(e);return this.faces.delete(t)}recreateFaces(){this.faces.clear();for(let t of this.edges)t.face=null;let t,e=!0;for(;e;){e=!1;for(let n of this.edges)if(null===n.face){t=n,e=!0;break}if(e){let e=t;do{e=e.next}while(e.next!==t);this.addFace(t,e)}}}removeChain(t,e,n){if(n.next!==e){for(let s=e;s!==n.next;s=s.next)if(t.remove(s),this.edges.delete(s),t.isEmpty()){this.deleteFace(t);break}}else this.deleteFace(t)}addVertex(t,e){let n=e.shape.split(t);if(null===n[0])return e.prev;if(null===n[1])return e;let s=new $i.Edge(n[0]),o=e.prev;return e.face.insert(s,o),this.edges.delete(e),this.edges.add(s),e.shape=n[1],this.edges.add(e),s}removeEndVertex(t){const e=t.next;e!==t&&(t.face.merge_with_next_edge(t),this.edges.delete(e))}cut(t){const e=this.splitToIslands().flatMap(e=>e._cutSingleIsland(t)).filter(t=>t.isValid()&&!1===t.isEmpty());return this.createFromArray(e)}_cutSingleIsland(t){let e=this.clone();const n=t.clone();let s,o,i={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let t of n.edges)for(let n of e.edges){let e=pr(t,n);for(let s of e)Ir(t,s,i.int_points1),Ir(n,s,i.int_points2)}if(0===i.int_points1.length)return e;i.int_points1_sorted=Cr(i.int_points1),i.int_points2_sorted=Cr(i.int_points2),Ar(n,i.int_points1_sorted),Ar(e,i.int_points2_sorted),Er(i),i.int_points1_sorted=Cr(i.int_points1),i.int_points2_sorted=Cr(i.int_points2),wr(i.int_points1),Rr(i.int_points1,e);for(let t of i.int_points1_sorted)t.edge_before&&t.edge_after&&t.edge_before.bv===t.edge_after.bv&&(i.int_points2[t.id]=-1,t.id=-1);if(i.int_points1=i.int_points1.filter(t=>t.id>=0),i.int_points2=i.int_points2.filter(t=>t.id>=0),i.int_points1.forEach((t,e)=>{t.id=e}),i.int_points2.forEach((t,e)=>{t.id=e}),0===i.int_points1.length)return e;i.int_points1_sorted=Cr(i.int_points1),i.int_points2_sorted=Cr(i.int_points2);for(let t=1;t<i.int_points1_sorted.length;t++)if(o=i.int_points1_sorted[t],s=i.int_points1_sorted[t-1],o.edge_before&&1===o.edge_before.bv){let t=s.edge_after,r=o.edge_before,a=n.getChain(t,r);zr(i.int_points2[s.id],i.int_points2[o.id],a),a.forEach(t=>e.edges.add(t)),a=a.reverse().map(t=>new $i.Edge(t.shape.reverse()));for(let t=0;t<a.length-1;t++)a[t].next=a[t+1],a[t+1].prev=a[t];zr(i.int_points2[o.id],i.int_points2[s.id],a),a.forEach(t=>e.edges.add(t))}return e.recreateFaces(),e}cutWithLine(t){let e=new Nr([t]);return this.cut(e)}findEdgeByPoint(t){let e;for(let n of this.faces)if(e=n.findEdgeByPoint(t),void 0!==e)break;return e}splitToIslands(){if(this.isEmpty())return[];let t=this.toArray();t.sort((t,e)=>e.area()-t.area());let e=[...t[0].faces][0].orientation(),n=t.filter(t=>[...t.faces][0].orientation()===e);for(let s of t){let t=[...s.faces][0];if(t.orientation()!==e)for(let e of n)if(t.shapes.every(t=>e.contains(t))){e.addFace(t.shapes);break}}return n}rearrange(){if(this.faces.size<=1)return this.clone();const e=this.splitToIslands(),n=new t;return e.forEach(t=>{t.faces.forEach(t=>n.addFace(t.shapes))}),n}orientation(){return this.isEmpty()?Ri.NOT_ORIENTABLE:[...this.faces][0].orientation()}isOuter(t){return t.orientation()===this.orientation()}isMultiPolygon(){let t=0;return this.faces.forEach(e=>{this.isOuter(e)&&t++}),t>1}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof $i.Point){let e=da(this,t);return 1===e||2===e}return ma(this,t)}distanceTo(t){if(t instanceof $i.Point){let[e,n]=$i.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof $i.Circle||t instanceof $i.Line||t instanceof $i.Segment||t instanceof $i.Arc){let[e,n]=$i.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof $i.Polygon){let e,n,s=[Number.POSITIVE_INFINITY,new $i.Segment];for(let o of this.edges){let i=s[0];[e,n]=$i.Distance.shape2planarSet(o.shape,t.edges,i),$i.Utils.LT(e,i)&&(s=[e,n])}return s}}intersect(t){return t instanceof $i.Point?this.contains(t)?[t]:[]:t instanceof $i.Line?dr(t,this):t instanceof $i.Ray?Pr(t,this):t instanceof $i.Circle?ur(t,this):t instanceof $i.Segment?hr(t,this):t instanceof $i.Arc?lr(t,this):t instanceof $i.Polygon?function(t,e){let n=[];if(t.isEmpty()||e.isEmpty())return n;if(t.box.not_intersect(e.box))return n;for(let s of t.edges)n=[...n,...fr(s,e)];return n}(t,this):t instanceof $i.Multiline?function(t,e){let n=[];if(e.isEmpty()||0===t.size)return n;for(let s of t)n=[...n,...fr(s,e)];return n}(t,this):void 0}translate(e){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=>t.translate(e)));return n}rotate(e=0,n=new $i.Point){let s=new t;for(let t of this.faces)s.addFace(t.shapes.map(t=>t.rotate(e,n)));return s}scale(e,n){let s=new t;for(let t of this.faces)s.addFace(t.shapes.map(t=>t.scale(e,n)));return s}transform(e=new $i.Matrix){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=>t.transform(e)));return n}toJSON(){return[...this.faces].map(t=>t.toJSON())}toArray(){return[...this.faces].map(t=>t.toPolygon())}dpath(){return[...this.faces].reduce((t,e)=>t+e.svg(),"")}svg(t={}){let e=`\n<path ${Ui({fillRule:"evenodd",fill:"lightcyan",...t})} d="`;for(let t of this.faces)e+=`\n${t.svg()}`;return e+='" >\n</path>',e}};$i.Polygon=Aa;$i.polygon=(...t)=>new $i.Polygon(...t);var{Circle:za,Line:Da,Point:La,Vector:Fa,Utils:Ya}=$i;$i.Inversion=class t{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new Fa(t.pc,e),s=t.r*t.r,o=n.dot(n);return Ya.EQ_0(o)?new La(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(s/o))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(Ya.EQ(n,e.r)){let n=t.r*t.r/(2*e.r),s=new Fa(t.pc,e.pc);s=s.normalize();let o=t.pc.translate(s.multiply(n));return new Da(o,s)}{let n=new Fa(t.pc,e.pc),s=t.r*t.r/(n.dot(n)-e.r*e.r),o=t.pc.translate(n.multiply(s)),i=Math.abs(s)*e.r;return new za(o,i)}}static inverseLine(t,e){const[n,s]=t.pc.distanceTo(e);if(Ya.EQ_0(n))return e.clone();{let e=t.r*t.r/(2*n),o=new Fa(t.pc,s.end);return o=o.multiply(e/n),new za(t.pc.translate(o),e)}}inverse(e){return e instanceof La?t.inversePoint(this.circle,e):e instanceof za?t.inverseCircle(this.circle,e):e instanceof Da?t.inverseLine(this.circle,e):void 0}};$i.inversion=t=>new $i.Inversion(t);$i.Distance=class t{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new $i.Vector(t,n).length,new $i.Segment(t,n)]}static point2circle(t,e){let[n,s]=t.distanceTo(e.center);if($i.Utils.EQ_0(n))return[e.r,new $i.Segment(t,e.toArc().start)];{let s=Math.abs(n-e.r),o=new $i.Vector(e.pc,t).normalize().multiply(e.r),i=e.pc.translate(o);return[s,new $i.Segment(t,i)]}}static point2segment(e,n){if(n.start.equalTo(n.end))return t.point2point(e,n.start);let s,o,i=new $i.Vector(n.start,n.end),r=new $i.Vector(n.start,e),a=new $i.Vector(n.end,e),c=i.dot(r),h=-i.dot(a);if($i.Utils.GE(c,0)&&$i.Utils.GE(h,0)){let t=n.tangentInStart();return s=Math.abs(t.cross(r)),o=n.start.translate(t.multiply(t.dot(r))),[s,new $i.Segment(e,o)]}return c<0?e.distanceTo(n.start):e.distanceTo(n.end)}static point2arc(e,n){let s,o,i=new $i.Circle(n.pc,n.r),r=[];return[s,o]=t.point2circle(e,i),o.end.on(n)&&r.push(t.point2circle(e,i)),r.push(t.point2point(e,n.start)),r.push(t.point2point(e,n.end)),t.sort(r),r[0]}static point2edge(e,n){return n.shape instanceof $i.Segment?t.point2segment(e,n.shape):t.point2arc(e,n.shape)}static segment2line(e,n){let s=e.intersect(n);if(s.length>0)return[0,new $i.Segment(s[0],s[0])];let o=[];return o.push(t.point2line(e.start,n)),o.push(t.point2line(e.end,n)),t.sort(o),o[0]}static segment2segment(e,n){let s=Ki(e,n);if(s.length>0)return[0,new $i.Segment(s[0],s[0])];let o,i,r=[];return[o,i]=t.point2segment(n.start,e),r.push([o,i.reverse()]),[o,i]=t.point2segment(n.end,e),r.push([o,i.reverse()]),r.push(t.point2segment(e.start,n)),r.push(t.point2segment(e.end,n)),t.sort(r),r[0]}static segment2circle(e,n){let s=e.intersect(n);if(s.length>0)return[0,new $i.Segment(s[0],s[0])];let o=new $i.Line(e.ps,e.pe),[i,r]=t.point2line(n.center,o);if($i.Utils.GE(i,n.r)&&r.end.on(e))return t.point2circle(r.end,n);{let[s,o]=t.point2circle(e.start,n),[i,r]=t.point2circle(e.end,n);return $i.Utils.LT(s,i)?[s,o]:[i,r]}}static segment2arc(e,n){let s=e.intersect(n);if(s.length>0)return[0,new $i.Segment(s[0],s[0])];let o=new $i.Line(e.ps,e.pe),i=new $i.Circle(n.pc,n.r),[r,a]=t.point2line(i.center,o);if($i.Utils.GE(r,i.r)&&a.end.on(e)){let[e,s]=t.point2circle(a.end,i);if(s.end.on(n))return[e,s]}let c,h,l=[];return l.push(t.point2arc(e.start,n)),l.push(t.point2arc(e.end,n)),[c,h]=t.point2segment(n.start,e),l.push([c,h.reverse()]),[c,h]=t.point2segment(n.end,e),l.push([c,h.reverse()]),t.sort(l),l[0]}static circle2circle(e,n){let s=e.intersect(n);if(s.length>0)return[0,new $i.Segment(s[0],s[0])];if(e.center.equalTo(n.center)){let s=e.toArc(),o=n.toArc();return t.point2point(s.start,o.start)}{let s=new $i.Line(e.center,n.center),o=s.intersect(e),i=s.intersect(n),r=[];return r.push(t.point2point(o[0],i[0])),r.push(t.point2point(o[0],i[1])),r.push(t.point2point(o[1],i[0])),r.push(t.point2point(o[1],i[1])),t.sort(r),r[0]}}static circle2line(e,n){let s=e.intersect(n);if(s.length>0)return[0,new $i.Segment(s[0],s[0])];let[o,i]=t.point2line(e.center,n),[r,a]=t.point2circle(i.end,e);return a=a.reverse(),[r,a]}static arc2line(e,n){let s=n.intersect(e);if(s.length>0)return[0,new $i.Segment(s[0],s[0])];let o=new $i.Circle(e.center,e.r),[i,r]=t.point2line(o.center,n);if(!$i.Utils.GE(i,o.r)){let s=[];return s.push(t.point2line(e.start,n)),s.push(t.point2line(e.end,n)),t.sort(s),s[0]}{let[n,s]=t.point2circle(r.end,o);if(s.end.on(e))return[n,s]}}static arc2circle(e,n){let s=e.intersect(n);if(s.length>0)return[0,new $i.Segment(s[0],s[0])];let o=new $i.Circle(e.center,e.r),[i,r]=t.circle2circle(o,n);if(r.start.on(e))return[i,r];{let s=[];return s.push(t.point2circle(e.start,n)),s.push(t.point2circle(e.end,n)),t.sort(s),s[0]}}static arc2arc(e,n){let s=e.intersect(n);if(s.length>0)return[0,new $i.Segment(s[0],s[0])];let o=new $i.Circle(e.center,e.r),i=new $i.Circle(n.center,n.r),[r,a]=t.circle2circle(o,i);if(a.start.on(e)&&a.end.on(n))return[r,a];{let s,o,i=[];return[s,o]=t.point2arc(e.start,n),o.end.on(n)&&i.push([s,o]),[s,o]=t.point2arc(e.end,n),o.end.on(n)&&i.push([s,o]),[s,o]=t.point2arc(n.start,e),o.end.on(e)&&i.push([s,o.reverse()]),[s,o]=t.point2arc(n.end,e),o.end.on(e)&&i.push([s,o.reverse()]),[s,o]=t.point2point(e.start,n.start),i.push([s,o]),[s,o]=t.point2point(e.start,n.end),i.push([s,o]),[s,o]=t.point2point(e.end,n.start),i.push([s,o]),[s,o]=t.point2point(e.end,n.end),i.push([s,o]),t.sort(i),i[0]}}static point2polygon(e,n){let s=[Number.POSITIVE_INFINITY,new $i.Segment];for(let o of n.edges){let[n,i]=t.point2edge(e,o);$i.Utils.LT(n,s[0])&&(s=[n,i])}return s}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new $i.Segment];for(let s of e.edges){let[e,o]=t.distanceTo(s.shape);$i.Utils.LT(e,n[0])&&(n=[e,o])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new $i.Segment];for(let s of t.edges)for(let t of e.edges){let[e,o]=s.shape.distanceTo(t.shape);$i.Utils.LT(e,n[0])&&(n=[e,o])}return n}static box2box_minmax(t,e){let n=Math.max(Math.max(t.xmin-e.xmax,0),Math.max(e.xmin-t.xmax,0)),s=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),o=n*n+s*s,i=t.merge(e),r=i.xmax-i.xmin,a=i.ymax-i.ymin;return[o,r*r+a*a]}static minmax_tree_process_level(e,n,s,o){let i,r;for(let a of n){[i,r]=t.box2box_minmax(e.box,a.item.key);for(let t of a.item.values)t instanceof $i.Edge?o.insert([i,r],t.shape):o.insert([i,r],t);$i.Utils.LT(r,s)&&(s=r)}if(0===n.length)return s;let a=[...n.map(t=>t.left.isNil()?void 0:t.left).filter(t=>void 0!==t),...n.map(t=>t.right.isNil()?void 0:t.right).filter(t=>void 0!==t)].filter(n=>{let[o,i]=t.box2box_minmax(e.box,n.max);return $i.Utils.LE(o,s)});return s=t.minmax_tree_process_level(e,a,s,o)}static minmax_tree(e,n,s){let o=new Na,i=[n.index.root],r=s<Number.POSITIVE_INFINITY?s*s:Number.POSITIVE_INFINITY;return r=t.minmax_tree_process_level(e,i,r,o),o}static minmax_tree_calc_distance(e,n,s){let o,i;if(null!=n&&!n.isNil()){if([o,i]=t.minmax_tree_calc_distance(e,n.left,s),i)return[o,i];if($i.Utils.LT(o[0],Math.sqrt(n.item.key.low)))return[o,!0];let[r,a]=t.distanceToArray(e,n.item.values);return $i.Utils.LT(r,o[0])&&(o=[r,a]),[o,i]=t.minmax_tree_calc_distance(e,n.right,o),[o,i]}return[s,!1]}static shape2planarSet(e,n,s=Number.POSITIVE_INFINITY){let o=[s,new $i.Segment],i=!1;if(n instanceof $i.PlanarSet){let r=t.minmax_tree(e,n,s);[o,i]=t.minmax_tree_calc_distance(e,r.root,o)}return o}static sort(t){t.sort((t,e)=>$i.Utils.LT(t[0],e[0])?-1:$i.Utils.GT(t[0],e[0])?1:0)}static distance(t,e){return t.distanceTo(e)}static distanceToArray(t,e){let n=[Number.POSITIVE_INFINITY,new $i.Segment];for(let s of e){let[e,o]=t.distanceTo(s);$i.Utils.LT(e,n[0])&&(n=[e,o])}return n}static shape2multiline(e,n){let s=[Number.POSITIVE_INFINITY,new $i.Segment];for(let o of n){let[n,i]=t.distance(e,o.shape);$i.Utils.LT(n,s[0])&&(s=[n,i])}return s}static multiline2multiline(e,n){let s=[Number.POSITIVE_INFINITY,new $i.Segment];for(let o of e)for(let e of n){let[n,i]=t.distance(o.shape,e.shape);$i.Utils.LT(n,s[0])&&(s=[n,i])}return s}};var{Multiline:Xa,Point:ka,Segment:$a,Polygon:Ba}=$i;function ja(t){return new ka(t.split(" ").map(Number))}function Wa(t){return t.split(", ").map(ja)}function Ha(t){const e=Wa(t);let n=[];for(let t=0;t<e.length-1;t++)n.push(new $a(e[t],e[t+1]));return new Xa(n)}function Ua(t){const e=t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), ("),n=new Ba;let s;return e.forEach((t,e)=>{let o=t.split(", ").map(t=>new ka(t.split(" ").map(Number)));const i=n.addFace(o);0===e?s=i.orientation():i.orientation()===s&&i.reverse()}),n}function Va(t){if(t.startsWith("POLYGON")){return Ua(t.replace(/^POLYGON /,""))}return function(t){const e=t.split(/\)\), \(\(/).map(t=>"(("+t+"))").map(Ua),n=new Ba;return e.reduce((t,e)=>[...t,...e?.faces],[]).forEach(t=>n.addFace([...t?.shapes])),n}(t.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/,"$1"))}function Ga(t){return t.split("\n")?.every(t=>t.includes("POINT"))}function Za(t){return t.split("\n")?.every(t=>t.includes("LINESTRING"))}$i.isWktString=function(t){return t.startsWith("POINT")||Ga(t)||t.startsWith("LINESTRING")||Za(t)||t.startsWith("MULTILINESTRING")||t.startsWith("POLYGON")||t.startsWith("MULTIPOINT")||t.startsWith("MULTIPOLYGON")||t.startsWith("GEOMETRYCOLLECTION")},$i.parseWKT=function t(e){if(e.startsWith("POINT")){return ja(e.replace(/^POINT \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTIPOINT")){return Wa(e.replace(/^MULTIPOINT \(/,"").replace(/\)$/,""))}if(e.startsWith("LINESTRING")){return Ha(e.replace(/^LINESTRING \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTILINESTRING")){return function(t){return t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), (").map(Ha)}(e.replace(/^MULTILINESTRING /,""))}if(e.startsWith("POLYGON")||e.startsWith("MULTIPOLYGON"))return Va(e);if(e.startsWith("GEOMETRYCOLLECTION")){const n=/(?<type>POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \((?:[^\(\)]|\([^\)]*\))*\)/g,s=e.match(n);s[0].startsWith("GEOMETRYCOLLECTION")&&(s[0]=s[0].replace("GEOMETRYCOLLECTION (",""));return s.map(t).map(t=>t instanceof Array?t:[t]).reduce((t,e)=>[...t,...e],[])}return Ga(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map(ja)}(e):Za(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map(Ha).reduce((t,e)=>[...t,...e],[])}(e):[]},$i.BooleanOperations=oa,$i.Relations=va;var qa,Ja,Ka,Qa=(qa=go(),Ja=1,Ka=null!=qa?qs(to(qa)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of Qs(e))eo.call(t,o)||o===n||Js(t,o,{get:()=>e[o],enumerable:!(s=Ks(e,o))||s.enumerable});return t})(!Ja&&qa&&qa.__esModule?Ka:Js(Ka,"default",{value:qa,enumerable:!0}),qa)),tc=Object.create,ec=Object.defineProperty,nc=Object.getOwnPropertyDescriptor,sc=Object.getOwnPropertyNames,oc=Object.getPrototypeOf,ic=Object.prototype.hasOwnProperty,rc=(t,e)=>function(){return e||(0,t[sc(t)[0]])((e={exports:{}}).exports,e),e.exports},ac=(t,e,n)=>(n=null!=t?tc(oc(t)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of sc(e))ic.call(t,o)||o===n||ec(t,o,{get:()=>e[o],enumerable:!(s=nc(e,o))||s.enumerable});return t})(!e&&t&&t.__esModule?n:ec(n,"default",{value:t,enumerable:!0}),t)),cc=rc({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),hc=rc({"node_modules/kind-of/index.js"(t,e){var n=cc(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),lc=rc({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),dc=rc({"node_modules/deep-rename-keys/index.js"(t,e){var n=hc(),s=lc();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),uc=rc({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),pc=rc({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=uc(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),fc=rc({"node_modules/xml-reader/dist/reader.js"(t,e){var n=uc(),s=pc(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}}),{cos:mc,sin:gc,PI:yc}=Math,{tan:xc}=Math;ac(dc()),ac(fc());function vc(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.infiniteLines)for(const n of t.infiniteLines)n.step=e;if(t.polygons)for(const n of t.polygons)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var bc=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function Pc(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var Sc=class extends bc{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,s=this.firstIterationOfStage[e.solverName]||0,o=this.iterations,i=e.solverName===this.getCurrentStageName()?o-s:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:i,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(vc(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const s=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const s=this[e.solverName],o=s?.visualize();return o?(vc(o,n+t),o):null}).filter(Boolean));return 0===s.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(vc(n,s.length+t+1),s.push(n)),1===s.length?s[0]:{points:s.flatMap(t=>t.points||[]),rects:s.flatMap(t=>t.rects||[]),lines:s.flatMap(t=>t.lines||[]),circles:s.flatMap(t=>t.circles||[]),texts:s.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},Mc=t=>{const{o:e,a:n,b:s}=t;return(n.x-e.x)*(s.y-e.y)-(n.y-e.y)*(s.x-e.x)},Nc=(t,e)=>{const n=[...new Set(t)].map(t=>{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=>null!==t);if(n.sort((t,e)=>t.x-e.x||t.y-e.y),n.length<=2)return n.map(t=>t.i);const s=[],o=[];for(const t of n){for(;s.length>=2;){const e=s[s.length-2],n=s[s.length-1];if(!e||!n||Mc({o:e,a:n,b:t})>1e-10)break;s.pop()}s.push(t)}for(let t=n.length-1;t>=0;t--){const e=n[t];if(e){for(;o.length>=2;){const t=o[o.length-2],n=o[o.length-1];if(!t||!n||Mc({o:t,a:n,b:e})>1e-10)break;o.pop()}o.push(e)}}return s.pop(),o.pop(),s.concat(o).map(t=>t.i)},Ic=t=>void 0!==t,_c=class extends bc{input;output=null;constructor(t){super(),this.input=t}_step(){const{regions:t,hulls:e}={regions:(n=this.input).cells.map(t=>t.map(t=>n.pts[t]).filter(Ic)),hulls:n.cells.map(t=>Nc(t,n.pts).map(t=>n.pts[t]).filter(Ic))};var n;this.output={pts:this.input.pts,validTris:this.input.validTris,regions:t,hulls:e,depths:this.input.depths},this.stats={regions:t.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output;return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.regions.flatMap(t=>t.flatMap((e,n)=>{const s=t[(n+1)%t.length];return s?[{points:[e,s],strokeColor:"#0f766e"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`regions: ${t.regions.length}`,color:"#1f2937"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},Cc=t=>{const{polygon:e,clearance:n,verticesOnly:s=!1}=t,o=e.points,i=o.length;if(i<3)return[];const r=new Aa(o.map(t=>Ca(t.x,t.y))).orientation()===Ri.CCW,a=[];for(let t=0;t<i;t++){const e=o[t],s=o[(t+1)%i],c=Ta(s.x-e.x,s.y-e.y);if(0===c.length){a.push(Ra(Ca(e.x,e.y),Ta(1,0)));continue}const h=c.normalize(),l=r?Ta(h.y,-h.x):Ta(-h.y,h.x),d=Ca(e.x+n*l.x,e.y+n*l.y);a.push(Ra(d,l))}const c=[];for(let t=0;t<i;t++){const e=a[(t-1+i)%i],n=a[t],s=e.intersect(n);if(s.length>0){const t=s[0];c.push({x:t.x,y:t.y})}else c.push({x:n.pt.x,y:n.pt.y})}if(s)return c;const h=[];for(let t=0;t<i;t++){const e=c[t],n=c[(t+1)%i],s=Ea(Ca(e.x,e.y),Ca(n.x,n.y)).length,o=Math.max(2,Math.ceil(s/20));for(let t=0;t<o;t++){const s=t/o;h.push({x:e.x+s*(n.x-e.x),y:e.y+s*(n.y-e.y)})}}return h},Tc=t=>{const{localX:e,localY:n,rect:s}=t,o=Math.cos(s.ccwRotation),i=Math.sin(s.ccwRotation);return{x:s.center.x+e*o-n*i,y:s.center.y+e*i+n*o}},Ec=t=>{const{bounds:e,vias:n,clearance:s,rects:o,polygons:i=[],viaSegments:r=24}=t,a=[],{minX:c,maxX:h,minY:l,maxY:d}=e;a.push({x:c,y:l},{x:h,y:l},{x:h,y:d},{x:c,y:d});for(let t=1;t<10;t++){const e=t/10;a.push({x:c+e*(h-c),y:l}),a.push({x:h,y:l+e*(d-l)}),a.push({x:h-e*(h-c),y:d}),a.push({x:c,y:d-e*(d-l)})}for(const t of n){const e=t.diameter/2+s;for(let n=0;n<r;n++){const s=2*Math.PI*n/r;a.push({x:t.center.x+e*Math.cos(s),y:t.center.y+e*Math.sin(s)})}}for(const t of o){const e=t.width/2+s,n=t.height/2+s,o=Math.max(2,Math.ceil(Math.max(2*e,2*n)/20));for(let s=0;s<o;s++){const i=s/o;a.push(Tc({localX:2*i*e-e,localY:-n,rect:t})),a.push(Tc({localX:e,localY:2*i*n-n,rect:t})),a.push(Tc({localX:e-2*i*e,localY:n,rect:t})),a.push(Tc({localX:-e,localY:n-2*i*n,rect:t}))}}for(const t of i){if(t.points.length<3)continue;const e=Cc({polygon:t,clearance:s});a.push(...e)}return a.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))},wc=(t,e,n)=>{const s=e.length;e.push(...t);const o=t.length;for(let t=0;t<o;t++)n.push([s+t,s+(t+1)%o])},Rc=t=>{const{bounds:e,vias:n,clearance:s,rects:o,polygons:i=[],viaSegments:r=8}=t,a=[],c=[],h=[],{minX:l,maxX:d,minY:u,maxY:p}=e,f=10,m=[];for(let t=0;t<f;t++){const e=t/f;m.push({x:l+e*(d-l),y:u})}for(let t=0;t<f;t++){const e=t/f;m.push({x:d,y:u+e*(p-u)})}for(let t=0;t<f;t++){const e=t/f;m.push({x:d-e*(d-l),y:p})}for(let t=0;t<f;t++){const e=t/f;m.push({x:l,y:p-e*(p-u)})}h.push(c.length),wc(m,a,c);for(const t of n){const e=t.diameter/2+s,n=[];for(let s=0;s<r;s++){const o=2*Math.PI*s/r;n.push({x:t.center.x+e*Math.cos(o),y:t.center.y+e*Math.sin(o)})}h.push(c.length),wc(n,a,c)}for(const t of o){const e=t.width/2+s,n=t.height/2+s,o=[Tc({localX:-e,localY:-n,rect:t}),Tc({localX:e,localY:-n,rect:t}),Tc({localX:e,localY:n,rect:t}),Tc({localX:-e,localY:n,rect:t})];h.push(c.length),wc(o,a,c)}for(const t of i){if(t.points.length<3)continue;const e=Cc({polygon:t,clearance:s,verticesOnly:!0});h.push(c.length),wc(e,a,c)}const g=((t,e,n)=>{const s=new Array(e.length);for(let t=0;t<e.length;t++)for(let e=n.length-1;e>=0;e--)if(t>=n[e]){s[t]=e;break}const o=new Map,i=t.slice();for(let t=0;t<e.length;t++)for(let n=t+1;n<e.length;n++){if(s[t]===s[n])continue;const[r,a]=e[t],[c,h]=e[n],l=i[r],d=i[a],u=i[c],p=i[h],f=d.x-l.x,m=d.y-l.y,g=p.x-u.x,y=p.y-u.y,x=f*y-m*g;if(Math.abs(x)<1e-10)continue;const v=((u.x-l.x)*y-(u.y-l.y)*g)/x,b=((u.x-l.x)*m-(u.y-l.y)*f)/x;if(v>1e-6&&v<.999999&&b>1e-6&&b<.999999){const e=l.x+v*f,s=l.y+v*m,r=i.length;i.push({x:e,y:s}),o.has(t)||o.set(t,[]),o.get(t).push({t:v,idx:r}),o.has(n)||o.set(n,[]),o.get(n).push({t:b,idx:r})}}if(0===o.size)return{pts:t,constraintEdges:e,hadCrossings:!1};const r=[];for(let t=0;t<e.length;t++){const n=o.get(t);if(!n||0===n.length){r.push(e[t]);continue}n.sort((t,e)=>t.t-e.t);const[s,i]=e[t];let a=s;for(const t of n)r.push([a,t.idx]),a=t.idx;r.push([a,i])}return{pts:i,constraintEdges:r,hadCrossings:!0}})(a,c,h);return{pts:g.pts.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)})),constraintEdges:g.constraintEdges,hadCrossings:g.hadCrossings}},Oc=class extends bc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=this.input.polygons??[];if(!1!==this.input.useConstrainedDelaunay){const s=Rc({bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n,viaSegments:this.input.viaSegments});this.output={pts:s.pts,constraintEdges:s.constraintEdges,hadCrossings:s.hadCrossings}}else this.output={pts:Ec({bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n,viaSegments:this.input.viaSegments})};this.stats={points:this.output.pts.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=(this.output?.pts??[]).map(t=>({x:t.x,y:t.y,color:"#2563eb"}));return{points:t,lines:[],rects:[],circles:(this.input.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2+this.input.clearance,stroke:"#ef4444"})),texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`sample points: ${t.length}`,color:"#1f2937"}]}}},Ac=t=>{const{p:e,a:n,b:s}=t,o=s.x-n.x,i=s.y-n.y,r=o*o+i*i;if(r<1e-10)return Math.hypot(e.x-n.x,e.y-n.y);let a=((e.x-n.x)*o+(e.y-n.y)*i)/r;return a=Math.max(0,Math.min(1,a)),Math.hypot(e.x-n.x-a*o,e.y-n.y-a*i)},zc=(t,e)=>{if(t.length<=3)return 0;const n=Nc(t,e),s=new Set(n),o=n.map(t=>e[t]).filter(t=>Boolean(t));let i=0;for(const n of t){if(s.has(n))continue;const t=e[n];if(!t)continue;let r=Number.POSITIVE_INFINITY;for(let e=0;e<o.length;e++){const n=o[e],s=o[(e+1)%o.length];n&&s&&(r=Math.min(r,Ac({p:t,a:n,b:s})))}i=Math.max(i,r)}return i},Dc=(t,e)=>t<e?1e5*t+e:1e5*e+t,Lc=(t,e)=>{const n=t.map((e,n)=>[e,t[(n+1)%t.length]]),s=e.map((t,n)=>[t,e[(n+1)%e.length]]),o=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,i]of s)void 0!==i&&t===i&&e===n&&o.add(Dc(t,e));if(0===o.size)return null;const i=[];for(const[t,e]of n)void 0!==e&&(o.has(Dc(t,e))||i.push([t,e]));for(const[t,e]of s)void 0!==e&&(o.has(Dc(t,e))||i.push([t,e]));if(0===i.length)return null;const r=new Map;for(const[t,e]of i)r.set(t,e);const a=i[0]?.[0];if(void 0===a)return null;const c=[a];let h=r.get(a),l=0;for(;void 0!==h&&h!==a&&l++<i.length+5;)c.push(h),h=r.get(h);return h!==a||c.length!==i.length?null:c},Fc=(t,e)=>t<e?1e5*t+e:1e5*e+t,Yc=class extends bc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=(t=>{const{triangles:e,pts:n,concavityTolerance:s}=t;if(!e.length)return{cells:[],depths:[]};const o=e.map(([t,e,s])=>{const o=n[t],i=n[e],r=n[s];return o&&i&&r&&Mc({o:o,a:i,b:r})<0?[t,s,e]:[t,e,s]});let i=!0,r=0;for(;i&&r++<800;){i=!1;const t=new Map,e=o.map(()=>new Set);for(let n=0;n<o.length;n++){const s=o[n];if(s)for(let o=0;o<s.length;o++){const i=s[o],r=s[(o+1)%s.length];if(void 0===i||void 0===r)continue;const a=Fc(i,r);if(t.has(a)){const s=t.get(a);void 0!==s&&(e[n]?.add(s),e[s]?.add(n))}else t.set(a,n)}}let r=-1,a=-1,c=null,h=Number.POSITIVE_INFINITY;for(let t=0;t<o.length;t++){const i=e[t];if(i)for(const e of i){if(e<=t)continue;const i=Lc(o[t]??[],o[e]??[]);if(!i)continue;const l=zc(i,n);l<=s+1e-6&&l<h&&(h=l,r=t,a=e,c=i)}}if(r<0||a<0||!c)break;o[r]=c,o.splice(a,1),i=!0}const a=o.map(t=>zc(t,n));return{cells:o,depths:a}})({triangles:this.input.validTris,pts:this.input.pts,concavityTolerance:this.input.concavityTolerance});this.output={pts:this.input.pts,validTris:this.input.validTris,cells:t.cells,depths:t.depths},this.stats={mergedCells:t.cells.length,maxDepth:t.depths.length?Math.max(...t.depths):0},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.cells??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.flatMap(t=>t.flatMap((e,n)=>{const s=this.input.pts[e],o=t[(n+1)%t.length],i=void 0===o?void 0:this.input.pts[o];return s&&i?[{points:[s,i],strokeColor:"#10b981"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`merged cells: ${t.length}`,color:"#1f2937"}]}}},Xc=t=>{const{a:e,b:n,c:s}=t,o=2*(e.x*(n.y-s.y)+n.x*(s.y-e.y)+s.x*(e.y-n.y));if(Math.abs(o)<1e-10)return{x:0,y:0,r2:1e18};const i=e.x*e.x+e.y*e.y,r=n.x*n.x+n.y*n.y,a=s.x*s.x+s.y*s.y,c=(i*(n.y-s.y)+r*(s.y-e.y)+a*(e.y-n.y))/o,h=(i*(s.x-n.x)+r*(e.x-s.x)+a*(n.x-e.x))/o;return{x:c,y:h,r2:(e.x-c)**2+(e.y-h)**2}},kc=(t,e,n)=>[t.a,t.b,t.c].includes(e)&&[t.a,t.b,t.c].includes(n),$c=t=>{const{px:e,py:n,polygonPoints:s,clearance:o}=t;if(s.length<3)return!1;const i=s.map(t=>Ca(t.x,t.y)),r=[];for(let t=0;t<i.length;t++){const e=i[t],n=i[(t+1)%i.length];r.push(Ea(e,n))}const a=new Aa;a.addFace(r);const c=Ca(e,n);if(a.contains(c))return!0;const[h]=a.distanceTo(c);return h<o-.1},Bc=t=>{const{triangles:e,pts:n,bounds:s,vias:o,clearance:i,rects:r,polygons:a}=t;return e.filter(([t,e,c])=>{const h=n[t],l=n[e],d=n[c];if(!h||!l||!d)return!1;if(!(t=>{const{px:e,py:n,bounds:s,vias:o,clearance:i,rects:r,polygons:a}=t,{minX:c,maxX:h,minY:l,maxY:d}=s;if(e<c-.1||e>h+.1||n<l-.1||n>d+.1)return!1;for(const t of o){const s=t.diameter/2+i;if((e-t.center.x)**2+(n-t.center.y)**2<s*s-.1)return!1}for(const t of r){const s=t.width/2+i,o=t.height/2+i,r=e-t.center.x,a=n-t.center.y,c=Math.cos(t.ccwRotation),h=Math.sin(t.ccwRotation),l=r*c+a*h,d=-r*h+a*c;if(Math.abs(l)<s-.1&&Math.abs(d)<o-.1)return!1}for(const t of a)if($c({px:e,py:n,polygonPoints:t.points,clearance:i}))return!1;return!0})({px:(h.x+l.x+d.x)/3,py:(h.y+l.y+d.y)/3,bounds:s,vias:o,clearance:i,rects:r,polygons:a}))return!1;if(a.length>0){const t=[h,l,d,{x:(h.x+l.x)/2,y:(h.y+l.y)/2},{x:(l.x+d.x)/2,y:(l.y+d.y)/2},{x:(d.x+h.x)/2,y:(d.y+h.y)/2}];for(const e of t)for(const t of a)if($c({px:e.x,py:e.y,polygonPoints:t.points,clearance:i}))return!1}return!0})},jc=class extends bc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=this.input.polygons??[];let s;if(!1!==this.input.useConstrainedDelaunay&&this.input.constraintEdges){const o=((t,e)=>{const n=t.map(t=>[t.x,t.y]);return(0,Qa.default)(n,e,{exterior:!1})})(this.input.pts,this.input.constraintEdges);s=this.input.hadCrossings?Bc({triangles:o,pts:this.input.pts,bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n}):o}else{const o=(t=>{const e=t.map((t,e)=>({...t,i:e}));if(e.length<3)return[];let n=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),s=Math.min(s,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);const r=Math.max(o-n,i-s)||1,a=(n+o)/2,c=(s+i)/2,h={x:a-30*r,y:c-r,i:-1},l={x:a,y:c+30*r,i:-2},d={x:a+30*r,y:c-r,i:-3};let u=[{a:h,b:l,c:d,cc:Xc({a:h,b:l,c:d})}];for(const t of e){const e=u.filter(e=>{const n=t.x-e.cc.x,s=t.y-e.cc.y;return n*n+s*s<e.cc.r2+1e-6}),n=new Set(e),s=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[o,i]of n){let n=!1;for(const s of e)if(s!==t&&kc(s,o,i)){n=!0;break}n||s.push([o,i])}}u=u.filter(t=>!n.has(t));for(const[e,n]of s)u.push({a:e,b:n,c:t,cc:Xc({a:e,b:n,c:t})})}return u.filter(t=>t.a.i>=0&&t.b.i>=0&&t.c.i>=0).map(t=>[t.a.i,t.b.i,t.c.i])})(this.input.pts);s=Bc({triangles:o,pts:this.input.pts,bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n})}this.output={pts:this.input.pts,validTris:s},this.stats={validTriangles:s.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.validTris??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#2563eb"})),lines:t.flatMap(([t,e,n])=>{const s=this.input.pts[t],o=this.input.pts[e],i=this.input.pts[n];return s&&o&&i?[{points:[s,o],strokeColor:"#64748b"},{points:[o,i],strokeColor:"#64748b"},{points:[i,s],strokeColor:"#64748b"}]:[]}),rects:[],circles:[],texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`valid triangles: ${t.length}`,color:"#1f2937"}]}}},Wc=class extends Sc{pipelineDef=[Pc("generatePoints",Oc,t=>[t.inputProblem]),Pc("triangulate",jc,t=>{const e=t.getStageOutput("generatePoints");if(!e)throw new Error("generatePoints output missing");return[{pts:e.pts,bounds:t.inputProblem.bounds,vias:t.inputProblem.vias,rects:t.inputProblem.rects,polygons:t.inputProblem.polygons,clearance:t.inputProblem.clearance,useConstrainedDelaunay:t.inputProblem.useConstrainedDelaunay,constraintEdges:e.constraintEdges,hadCrossings:e.hadCrossings}]}),Pc("mergeCells",Yc,t=>{const e=t.getStageOutput("triangulate");if(!e)throw new Error("triangulate output missing");return[{pts:e.pts,validTris:e.validTris,concavityTolerance:t.inputProblem.concavityTolerance}]}),Pc("buildRegions",_c,t=>{const e=t.getStageOutput("mergeCells");if(!e)throw new Error("mergeCells output missing");return[e]})];getConstructorParams(){return[this.inputProblem]}getOutput(){return this.getStageOutput("buildRegions")??null}visualize(){const t=this.getOutput();if(!t)return{points:[],lines:[],rects:[],circles:[],texts:[]};const e=(this.inputProblem.polygons??[]).flatMap(t=>{const e=t.points;return e.map((t,n)=>{const s=e[(n+1)%e.length];return{points:[{x:t.x,y:t.y},{x:s.x,y:s.y}],strokeColor:"#ff9f43",strokeWidth:2}})}),n=(this.inputProblem.rects??[]).flatMap(t=>{const e=t.width/2,n=t.height/2,s=Math.cos(t.ccwRotation),o=Math.sin(t.ccwRotation),i=[{lx:-e,ly:-n},{lx:e,ly:-n},{lx:e,ly:n},{lx:-e,ly:n}].map(({lx:e,ly:n})=>({x:t.center.x+e*s-n*o,y:t.center.y+e*o+n*s}));return i.map((t,e)=>{const n=i[(e+1)%i.length];return{points:[{x:t.x,y:t.y},{x:n.x,y:n.y}],strokeColor:"#ff6b6b",strokeWidth:2}})});return{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#38b6ff"})),lines:[...t.regions.flatMap(t=>t.map((e,n)=>{const s=t[(n+1)%t.length]??e;return{points:[{x:e.x,y:e.y},{x:s.x,y:s.y}],strokeColor:"#4ecb82"}})),...e,...n],rects:[],circles:(this.inputProblem.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2,stroke:"#ff6b6b"})),texts:[{x:this.inputProblem.bounds.minX+8,y:this.inputProblem.bounds.minY+16,text:`regions=${t.regions.length}`,color:"#ffffff"}]}}};function Hc(t,e,n,s,o){const i=e.x-t.x,r=e.y-t.y,a=s.x-n.x,c=s.y-n.y,h=i*c-r*a,l=Math.sqrt(i*i+r*r),d=Math.sqrt(a*a+c*c);if(l<o||d<o)return!1;if(Math.abs(h)/(l*d)>o)return!1;const u=n.x-t.x,p=n.y-t.y;return Math.abs(i*p-r*u)/l<o}function Uc(t,e,n){const s=n.x-e.x,o=n.y-e.y,i=s*s+o*o;if(i<1e-12){return{t:0,distance:Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2)}}const r=((t.x-e.x)*s+(t.y-e.y)*o)/i,a=e.x+r*s,c=e.y+r*o;return{t:r,distance:Math.sqrt((t.x-a)**2+(t.y-c)**2)}}function Vc(t,e,n,s){const o=Math.min(t,e),i=Math.max(t,e),r=Math.min(n,s),a=Math.max(n,s),c=Math.max(o,r),h=Math.min(i,a);return h-c<1e-6?null:{from:c,to:h}}function Gc(t,e,n=.01){const s=[];for(let o=0;o<t.length;o++){const i=t[o],r=t[(o+1)%t.length];for(let t=0;t<e.length;t++){const o=e[t],a=e[(t+1)%e.length];if(!Hc(i,r,o,a,n))continue;const c=Uc(o,i,r),h=Uc(a,i,r);if(c.distance>n||h.distance>n)continue;const l=Vc(0,1,c.t,h.t);if(!l)continue;const d=r.x-i.x,u=r.y-i.y,p={x:i.x+l.from*d,y:i.y+l.from*u},f={x:i.x+l.to*d,y:i.y+l.to*u};s.push({from:p,to:f})}}return s}function Zc(t,e=.4){const n=t.to.x-t.from.x,s=t.to.y-t.from.y,o=Math.sqrt(n*n+s*s);if(o<.001)return[];const i=Math.max(1,Math.floor(o/e)),r=[];for(let e=0;e<i;e++){const o=(e+.5)/i;r.push({x:t.from.x+o*n,y:t.from.y+o*s})}return r}function qc(t,e=.001){if(t.length<=1)return t;const n=[t[0]];for(let s=1;s<t.length;s++){const o=n[n.length-1],i=t[s];Math.sqrt((i.x-o.x)**2+(i.y-o.y)**2)>e&&n.push(i)}if(n.length>1){const t=n[0],s=n[n.length-1];Math.sqrt((s.x-t.x)**2+(s.y-t.y)**2)<e&&n.pop()}return n}function Jc(t){let e=1/0,n=-1/0,s=1/0,o=-1/0;for(const i of t)i.x<e&&(e=i.x),i.x>n&&(n=i.x),i.y<s&&(s=i.y),i.y>o&&(o=i.y);return{minX:e,maxX:n,minY:s,maxY:o}}function Kc(t){let e=0,n=0;for(const s of t)e+=s.x,n+=s.y;return{x:e/t.length,y:n/t.length}}function Qc(t,e,n){return{regionId:t,ports:[],d:{bounds:Jc(e),center:Kc(e),polygon:e,isPad:!1,isViaRegion:n?.isViaRegion}}}function th(t){if(0===t.length)return[];const e=t.reduce((t,e)=>e.position.y>t.position.y?e:t),n=t.reduce((t,e)=>e.position.y<t.position.y?e:t),s=t.reduce((t,e)=>e.position.x<t.position.x?e:t),o=t.reduce((t,e)=>e.position.x>t.position.x?e:t),i={xStart:e.position.x-e.diameter/2,xEnd:e.position.x+e.diameter/2,y:e.position.y+e.diameter/2},r={xStart:n.position.x-n.diameter/2,xEnd:n.position.x+n.diameter/2,y:n.position.y-n.diameter/2},a={x:s.position.x-s.diameter/2,yStart:s.position.y-s.diameter/2,yEnd:s.position.y+s.diameter/2},c={x:o.position.x+o.diameter/2,yStart:o.position.y-o.diameter/2,yEnd:o.position.y+o.diameter/2};return qc([{x:i.xStart,y:i.y},{x:i.xEnd,y:i.y},{x:c.x,y:c.yEnd},{x:c.x,y:c.yStart},{x:r.xEnd,y:r.y},{x:r.xStart,y:r.y},{x:a.x,y:a.yStart},{x:a.x,y:a.yEnd}])}function eh(t,e,n,s){return t.map(t=>({viaId:`${s}:${t.viaId}`,diameter:t.diameter,position:{x:t.position.x+e,y:t.position.y+n}}))}function nh(t,e,n,s){return t.map(t=>({routeId:`${s}:${t.routeId}`,fromPort:`${s}:${t.fromPort}`,toPort:`${s}:${t.toPort}`,layer:t.layer,segments:t.segments.map(t=>({x:t.x+e,y:t.y+n}))}))}function sh(t,e,n){return t.map(t=>({x:t.x+e,y:t.y+n}))}function oh(t){return[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}]}function ih(t){if(t.length<3)return{top:null,bottom:null,left:null,right:null};const e=Jc(t),n=.001;let s=null,o=null,i=null,r=null;for(let a=0;a<t.length;a++){const c=t[a],h=t[(a+1)%t.length];Math.abs(c.y-e.maxY)<n&&Math.abs(h.y-e.maxY)<n&&(s={x:(c.x+h.x)/2,y:e.maxY}),Math.abs(c.y-e.minY)<n&&Math.abs(h.y-e.minY)<n&&(o={x:(c.x+h.x)/2,y:e.minY}),Math.abs(c.x-e.minX)<n&&Math.abs(h.x-e.minX)<n&&(i={x:e.minX,y:(c.y+h.y)/2}),Math.abs(c.x-e.maxX)<n&&Math.abs(h.x-e.maxX)<n&&(r={x:e.maxX,y:(c.y+h.y)/2})}return{top:s,bottom:o,left:i,right:r}}function rh(t,e,n=.1){if(0===t.length)return t;const s=Jc(t),o=s.minX-e.minX,i=e.maxX-s.maxX,r=s.minY-e.minY,a=e.maxY-s.maxY,c=o>0&&o<n,h=i>0&&i<n,l=r>0&&r<n,d=a>0&&a<n;if(!(c||h||l||d))return t;return qc(t.map(t=>{let n=t.x,o=t.y;return c&&Math.abs(t.x-s.minX)<.001&&(n=e.minX),h&&Math.abs(t.x-s.maxX)<.001&&(n=e.maxX),l&&Math.abs(t.y-s.minY)<.001&&(o=e.minY),d&&Math.abs(t.y-s.maxY)<.001&&(o=e.maxY),{x:n,y:o}}))}function ah(t,e){let n=!1;const s=e.length;for(let o=0,i=s-1;o<s;i=o++){const s=e[o].x,r=e[o].y,a=e[i].x,c=e[i].y;if(Math.abs((t.y-r)*(a-s)-(t.x-s)*(c-r))<.001&&t.x>=Math.min(s,a)-.001&&t.x<=Math.max(s,a)+.001&&t.y>=Math.min(r,c)-.001&&t.y<=Math.max(r,c)+.001)return!0;if(r>t.y!=c>t.y){const e=(a-s)*(t.y-r)/(c-r)+s;t.x<e&&(n=!n)}}return n}function ch(t,e){for(const n of e)if(n.d.polygon&&ah(t,n.d.polygon))return n;return null}function hh(t){const e=t.tileWidth??t.tileSize??t.viaTile.tileWidth,n=t.tileHeight??t.tileSize??t.viaTile.tileHeight;if(void 0===e||void 0===n)throw new Error("tileWidth and tileHeight must be provided either in opts or in viaTile");const s=t.portPitch??.4,o=t.clearance??.1,i=t.concavityTolerance??0,{bounds:r,viaTile:a}=t,{viasByNet:c,routeSegments:h}=a,l=r.maxX-r.minX,d=r.maxY-r.minY,u=Math.floor(l/e),p=Math.floor(d/n),f=[],m=[],g={viasByNet:{},routeSegments:[]},y=[],x=[],v=u*e,b=p*n,P=r.minX+(l-v)/2,S=r.minY+(d-b)/2,M=P+v,N=S+b,I=e/2,_=n/2;let C=0;const T=new Set,E=(t,e,n,s)=>{const o=(i=s.x,r=s.y,`${i.toFixed(4)},${r.toFixed(4)}`);var i,r;if(T.has(o))return null;T.add(o);const a={portId:t,region1:e,region2:n,d:{x:s.x,y:s.y}};return e.ports.push(a),n.ports.push(a),m.push(a),a};let w=null;if(p>0&&u>0&&(w=function(t,e,n,s,o){const i=e/2,r=n/2,a={minX:-i,maxX:i,minY:-r,maxY:r},c=[];for(const[e,n]of Object.entries(t.viasByNet)){if(0===n.length)continue;const t=th(n);0!==t.length&&c.push({netName:e,polygon:t,bounds:Jc(t),center:Kc(t)})}const h=c.map(t=>({points:rh(t.polygon,a)})),l=new Wc({bounds:a,polygons:h,clearance:s,concavityTolerance:o});l.solve();const d=l.getOutput();if(!d)throw new Error("ConvexRegionsSolver failed to compute unit tile regions");return{viaRegions:c,convexRegions:d.regions.map(t=>({polygon:t,bounds:Jc(t),center:Kc(t)})),tileWidth:e,tileHeight:n}}(a,e,n,o,i)),p>0&&u>0&&w)for(let t=0;t<p;t++)for(let s=0;s<u;s++){const o=P+s*e+I,i=S+t*n+_,r=`t${t}_${s}`;for(const t of w.viaRegions){const e=sh(t.polygon,o,i),n=Qc(`${r}:v:${t.netName}`,e,{isViaRegion:!0});y.push(n),f.push(n)}for(let t=0;t<w.convexRegions.length;t++){const e=Qc(`${r}:convex:${t}`,sh(w.convexRegions[t].polygon,o,i));x.push(e),f.push(e)}for(const[t,e]of Object.entries(c)){if(0===e.length)continue;const n=eh(e,o,i,r);g.viasByNet[t]||(g.viasByNet[t]=[]),g.viasByNet[t].push(...n)}g.routeSegments.push(...nh(h,o,i,r))}const R=[],O=r.maxY-N,A=S-r.minY,z=P-r.minX,D=r.maxX-M,L=Math.max(O,A)>=Math.max(z,D),F=L?r.minX:P,Y=L?r.maxX:M,X=L?r.minX:P,k=L?r.maxX:M,$=L?S:r.minY,B=L?N:r.maxY,j=L?S:r.minY,W=L?N:r.maxY;if(O>.001){const t=Y-F,e=Math.max(O,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Qc(`filler:top:${t}`,oh({minX:F+t*o,maxX:F+(t+1)*o,minY:N,maxY:r.maxY}));R.push(e),f.push(e)}}if(A>.001){const t=k-X,e=Math.max(A,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Qc(`filler:bottom:${t}`,oh({minX:X+t*o,maxX:X+(t+1)*o,minY:r.minY,maxY:S}));R.push(e),f.push(e)}}if(z>.001){const t=B-$,e=Math.max(z,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Qc(`filler:left:${t}`,oh({minX:r.minX,maxX:P,minY:$+t*o,maxY:$+(t+1)*o}));R.push(e),f.push(e)}}if(D>.001){const t=W-j,e=Math.max(D,s),n=Math.max(1,Math.floor(t/e)),o=t/n;for(let t=0;t<n;t++){const e=Qc(`filler:right:${t}`,oh({minX:M,maxX:r.maxX,minY:j+t*o,maxY:j+(t+1)*o}));R.push(e),f.push(e)}}if(w&&p>0&&u>0){const t=w.convexRegions.length;for(let e=0;e<p;e++)for(let n=0;n<u;n++){const i=(e*u+n)*t;for(let r=0;r<t;r++)for(let a=r+1;a<t;a++){const t=x[i+r],c=x[i+a],h=Gc(t.d.polygon,c.d.polygon,2*o);for(const o of h){const i=Zc(o,s);for(const s of i)E(`t${e}_${n}:convex:${r}-${a}:${C++}`,t,c,s)}}}}if(w&&p>0&&u>0){const t=w.convexRegions.length,o=w.viaRegions.length,i=Math.floor(n/s),r=[];for(let t=0;t<i;t++)r.push((t+.5)*s-_);const a=Math.floor(e/s),c=[];for(let t=0;t<a;t++)c.push((t+.5)*s-I);for(let s=0;s<p;s++)for(let i=0;i<u;i++){const a=s*u+i,h=a*t,l=a*o,d=P+i*e+I,f=S+s*n+_,m=[...x.slice(h,h+t),...y.slice(l,l+o)];if(i+1<u){const e=s*u+(i+1),n=e*t,a=e*o,c=[...x.slice(n,n+t),...y.slice(a,a+o)],h=d+I;for(const t of r){const e=f+t,n={x:h+.01,y:e},o=ch({x:h-.01,y:e},m),r=ch(n,c);o&&r&&E(`tile:${s}_${i}-${s}_${i+1}:${C++}`,o,r,{x:h,y:e})}}if(s+1<p){const e=(s+1)*u+i,n=e*t,r=e*o,a=[...x.slice(n,n+t),...y.slice(r,r+o)],h=f+_;for(const t of c){const e=d+t,n={x:e,y:h+.01},o=ch({x:e,y:h-.01},m),r=ch(n,a);o&&r&&E(`tile:${s}_${i}-${s+1}_${i}:${C++}`,o,r,{x:e,y:h})}}}}const H=new Map;for(const t of R){H.set(t.regionId,[]);const e=t.d.bounds,n=e.maxX-e.minX,i=e.maxY-e.minY,r=n>i,a=r?n:i,c=(Math.max(1,Math.floor(a/s)),2*o),h=t.regionId.startsWith("filler:top:"),l=t.regionId.startsWith("filler:bottom:"),d=t.regionId.startsWith("filler:left:"),u=t.regionId.startsWith("filler:right:"),p=[...x,...y];for(const n of p){const o=n.d.bounds,i=.001;let a,p,f=!1,m=null,g=null;if(r){const t=Math.max(e.minX,o.minX);Math.min(e.maxX,o.maxX)>t+i&&(h?(f=Math.abs(o.maxY-e.minY)<c,g=e.minY):l&&(f=Math.abs(o.minY-e.maxY)<c,g=e.maxY))}else{const t=Math.max(e.minY,o.minY);Math.min(e.maxY,o.maxY)>t+i&&(d?(f=Math.abs(o.minX-e.maxX)<c,m=e.maxX):u&&(f=Math.abs(o.maxX-e.minX)<c,m=e.minX))}if(!f)continue;r?(a=Math.max(e.minX,o.minX),p=Math.min(e.maxX,o.maxX)):(a=Math.max(e.minY,o.minY),p=Math.min(e.maxY,o.maxY));const y=p-a;if(y<i)continue;const x=Math.max(1,Math.floor(y/s)),v=y/x;for(let i=0;i<x;i++){let c;if(r){c={x:a+(i+.5)*v,y:g}}else{c={x:m,y:a+(i+.5)*v}}if(n.d.polygon){let t;if(h){const n=e.minY-o.maxY+.01;t={x:c.x,y:c.y-n}}else if(l){const n=o.minY-e.maxY+.01;t={x:c.x,y:c.y+n}}else if(d){const n=o.minX-e.maxX+.01;t={x:c.x+n,y:c.y}}else{const n=e.minX-o.maxX+.01;t={x:c.x-n,y:c.y}}if(!ah(t,n.d.polygon))continue}const u=H.get(t.regionId);u.some(t=>Math.sqrt((c.x-t.x)**2+(c.y-t.y)**2)<s)||(u.push(c),E(`filler:${n.regionId}-${t.regionId}:${C++}`,n,t,c))}}}for(let t=0;t<R.length;t++)for(let e=t+1;e<R.length;e++){const n=R[t],o=R[e],i=Gc(n.d.polygon,o.d.polygon,.01);for(const t of i){const e=Math.sqrt((t.to.x-t.from.x)**2+(t.to.y-t.from.y)**2);if(e<.01)continue;let i;i=e<s?[{x:(t.from.x+t.to.x)/2,y:(t.from.y+t.to.y)/2}]:Zc(t,s);for(const t of i)E(`filler:${n.regionId}-${o.regionId}:${C++}`,n,o,t)}}const U=f.filter(t=>!t.d.isViaRegion),V=new Set;for(const t of y){const e=ih(t.d.polygon),n=t.d.bounds,s=["top","bottom","left","right"];for(const o of s){const s=e[o];if(!s)continue;const i=`${t.regionId}:${o}`;if(V.has(i))continue;const r=.2,a=r;let c;switch(o){case"top":c={x:s.x,y:n.maxY+a};break;case"bottom":c={x:s.x,y:n.minY-a};break;case"left":c={x:n.minX-a,y:s.y};break;case"right":c={x:n.maxX+a,y:s.y}}for(const e of U){const a=e.d.bounds;let h=!1;switch(o){case"top":h=Math.abs(a.minY-n.maxY)<r&&a.minX<s.x&&a.maxX>s.x;break;case"bottom":h=Math.abs(a.maxY-n.minY)<r&&a.minX<s.x&&a.maxX>s.x;break;case"left":h=Math.abs(a.maxX-n.minX)<r&&a.minY<s.y&&a.maxY>s.y;break;case"right":h=Math.abs(a.minX-n.maxX)<r&&a.minY<s.y&&a.maxY>s.y}if(h&&(e.d.polygon&&ah(c,e.d.polygon))){E(`via-side:${t.regionId}:${o}:${C++}`,t,e,s),V.add(i);break}}}}return{regions:f,ports:m,viaTile:g,tileCount:{rows:p,cols:u}}}function lh(t,e=ci,n){const s=function(t){if(0===t.length)throw new Error("Cannot calculate bounds from empty connections array");let e=1/0,n=-1/0,s=1/0,o=-1/0;for(const i of t)e=Math.min(e,i.start.x,i.end.x),n=Math.max(n,i.start.x,i.end.x),s=Math.min(s,i.start.y,i.end.y),o=Math.max(o,i.start.y,i.end.y);return{minX:e,maxX:n,minY:s,maxY:o}}(t),{regions:o,ports:i,viaTile:r,tileCount:a}=hh({viaTile:e,bounds:s,tileWidth:n?.tileWidth??e.tileWidth,tileHeight:n?.tileHeight??e.tileHeight,tileSize:n?.tileSize,portPitch:n?.portPitch,clearance:n?.clearance,concavityTolerance:n?.concavityTolerance}),c=((t,e)=>{const n=[...t.regions],s=[...t.ports],o=[];for(const i of e){const{start:e,end:r,connectionId:a}=i,c=Qo(`conn:${a}:start`,e.x,e.y);n.push(c);const h=Qo(`conn:${a}:end`,r.x,r.y);n.push(h);const l=Ei({x:e.x,y:e.y,regions:t.regions});if(l){const t=Ko(`conn:${a}:start-port`,c,l.region,l.portPosition);s.push(t)}const d=Ei({x:r.x,y:r.y,regions:t.regions});if(d){const t=Ko(`conn:${a}:end-port`,h,d.region,d.portPosition);s.push(t)}const u={connectionId:a,mutuallyConnectedNetworkId:a,startRegion:c,endRegion:h};o.push(u)}return{regions:n,ports:s,connections:o}})({regions:o,ports:i},t);return{...c,viaTile:r,tileCount:a}}var dh=class extends Ln{getSolverName(){return"FixedTopologyHighDensityIntraNodeSolver"}constructorParams;nodeWithPortPoints;colorMap;traceWidth;viaDiameter;viaTile;connMap;rootConnectionNameByConnectionId=new Map;lastActiveSubSolver=null;solvedRoutes=[];vias=[];tiledViasByNet={};constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.viaTile=ci,this.viaDiameter=this._resolveViaDiameter(t.viaDiameter),this.connMap=t.connMap,this.MAX_ITERATIONS=24411*(t.effort??1),0===Object.keys(this.colorMap).length&&(this.colorMap=(t=>{const e=["#e6194b","#3cb44b","#ffe119","#4363d8","#f58231","#911eb4","#46f0f0","#f032e6","#bcf60c","#fabebe"],n={},s=new Set;for(const e of t.portPoints)s.add(e.connectionName);let o=0;for(const t of Array.from(s))n[t]=e[o%e.length],o++;return n})(this.nodeWithPortPoints))}getConstructorParams(){return this.constructorParams}_getViaTileDiameter(t){for(const e of Object.values(t.viasByNet))if(e.length>0)return e[0].diameter;return.3}_resolveViaDiameter(t){const e=this._getViaTileDiameter(this.viaTile);return void 0!==t&&Math.abs(t-e)<=1e-6?t:e}_initializeGraph(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=t.get(e.connectionName);n?n.points.push(e):t.set(e.connectionName,{points:[e],rootConnectionName:e.rootConnectionName})}this.rootConnectionNameByConnectionId.clear();const e=[];for(const[n,s]of t.entries())s.points.length<2||(this.rootConnectionNameByConnectionId.set(n,s.rootConnectionName),e.push({connectionId:n,start:{x:s.points[0].x,y:s.points[0].y},end:{x:s.points[s.points.length-1].x,y:s.points[s.points.length-1].y}}));if(0===e.length)return null;const n=lh(e,this.viaTile);return this.tiledViasByNet=n.viaTile.viasByNet??{},new Ci({inputGraph:{regions:n.regions,ports:n.ports},inputConnections:n.connections,viaTile:n.viaTile})}_step(){let t=this.activeSubSolver;if(!t){if(t=this._initializeGraph(),!t)return void(this.solved=!0);this.activeSubSolver=t,this.lastActiveSubSolver=t}t.step(),t.solved?(this._processResults(t),this.lastActiveSubSolver=t,this.activeSubSolver=null,this.solved=!0):t.failed&&(this.error=t.error,this.lastActiveSubSolver=t,this.activeSubSolver=null,this.failed=!0)}_upsertGlobalVia(t,e,n,s){const o=`${e.x.toFixed(4)},${e.y.toFixed(4)}`;t.has(o)||t.set(o,{center:{x:e.x,y:e.y},diameter:n,connectedTo:new Set}),t.get(o).connectedTo.add(s)}_upsertRouteViaRegion(t,e,n,s,o){t.some(t=>Math.abs(t.center.x-e.x)<.01&&Math.abs(t.center.y-e.y)<.01)||t.push({viaRegionId:o,center:{x:e.x,y:e.y},diameter:n,connectedTo:[s]})}_appendRoutePoint(t,e){const n=t[t.length-1];n&&Math.abs(n.x-e.x)<=1e-6&&Math.abs(n.y-e.y)<=1e-6&&n.z===e.z||t.push(e)}_parseViaRegionNetName(t){const e=t.lastIndexOf(":v:");if(-1!==e)return t.slice(e+3);const n=t.lastIndexOf(":");return-1===n?t:t.slice(n+1)}_parseViaRegionTilePrefix(t){const e=t.lastIndexOf(":v:");return e<=0?null:t.slice(0,e)}_selectViasForTraversedRegion(t,e){const n=this._parseViaRegionNetName(e.regionId);if(!n)return[];const s=t.viasByNet[n];if(!s||0===s.length)return[];const o=this._parseViaRegionTilePrefix(e.regionId);if(!o)return s;const i=s.filter(t=>t.viaId.startsWith(`${o}:`));return i.length>0?i:s}_findNearestVia(t,e){let n=null,s=1/0;for(const o of t){const t=o.position.x-e.x,i=o.position.y-e.y,r=t*t+i*i;r<s&&(s=r,n=o)}return n}_getBottomRoutePointsBetweenVias(t,e,n,s){if(n.viaId===s.viaId)return[n.position];const o=new Set(e.map(t=>t.viaId)),i=t.routeSegments.filter(t=>"bottom"===t.layer&&t.segments.length>=2&&o.has(t.fromPort)&&o.has(t.toPort)),r=new Map,a=(t,e,n)=>{r.has(t)||r.set(t,[]),r.get(t).push({to:e,points:n})};for(const t of i)a(t.fromPort,t.toPort,t.segments),a(t.toPort,t.fromPort,[...t.segments].reverse());const c=[n.viaId],h=new Set([n.viaId]),l=new Map;for(;c.length>0;){const t=c.shift();if(t===s.viaId)break;for(const e of r.get(t)??[])h.has(e.to)||(h.add(e.to),l.set(e.to,{from:t,points:e.points}),c.push(e.to))}if(!l.has(s.viaId))return null;const d=[];let u=s.viaId;for(;u!==n.viaId;){const t=l.get(u);if(!t)return null;d.push(t.points),u=t.from}d.reverse();const p=[];for(const t of d)for(const e of t){const t=p[p.length-1];(!t||Math.abs(t.x-e.x)>1e-6||Math.abs(t.y-e.y)>1e-6)&&p.push(e)}return p.length>0?p:null}_appendViaUsage(t,e,n,s,o){o&&(this._upsertGlobalVia(t,o.position,o.diameter,n),this._upsertRouteViaRegion(e,o.position,o.diameter,n,s))}_processResults(t){this.solvedRoutes=[];const e=t.viaTile,n=new Map;for(const s of t.solvedRoutes){const t=s.connection.connectionId,o=this.rootConnectionNameByConnectionId.get(t),i=[],r=[],a=s.path;if(0===a.length)continue;const c=a[0].port;this._appendRoutePoint(i,{x:c.d.x,y:c.d.y,z:0});for(let s=1;s<a.length;s++){const o=a[s-1],c=a[s],h={x:o.port.d.x,y:o.port.d.y},l={x:c.port.d.x,y:c.port.d.y},d=c.lastRegion;if(!d?.d?.isViaRegion||!e){this._appendRoutePoint(i,{x:l.x,y:l.y,z:0});continue}const u=this._selectViasForTraversedRegion(e,d);if(0===u.length){this._appendRoutePoint(i,{x:l.x,y:l.y,z:0});continue}const p=this._findNearestVia(u,h),f=this._findNearestVia(u,l);if(!p||!f){this._appendRoutePoint(i,{x:l.x,y:l.y,z:0});continue}const m=this._getBottomRoutePointsBetweenVias(e,u,p,f);if(m&&0!==m.length){this._appendViaUsage(n,r,t,d.regionId,p),this._appendViaUsage(n,r,t,d.regionId,f),this._appendRoutePoint(i,{x:p.position.x,y:p.position.y,z:0}),this._appendRoutePoint(i,{x:p.position.x,y:p.position.y,z:1});for(const t of m)this._appendRoutePoint(i,{x:t.x,y:t.y,z:1});this._appendRoutePoint(i,{x:f.position.x,y:f.position.y,z:1}),this._appendRoutePoint(i,{x:f.position.x,y:f.position.y,z:0}),this._appendRoutePoint(i,{x:l.x,y:l.y,z:0})}else this._appendRoutePoint(i,{x:l.x,y:l.y,z:0})}const h=r.map(t=>({x:t.center.x,y:t.center.y}));this.solvedRoutes.push({connectionName:t,rootConnectionName:o,traceThickness:this.traceWidth,viaDiameter:r.length>0?Math.max(...r.map(t=>t.diameter)):this.viaDiameter,route:i,vias:h,viaRegions:r})}let s=0;this.vias=Array.from(n.values()).map(t=>({viaRegionId:"via_"+s++,center:t.center,diameter:t.diameter,connectedTo:Array.from(t.connectedTo)}))}getOutput(){return this.solvedRoutes}getOutputVias(){return this.vias}visualize(){return this.activeSubSolver?this.activeSubSolver.visualize():this.lastActiveSubSolver?this.lastActiveSubSolver.visualize():super.visualize()}},uh=class extends is{getSolverName(){return"HyperSingleIntraNodeSolver"}constructorParams;solvedRoutes=[];nodeWithPortPoints;connMap;effort;constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.connMap=t.connMap,this.constructorParams=t,this.effort=t.effort??1,this.MAX_ITERATIONS=1e7*this.effort,this.GREEDY_MULTIPLIER=5,this.MIN_SUBSTEPS=100}getCombinationDefs(){return[["multiHeadPolyLine"],["majorCombinations","orderings6","cellSizeFactor"],["noVias"],["orderings50"],["flipTraceAlignmentDirection","orderings6"],["closedFormSingleTrace"],["highDensityA01"],["highDensityA02"],["fixedTopologyHighDensityIntraNodeSolver"]]}getHyperParameterDefs(){return[{name:"majorCombinations",possibleValues:[{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:2,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROXIMITY_VD:10,MISALIGNED_DIST_PENALTY_FACTOR:5},{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:.5,FUTURE_CONNECTION_PROXIMITY_VD:5,MISALIGNED_DIST_PENALTY_FACTOR:2},{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:10,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROXIMITY_VD:5,MISALIGNED_DIST_PENALTY_FACTOR:10,VIA_PENALTY_FACTOR_2:1}]},{name:"orderings6",possibleValues:[{SHUFFLE_SEED:0},{SHUFFLE_SEED:1},{SHUFFLE_SEED:2},{SHUFFLE_SEED:3},{SHUFFLE_SEED:4},{SHUFFLE_SEED:5}]},{name:"cellSizeFactor",possibleValues:[{CELL_SIZE_FACTOR:.5},{CELL_SIZE_FACTOR:1}]},{name:"flipTraceAlignmentDirection",possibleValues:[{FLIP_TRACE_ALIGNMENT_DIRECTION:!0}]},{name:"noVias",possibleValues:[{CELL_SIZE_FACTOR:2,VIA_PENALTY_FACTOR_2:10}]},{name:"orderings50",possibleValues:Array.from({length:20},(t,e)=>({SHUFFLE_SEED:100+e}))},{name:"closedFormSingleTrace",possibleValues:[{CLOSED_FORM_SINGLE_TRANSITION:!0}]},{name:"multiHeadPolyLine",possibleValues:[{MULTI_HEAD_POLYLINE_SOLVER:!0,SEGMENTS_PER_POLYLINE:6,BOUNDARY_PADDING:.05},{MULTI_HEAD_POLYLINE_SOLVER:!0,SEGMENTS_PER_POLYLINE:6,BOUNDARY_PADDING:-.05,ITERATION_PENALTY:1e4,MINIMUM_FINAL_ACCEPTANCE_GAP:.001}]},{name:"highDensityA01",possibleValues:[{HIGH_DENSITY_A01:!0}]},{name:"fixedTopologyHighDensityIntraNodeSolver",possibleValues:[{FIXED_TOPOLOGY_HIGH_DENSITY_INTRA_NODE_SOLVER:!0}]},{name:"highDensityA02",possibleValues:[{HIGH_DENSITY_A02:!0}]}]}computeG(t){return t instanceof Gs||t instanceof Zs?t.iterations/1e6:t?.hyperParameters?.MULTI_HEAD_POLYLINE_SOLVER?1e3+((t.hyperParameters?.ITERATION_PENALTY??0)+t.iterations)/1e4+1e4*(t.hyperParameters.SEGMENTS_PER_POLYLINE-3):t.iterations/1e4}computeH(t){return 1-(t.progress||0)}generateSolver(t){if(t.HIGH_DENSITY_A01){const e=new Gs({nodeWithPortPoints:this.nodeWithPortPoints,cellSizeMm:.1,viaDiameter:this.constructorParams.viaDiameter??.3,viaMinDistFromBorder:.15,traceMargin:.15,traceThickness:this.constructorParams.traceWidth??.15,hyperParameters:{shuffleSeed:t.SHUFFLE_SEED??0}});return e.MAX_ITERATIONS=1e7,e}if(t.HIGH_DENSITY_A02){const e=new Zs({nodeWithPortPoints:this.nodeWithPortPoints,outerGridCellSize:.1,outerGridCellThickness:2,innerGridCellSize:.4,viaDiameter:this.constructorParams.viaDiameter??.3,viaMinDistFromBorder:.15,traceMargin:.15,enableDeferredConflictRepair:!0,maxDeferredRepairPasses:48,edgePenaltyStrength:.2,traceThickness:.1,hyperParameters:{greedyMultiplier:1.2,shuffleSeed:t.SHUFFLE_SEED??0,ripCost:1}});return e.MAX_ITERATIONS=2e7*this.effort,e}return t.CLOSED_FORM_TWO_TRACE_SAME_LAYER?new as({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING?new vs({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.CLOSED_FORM_SINGLE_TRANSITION?new bs({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.MULTI_HEAD_POLYLINE_SOLVER?new Vs({nodeWithPortPoints:this.nodeWithPortPoints,connMap:this.connMap,hyperParameters:t,viaDiameter:this.constructorParams.viaDiameter}):t.FIXED_TOPOLOGY_HIGH_DENSITY_INTRA_NODE_SOLVER?new dh({nodeWithPortPoints:this.nodeWithPortPoints,connMap:this.connMap,colorMap:this.constructorParams.colorMap,viaDiameter:this.constructorParams.viaDiameter,traceWidth:this.constructorParams.traceWidth,effort:this.effort}):new os({...this.constructorParams,hyperParameters:t})}onSolve(t){let e;e=t.solver instanceof Gs||t.solver instanceof Zs?t.solver.getOutput():t.solver.solvedRoutes,this.solvedRoutes=e.map(t=>{const e=this.nodeWithPortPoints.portPoints.find(e=>e.connectionName===t.connectionName);return e?.rootConnectionName?{...t,rootConnectionName:e.rootConnectionName}:t})}},ph=class extends Ln{getSolverName(){return"HighDensitySolver"}unsolvedNodePortPoints;routes;colorMap;defaultViaDiameter=.3;defaultTraceThickness=.15;viaDiameter;traceWidth;effort;failedSolvers;activeSubSolver=null;connMap;constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:s,traceWidth:o,effort:i}){super(),this.unsolvedNodePortPoints=t,this.colorMap=e??{},this.connMap=n,this.routes=[],this.failedSolvers=[],this.effort=i??1,this.MAX_ITERATIONS=1e7*this.effort,this.viaDiameter=s??this.defaultViaDiameter,this.traceWidth=o??this.defaultTraceThickness}_step(){if(this.updateCacheStats(),this.activeSubSolver)return this.activeSubSolver.step(),this.activeSubSolver.solved?(this.routes.push(...this.activeSubSolver.solvedRoutes),this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSolvers.push(this.activeSubSolver),this.activeSubSolver=null),void this.updateCacheStats();if(0===this.unsolvedNodePortPoints.length)return this.failedSolvers.length>0?(this.solved=!1,this.failed=!0,this.error=`Failed to solve ${this.failedSolvers.length} nodes, ${this.failedSolvers.slice(0,5).map(t=>t.nodeWithPortPoints.capacityMeshNodeId)}. err0: ${this.failedSolvers[0].error}.`,void this.updateCacheStats()):(this.solved=!0,void this.updateCacheStats());const t=this.unsolvedNodePortPoints.pop();this.activeSubSolver=new uh({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,effort:this.effort}),this.updateCacheStats()}updateCacheStats(){const t=Me();this.stats.intraNodeCacheHits=t.cacheHits,this.stats.intraNodeCacheMisses=t.cacheMisses}visualize(){let t={lines:[],points:[],rects:[],circles:[]};for(const e of this.routes){const n=Wn(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const s of n)t.lines.push({points:s.points,label:s.connectionName,strokeColor:0===s.z?s.color:In(s.color,.75),layer:`z${s.z}`,strokeWidth:e.traceThickness,strokeDash:0!==s.z?"10, 5":void 0});for(const n of e.vias)t.circles.push({center:n,layer:"z0,1",radius:e.viaDiameter/2,fill:this.colorMap[e.connectionName],label:`${e.connectionName} via`})}for(const e of this.failedSolvers){const n=e.nodeWithPortPoints,s=.1*n.width,o=.1*n.height;t.rects.push({center:{x:n.center.x-s/2,y:n.center.y-o/2},layer:"did_not_connect",width:s,height:o,fill:"red",label:`Failed: ${n.capacityMeshNodeId}`});const i={};for(const t of n.portPoints)i[t.connectionName]||(i[t.connectionName]=[]),i[t.connectionName].push({x:t.x,y:t.y,z:t.z});for(const[e,n]of Object.entries(i))for(let e=0;e<n.length-1;e++){const s=n[e],o=n[e+1];t.lines.push({points:[s,o],strokeColor:"red",strokeDash:"10, 5",layer:"did_not_connect"})}}return this.activeSubSolver&&(t=jn(t,this.activeSubSolver.visualize())),t}};function fh(t,e){const n=[],s=e.filter(t=>t._containsTarget),o=new Map;for(const i of t.connections){const t=[];for(const n of i.pointsToConnect){let o=e[0],i=Number.MAX_VALUE;for(const t of s){const e=Math.sqrt((t.center.x-n.x)**2+(t.center.y-n.y)**2);e<i&&(i=e,o=t)}t.push(o)}if(t.length<2)throw new Error(`Not enough nodes for connection "${i.name}", only ${t.length} found`);o.set(i.name,t.map(t=>t.capacityMeshNodeId)),n.push({connection:i,nodeIds:[t[0].capacityMeshNodeId,t[t.length-1].capacityMeshNodeId],straightLineDistance:k(t[0].center,t[t.length-1].center)})}return{unshuffledConnectionsWithResults:n,connectionNameToGoalNodeIds:o}}function mh(t,e){const n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),s=e.map(t=>(t.width+t.height)/2).filter(t=>Number.isFinite(t)&&t>0),o=s.length>0?s.reduce((t,e)=>t+e,0)/s.length:1,i=e.filter(t=>t._offBoardConnectionId),r=new Map,a=new Map,c=new Map;for(const t of e)a.set(t.capacityMeshNodeId,[]),c.set(t.capacityMeshNodeId,[]);for(const t of e)for(const e of t.portPoints){r.set(e.portPointId,e);for(const t of e.connectionNodeIds){const n=a.get(t);n&&!n.some(t=>t.portPointId===e.portPointId)&&n.push(e)}}const{unshuffledConnectionsWithResults:h,connectionNameToGoalNodeIds:l}=fh(t,e);return{nodeMap:n,avgNodePitch:o,offBoardNodes:i,portPointMap:r,nodePortPointsMap:a,nodeAssignedPortPoints:c,unshuffledConnectionsWithResults:h,connectionNameToGoalNodeIds:l}}function gh(t,e,n,s,o){const i=n-e,r=o-s,a=1e-6;if(Math.abs(t.y-o)<a)return t.x-e;if(Math.abs(t.x-n)<a)return i+(o-t.y);if(Math.abs(t.y-s)<a)return i+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*i+r+(t.y-s);const c=Math.abs(t.y-o),h=Math.abs(t.x-n),l=Math.abs(t.y-s),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(i,t.x-e)):u===h?i+Math.max(0,Math.min(r,o-t.y)):u===l?i+r+Math.max(0,Math.min(i,n-t.x)):2*i+r+Math.max(0,Math.min(r,t.y-s))}function yh(t,e,n=1e-6){return Math.abs(t-e)<n}function xh(t){if(t.length<2)return 0;const e=t.map(([t,e])=>t<e?[t,e]:[e,t]);let n=0;for(let t=0;t<e.length;t++){const[s,o]=e[t];for(let i=t+1;i<e.length;i++){const[t,r]=e[i];yh(s,t)||yh(s,r)||yh(o,t)||yh(o,r)||(s<t&&t<o&&o<r||t<s&&s<r&&r<o)&&n++}}return n}var vh=t=>{const e=t.center.x-t.width/2,n=t.center.x+t.width/2,s=t.center.y-t.height/2,o=t.center.y+t.height/2,i=new Map;for(const e of t.portPoints){const t=i.get(e.connectionName)??[];t.some(t=>t.x===e.x&&t.y===e.y&&t.z===e.z)||t.push({x:e.x,y:e.y,z:e.z}),i.set(e.connectionName,t)}const r=new Map,a=[];let c=0;for(const[t,h]of i){if(h.length<2)continue;const t=h[0],i=h[1],l=gh(t,e,n,s,o),d=gh(i,e,n,s,o);if(t.z===i.z){const e=t.z,n=r.get(e)??[];n.push([l,d]),r.set(e,n)}else c++,a.push([l,d])}let h=0;for(const[t,e]of r)h+=xh(e);return{numSameLayerCrossings:h,numEntryExitLayerChanges:c,numTransitionPairCrossings:xh(a)}},bh=(t,e=1,n={})=>{const s=n.viaDiameter??.3,o="width"in t?t.width:t,i=n.obstacleMargin??.2,r="height"in t&&"number"==typeof t.height?t.height:o,a=Math.min(o,r)/(s+i),c=(Math.sqrt(o*r)*Math.min(1.2,Math.max(.85,a**.05))/(s/2+i)/2)**1.1*e;return 1===t.availableZ?.length&&c>1?1:c},Ph=(t,e=.5,n=16)=>{let s=0,o=t;for(;s<n;){if(bh({width:o})<=e)break;o/=2,s++}return Math.max(1,s)},Sh=(t,e,n,s)=>{if(t?._containsTarget)return 0;if(1===(t.availableZ?.length??2)&&(e>0||n>0||s>0))return 1;return((.82*e+.41*n+.2*s)/2)**1.1/bh(t)};function Mh(t,e,n){let s=0;const o=n?.NODE_MAX_PF??.99999;for(const n of t){const t=e.get(n.capacityMeshNodeId);if(!t)continue;if(t._containsTarget)continue;const i=vh(n),r=Math.min(Sh(t,i.numSameLayerCrossings,i.numEntryExitLayerChanges,i.numTransitionPairCrossings),o);s+=Math.log(1-r)}return s}function Nh(t,e){if(e._containsTarget)return 0;const n=vh(t);return Sh(e,n.numSameLayerCrossings,n.numEntryExitLayerChanges,n.numTransitionPairCrossings)}function Ih(t,e,n,s,o){const i=n-e,r=o-s,a=1e-6;if(Math.abs(t.y-o)<a)return t.x-e;if(Math.abs(t.x-n)<a)return i+(o-t.y);if(Math.abs(t.y-s)<a)return i+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*i+r+(t.y-s);const c=Math.abs(t.y-o),h=Math.abs(t.x-n),l=Math.abs(t.y-s),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(i,t.x-e)):u===h?i+Math.max(0,Math.min(r,o-t.y)):u===l?i+r+Math.max(0,Math.min(i,n-t.x)):2*i+r+Math.max(0,Math.min(r,t.y-s))}var _h=1.6*3.2,Ch=(t,e)=>{const n=Math.ceil(e/2),s=Math.min(t.width,t.height),o=Math.max(t.width,t.height),i=(Math.floor(s/1.6)+.1)*(Math.floor(o/3.2)+.1)/_h;return Math.min(1,n/i)};function Th(t,e,n,s){const o=e.x-n/2,i=e.x+n/2,r=e.y-s/2,a=e.y+s/2,c=Math.abs(t.y-a),h=Math.abs(t.x-i),l=Math.abs(t.y-r),d=Math.abs(t.x-o),u=Math.min(c,h,l,d);return u>.001?"interior":u===c?"top":u===h?"right":u===l?"bottom":"left"}function Eh(t,e,n,s,o){const i=Th(t,n,s,o),r=Th(e,n,s,o);return"interior"!==i&&i===r}function wh(t,e,n,s,o){const i=Th(t,n,s,o);let r;if("top"===i||"bottom"===i){const n=s;r=Math.abs(e.x-t.x)/n}else{const n=o;r=Math.abs(e.y-t.y)/n}r=Math.min(1,Math.max(0,r));const a=(t.x+e.x)/2,c=(t.y+e.y)/2;return{x:a+(n.x-a)*r,y:c+(n.y-c)*r}}function Rh(t){return"computeNodePf"in t&&"function"==typeof t.computeNodePf}function Oh(t){const e={lines:[],points:[],rects:[],circles:[]};for(const n of t.inputNodes){let s=0,o=0,i={numSameLayerCrossings:0,numEntryExitLayerChanges:0,numTransitionPairCrossings:0},r=0;if(Rh(t)){s=t.computeNodePf(n),o=t.nodeMemoryPfMap.get(n.capacityMeshNodeId)??0;const e=t.buildNodeWithPortPointsForCrossing(n);i=vh(e);const a=new Set,c=t.nodeAssignedPortPoints.get(n.capacityMeshNodeId)??[];for(const t of c)t.connectionName&&a.add(t.connectionName);r=a.size}else{s=t.nodePfMap.get(n.capacityMeshNodeId)??0;const e=t.nodeAssignedPortPoints.get(n.capacityMeshNodeId)??[],o={capacityMeshNodeId:n.capacityMeshNodeId,center:n.center,width:n.width,height:n.height,portPoints:e,availableZ:n.availableZ};i=vh(o);const a=new Set;for(const t of e)t.connectionName&&a.add(t.connectionName);r=a.size}const a=Math.min(255,Math.floor(512*s)),c=Math.max(0,255-Math.floor(512*s));let h=`rgba(${a}, ${c}, ${c}, ${s<.001?"0.1":"0.3"})`;n._containsObstacle&&(h="rgba(255, 0, 0, 0.3)"),n._offBoardConnectedCapacityMeshNodeIds?.length&&(h="rgba(255, 165, 0, 0.3)"),e.rects.push({center:n.center,width:n.width-.2,height:n.height-.2,layer:`z${n.availableZ.join(",")}`,fill:h,label:`${n.capacityMeshNodeId}\npf: ${s.toFixed(3)}, memPf: ${o.toFixed(3)}\nC#: ${r}\nxSame: ${i.numSameLayerCrossings}, xLC: ${i.numEntryExitLayerChanges}, xTransition: ${i.numTransitionPairCrossings}\nobCmid: ${n._offBoardConnectedCapacityMeshNodeIds?.join(",")}\nobs: ${n._containsObstacle?"yes":"no"}`})}if(Rh(t))for(const[n,s]of t.portPointMap){const o=t.assignedPortPoints.get(n),i=o?t.colorMap[o.connectionName]??"blue":"rgba(150, 150, 150, 0.5)";e.circles.push({center:{x:s.x,y:s.y},radius:.05,fill:i,layer:`z${s.z}`,label:[n,`conn: ${o?.connectionName}`,`cd: ${s.distToCentermostPortOnZ}`,`connects: ${s.connectionNodeIds.join(",")}`,`rootConn: ${o?.rootConnectionName}`].filter(Boolean).join("\n")})}const n=Rh(t)?t.connectionsWithResults:t.connectionResults;for(const s of n){if(!s.path)continue;const n=s.connection,o=t.colorMap[n.name]??"blue",i=[];for(const t of s.path)i.push({x:t.point.x,y:t.point.y,z:t.z,nodeId:t.currentNodeId});for(let n=0;n<i.length-1;n++){const s=i[n],r=i[n+1],a=s.z===r.z,c=s.z;let h;h=a?0===c?void 0:"10 5":"3 3 10";const l=s.nodeId?t.nodeMap.get(s.nodeId):null;if(l&&Eh(s,r,l.center,l.width,l.height)){const t=wh(s,r,l.center,l.width,l.height);e.lines.push({points:[{x:s.x,y:s.y},{x:t.x,y:t.y}],strokeColor:o,strokeDash:h}),e.lines.push({points:[{x:t.x,y:t.y},{x:r.x,y:r.y}],strokeColor:o,strokeDash:h})}else e.lines.push({points:[{x:s.x,y:s.y},{x:r.x,y:r.y}],strokeColor:o,strokeDash:h})}}if(Rh(t)&&!t.solved&&t.candidates&&t.candidates.length>0){const n=t.currentConnection,s=n?t.colorMap[n.connection.name]??"blue":"blue";if(n){const[o,i]=n.nodeIds,r=t.nodeMap.get(o),a=t.nodeMap.get(i),c=n.connection.pointsToConnect[0],h=n.connection.pointsToConnect[n.connection.pointsToConnect.length-1];if(r&&a){const t=c?{x:c.x,y:c.y}:r.center,o=h?{x:h.x,y:h.y}:a.center;e.lines.push({points:[t,o],strokeColor:In(s,.5),strokeDash:"5 5"}),e.points.push({x:t.x,y:t.y,color:s,label:[`Start: ${n.connection.name}`,`${n.connection.rootConnectionName}`].join("\n")}),e.points.push({x:o.x,y:o.y,color:s,label:[`End: ${n.connection.name}`,`${n.connection.rootConnectionName}`].join("\n")}),e.circles.push({center:o,radius:.08,stroke:s,label:`Goal: ${n.connection.name}`})}}const o=[...t.candidates].sort((t,e)=>t.f-e.f).slice(0,1);for(const i of o){const o=[];let r=i;for(;r;)o.unshift({x:r.point.x,y:r.point.y,z:r.z,lastMoveWasOffBoard:r.lastMoveWasOffBoard,nodeId:r.currentNodeId}),r=r.prevCandidate;for(let n=0;n<o.length-1;n++){const i=o[n],r=o[n+1],a=i.z===r.z,c=i.z;let h;h=r.lastMoveWasOffBoard?"2 2":a?0===c?void 0:"10 5":"3 3 10";const l=i.nodeId?t.nodeMap.get(i.nodeId):null,d=.02*i.z;if(l&&Eh(i,r,l.center,l.width,l.height)){const t=wh(i,r,l.center,l.width,l.height);e.lines.push({points:[{x:i.x+d,y:i.y+d},{x:t.x+d,y:t.y+d}],strokeColor:In(s,.25),strokeDash:h}),e.lines.push({points:[{x:t.x+d,y:t.y+d},{x:r.x+d,y:r.y+d}],strokeColor:In(s,.25),strokeDash:h})}else e.lines.push({points:[{x:i.x+d,y:i.y+d},{x:r.x+d,y:r.y+d}],strokeColor:In(s,.25),strokeDash:h})}if(o.length>=1){const r=o[o.length-1];let a=0,c=0,h=0,l=0,d=0,u=0;const p=t.nodeMap.get(i.prevCandidate?.currentNodeId);if(p&&i.prevCandidate&&i.portPoint&&n){const e=n.connection.name,s={x:i.prevCandidate.point.x,y:i.prevCandidate.point.y,z:i.prevCandidate.z,connectionName:e},o={x:i.portPoint.x,y:i.portPoint.y,z:i.portPoint.z,connectionName:e},r=t.buildNodeWithPortPointsForCrossing(p,[s,o]),f=Ns(r);h=f.numSameLayerCrossings,l=f.numTransitionPairCrossings,d=f.numEntryExitLayerChanges;const m=t.capacityMeshNodeMap.get(p.capacityMeshNodeId);m&&(c=t.JUMPER_PF_FN_ENABLED&&1===p.availableZ.length?Ch(m,h):Sh(m,h,d,l),a=c**2*t.NODE_PF_FACTOR),u=i.prevCandidate.g>0?i.g-i.prevCandidate.g:i.g}if(!n)continue;const[f,m]=n.nodeIds,g=t.nodeMap.get(m),y=g?Math.sqrt((r.x-g.center.x)**2+(r.y-g.center.y)**2):0,x=t.avgNodePitch>0?y/t.avgNodePitch:0,v=x*t.BASE_CANDIDATE_COST,b=t.nodeMemoryPfMap.get(i.currentNodeId)??0,P=-Math.log(1-b)*t.MEMORY_PF_FACTOR;e.circles.push({center:r,radius:.03,fill:In(s,.25),layer:`z${i.z}`,label:[`f: ${i.f.toFixed(2)}`,`g: ${i.g.toFixed(2)} (nodeDelta: ${u.toFixed(2)})`,`h: ${i.h.toFixed(2)}`,` dist: ${y.toFixed(2)}`,` estHops: ${x.toFixed(1)}`,` estStepCost: ${v.toFixed(2)}`,` memRiskCost: ${P.toFixed(2)}`,`z: ${i.z}`,`node: ${i.currentNodeId}`,`Cost(Pf): ${a.toFixed(3)}`,`Pf: ${c.toFixed(3)}`,`xSame: ${h}, xTrans: ${l}, xLC: ${d}`,`routeOffBoard=${t.currentConnectionShouldRouteOffBoard}`,`offBoardTouched=${i.hasTouchedOffBoardNode??!1}`,`lastMoveWasOffBoard=${i.lastMoveWasOffBoard??!1}`].join("\n")})}}}return e}function Ah(t,e,n){let s=0;const o=n?.NODE_MAX_PF??.99999;for(const n of t){const t=e.get(n.capacityMeshNodeId);if(!t)continue;if(t._containsTarget)continue;const i=vh(n),r=Math.min(Ch(t,i.numSameLayerCrossings),o);s+=Math.log(1-r)}return s}var zh=class extends Ln{constructor(t){super(),this.input=t;const{simpleRouteJson:e,capacityMeshNodes:n,inputNodes:s,colorMap:o,nodeMemoryPfMap:i,hyperParameters:r,precomputedInitialParams:a,fixedRoutes:c}=t;if(this.input=structuredClone(t),this.MAX_ITERATIONS=1e8,this.simpleRouteJson=e,this.inputNodes=s,this.colorMap=o??{},this.capacityMeshNodeMap=new Map(n.map(t=>[t.capacityMeshNodeId,t])),this.nodeMemoryPfMap=i??new Map,this.hyperParameters=r??{},a){this.nodeMap=a.nodeMap,this.avgNodePitch=a.avgNodePitch,this.offBoardNodes=a.offBoardNodes,this.portPointMap=a.portPointMap,this.nodePortPointsMap=a.nodePortPointsMap,this.connectionNameToGoalNodeIds=a.connectionNameToGoalNodeIds;const{nodeAssignedPortPoints:t}=function(t){const e=new Map;for(const[n,s]of t.nodeAssignedPortPoints)e.set(n,[...s]);return{nodeAssignedPortPoints:e}}(a);this.nodeAssignedPortPoints=t,this.connectionsWithResults=Gn(structuredClone(a.unshuffledConnectionsWithResults),this.hyperParameters.SHUFFLE_SEED??0)}else{this.nodeMap=new Map(s.map(t=>[t.capacityMeshNodeId,t]));const t=s.map(t=>(t.width+t.height)/2).filter(t=>Number.isFinite(t)&&t>0);this.avgNodePitch=t.length>0?t.reduce((t,e)=>t+e,0)/t.length:1,this.offBoardNodes=s.filter(t=>t._offBoardConnectionId),this.portPointMap=new Map,this.nodePortPointsMap=new Map;for(const t of s)this.nodePortPointsMap.set(t.capacityMeshNodeId,[]),this.nodeAssignedPortPoints.set(t.capacityMeshNodeId,[]);for(const t of s)for(const e of t.portPoints){this.portPointMap.set(e.portPointId,e);for(const t of e.connectionNodeIds){const n=this.nodePortPointsMap.get(t);n&&!n.some(t=>t.portPointId===e.portPointId)&&n.push(e)}}const{connectionsWithResults:e,connectionNameToGoalNodeIds:n}=this.getConnectionsWithNodes();this.connectionsWithResults=e,this.connectionNameToGoalNodeIds=n}if(c&&c.length>0)for(const t of c)if(this.connectionsWithResults.push(t),t.portPoints)for(const e of t.portPoints)e.portPointId&&this.assignedPortPoints.set(e.portPointId,{connectionName:e.connectionName,rootConnectionName:e.rootConnectionName});for(const t of this.connectionsWithResults)t.path?this.processedConnectionQueue.push(t):this.unprocessedConnectionQueue.push(t);this.totalConnectionCount=this.connectionsWithResults.length}getSolverName(){return"PortPointPathingSolver"}hyperParameters;simpleRouteJson;inputNodes;nodeMap;nodePortPointsMap;portPointMap;connectionsWithResults=[];failedConnection=null;assignedPortPoints=new Map;nodeAssignedPortPoints=new Map;PORT_POINT_REUSE_FACTOR=1e3;BASE_COST_FOR_NOT_GOING_OFF_BOARD=100;get NODE_PF_FACTOR(){return this.hyperParameters.NODE_PF_FACTOR??50}get RANDOM_WALK_DISTANCE(){return this.hyperParameters.RANDOM_WALK_DISTANCE??0}get MEMORY_PF_FACTOR(){return this.hyperParameters.MEMORY_PF_FACTOR??0}get CENTER_OFFSET_FOCUS_SHIFT(){return this.hyperParameters.CENTER_OFFSET_FOCUS_SHIFT??0}get RANDOM_COST_MAGNITUDE(){return this.hyperParameters.RANDOM_COST_MAGNITUDE??0}get BASE_CANDIDATE_COST(){return this.hyperParameters.BASE_CANDIDATE_COST??0}get NODE_PF_MAX_PENALTY(){return this.hyperParameters.NODE_PF_MAX_PENALTY??1e4}get FORCE_CENTER_FIRST(){return this.hyperParameters.FORCE_CENTER_FIRST??!0}get FORCE_OFF_BOARD_FREQUENCY(){return 0===this.offBoardNodes.length?0:this.hyperParameters.FORCE_OFF_BOARD_FREQUENCY??0}get FORCE_OFF_BOARD_SEED(){return this.hyperParameters.FORCE_OFF_BOARD_SEED??0}get NODE_MAX_PF(){return Math.min(.99999,1-Math.exp(-this.NODE_PF_MAX_PENALTY))}get CENTER_OFFSET_DIST_PENALTY_FACTOR(){return this.hyperParameters.CENTER_OFFSET_DIST_PENALTY_FACTOR??0}get STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR(){return this.hyperParameters.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR??0}colorMap;get GREEDY_MULTIPLIER(){return this.hyperParameters.GREEDY_MULTIPLIER??1.3}MAX_CANDIDATES_IN_MEMORY=5e3;get MAX_ITERATIONS_PER_PATH(){return this.hyperParameters.MAX_ITERATIONS_PER_PATH??1e4}ITERATIONS_PER_MM_FOR_PATH=30;BASE_ITERATIONS_PER_PATH=1e4;get RIPPING_ENABLED(){return this.hyperParameters.RIPPING_ENABLED??!1}get RIPPING_PF_THRESHOLD(){const t=this.hyperParameters.START_RIPPING_PF_THRESHOLD,e=this.hyperParameters.END_RIPPING_PF_THRESHOLD;if(void 0!==t&&void 0!==e){const n=this.MAX_RIPS;return t+(n>0?this.totalRipCount/n:0)*(e-t)}return this.hyperParameters.RIPPING_PF_THRESHOLD??.3}get MAX_RIPS(){return this.hyperParameters.MAX_RIPS??100}get RANDOM_RIP_FRACTION(){return this.hyperParameters.RANDOM_RIP_FRACTION??0}get JUMPER_PF_FN_ENABLED(){return this.hyperParameters.JUMPER_PF_FN_ENABLED??!1}jumpersPerMmSquared=.1;testedRipConnections=new Map;totalRipCount=0;get MIN_ALLOWED_BOARD_SCORE(){return this.hyperParameters.MIN_ALLOWED_BOARD_SCORE??-1e4}nodeMemoryPfMap;unprocessedConnectionQueue=[];processedConnectionQueue=[];currentConnection=null;totalConnectionCount=0;currentPathIterations=0;candidates;visitedPortPoints;connectionNameToGoalNodeIds;capacityMeshNodeMap;avgNodePitch;currentConnectionShouldRouteOffBoard=!1;activeCandidateStraightLineDistance;offBoardNodes=[];baseNodeCostCache=new Map;getConstructorParams(){return this.input}clearCostCaches(){this.baseNodeCostCache.clear()}clampPf(t){return Number.isFinite(t)?Math.min(Math.max(t,0),.999999):.999999}pfToFailureCost(t){const e=this.clampPf(t);return e>=this.NODE_MAX_PF?this.NODE_PF_MAX_PENALTY:-Math.log(1-e)}getBaseNodeFailureCost(t){const e=this.baseNodeCostCache.get(t);if(null!=e)return e;const n=this.nodeMap.get(t);if(!n)return 0;const s=this.computeNodePf(n),o=this.pfToFailureCost(s);return this.baseNodeCostCache.set(t,o),o}computeBoardScore(){const t=this.getNodesWithPortPoints();return this.JUMPER_PF_FN_ENABLED?Ah(t,this.capacityMeshNodeMap):Mh(t,this.capacityMeshNodeMap)}getMaxIterationsForCurrentPath(){const t=this.activeCandidateStraightLineDistance??0;return Math.min(this.BASE_ITERATIONS_PER_PATH+this.ITERATIONS_PER_MM_FOR_PATH*t,this.MAX_ITERATIONS_PER_PATH)}getNodeDeltaFailureCostForSegment(t,e,n){const s=this.nodeMap.get(t);if(!s)return 0;const o=this.getBaseNodeFailureCost(t),i=this.computeNodePf(s,[e,n]),r=this.pfToFailureCost(i),a=Math.max(0,r-o);return i>=this.NODE_MAX_PF?this.NODE_PF_MAX_PENALTY:a*this.NODE_PF_FACTOR}getConnectionsWithNodes(){const{unshuffledConnectionsWithResults:t,connectionNameToGoalNodeIds:e}=fh(this.simpleRouteJson,this.inputNodes);return{connectionsWithResults:Gn(t,this.hyperParameters.SHUFFLE_SEED??0),connectionNameToGoalNodeIds:e}}buildNodeWithPortPointsForCrossing(t,e){const n=this.nodeAssignedPortPoints.get(t.capacityMeshNodeId)??[],s=e?[...n,...e]:n;return{capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:s,availableZ:t.availableZ}}computeNodePf(t,e){if(t._containsTarget)return 0;const n=this.buildNodeWithPortPointsForCrossing(t,e),s=vh(n);return this.JUMPER_PF_FN_ENABLED&&1===t.availableZ.length?Ch(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),s.numSameLayerCrossings):Sh(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),s.numSameLayerCrossings,s.numEntryExitLayerChanges,s.numTransitionPairCrossings)}getPortPointReusePenalty(t,e){const n=this.assignedPortPoints.get(t);return n?e===n.rootConnectionName?0:this.PORT_POINT_REUSE_FACTOR:0}getOtherNodeId(t,e){const[n,s]=t.connectionNodeIds;return n===e?s:s===e?n:null}computeG(t,e,n,s,o){const i=t.currentNodeId,r=t.point,a={x:r.x,y:r.y,z:t.z,connectionName:s,rootConnectionName:o},c={x:e.x,y:e.y,z:e.z,connectionName:s,rootConnectionName:o},h=this.getNodeDeltaFailureCostForSegment(i,a,c);return t.g+h}computeGToEndTarget(t,e,n,s){const o=t.currentNodeId,i={x:t.point.x,y:t.point.y,z:t.z,connectionName:n,rootConnectionName:s},r={x:e.x,y:e.y,z:t.z,connectionName:n,rootConnectionName:s},a=this.getNodeDeltaFailureCostForSegment(o,i,r);return t.g+a}computeDistanceToNearestOffBoardNode(t){if(0===this.offBoardNodes.length)return 1/0;let e=1/0;for(const n of this.offBoardNodes){const s=k(t,n.center);s<e&&(e=s)}return e}computeH(t,e,n,s,o,i){if(this.RANDOM_WALK_DISTANCE>0&&o<this.RANDOM_WALK_DISTANCE)return 0;if(this.currentConnectionShouldRouteOffBoard&&!i)return this.BASE_COST_FOR_NOT_GOING_OFF_BOARD+this.computeDistanceToNearestOffBoardNode(t);const r=this.nodeMap.get(n);if(!r)return 0;const a=k(t,r.center),c=this.avgNodePitch>0?a/this.avgNodePitch:0,h=this.clampPf(this.nodeMemoryPfMap.get(e)??0),l=this.pfToFailureCost(h)*this.MEMORY_PF_FACTOR,d=c*this.BASE_CANDIDATE_COST,u=this.CENTER_OFFSET_DIST_PENALTY_FACTOR*t.distToCentermostPortOnZ**2;let p=0;if(this.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR>0&&this.currentConnection){const e=X(t,this.currentConnection.connection.pointsToConnect[0],this.currentConnection.connection.pointsToConnect[1]);p=this.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR*e}return a+d+l+u+p}getVisitedPortPointKey(t,e){return this.currentConnectionShouldRouteOffBoard&&e?`${t}:touched_off_board`:t}getAvailableExitPortPoints(t,e){const n=this.currentConnection?.connection.rootConnectionName,s=this.nodePortPointsMap.get(t)??[],o=[];for(const t of s){const s=this.getVisitedPortPointKey(t.portPointId,e);if(this.visitedPortPoints?.has(s))continue;const i=this.assignedPortPoints.get(t.portPointId);i&&i?.rootConnectionName!==n||o.push(t)}return o}getAvailableExitPortPointsWithOmissions(t,e,n){const s=this.nodePortPointsMap.get(t)??[],o=this.currentConnection?.connection.rootConnectionName,i=new Map;for(const e of s){const s=this.getVisitedPortPointKey(e.portPointId,n);if(this.visitedPortPoints?.has(s))continue;const o=this.getOtherNodeId(e,t);if(!o)continue;this.nodeMap.get(o);const r=`${o}|${e.z}`,a=i.get(r)??[];a.push(e),i.set(r,a)}const r=[];for(const[,t]of i){t.sort((t,e)=>t.distToCentermostPortOnZ-e.distToCentermostPortOnZ);const e=t[0];if(!e)continue;const n=this.assignedPortPoints.get(e.portPointId),s=n&&n.rootConnectionName===o;if(!n||s){r.push(e);continue}const i=[...t].sort((t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y),a=[];let c=[];for(const t of i){const e=this.assignedPortPoints.get(t.portPointId);!e||e.rootConnectionName===o?c.push(t):c.length>0&&(a.push(c),c=[])}c.length>0&&a.push(c);for(const t of a){const e=Math.floor(t.length/2);r.push(t[e])}}return r}getAvailableExitPortPointsForOffboardConnection(t,e){const n=this.nodeMap.get(t);if(!n)return[];const s=this.currentConnection?.connection.rootConnectionName,o=[];for(const i of n?._offBoardConnectedCapacityMeshNodeIds??[]){if(i===t)continue;if(!this.nodeMap.get(i))continue;const n=this.nodePortPointsMap.get(i)??[];for(const t of n){const n=this.getVisitedPortPointKey(t.portPointId,e);if(this.visitedPortPoints?.has(n))continue;const r=this.assignedPortPoints.get(t.portPointId);r&&r.rootConnectionName!==s||o.push({...t,throughNodeId:i})}}return o}canTravelThroughObstacle(t,e,n){const s=this.connectionNameToGoalNodeIds.get(e);return s?.includes(t.capacityMeshNodeId)||Boolean(t._offBoardConnectionId)}isAtEndGoal(t,e){return t===e}getBacktrackedPath(t){const e=[];let n=t;for(;n;){if(n.lastMoveWasOffBoard&&n.throughNodeId){const t=this.nodeMap.get(n.throughNodeId),s=n.prevCandidate?this.nodeMap.get(n.prevCandidate.currentNodeId):null;e.push(n),t&&e.push({prevCandidate:null,portPoint:null,currentNodeId:n.throughNodeId,point:t.center,z:n.z,f:0,g:0,h:0,distanceTraveled:0}),s&&s._offBoardConnectionId&&e.push({prevCandidate:null,portPoint:null,currentNodeId:n.prevCandidate.currentNodeId,point:s.center,z:n.z,f:0,g:0,h:0,distanceTraveled:0})}else e.push(n);n=n.prevCandidate}return e.reverse()}assignPortPointsForPath(t,e,n){const s=[];for(let o=0;o<t.length;o++){const i=t[o];if(!i.portPoint){const r=0===o,a=o===t.length-1;if(!r&&!a){const t={x:i.point.x,y:i.point.y,z:i.z,connectionName:e,rootConnectionName:n};s.push(t);const o=this.nodeAssignedPortPoints.get(i.currentNodeId)??[];o.push(t),this.nodeAssignedPortPoints.set(i.currentNodeId,o)}continue}const r=i.portPoint;this.assignedPortPoints.set(r.portPointId,{connectionName:e,rootConnectionName:n});const a={portPointId:r.portPointId,x:r.x,y:r.y,z:r.z,connectionName:e,rootConnectionName:n};s.push(a);for(const t of r.connectionNodeIds){const e=this.nodeAssignedPortPoints.get(t)??[];e.push(a),this.nodeAssignedPortPoints.set(t,e)}}const o=Array.from(new Set(t.map(t=>t.currentNodeId)));for(const t of o){const s=this.nodeMap.get(t);if(s&&s._offBoardConnectionId)for(const t of s?._offBoardConnectedCapacityMeshNodeIds??[]){const s=this.nodePortPointsMap.get(t)??[];for(const t of s)this.assignedPortPoints.set(t.portPointId,{connectionName:e,rootConnectionName:n})}}return s}addTargetPointsToNodes(t,e){const n=t[0],s=t[t.length-1],o=e.pointsToConnect[0],i=e.pointsToConnect[e.pointsToConnect.length-1];if(n&&o){const t=this.nodeAssignedPortPoints.get(n.currentNodeId)??[];t.push({x:o.x,y:o.y,z:n.z,connectionName:e.name,rootConnectionName:e.rootConnectionName}),this.nodeAssignedPortPoints.set(n.currentNodeId,t)}if(s&&i){const t=this.nodeAssignedPortPoints.get(s.currentNodeId)??[];t.push({x:i.x,y:i.y,z:s.z,connectionName:e.name,rootConnectionName:e.rootConnectionName}),this.nodeAssignedPortPoints.set(s.currentNodeId,t)}}isPortPointInPathChain(t,e){let n=t;for(;n;){if(n.portPoint?.portPointId===e)return!0;n=n.prevCandidate}return!1}isNodeInPathChain(t,e){let n=t;for(;n;){if(n.currentNodeId===e)return!0;n=n.prevCandidate}return!1}_step(){if(this.currentConnection||(this.currentConnection=this.unprocessedConnectionQueue.shift()??null),!this.currentConnection){const t=this.computeBoardScore();return this.stats={boardScore:t,totalRipCount:this.totalRipCount},t<this.MIN_ALLOWED_BOARD_SCORE?(this.failedConnection=null,this.failed=!0,void(this.error=`Board score ${t.toFixed(2)} is less than MIN_ALLOWED_BOARD_SCORE ${this.MIN_ALLOWED_BOARD_SCORE.toFixed(2)}`)):void(this.solved=!0)}const t=this.currentConnection;this.activeCandidateStraightLineDistance=t.straightLineDistance,this.currentPathIterations++;const e=this.getMaxIterationsForCurrentPath();if(this.currentPathIterations>e)return this.failedConnection=t,this.processedConnectionQueue.push(t),this.currentConnection=null,this.candidates=null,this.visitedPortPoints=null,this.currentPathIterations=0,this.failed=!0,void(this.error=`Exceeded max iterations for path (${e}) on connection ${t.connection.name}`);const[n,s]=t.nodeIds,o=this.nodeMap.get(n),i=this.nodeMap.get(s);if(!o||!i)return this.processedConnectionQueue.push(t),this.currentConnection=null,void(this.currentPathIterations=0);const r=t.connection.name,a=t.connection.rootConnectionName,c=t.connection.pointsToConnect[0];if(!this.candidates){if(this.clearCostCaches(),this.FORCE_OFF_BOARD_FREQUENCY>0){const t=Un(17*(this.hyperParameters.SHUFFLE_SEED??0)+this.FORCE_OFF_BOARD_SEED+this.processedConnectionQueue.length);this.currentConnectionShouldRouteOffBoard=t()<this.FORCE_OFF_BOARD_FREQUENCY}else this.currentConnectionShouldRouteOffBoard=!1;this.candidates=[],this.visitedPortPoints=new Set;for(const t of o.availableZ){const e=c?{x:c.x,y:c.y}:o.center,i=this.computeH({...e,distToCentermostPortOnZ:0},n,s,t,0,!1),r=0+i*this.GREEDY_MULTIPLIER;this.candidates.push({prevCandidate:null,portPoint:null,currentNodeId:n,point:e,z:t,f:r,g:0,h:i,distanceTraveled:0,hasTouchedOffBoardNode:!1})}}this.candidates.sort((t,e)=>t.f-e.f);let h,l=this.candidates.shift();for(;l?.portPoint&&this.visitedPortPoints;){const t=this.getVisitedPortPointKey(l.portPoint.portPointId,l.hasTouchedOffBoardNode);if(!this.visitedPortPoints.has(t))break;l=this.candidates.shift()}if(this.candidates.length>this.MAX_CANDIDATES_IN_MEMORY&&this.candidates.splice(this.MAX_CANDIDATES_IN_MEMORY,this.candidates.length-this.MAX_CANDIDATES_IN_MEMORY),!l)return this.error=`Ran out of candidates on connection ${r}`,this.failedConnection=t,this.processedConnectionQueue.push(t),this.currentConnection=null,this.candidates=null,this.visitedPortPoints=null,this.currentPathIterations=0,void(this.failed=!0);if(l.portPoint&&this.visitedPortPoints){const t=this.getVisitedPortPointKey(l.portPoint.portPointId,l.hasTouchedOffBoardNode);this.visitedPortPoints.add(t)}if(this.isAtEndGoal(l.currentNodeId,s)){const e=t.connection.pointsToConnect[t.connection.pointsToConnect.length-1],n=e?{x:e.x,y:e.y}:i.center,o=this.computeGToEndTarget(l,n,r,a),c={prevCandidate:l,portPoint:null,currentNodeId:s,point:n,z:l.z,g:o,h:0,f:o,distanceTraveled:l.distanceTraveled+k(l.point,n)},h=this.getBacktrackedPath(c);return t.path=h,t.portPoints=this.assignPortPointsForPath(h,r,a),this.addTargetPointsToNodes(h,t.connection),this.clearCostCaches(),this.RIPPING_ENABLED&&this.processRippingForPath(h,r),this.processedConnectionQueue.push(t),this.currentConnection=null,this.progress=this.processedConnectionQueue.length/this.totalConnectionCount,this.candidates=null,this.visitedPortPoints=null,void(this.currentPathIterations=0)}const d=this.nodeMap.get(l.currentNodeId);h=d?._offBoardConnectionId?this.getAvailableExitPortPointsForOffboardConnection(l.currentNodeId,l.hasTouchedOffBoardNode):this.FORCE_CENTER_FIRST?this.getAvailableExitPortPointsWithOmissions(l.currentNodeId,s,l.hasTouchedOffBoardNode):this.getAvailableExitPortPoints(l.currentNodeId,l.hasTouchedOffBoardNode);for(const t of h){if(this.isPortPointInPathChain(l,t.portPointId))continue;if(this.visitedPortPoints?.has(t.portPointId))continue;const e=this.getOtherNodeId(t,t.throughNodeId??l.currentNodeId);if(!e)continue;if(this.isNodeInPathChain(l,e))continue;const n="throughNodeId"in t?t.throughNodeId:void 0,o=n?this.nodeMap.get(n):null,i=this.nodeMap.get(e);if(!i)continue;if(i._containsObstacle&&!this.canTravelThroughObstacle(i,r,a))continue;const c=this.computeG(l,t,e,r,a);if(!this.RIPPING_ENABLED&&c>-this.MIN_ALLOWED_BOARD_SCORE)continue;const h=l.distanceTraveled+k(l.point,t),u=l.hasTouchedOffBoardNode||Boolean(i._offBoardConnectionId),p=this.computeH(t,e,s,t.z,h,u),f=c+p*this.GREEDY_MULTIPLIER,m=Boolean(d?._offBoardConnectionId)&&Boolean(o?._offBoardConnectionId);this.candidates.push({prevCandidate:l,portPoint:t,currentNodeId:e,point:{x:t.x,y:t.y},z:t.z,f:f,g:c,h:p,distanceTraveled:h,lastMoveWasOffBoard:m,throughNodeId:m?n:void 0,hasTouchedOffBoardNode:u||Boolean(i._offBoardConnectionId)||Boolean(d?._offBoardConnectionId)})}}getNodesWithPortPoints(){const t=[];for(const e of this.inputNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];n.length>0&&t.push({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ})}return t}getConnectionsInNode(t,e){const n=[],s=new Set;for(const o of this.connectionsWithResults)if(o.path&&o.connection.name!==e&&!s.has(o.connection.name))for(const e of o.path)if(e.currentNodeId===t){n.push(o),s.add(o.connection.name);break}return n}computeNodePfWithoutConnection(t,e){if(t._containsTarget)return{pf:0,totalCrossings:0};const n=(this.nodeAssignedPortPoints.get(t.capacityMeshNodeId)??[]).filter(t=>t.connectionName!==e),s={capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:n,availableZ:t.availableZ},o=vh(s),i=o.numSameLayerCrossings+o.numEntryExitLayerChanges+o.numTransitionPairCrossings;return{pf:Sh(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.numTransitionPairCrossings),totalCrossings:i}}computeNodeCrossings(t){if(t._containsTarget)return 0;const e=this.buildNodeWithPortPointsForCrossing(t),n=vh(e);return n.numSameLayerCrossings+n.numEntryExitLayerChanges+n.numTransitionPairCrossings}ripConnection(t){const e=t.connection.name;for(const[t,n]of this.assignedPortPoints.entries())n.connectionName===e&&this.assignedPortPoints.delete(t);for(const[t,n]of this.nodeAssignedPortPoints.entries()){const s=n.filter(t=>t.connectionName!==e);this.nodeAssignedPortPoints.set(t,s)}t.path=void 0,t.portPoints=void 0}requeueConnection(t){this.totalRipCount++;const e=this.processedConnectionQueue.indexOf(t);if(-1!==e)return this.processedConnectionQueue.splice(e,1),this.unprocessedConnectionQueue.push(t),!0;const n=this.unprocessedConnectionQueue.indexOf(t);return-1!==n&&(this.unprocessedConnectionQueue.splice(n,1),this.unprocessedConnectionQueue.unshift(t)),!0}processRippingForPath(t,e){const n=Array.from(new Set(t.map(t=>t.currentNodeId)));let s=!1;for(const t of n){if(this.totalRipCount>this.MAX_RIPS)break;const n=this.nodeMap.get(t);if(!n)continue;let o=this.computeNodePf(n);if(o<=this.RIPPING_PF_THRESHOLD)continue;this.testedRipConnections.has(t)||this.testedRipConnections.set(t,new Set);const i=this.testedRipConnections.get(t),r=Gn(this.getConnectionsInNode(t,e),(this.hyperParameters.SHUFFLE_SEED??0)+this.processedConnectionQueue.length);for(const t of r){if(o<=this.RIPPING_PF_THRESHOLD)break;const e=t.connection.name;i.add(e);const{pf:r}=this.computeNodePfWithoutConnection(n,e);this.ripConnection(t);if(!this.requeueConnection(t))return;o=r,s=!0,this.clearCostCaches()}}s&&this.RANDOM_RIP_FRACTION>0&&this.processRandomRipping(e)}processRandomRipping(t){const e=this.processedConnectionQueue.filter(e=>void 0!==e.path&&e.connection.name!==t);if(0===e.length)return;const n=Math.max(1,Math.floor(this.RANDOM_RIP_FRACTION*e.length)),s=Gn(e,(this.hyperParameters.SHUFFLE_SEED??0)+this.totalRipCount+this.processedConnectionQueue.length);for(let t=0;t<n&&t<s.length&&!(this.totalRipCount>this.MAX_RIPS);t++){const e=s[t];this.ripConnection(e);if(!this.requeueConnection(e))return;this.clearCostCaches()}}visualize(){let t={};if(this.failed){const e=this.failedConnection?.connection.pointsToConnect[0],n=this.failedConnection?.connection.pointsToConnect[1];e&&n&&(t={lines:[{points:[e,n],label:`Failed Connection ${this.failedConnection?.connection.name}`,strokeWidth:1,strokeColor:"red",strokeDash:[2,2]}]})}return M(Oh(this),t)}},Dh=class extends is{getSolverName(){return"HyperPortPointPathingSolver"}params;precomputedInitialParams;constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1e8,this.GREEDY_MULTIPLIER=1.2,this.MIN_SUBSTEPS=50,this.precomputedInitialParams=t.precomputedInitialParams??mh(t.simpleRouteJson,t.inputNodes)}getHyperParameterDefs(){const t=this.params.numShuffleSeeds??50;return[{name:"SHUFFLE_SEED",possibleValues:Array.from({length:t},(t,e)=>({SHUFFLE_SEED:e+1700*(this.params.hyperParameters?.SHUFFLE_SEED??0)}))}]}getCombinationDefs(){return[["SHUFFLE_SEED"]]}generateSolver(t){return new zh({simpleRouteJson:this.params.simpleRouteJson,capacityMeshNodes:this.params.capacityMeshNodes,inputNodes:this.params.inputNodes,colorMap:this.params.colorMap,nodeMemoryPfMap:this.params.nodeMemoryPfMap,hyperParameters:{...this.params.hyperParameters,...t,MIN_ALLOWED_BOARD_SCORE:this.params.minAllowedBoardScore??t.MIN_ALLOWED_BOARD_SCORE??this.params.hyperParameters?.MIN_ALLOWED_BOARD_SCORE},precomputedInitialParams:this.precomputedInitialParams,fixedRoutes:this.params.fixedRoutes})}computeG(t){return-t.computeBoardScore()}computeH(t){const e=t.progress||0;if(e<.1)return 0;return-(t.computeBoardScore()/e)*(1-e)}getNodesWithPortPoints(){if(this.winningSolver)return this.winningSolver.getNodesWithPortPoints();const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.getNodesWithPortPoints():[]}get connectionsWithResults(){if(this.winningSolver)return this.winningSolver.connectionsWithResults;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.connectionsWithResults:[]}get inputNodes(){if(this.winningSolver)return this.winningSolver.inputNodes;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.inputNodes:this.params.inputNodes}get nodeMap(){if(this.winningSolver)return this.winningSolver.nodeMap;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.nodeMap:new Map(this.params.inputNodes.map(t=>[t.capacityMeshNodeId,t]))}get assignedPortPoints(){if(this.winningSolver)return this.winningSolver.assignedPortPoints;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.assignedPortPoints:new Map}get nodeAssignedPortPoints(){if(this.winningSolver)return this.winningSolver.nodeAssignedPortPoints;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.nodeAssignedPortPoints:new Map}computeBoardScore(){if(this.winningSolver)return this.winningSolver.computeBoardScore();const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.computeBoardScore():0}onSolve(t){this.stats={...t.solver.stats,winningHyperParameters:this.winningSolver?.hyperParameters}}visualize(){return this.winningSolver?this.winningSolver.visualize():super.visualize()}};function Lh(t){let e=t;return()=>{e+=1831565813;let t=e;return t=Math.imul(t^t>>>15,1|t),t^=t+Math.imul(t^t>>>7,61|t),((t^t>>>14)>>>0)/4294967296}}var Fh=[{SHUFFLE_SEED:100,NODE_PF_FACTOR:100,NODE_PF_MAX_PENALTY:100,MEMORY_PF_FACTOR:0,EXPANSION_DEGREES:10,FORCE_CENTER_FIRST:!0,FORCE_OFF_BOARD_FREQUENCY:0,CENTER_OFFSET_DIST_PENALTY_FACTOR:0}],Yh=class extends Ln{getSolverName(){return"MultiSectionPortPointOptimizer"}simpleRouteJson;inputNodes;capacityMeshNodes;capacityMeshEdges;colorMap;nodeMap;capacityMeshNodeMap;connectionResults;assignedPortPoints;nodeAssignedPortPoints;sections=[];activeSubSolver=null;currentSection=null;sectionScoreBeforeOptimization=0;currentSectionCenterNodeId=null;currentScheduleIndex=0;nodePfMap=new Map;attemptsToFixNode=new Map;sectionAttempts=0;MAX_ATTEMPTS_PER_NODE=100;MAX_SECTION_ATTEMPTS=15;ACCEPTABLE_PF=.05;FRACTION_TO_REPLACE=.2;JUMPER_PF_FN_ENABLED=!1;SHUFFLE_SEEDS_PER_SECTION=null;ALWAYS_RIP_INTERSECTIONS=!0;effort=1;HYPERPARAMETER_SCHEDULE=Fh;constructor(t){super(),this.MAX_ITERATIONS=1e6,this.simpleRouteJson=t.simpleRouteJson,this.inputNodes=t.inputNodes,this.capacityMeshNodes=t.capacityMeshNodes,this.capacityMeshEdges=t.capacityMeshEdges,this.colorMap=t.colorMap??{},this.effort=t.effort??1,void 0!==t.FRACTION_TO_REPLACE&&(this.FRACTION_TO_REPLACE=t.FRACTION_TO_REPLACE),void 0!==t.ALWAYS_RIP_INTERSECTIONS&&(this.ALWAYS_RIP_INTERSECTIONS=t.ALWAYS_RIP_INTERSECTIONS),void 0!==t.MAX_ATTEMPTS_PER_NODE&&(this.MAX_ATTEMPTS_PER_NODE=t.MAX_ATTEMPTS_PER_NODE),void 0!==t.MAX_SECTION_ATTEMPTS&&(this.MAX_SECTION_ATTEMPTS=t.MAX_SECTION_ATTEMPTS),void 0!==t.HYPERPARAMETER_SCHEDULE&&(this.HYPERPARAMETER_SCHEDULE=t.HYPERPARAMETER_SCHEDULE),this.JUMPER_PF_FN_ENABLED=t.JUMPER_PF_FN_ENABLED??this.JUMPER_PF_FN_ENABLED,this.SHUFFLE_SEEDS_PER_SECTION=t.SHUFFLE_SEEDS_PER_SECTION,this.nodeMap=new Map(t.inputNodes.map(t=>[t.capacityMeshNodeId,t])),this.capacityMeshNodeMap=new Map(t.capacityMeshNodes.map(t=>[t.capacityMeshNodeId,t])),this.connectionResults=[...t.initialConnectionResults],this.assignedPortPoints=new Map(t.initialAssignedPortPoints),this.nodeAssignedPortPoints=new Map(t.initialNodeAssignedPortPoints),this.nodePfMap=this.computeInitialPfMap();const e=this.computeBoardScore();this.stats.successfulOptimizations=0,this.stats.failedOptimizations=0,this.stats.nodesExamined=0,this.stats.sectionAttempts=0,this.stats.sectionScores={},this.stats.initialBoardScore=e,this.stats.currentBoardScore=e,this.stats.errors=0}computeInitialPfMap(){const t=new Map;for(const e of this.capacityMeshNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];if(0===n.length)continue;const s={capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ},o=this.JUMPER_PF_FN_ENABLED&&1===e.availableZ.length?Ch(e,vh(s).numSameLayerCrossings):Nh(s,e);t.set(e.capacityMeshNodeId,o)}return t}computeBoardScore(){const t=this.getNodesWithPortPoints();return this.computeScoreForNodes(t)}computeScoreForNodes(t){return this.JUMPER_PF_FN_ENABLED?Ah(t,this.capacityMeshNodeMap):Mh(t,this.capacityMeshNodeMap)}recomputePfForNodes(t){for(const e of t){const t=this.capacityMeshNodeMap.get(e);if(!t)continue;const n=this.nodeAssignedPortPoints.get(e)??[];if(0===n.length){this.nodePfMap.set(e,0);continue}const s={capacityMeshNodeId:e,center:t.center,width:t.width,height:t.height,portPoints:n,availableZ:t.availableZ},o=this.JUMPER_PF_FN_ENABLED&&1===t.availableZ.length?Ch(t,vh(s).numSameLayerCrossings):Nh(s,t);this.nodePfMap.set(e,o)}}getCreatePortPointSectionInput(){return{inputNodes:this.inputNodes,capacityMeshNodes:this.capacityMeshNodes,capacityMeshEdges:this.capacityMeshEdges,nodeMap:this.nodeMap,connectionResults:this.connectionResults}}createSection(t){return function(t,e){const{inputNodes:n,capacityMeshNodes:s,capacityMeshEdges:o,connectionResults:i}=t,{centerOfSectionCapacityNodeId:r,expansionDegrees:a}=e,c=new Map;for(const t of o){const[e,n]=t.nodeIds;c.has(e)||c.set(e,new Set),c.has(n)||c.set(n,new Set),c.get(e).add(n),c.get(n).add(e)}const h=new Set,l=new Set,d=[];for(d.push({nodeId:r,depth:0}),l.add(r);d.length>0;){const{nodeId:t,depth:e}=d.shift();if(h.add(t),e<a){const n=c.get(t)??new Set;for(const t of n)l.has(t)||(l.add(t),d.push({nodeId:t,depth:e+1}))}}const u=n.filter(t=>h.has(t.capacityMeshNodeId)),p=s.filter(t=>h.has(t.capacityMeshNodeId)),f=[],m=[];for(const t of o){const[e,n]=t.nodeIds,s=h.has(e),o=h.has(n);s&&o?f.push(t):(s||o)&&m.push(t)}const g=u.map(t=>{const e=t.portPoints.filter(t=>{const[e,n]=t.connectionNodeIds,s=h.has(e),o=h.has(n);return s||o});return{...t,portPoints:e}}),y=function(t,e){const n=[];for(const s of t){if(!s.path||0===s.path.length)continue;const t=s.connection.name,o=s.connection.rootConnectionName,i=[];for(let t=0;t<s.path.length;t++){const n=s.path[t];e.has(n.currentNodeId)&&i.push(t)}if(0===i.length)continue;const r=i[0],a=i[i.length-1];let c=r,h=a;if(r>0){const t=s.path[0].currentNodeId;(s.nodeIds[0]===t||s.nodeIds[1]===t)&&(c=0)}if(a<s.path.length-1){const t=s.path.length-1,e=s.path[t].currentNodeId;(s.nodeIds[0]===e||s.nodeIds[1]===e)&&(h=t)}const l=s.path.slice(c,h+1),d=c>0,u=h<s.path.length-1;n.push({connectionName:t,rootConnectionName:o,points:l.map(t=>({x:t.point.x,y:t.point.y,z:t.z,nodeId:t.currentNodeId,portPointId:t.portPoint?.portPointId})),originalStartIndex:c,originalEndIndex:h,hasEntryFromOutside:d,hasExitToOutside:u})}return n}(i??[],h);return{centerNodeId:r,expansionDegrees:a,nodeIds:h,inputNodes:g,capacityMeshNodes:p,internalEdges:f,boundaryEdges:m,sectionPaths:y}}(this.getCreatePortPointSectionInput(),t)}getSectionNodesWithPortPoints(t){const e=[];for(const n of t.nodeIds){const t=this.nodeMap.get(n),s=this.capacityMeshNodeMap.get(n);if(!t||!s)continue;const o=this.nodeAssignedPortPoints.get(n)??[];o.length>0&&e.push({capacityMeshNodeId:n,center:t.center,width:t.width,height:t.height,portPoints:o,availableZ:t.availableZ})}return e}getNodesWithPortPoints(){const t=[];for(const e of this.inputNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];n.length>0&&t.push({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ})}return t}findHighestPfNode(){let t=null,e=0;for(const[n,s]of this.nodePfMap.entries()){s*(1-(this.attemptsToFixNode.get(n)??0)/this.MAX_ATTEMPTS_PER_NODE)**2>e&&(e=s,t=n)}return!t||e<this.ACCEPTABLE_PF?null:t}currentSectionCutPathInfo=new Map;currentSectionKeptPortPoints=new Map;currentSectionFixedRoutes=[];determineConnectionsToRip(t,e){const n=31337*this.sectionAttempts,s=Lh(n);if(this.FRACTION_TO_REPLACE>=1)return new Set(e);const o=function(t,e){const n=Lh(e),s=[...t];for(let t=s.length-1;t>0;t--){const e=Math.floor(n()*(t+1));[s[t],s[e]]=[s[e],s[t]]}return s}(e,n),i=Math.max(1,Math.ceil(o.length*this.FRACTION_TO_REPLACE)),r=new Set(o.slice(0,i));if(this.ALWAYS_RIP_INTERSECTIONS){const n=function(t){const{section:e,nodePfMap:n,capacityMeshNodeMap:s,nodeAssignedPortPoints:o,acceptablePf:i}=t,r=[];for(const t of e.nodeIds){if((n.get(t)??0)<=i)continue;const e=s.get(t);if(!e)continue;const a=o.get(t)??[];if(a.length<2)continue;const c=e.center.x-e.width/2,h=e.center.x+e.width/2,l=e.center.y-e.height/2,d=e.center.y+e.height/2,u=new Map;for(const t of a){const e=u.get(t.connectionName)??[];e.some(e=>e.x===t.x&&e.y===t.y&&e.z===t.z)||e.push({x:t.x,y:t.y,z:t.z}),u.set(t.connectionName,e)}const p=new Map;for(const[t,e]of u){if(e.length<2)continue;const n=e[0],s=e[1];if(n.z!==s.z)continue;const o=Ih(n,c,h,l,d),i=Ih(s,c,h,l,d),r=n.z,a=p.get(r)??[];a.push({connectionName:t,t1:o,t2:i}),p.set(r,a)}const f=1e-6;for(const[,t]of p){const e=t.map(t=>({connectionName:t.connectionName,a:Math.min(t.t1,t.t2),b:Math.max(t.t1,t.t2)}));for(let t=0;t<e.length;t++){const{connectionName:n,a:s,b:o}=e[t];for(let i=t+1;i<e.length;i++){const{connectionName:t,a:a,b:c}=e[i];Math.abs(s-a)<f||Math.abs(s-c)<f||Math.abs(o-a)<f||Math.abs(o-c)<f||(s<a&&a<o&&o<c||a<s&&s<c&&c<o)&&r.push([n,t])}}}}return r}({section:t,nodePfMap:this.nodePfMap,capacityMeshNodeMap:this.capacityMeshNodeMap,nodeAssignedPortPoints:this.nodeAssignedPortPoints,acceptablePf:this.ACCEPTABLE_PF});for(const[t,o]of n){if(r.has(t)||r.has(o))continue;const n=e.includes(t),i=e.includes(o);if(n&&i){const e=s()<.5;r.add(e?t:o)}else n?r.add(t):i&&r.add(o)}}return this.stats.lastRipCount=r.size,r}createSectionSimpleRouteJson(t){const e=[];this.currentSectionCutPathInfo.clear(),this.currentSectionKeptPortPoints.clear(),this.currentSectionFixedRoutes=[];const n=[],s=[];for(const e of this.connectionResults){if(!e.path||0===e.path.length)continue;const[o,i]=e.nodeIds,r=t.nodeIds.has(o),a=t.nodeIds.has(i);r&&a&&(s.push(e),n.push(e.connection.name))}const o=[];for(const e of t.sectionPaths){if(!e.hasEntryFromOutside&&!e.hasExitToOutside)continue;if(e.points.length<2)continue;const t=this.connectionResults.find(t=>t.connection.name===e.connectionName);t&&(o.push({sectionPath:e,originalResult:t}),n.includes(e.connectionName)||n.push(e.connectionName))}const i=this.determineConnectionsToRip(t,n);for(const t of s)i.has(t.connection.name)&&e.push(t.connection);for(const{sectionPath:t,originalResult:n}of o){if(!i.has(t.connectionName))continue;const s=`__cut__${t.connectionName}__${t.originalStartIndex}`;this.colorMap[s]=this.colorMap[t.connectionName];const o=t.points[0],r=t.points[t.points.length-1],a={name:s,rootConnectionName:t.rootConnectionName??t.connectionName,pointsToConnect:[{x:o.x,y:o.y,layers:[`layer${o.z+1}`]},{x:r.x,y:r.y,layers:[`layer${r.z+1}`]}]};e.push(a),this.currentSectionCutPathInfo.set(s,{sectionPath:t,originalConnectionResult:n})}const r=new Set(n.filter(t=>!i.has(t)));if(r.size>0){for(const e of t.nodeIds){const t=(this.nodeAssignedPortPoints.get(e)??[]).filter(t=>r.has(t.connectionName));t.length>0&&this.currentSectionKeptPortPoints.set(e,t)}for(const t of s)r.has(t.connection.name)&&this.currentSectionFixedRoutes.push(t);for(const{sectionPath:t,originalResult:e}of o)if(r.has(t.connectionName)){const n={connection:{name:t.connectionName,rootConnectionName:t.rootConnectionName,pointsToConnect:e.connection.pointsToConnect},path:t.points.map(t=>({prevCandidate:null,portPoint:null,currentNodeId:t.nodeId,point:{x:t.x,y:t.y},z:t.z,f:0,g:0,h:0,distanceTraveled:0})),portPoints:t.points.map(e=>({portPointId:e.portPointId,x:e.x,y:e.y,z:e.z,connectionName:t.connectionName,rootConnectionName:t.rootConnectionName})),nodeIds:e.nodeIds,straightLineDistance:e.straightLineDistance};this.currentSectionFixedRoutes.push(n)}}return{...this.simpleRouteJson,connections:e}}prepareSectionInputNodesForCutPaths(t){const e=new Set;for(const[,t]of this.currentSectionCutPathInfo.entries()){const{sectionPath:n}=t;if(0===n.points.length)continue;const s=n.points[0].nodeId;e.add(s);const o=n.points[n.points.length-1].nodeId;e.add(o)}return t.inputNodes.map(t=>e.has(t.capacityMeshNodeId)?{...t,_containsTarget:!0}:t)}getHyperParametersForScheduleIndex(t,e){const n=this.HYPERPARAMETER_SCHEDULE[t];return{...n,SHUFFLE_SEED:(n.SHUFFLE_SEED??0)+17*e}}createSectionSolver(t){const e=this.createSectionSimpleRouteJson(t),n=this.prepareSectionInputNodesForCutPaths(t),s=mh(e,n);for(const[t,e]of this.currentSectionKeptPortPoints){const n=s.nodeAssignedPortPoints.get(t)??[];s.nodeAssignedPortPoints.set(t,[...n,...e])}return new Dh({simpleRouteJson:e,inputNodes:n,capacityMeshNodes:t.capacityMeshNodes,colorMap:this.colorMap,nodeMemoryPfMap:this.nodePfMap,numShuffleSeeds:this.SHUFFLE_SEEDS_PER_SECTION??2*e.connections.length*this.effort,hyperParameters:{...this.getHyperParametersForScheduleIndex(this.currentScheduleIndex,this.sectionAttempts)},precomputedInitialParams:s,fixedRoutes:this.currentSectionFixedRoutes})}reattachSection(t,e,n,s){const o=[],i=[];for(const t of e)t.connection.name.startsWith("__cut__")?i.push(t):o.push(t);const r=new Set(o.map(t=>t.connection.name));this.connectionResults=this.connectionResults.filter(t=>!r.has(t.connection.name)),this.connectionResults.push(...o);for(const[e,n]of this.nodeAssignedPortPoints.entries()){if(!t.nodeIds.has(e))continue;const s=n.filter(t=>!r.has(t.connectionName));this.nodeAssignedPortPoints.set(e,s)}for(const[t,e]of this.assignedPortPoints.entries())r.has(e.connectionName)&&this.assignedPortPoints.delete(t);for(const e of i){const n=this.currentSectionCutPathInfo.get(e.connection.name);if(!n||!e.path)continue;const{sectionPath:s,originalConnectionResult:o}=n,i=o.path;if(!i)continue;const r=s.connectionName;for(const[e,n]of this.nodeAssignedPortPoints.entries()){const s=n.filter(n=>n.connectionName!==r||!t.nodeIds.has(e));this.nodeAssignedPortPoints.set(e,s)}const a=i.slice(0,s.originalStartIndex),c=i.slice(s.originalEndIndex+1),h=[];let l=a.length>0?a[a.length-1]:null;for(const t of e.path){const e={...t,prevCandidate:l};h.push(e),l=e}if(c.length>0&&h.length>0&&(c[0]={...c[0],prevCandidate:h[h.length-1]}),o.path=[...a,...h,...c],e.portPoints)for(const n of e.portPoints){const e={...n,connectionName:r,rootConnectionName:s.rootConnectionName??r};for(const s of t.inputNodes)for(const t of s.portPoints)if(Math.abs(t.x-n.x)<.001&&Math.abs(t.y-n.y)<.001&&t.z===n.z){for(const n of t.connectionNodeIds){const t=this.nodeAssignedPortPoints.get(n)??[];t.push(e),this.nodeAssignedPortPoints.set(n,t)}break}}}for(const[t,e]of n.entries())e.connectionName.startsWith("__cut__")||this.assignedPortPoints.set(t,e);for(const[t,e]of s.entries()){const n=e.filter(t=>!t.connectionName.startsWith("__cut__"));if(n.length>0){const e=this.nodeAssignedPortPoints.get(t)??[];this.nodeAssignedPortPoints.set(t,[...e,...n])}}}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved||this.activeSubSolver.failed){if(this.activeSubSolver.failed){if(this.currentScheduleIndex++,this.activeSubSolver.error&&this.stats.errors++,this.currentScheduleIndex<this.HYPERPARAMETER_SCHEDULE.length&&this.currentSectionCenterNodeId){const t=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:this.currentSectionCenterNodeId,expansionDegrees:t.EXPANSION_DEGREES}),this.activeSubSolver=this.createSectionSolver(this.currentSection)}else this.stats.failedOptimizations++,this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0;return}const t=this.activeSubSolver.getNodesWithPortPoints().map(t=>({...t,portPoints:t.portPoints.map(t=>{if(t.connectionName.startsWith("__cut__")){const e=t.connectionName.slice(7),n=e.lastIndexOf("__"),s=n>=0?e.slice(0,n):e;return{...t,connectionName:s}}return t})})),e=new Set;for(const n of t)for(const t of n.portPoints)e.add(t.connectionName);const n=this.getSectionNodesWithPortPoints(this.currentSection).map(t=>({...t,portPoints:t.portPoints.filter(t=>e.has(t.connectionName))})).filter(t=>t.portPoints.length>0),s=this.computeScoreForNodes(n),o=this.computeScoreForNodes(t),i=`attempt${this.sectionAttempts}`;if(this.stats.lastSectionScore=o,o>s){const t=this.stats.currentBoardScore;this.stats.lastBoardScore=t;const e=[...this.connectionResults],n=new Map(this.assignedPortPoints),s=new Map(Array.from(this.nodeAssignedPortPoints.entries()).map(([t,e])=>[t,[...e]]));this.reattachSection(this.currentSection,this.activeSubSolver.connectionsWithResults,this.activeSubSolver.assignedPortPoints,this.activeSubSolver.nodeAssignedPortPoints),this.recomputePfForNodes(this.currentSection.nodeIds);const o=this.computeBoardScore();this.stats.sectionScores[i]=o,o>t?(this.stats.successfulOptimizations++,this.stats.currentBoardScore=o):(this.connectionResults=e,this.assignedPortPoints=n,this.nodeAssignedPortPoints=s,this.recomputePfForNodes(this.currentSection.nodeIds),this.stats.failedOptimizations++),this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0}else if(this.currentScheduleIndex++,this.currentScheduleIndex<this.HYPERPARAMETER_SCHEDULE.length&&this.currentSectionCenterNodeId){const t=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:this.currentSectionCenterNodeId,expansionDegrees:t.EXPANSION_DEGREES}),this.activeSubSolver=this.createSectionSolver(this.currentSection)}else this.stats.failedOptimizations++,this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0}return}if(this.sectionAttempts>=this.MAX_SECTION_ATTEMPTS)return void(this.solved=!0);const t=this.findHighestPfNode();if(!t)return void(this.solved=!0);this.sectionAttempts++,this.stats.sectionAttempts=this.sectionAttempts,this.stats.nodesExamined++,this.attemptsToFixNode.set(t,(this.attemptsToFixNode.get(t)??0)+1),this.currentSectionCenterNodeId=t,this.currentScheduleIndex=0;const e=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:t,expansionDegrees:e.EXPANSION_DEGREES});const n=this.getSectionNodesWithPortPoints(this.currentSection);this.sectionScoreBeforeOptimization=this.computeScoreForNodes(n);if(0===this.createSectionSimpleRouteJson(this.currentSection).connections.length)return this.currentSection=null,void(this.currentSectionCenterNodeId=null);this.activeSubSolver=this.createSectionSolver(this.currentSection)}computeProgress(){return this.sectionAttempts/this.MAX_SECTION_ATTEMPTS}visualize(){return this.solved?Oh(this):this.activeSubSolver?this.activeSubSolver.visualize():this.currentSection?function(t,e){const n={lines:[],points:[],rects:[],circles:[]};for(const e of t.inputNodes){const s=e.capacityMeshNodeId===t.centerNodeId,o=s?"rgba(0, 200, 0, 0.3)":"rgba(200, 200, 200, 0.3)";n.rects.push({center:e.center,width:.9*e.width,height:.9*e.height,layer:`z${e.availableZ.join(",")}`,fill:o,label:`${e.capacityMeshNodeId}${s?" (CENTER)":""}`})}for(const e of t.inputNodes)for(const t of e.portPoints){const e="rgba(150, 150, 150, 0.5)";n.circles.push({center:{x:t.x,y:t.y},radius:.05,fill:e,layer:`z${t.z}`,label:[t.portPointId,`cd: ${t.distToCentermostPortOnZ}`,`connects: ${t.connectionNodeIds.join(",")}`].filter(Boolean).join("\n")})}for(const s of t.sectionPaths){const t=e?.[s.connectionName]??"blue";for(let e=0;e<s.points.length-1;e++){const o=s.points[e],i=s.points[e+1],r=o.z===i.z,a=o.z;let c;c=r?0===a?"5 5":"10 5":"3 3 10",n.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:t,strokeDash:c})}}return n}(this.currentSection,this.colorMap):Oh(this)}},Xh=class{parent={};constructor(t){for(const e of t)this.parent[e]=e}find(t){return this.parent[t]===t?t:this.parent[t]=this.find(this.parent[t])}union(t,e){const n=this.find(t),s=this.find(e);n!==s&&(this.parent[s]=n)}getGroup(t){const e=this.find(t),n=[];for(const t in this.parent)this.find(t)===e&&n.push(t);return n}},kh=class{point;left=null;right=null;constructor(t){this.point=t}},$h=class{root=null;constructor(t){t.length>0&&(this.root=this.buildTree(t,0))}buildTree(t,e){const n=e%2==0?"x":"y";t.sort((t,e)=>t[n]-e[n]);const s=Math.floor(t.length/2),o=new kh(t[s]);return s>0&&(o.left=this.buildTree(t.slice(0,s),e+1)),s<t.length-1&&(o.right=this.buildTree(t.slice(s+1),e+1)),o}findNearestNeighbor(t){if(!this.root)throw new Error("Tree is empty");const e=this.root.point,n=this.distance(t,e);return this.nearestNeighborSearch(this.root,t,0,e,n),e}nearestNeighborSearch(t,e,n,s,o){if(!t)return s;const i=n%2?"x":"y",r=this.distance(e,t.point);r<o&&(s=t.point,o=r);const a=e[i]-t.point[i],c=a<=0?t.left:t.right,h=a<=0?t.right:t.left;return s=this.nearestNeighborSearch(c,e,n+1,s,o),o=this.distance(e,s),Math.abs(a)<o&&(s=this.nearestNeighborSearch(h,e,n+1,s,o)),s}findKNearestNeighbors(t,e){if(!this.root)return[];const n=[];return this.kNearestNeighborSearch(this.root,t,0,n,e),n.sort((t,e)=>t.distance-e.distance).slice(0,e).map(t=>t.point)}kNearestNeighborSearch(t,e,n,s,o){if(!t)return;const i=n%2?"x":"y",r=this.distance(e,t.point);s.push({point:t.point,distance:r});const a=e[i]-t.point[i],c=a<=0?t.left:t.right,h=a<=0?t.right:t.left;this.kNearestNeighborSearch(c,e,n+1,s,o);let l=1/0;s.length>=o&&(s.sort((t,e)=>t.distance-e.distance),l=s[o-1]?.distance||1/0),(Math.abs(a)<l||s.length<o)&&this.kNearestNeighborSearch(h,e,n+1,s,o)}distance(t,e){return Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2)}},Bh=class{parent=new Map;rank=new Map;constructor(t){for(const e of t){const t=this.pointToKey(e);this.parent.set(t,t),this.rank.set(t,0)}}pointToKey(t){return`${t.x},${t.y}`}find(t){const e=this.pointToKey(t);if(!this.parent.has(e))throw new Error(`Point ${e} not found in DisjointSet`);let n=e;for(;n!==this.parent.get(n);)n=this.parent.get(n);let s=e;for(;s!==n;){const t=this.parent.get(s);this.parent.set(s,n),s=t}return n}union(t,e){const n=this.find(t),s=this.find(e);if(n===s)return!1;const o=this.rank.get(n)||0,i=this.rank.get(s)||0;return o<i?this.parent.set(n,s):o>i?this.parent.set(s,n):(this.parent.set(s,n),this.rank.set(n,o+1)),!0}};function jh(t){if(t.length<=1)return[];const e=[...t],n=new $h(e),s=[],o=Math.min(10,t.length-1);for(const t of e){const e=n.findKNearestNeighbors(t,o+1);for(const n of e){if(t.x===n.x&&t.y===n.y)continue;const e=Math.sqrt((t.x-n.x)**2+(t.y-n.y)**2);s.push({from:t,to:n,weight:e})}}s.sort((t,e)=>t.weight-e.weight);const i=new Bh(e),r=[];for(const t of s)if(i.union(t.from,t.to)&&(r.push(t),r.length===e.length-1))break;return r}function Wh(t){if(t.pointId)return t.pointId;let e="";var n;return"layer"in(n=t)&&"string"==typeof n.layer?e=t.layer:Cn(t)&&t.layers&&(e=t.layers.sort().join("-")),`${t.x.toFixed(4)},${t.y.toFixed(4)},${e}`}var Hh=class extends Ln{constructor(t,e={}){super(),this.ogSrj=t,this.colorMap=e,this.unprocessedConnections=function(t){if(0===t.length)return[];const e=t.map((t,e)=>`conn_${e}`),n=new Xh(e),s=new Map;t.forEach((t,e)=>{const n=`conn_${e}`;t.pointsToConnect.forEach(t=>{const e=Wh(t);s.has(e)||s.set(e,[]),s.get(e).push(n)})});for(const t of s.values())if(t.length>1){const e=t[0];for(let s=1;s<t.length;s++)n.union(e,t[s])}const o=new Map;t.forEach((t,e)=>{const s=`conn_${e}`,i=n.find(s);o.has(i)||o.set(i,[]),o.get(i).push(t)});const i=[];for(const t of o.values()){if(1===t.length){i.push(t[0]);continue}const e=new Map,n=new Set;let s=!1;const o=[],r=new Set;let a;t.forEach(t=>{t.pointsToConnect.forEach(t=>e.set(Wh(t),t)),n.add(t.name),t.isOffBoard&&(s=!0),t.externallyConnectedPointIds&&o.push(...t.externallyConnectedPointIds),t.netConnectionName&&r.add(t.netConnectionName),void 0===a&&void 0!==t.nominalTraceWidth&&(a=t.nominalTraceWidth)});const c={name:Array.from(n).join("__"),mergedConnectionNames:Array.from(n),pointsToConnect:Array.from(e.values()),isOffBoard:s,externallyConnectedPointIds:o.length>0?o:void 0,netConnectionName:r.size>0?Array.from(r).join("__"):void 0,nominalTraceWidth:a};i.push(c)}return i}([...t.connections]),this.newConnections=[]}getSolverName(){return"NetToPointPairsSolver"}unprocessedConnections;newConnections;_step(){if(0===this.unprocessedConnections.length)return void(this.solved=!0);const t=this.unprocessedConnections.pop(),e=t.externallyConnectedPointIds??[],n=new Map;e.forEach((t,e)=>t.forEach(t=>n.set(t,e)));const s=(t,e)=>{if(!t.pointId||!e.pointId)return!1;const s=n.get(t.pointId),o=n.get(e.pointId);return void 0!==s&&s===o};if(2===t.pointsToConnect.length){if(s(t.pointsToConnect[0],t.pointsToConnect[1]))return;return void this.newConnections.push({...t,rootConnectionName:t.name})}const o=jh(t.pointsToConnect);let i=0;for(const e of o)s(e.from,e.to)||this.newConnections.push({pointsToConnect:[e.from,e.to],name:`${t.name}_mst${i++}`,rootConnectionName:t.name,mergedConnectionNames:t.mergedConnectionNames,netConnectionName:t.netConnectionName})}getNewSimpleRouteJson(){return{...structuredClone(this.ogSrj),connections:structuredClone(this.newConnections)}}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Net To Point Pairs Visualization"};return this.unprocessedConnections.forEach(e=>{e.pointsToConnect.forEach(n=>{t.points.push({x:n.x,y:n.y,color:"red",label:e.name})});const n=e.pointsToConnect.length**2,s=Un(0),o=new Set;for(let i=0;i<Math.max(n,2*e.pointsToConnect.length);i++){const n=Math.floor(s()*e.pointsToConnect.length),i=Math.floor(s()*e.pointsToConnect.length);o.has(`${n}-${i}`)||(o.add(`${n}-${i}`),t.lines.push({points:[e.pointsToConnect[n],e.pointsToConnect[i]],strokeColor:"rgba(255,0,0,0.25)"}))}}),this.newConnections.forEach(e=>{const n=this.colorMap?.[e.name]||"blue";e.pointsToConnect.forEach(s=>{t.points.push({x:s.x,y:s.y,color:n,label:e.name})});for(let s=0;s<e.pointsToConnect.length-1;s++)for(let o=s+1;o<e.pointsToConnect.length;o++)t.lines.push({points:[e.pointsToConnect[s],e.pointsToConnect[o]],strokeColor:n})}),t}},Uh=class extends Hh{constructor(t,e={}){const n=t.connections.flatMap(t=>t.pointsToConnect),s=new Map;for(const t of n)t.pointId&&s.set(t.pointId,t);const o=n.map(t=>t.pointId).filter(t=>!!t),i=new Xh(o),r=[];for(const e of t.connections)e.isOffBoard?e.pointsToConnect.length>=2&&e.pointsToConnect[0].pointId&&e.pointsToConnect[1].pointId&&i.union(e.pointsToConnect[0].pointId,e.pointsToConnect[1].pointId):r.push(e);super({...t,connections:r},e),this.ogSrj=t,this.colorMap=e,this.connectionPointDsu=i,this.connectionPointMap=s,this.ogSrj=t}getSolverName(){return"NetToPointPairsSolver2_OffBoardConnection"}connectionPointDsu;connectionPointMap;_findBestConnectionPointsFromDisjointSets(t,e){if(!t.pointId||!e.pointId)return{pointsToConnect:[t,e]};const n=this.connectionPointDsu.getGroup(t.pointId).map(t=>this.connectionPointMap.get(t)),s=this.connectionPointDsu.getGroup(e.pointId).map(t=>this.connectionPointMap.get(t));let o=t,i=e,r=1/0;for(const t of n)for(const e of s){const n=Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2));n<r&&(r=n,o=t,i=e)}return{pointsToConnect:[o,i]}}_step(){if(0===this.unprocessedConnections.length)return void(this.solved=!0);const t=this.unprocessedConnections.pop(),e=t.externallyConnectedPointIds??[],n=new Map;e.forEach((t,e)=>t.forEach(t=>n.set(t,e)));const s=(t,e)=>{if(!t.pointId||!e.pointId)return!1;const s=n.get(t.pointId),o=n.get(e.pointId);return void 0!==s&&s===o};if(2===t.pointsToConnect.length){if(s(t.pointsToConnect[0],t.pointsToConnect[1]))return;const e=this._findBestConnectionPointsFromDisjointSets(t.pointsToConnect[0],t.pointsToConnect[1]);return void this.newConnections.push({...t,pointsToConnect:e.pointsToConnect,rootConnectionName:t.name})}const o=jh(t.pointsToConnect);let i=0;for(const e of o){if(s(e.from,e.to))continue;const n=this._findBestConnectionPointsFromDisjointSets(e.from,e.to);this.newConnections.push({pointsToConnect:n.pointsToConnect,name:`${t.name}_mst${i++}`,rootConnectionName:t.name,mergedConnectionNames:t.mergedConnectionNames,netConnectionName:t.netConnectionName})}}},Vh=class{netMap;idToNetMap;constructor(t){this.netMap=t,this.idToNetMap={};for(const[e,n]of Object.entries(t))for(const t of n)this.idToNetMap[t]=e}addConnections(t){for(const e of t){const t=new Set;for(const n of e){const e=this.idToNetMap[n];e&&t.add(e)}let n;if(0===t.size)n=`connectivity_net${Object.keys(this.netMap).length}`,this.netMap[n]=[];else if(1===t.size)n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;else{n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;for(const e of t)if(e!==n){const t=this.netMap[n],s=this.netMap[e];if(t&&s){t.push(...s),this.netMap[e]=t;for(const e of t)this.idToNetMap[e]=n}}}for(const t of e){const e=this.netMap[n];e&&!e.includes(t)&&e.push(t),this.idToNetMap[t]=n}}}getIdsConnectedToNet(t){return this.netMap[t]||[]}getNetConnectedToId(t){return this.idToNetMap[t]}areIdsConnected(t,e){if(t===e)return!0;const n=this.getNetConnectedToId(t);if(!n)return!1;const s=this.getNetConnectedToId(e);return!!s&&(n===s||s===t||s===t)}areAllIdsConnected(t){if(0===t.length)return!0;const e=this.getNetConnectedToId(t[0]);if(!e)return!1;for(const n of t){const t=this.getNetConnectedToId(n);if(void 0===t)return!1;if(t!==e)return!1}return!0}};function Gh(t,e={}){const n=[],s=[],o=e.color??"gray",i=e.label,r=wn[t.footprint]??wn["0603"],a=t.end.x-t.start.x,c=t.end.y-t.start.y,h=Math.abs(a)>Math.abs(c),l=h?r.padLength:r.padWidth,d=h?r.padWidth:r.padLength;return n.push({center:t.start,width:l,height:d,fill:In(o,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:i?`${i} (start)`:void 0}),n.push({center:t.end,width:l,height:d,fill:In(o,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:i?`${i} (end)`:void 0}),s.push({points:[t.start,t.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*r.padWidth,layer:"jumper-body"}),{rects:n,lines:s}}function Zh(t,e={}){const n={rects:[],lines:[]};for(const s of t){const{rects:t,lines:o}=Gh(s,e);n.rects.push(...t),n.lines.push(...o)}return n}var qh=1e5,Jh=.001,Kh=class extends Ln{getSolverName(){return"SingleHighDensityRouteStitchSolver"}mergedHdRoute;remainingHdRoutes;start;end;colorMap;constructor(t){if(super(),this.remainingHdRoutes=[...t.hdRoutes],this.colorMap=t.colorMap??{},0===t.hdRoutes.length){this.start=t.start,this.end=t.end;const e=[{x:t.start.x,y:t.start.y,z:t.start.z}],n=[];return t.start.z!==t.end.z&&(e.push({x:t.start.x,y:t.start.y,z:t.end.z}),n.push({x:t.start.x,y:t.start.y})),e.push({x:t.end.x,y:t.end.y,z:t.end.z}),this.mergedHdRoute={connectionName:t.connectionName,rootConnectionName:t.hdRoutes[0]?.rootConnectionName,route:e,vias:n,jumpers:[],viaDiameter:t.defaultViaDiameter??.3,traceThickness:t.defaultTraceThickness??.15},void(this.solved=!0)}let e=1/0,n=t.hdRoutes[0],s="start-to-end";for(const o of t.hdRoutes){const i=o.route[0],r=o.route[o.route.length-1],a=k(t.start,i),c=k(t.start,r),h=k(t.end,i),l=k(t.end,r),d=Math.min(a,c,h,l);d<e&&(e=d,n=o,s=Math.min(h,l)<Math.min(a,c)?"end-to-start":"start-to-end")}"start-to-end"===s?(this.start=t.start,this.end=t.end):(this.start=t.end,this.end=t.start);const o=n.route[0],i=n.route[n.route.length-1],r=k(this.start,o)<=k(this.start,i)?o:i;this.mergedHdRoute={connectionName:t.connectionName,rootConnectionName:n.rootConnectionName,route:[{x:this.start.x,y:this.start.y,z:r.z}],vias:[],jumpers:[],viaDiameter:n.viaDiameter,traceThickness:n.traceThickness}}getDisjointedRoute(){for(const t of this.remainingHdRoutes){if([t.route[0],t.route[t.route.length-1]].some(e=>!this.remainingHdRoutes.some(n=>{if(n===t)return!1;return[n.route[0],n.route[n.route.length-1]].some(t=>t.z===e.z&&k(e,t)<.001)})))return{firstRoute:t}}return{firstRoute:this.remainingHdRoutes[0]}}_step(){if(0===this.remainingHdRoutes.length){const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];return this.mergedHdRoute.route.push({x:this.end.x,y:this.end.y,z:t.z}),void(this.solved=!0)}const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];let e=-1,n="first",s=1/0;for(let o=0;o<this.remainingHdRoutes.length;o++){const i=this.remainingHdRoutes[o],r=i.route[0],a=i.route[i.route.length-1],c=k(t,r),h=k(t,a);let l=1/0;l=t.z===r.z?c<Jh?c:qh+c:c<Jh?1e3+c:qh+c,l<s&&(s=l,e=o,n="first");let d=1/0;d=t.z===a.z?h<Jh?h:qh+h:h<Jh?1e3+h:qh+h,d<s&&(s=d,e=o,n="last")}if(-1===e)return void(this.remainingHdRoutes=[]);const o=this.remainingHdRoutes[e];let i;this.remainingHdRoutes.splice(e,1),i="first"===n?o.route:[...o.route].reverse(),i.length>0&&k(t,i[0])<Jh&&t.z===i[0].z?this.mergedHdRoute.route.push(...i.slice(1)):this.mergedHdRoute.route.push(...i),this.mergedHdRoute.vias.push(...o.vias),o.jumpers&&this.mergedHdRoute.jumpers.push(...o.jumpers)}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Single High Density Route Stitch Solver"};if(t.points?.push({x:this.start.x,y:this.start.y,color:"green",label:"Start"},{x:this.end.x,y:this.end.y,color:"red",label:"End"}),this.mergedHdRoute&&this.mergedHdRoute.route.length>1){t.lines?.push({points:this.mergedHdRoute.route.map(t=>({x:t.x,y:t.y})),strokeColor:"green"});for(const e of this.mergedHdRoute.route)t.points?.push({x:e.x,y:e.y,color:"green"});for(const e of this.mergedHdRoute.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:this.mergedHdRoute.viaDiameter/2,fill:"green"});if(this.mergedHdRoute.jumpers&&this.mergedHdRoute.jumpers.length>0){const e=Zh(this.mergedHdRoute.jumpers,{color:"green",label:this.mergedHdRoute.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const[e,n]of this.remainingHdRoutes.entries()){const s=this.colorMap[n.connectionName]??"gray";n.route.length>1&&t.lines?.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:s});for(let o=0;o<n.route.length;o++){const i=n.route[o];t.points?.push({x:i.x+(e%2-.5)/500+(o%8-4)/1e3,y:i.y+(e%2-.5)/500+(o%8-4)/1e3,color:s,label:`Route ${n.connectionName} ${i===n.route[0]?"First":i===n.route[n.route.length-1]?"Last":""}`})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:s});if(n.jumpers&&n.jumpers.length>0){const e=Zh(n.jumpers,{color:s,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}return t}},Qh=t=>`${Math.round(100*t.x)},${Math.round(100*t.y)},${Math.round(100*t.z)}`,tl=class extends Ln{getSolverName(){return"MultipleHighDensityRouteStitchSolver"}unsolvedRoutes;activeSolver=null;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;constructor(t){super(),this.colorMap=t.colorMap??{};const e=t.hdRoutes[0];this.defaultTraceThickness=e?.traceThickness??.15,this.defaultViaDiameter=e?.viaDiameter??t.defaultViaDiameter??.3;const n=new Vh({}),s=[],o=new Map;for(let e=0;e<t.hdRoutes.length;e++){const n=t.hdRoutes[e],o=n.route[0],i=n.route[n.route.length-1];s.push([`route_island_${e}`,`${n.connectionName}:${Qh(o)}`,`${n.connectionName}:${Qh(i)}`])}n.addConnections(s);for(const t of s)for(const e of t.slice(1))o.set(e,(o.get(e)??0)+1);this.unsolvedRoutes=[];const i=Array.from(new Set(Object.values(n.idToNetMap)));for(const e of i){const s=n.getIdsConnectedToNet(e),i=t.hdRoutes.filter((t,e)=>s.includes(`route_island_${e}`));if(0===i.length)continue;const r=t.connections.find(t=>t.name===i[0].connectionName),a=i.flatMap(t=>[t.route[0],t.route[t.route.length-1]]),c=[];for(const t of a){const e=`${i[0].connectionName}:${Qh(t)}`;1===o.get(e)&&c.push(t)}if(0===c.length){console.log("no possible endpoints, can't stitch");continue}let h,l;2!==c.length?(h={...r.pointsToConnect[0],z:Rn(Tn(r.pointsToConnect[0]),t.layerCount)},l={...r.pointsToConnect[1],z:Rn(Tn(r.pointsToConnect[1]),t.layerCount)}):(h=c[0],l=c[1],k(h,r.pointsToConnect[1])<k(l,r.pointsToConnect[0])&&([h,l]=[l,h])),this.unsolvedRoutes.push({connectionName:i[0].connectionName,hdRoutes:i,start:h,end:l})}this.MAX_ITERATIONS=1e5}_step(){if(this.activeSolver)return this.activeSolver.step(),void(this.activeSolver.solved?(this.activeSolver instanceof Kh&&this.mergedHdRoutes.push(this.activeSolver.mergedHdRoute),this.activeSolver=null):this.activeSolver.failed&&(this.failed=!0,this.error=this.activeSolver.error));const t=this.unsolvedRoutes.pop();t?this.activeSolver=new Kh({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter}):this.solved=!0}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Multiple High Density Route Stitch Solver"};if(this.activeSolver){const e=this.activeSolver.visualize();e.points?.length&&t.points?.push(...e.points),e.lines?.length&&t.lines?.push(...e.lines),e.circles?.length&&t.circles?.push(...e.circles),e.rects?.length&&(t.rects||(t.rects=[]),t.rects.push(...e.rects))}for(const[e,n]of this.mergedHdRoutes.entries()){const s=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1],r=0!==o.z?In(s,.5):s;t.lines?.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:r,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?In(s,.5):s;t.points?.push({x:e.x,y:e.y,color:n})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:s});if(n.jumpers&&n.jumpers.length>0){const e=Zh(n.jumpers,{color:s,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.unsolvedRoutes){const n=this.colorMap[e.connectionName]??"gray";t.points?.push({x:e.start.x,y:e.start.y,color:n,label:`${e.connectionName} Start (z=${e.start.z})`},{x:e.end.x,y:e.end.y,color:n,label:`${e.connectionName} End (z=${e.end.z})`}),t.lines?.push({points:[{x:e.start.x,y:e.start.y},{x:e.end.x,y:e.end.y}],strokeColor:n,strokeDash:"2 2"});for(const s of e.hdRoutes){s.route.length>1&&t.lines?.push({points:s.route.map(t=>({x:t.x,y:t.y})),strokeColor:In(n,.5),strokeDash:"10 5"});for(const e of s.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:s.viaDiameter/2,fill:n});if(s.jumpers&&s.jumpers.length>0){const e=Zh(s.jumpers,{color:n,label:s.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}}return t}},el=class{tree;constructor(t=9){this.tree=new ot(t)}insert(t,e,n,s,o){this.tree.insert({minX:e,minY:n,maxX:s,maxY:o,data:t})}bulkLoad(t){const e=t.map(({item:t,minX:e,minY:n,maxX:s,maxY:o})=>({minX:e,minY:n,maxX:s,maxY:o,data:t}));this.tree.load(e)}search(t,e,n,s){return this.tree.search({minX:t,minY:e,maxX:n,maxY:s}).map(t=>t.data)}clear(){this.tree.clear()}},nl=class{index;items=[];currentIndex=0;capacity;constructor(t){this.capacity=Math.max(1,t),this.index=new E(this.capacity)}insert(t,e,n,s,o){if(this.currentIndex>=this.index.numItems)throw new Error("Exceeded initial capacity");this.items[this.currentIndex]=t,this.index.add(e,n,s,o),this.currentIndex++}finish(){this.index.finish()}search(t,e,n,s){return this.index.search(t,e,n,s).map(t=>this.items[t]||null).filter(Boolean)}clear(){this.items=[],this.currentIndex=0,this.index=new E(this.capacity)}},sl=class{idx;storage=[];constructor(t="native",e=[]){"flatbush"===t?0===e.length?(this.idx=new el,t="rbush"):this.idx=new nl(e.length):this.idx="rbush"===t?new el:new class{shi=new ol(e);insert(t){}search(t,e,n,s){const o=(t+n)/2,i=(e+s)/2,r=n-t,a=s-e;return this.shi.getNodesInArea(o,i,r,a)}clear(){}},e.forEach(t=>this.insert(t)),"flatbush"===t&&e.length>0&&this.idx.finish?.()}insert(t){this.storage.push(t),this.idx.insert(t,t.center.x-t.width/2,t.center.y-t.height/2,t.center.x+t.width/2,t.center.y+t.height/2)}search(t){return this.idx.search(t.minX,t.minY,t.maxX,t.maxY)}searchArea(t,e,n,s){return this.search({minX:t-n/2,minY:e-s/2,maxX:t+n/2,maxY:e+s/2})}},ol=class{constructor(t){this.obstacles=t,this.buckets=new Map;for(let e=0;e<t.length;e++){const n=t[e],s=n.center.x-n.width/2,o=n.center.y-n.height/2,i=n.center.x+n.width/2,r=n.center.y+n.height/2;for(let t=s;t<=i;t+=this.CELL_SIZE)for(let s=o;s<=r;s+=this.CELL_SIZE){const o=this.getBucketKey(t,s),i=this.buckets.get(o);i?i.push([n,e]):this.buckets.set(o,[[n,e]])}}}buckets;CELL_SIZE=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getNodesInArea(t,e,n,s){const o=[],i=new Set,r=e-s/2,a=t+n/2,c=e+s/2;for(let e=t-n/2;e<=a;e+=this.CELL_SIZE)for(let t=r;t<=c;t+=this.CELL_SIZE){const n=this.getBucketKey(e,t),s=this.buckets.get(n)||[];for(const t of s)i.has(t[1])||(i.add(t[1]),o.push(t[0]))}return o}},il=t=>({minX:Math.min(t[0].x,t[1].x),maxX:Math.max(t[0].x,t[1].x),minY:Math.min(t[0].y,t[1].y),maxY:Math.max(t[0].y,t[1].y)});function rl(t,e){const n=t.x-e.x,s=t.y-e.y;return n*n+s*s}function al(t,e,n){const s=rl(e,n);if(0===s)return rl(t,e);let o=((t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y))/s;o=Math.max(0,Math.min(1,o));return rl(t,{x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}function cl(t,e,n,s){if(L(t,e,n,s))return 0;const o={x:t.x,y:t.y},i={x:e.x,y:e.y},r={x:n.x,y:n.y},a={x:s.x,y:s.y};return Math.min(al(o,r,a),al(i,r,a),al(r,o,i),al(a,o,i))}var hl=class{segmentBuckets;viaBuckets;CELL_SIZE;constructor(t,e=1){this.segmentBuckets=new Map,this.viaBuckets=new Map,this.CELL_SIZE=e;for(const e of t)if(e&&e.connectionName){if(e.route&&e.route.length>=2)for(let t=0;t<e.route.length-1;t++){const n=e.route[t],s=e.route[t+1];if(n.x===s.x&&n.y===s.y)continue;if(n.insideJumperPad&&s.insideJumperPad)continue;const o=[n,s],i=il(o),r={segmentId:`${e.connectionName}-seg-${t}`,segment:o,parentRoute:e},a=Math.floor(i.minX/this.CELL_SIZE),c=Math.floor((i.maxX+1e-9)/this.CELL_SIZE),h=Math.floor(i.minY/this.CELL_SIZE),l=Math.floor((i.maxY+1e-9)/this.CELL_SIZE);for(let t=a;t<=c;t++)for(let e=h;e<=l;e++){const n=`${t}x${e}`;let s=this.segmentBuckets.get(n);s||(s=[],this.segmentBuckets.set(n,s)),s.push(r)}}if(e.vias&&e.vias.length>0)for(let t=0;t<e.vias.length;t++){const n=e.vias[t];if(null==n)continue;const s={viaId:`${e.connectionName}-via-${t}`,x:n.x,y:n.y,parentRoute:e},o=`${Math.floor(n.x/this.CELL_SIZE)}x${Math.floor(n.y/this.CELL_SIZE)}`;let i=this.viaBuckets.get(o);i||(i=[],this.viaBuckets.set(o,i)),i.push(s)}}else console.warn("Skipping route with missing data:",e)}getConflictingRoutesForSegment(t,e,n){const s=il([t,e]),o=s.minX-n,i=s.minY-n,r=s.maxX+n,a=s.maxY+n,c=Math.floor(o/this.CELL_SIZE),h=Math.floor((r+1e-9)/this.CELL_SIZE),l=Math.floor(i/this.CELL_SIZE),d=Math.floor((a+1e-9)/this.CELL_SIZE),u=new Map,p=new Set,f=new Set,m={x:t.x,y:t.y},g={x:e.x,y:e.y};for(let s=c;s<=h;s++)for(let o=l;o<=d;o++){const i=`${s}x${o}`,r=this.segmentBuckets.get(i);if(r)for(const s of r){if(p.has(s.segmentId))continue;p.add(s.segmentId);const o=s.parentRoute,[i,r]=s.segment,a=n+o.traceThickness/2,c=a*a,h=cl(t,e,i,r);if(h<c){const t=o.connectionName,e=u.get(t);(!e||h<e.minDistSq)&&u.set(t,{route:o,minDistSq:h})}}const a=this.viaBuckets.get(i);if(a)for(const t of a){if(f.has(t.viaId))continue;f.add(t.viaId);const e=t.parentRoute,s={x:t.x,y:t.y},o=n+e.viaDiameter/2,i=o*o,r=al(s,m,g);if(r<i){const t=e.connectionName,n=u.get(t);(!n||r<n.minDistSq)&&u.set(t,{route:e,minDistSq:r})}}}const y=[];for(const t of u.values())y.push({conflictingRoute:t.route,distance:Math.sqrt(t.minDistSq)});return y}removeRoute(t){for(const[e,n]of this.segmentBuckets){const s=n.filter(e=>e.parentRoute.connectionName!==t);0===s.length?this.segmentBuckets.delete(e):s.length!==n.length&&this.segmentBuckets.set(e,s)}for(const[e,n]of this.viaBuckets){const s=n.filter(e=>e.parentRoute.connectionName!==t);0===s.length?this.viaBuckets.delete(e):s.length!==n.length&&this.viaBuckets.set(e,s)}}addRoute(t){if(!t||!t.connectionName)return void console.warn("Skipping route with missing data:",t);if(t.route&&t.route.length>=2)for(let e=0;e<t.route.length-1;e++){const n=t.route[e],s=t.route[e+1];if(n.x===s.x&&n.y===s.y)continue;if(n.insideJumperPad&&s.insideJumperPad)continue;const o=[n,s],i=il(o),r={segmentId:`${t.connectionName}-seg-${e}`,segment:o,parentRoute:t},a=Math.floor(i.minX/this.CELL_SIZE),c=Math.floor((i.maxX+1e-9)/this.CELL_SIZE),h=Math.floor(i.minY/this.CELL_SIZE),l=Math.floor((i.maxY+1e-9)/this.CELL_SIZE);for(let t=a;t<=c;t++)for(let e=h;e<=l;e++){const n=`${t}x${e}`;let s=this.segmentBuckets.get(n);s||(s=[],this.segmentBuckets.set(n,s)),s.push(r)}}if(t.vias&&t.vias.length>0)for(let e=0;e<t.vias.length;e++){const n=t.vias[e];if(null==n)continue;const s={viaId:`${t.connectionName}-via-${e}`,x:n.x,y:n.y,parentRoute:t},o=`${Math.floor(n.x/this.CELL_SIZE)}x${Math.floor(n.y/this.CELL_SIZE)}`;let i=this.viaBuckets.get(o);i||(i=[],this.viaBuckets.set(o,i)),i.push(s)}}getConflictingRoutesNearPoint(t,e){const n=t.x-e,s=t.y-e,o=t.x+e,i=t.y+e,r=Math.floor(n/this.CELL_SIZE),a=Math.floor((o+1e-9)/this.CELL_SIZE),c=Math.floor(s/this.CELL_SIZE),h=Math.floor((i+1e-9)/this.CELL_SIZE),l=new Map,d=new Set,u=new Set;for(let n=r;n<=a;n++)for(let s=c;s<=h;s++){const o=`${n}x${s}`,i=this.segmentBuckets.get(o);if(i)for(const n of i){if(d.has(n.segmentId))continue;d.add(n.segmentId);const s=n.segment[0],o=n.segment[1];if(s.z!==o.z||s.z!==t.z)continue;const i=n.parentRoute,r={x:n.segment[0].x,y:n.segment[0].y},a={x:n.segment[1].x,y:n.segment[1].y},c=e+i.traceThickness/2,h=c*c,u=al(t,r,a);if(u<h){const t=i.connectionName,e=l.get(t);(!e||u<e.minDistSq)&&l.set(t,{route:i,minDistSq:u})}}const r=this.viaBuckets.get(o);if(r)for(const n of r){if(u.has(n.viaId))continue;u.add(n.viaId);const s=n.parentRoute,o={x:n.x,y:n.y},i=e+s.viaDiameter/2,r=i*i,a=rl(t,o);if(a<r){const t=s.connectionName,e=l.get(t);(!e||a<e.minDistSq)&&l.set(t,{route:s,minDistSq:a})}}}const p=[];for(const t of l.values())p.push({conflictingRoute:t.route,distance:Math.sqrt(t.minDistSq)});return p}},ll=class extends Ln{getSolverName(){return"SingleRouteUselessViaRemovalSolver"}obstacleSHI;hdRouteSHI;unsimplifiedRoute;routeSections;currentSectionIndex;TRACE_THICKNESS=.15;OBSTACLE_MARGIN=.1;constructor(t){super(),this.currentSectionIndex=0,this.obstacleSHI=t.obstacleSHI,this.hdRouteSHI=t.hdRouteSHI,this.unsimplifiedRoute=t.unsimplifiedRoute,this.routeSections=this.breakRouteIntoSections(this.unsimplifiedRoute)}breakRouteIntoSections(t){const e=[],n=t.route;if(0===n.length)return[];let s={startIndex:0,endIndex:-1,z:n[0].z,points:[n[0]]};for(let t=1;t<n.length;t++)n[t].z===s.z?s.points.push(n[t]):(s.endIndex=t-1,e.push(s),s={startIndex:t,endIndex:-1,z:n[t].z,points:[n[t]]});return s.endIndex=n.length-1,e.push(s),e}_step(){if(this.currentSectionIndex>=this.routeSections.length)return void(this.solved=!0);if(0===this.currentSectionIndex&&this.routeSections.length>1){const t=this.routeSections[0],e=this.routeSections[1];if(t.z!==e.z){const n=e.z,s=t.points[0];if(this.canEndpointConnectOnLayer(s.x,s.y,n)&&this.canSectionMoveToLayer({currentSection:t,targetZ:n}))return t.z=n,t.points=t.points.map(t=>({...t,z:n})),void(this.currentSectionIndex=2)}return void this.currentSectionIndex++}if(this.currentSectionIndex===this.routeSections.length-1){if(this.routeSections.length>=2){const t=this.routeSections[this.routeSections.length-1],e=this.routeSections[this.routeSections.length-2];if(t.z!==e.z){const n=e.z,s=t.points[t.points.length-1];this.canEndpointConnectOnLayer(s.x,s.y,n)&&this.canSectionMoveToLayer({currentSection:t,targetZ:n})&&(t.z=n,t.points=t.points.map(t=>({...t,z:n})))}}return void(this.solved=!0)}const t=this.routeSections[this.currentSectionIndex-1],e=this.routeSections[this.currentSectionIndex],n=this.routeSections[this.currentSectionIndex+1];if(t.z!==n.z)return void this.currentSectionIndex++;const s=t.z;if(this.canSectionMoveToLayer({currentSection:e,targetZ:s}))return e.z=s,e.points=e.points.map(t=>({...t,z:s})),void(this.currentSectionIndex+=2);this.currentSectionIndex++}canEndpointConnectOnLayer(t,e,n){const s=this.obstacleSHI.searchArea(t,e,2,2).filter(n=>{if(!n.connectedTo?.includes(this.unsimplifiedRoute.connectionName))return!1;const s=n.width/2+.05,o=n.height/2+.05,i=Math.abs(t-n.center.x)<=s,r=Math.abs(e-n.center.y)<=o;return i&&r});return!(s.length>0)||s.some(t=>t.zLayers?.includes(n))}canSectionMoveToLayer({currentSection:t,targetZ:e}){for(let n=0;n<t.points.length-1;n++){const s={...t.points[n],z:e},o={...t.points[n+1],z:e},i=this.hdRouteSHI.getConflictingRoutesForSegment(s,o,this.TRACE_THICKNESS);for(const{conflictingRoute:t,distance:e}of i)if(t.connectionName!==this.unsimplifiedRoute.connectionName&&e<this.TRACE_THICKNESS+t.traceThickness)return!1;const r={centerX:(s.x+o.x)/2,centerY:(s.y+o.y)/2,width:Math.abs(s.x-o.x),height:Math.abs(s.y-o.y)},a=this.obstacleSHI.searchArea(r.centerX,r.centerY,r.width+2*(this.TRACE_THICKNESS+this.OBSTACLE_MARGIN),r.height+2*(this.TRACE_THICKNESS+this.OBSTACLE_MARGIN));for(const t of a){if(t.connectedTo?.includes(this.unsimplifiedRoute.connectionName))continue;if(t.zLayers?.includes(e)){if(Math.abs(s.x-t.center.x)<.01&&Math.abs(s.y-t.center.y)<.01||Math.abs(o.x-t.center.x)<.01&&Math.abs(o.y-t.center.y)<.01)continue}if(Q(s,o,t)<this.TRACE_THICKNESS+this.OBSTACLE_MARGIN)return!1}}return!0}getConstructorParams(){return{obstacleSHI:this.obstacleSHI,hdRouteSHI:this.hdRouteSHI,unsimplifiedRoute:this.unsimplifiedRoute}}getOptimizedHdRoute(){const t=this.routeSections.flatMap(t=>t.points),e=[];for(let n=0;n<t.length-1;n++)t[n].z!==t[n+1].z&&e.push({x:t[n].x,y:t[n].y});return{connectionName:this.unsimplifiedRoute.connectionName,rootConnectionName:this.unsimplifiedRoute.rootConnectionName,route:t,traceThickness:this.unsimplifiedRoute.traceThickness,vias:e,viaDiameter:this.unsimplifiedRoute.viaDiameter,jumpers:this.unsimplifiedRoute.jumpers}}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Single Route Useless Via Removal Solver"};for(let e=0;e<this.routeSections.length;e++){const n=this.routeSections[e];t.lines.push({points:n.points,strokeWidth:this.TRACE_THICKNESS,strokeColor:e===this.currentSectionIndex?"orange":0===n.z?"red":"blue"})}return t}},dl=(t,e=2)=>{const n=Array.from({length:e},(t,e)=>e);return t.map(t=>{const s=t.zLayers??t.layers?.map(t=>Rn(t,e))??n,o=Array.from(new Set(s.filter(t=>t>=0&&t<e)));return{...t,zLayers:o.length>0?o:n}})},ul=class extends Ln{constructor(t){super(),this.input=t,this.input={...t,obstacles:dl(t.obstacles,t.layerCount)},this.MAX_ITERATIONS=1e6,this.unsimplifiedHdRoutes=t.unsimplifiedHdRoutes,this.optimizedHdRoutes=[],this.unprocessedRoutes=[...t.unsimplifiedHdRoutes],this.obstacleSHI=new sl("flatbush",this.input.obstacles),this.hdRouteSHI=new hl(this.unsimplifiedHdRoutes)}getSolverName(){return"UselessViaRemovalSolver"}unsimplifiedHdRoutes;optimizedHdRoutes;unprocessedRoutes;activeSubSolver=null;obstacleSHI=null;hdRouteSHI=null;_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.optimizedHdRoutes.push(this.activeSubSolver.getOptimizedHdRoute()),this.activeSubSolver=null):(this.activeSubSolver.failed||this.activeSubSolver.error)&&(this.error=this.activeSubSolver.error,this.failed=!0));const t=this.unprocessedRoutes.shift();t?this.activeSubSolver=new ll({hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,unsimplifiedRoute:t}):this.solved=!0}getOptimizedHdRoutes(){return this.optimizedHdRoutes}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Useless Via Removal Solver"};for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.optimizedHdRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888";for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:0===s.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${s.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const s=Zh(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...s.rects??[]),t.lines.push(...s.lines??[])}}return this.activeSubSolver&&t.lines.push(...this.activeSubSolver.visualize().lines??[]),t}},pl=class extends Ln{getSolverName(){return"SingleSimplifiedPathSolver"}newRoute;newVias;headIndex=0;tailIndex=0;inputRoute;otherHdRoutes;obstacles;connMap;colorMap;outline;constructor(t){super(),this.inputRoute=t.inputRoute,this.otherHdRoutes=t.otherHdRoutes,this.obstacles=t.obstacles,this.connMap=t.connMap,this.colorMap=t.colorMap,this.outline=t.outline,this.newRoute=[this.inputRoute.route[0]],this.newVias=[]}getConstructorParams(){return{inputRoute:this.inputRoute,otherHdRoutes:this.otherHdRoutes,obstacles:this.obstacles,connMap:this.connMap.netMap,colorMap:this.colorMap,outline:this.outline}}get simplifiedRoute(){return{connectionName:this.inputRoute.connectionName,rootConnectionName:this.inputRoute.rootConnectionName,traceThickness:this.inputRoute.traceThickness,viaDiameter:this.inputRoute.viaDiameter,route:this.newRoute,vias:this.newVias,jumpers:this.inputRoute.jumpers}}isValidPath(t){throw new Error("Not implemented")}_step(){throw new Error("Not implemented")}getVisualsForNewRouteAndObstacles(){const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:"Simplified Path Solver"};for(let e=0;e<this.inputRoute.route.length-1;e++)t.lines.push({points:[{x:this.inputRoute.route[e].x,y:this.inputRoute.route[e].y},{x:this.inputRoute.route[e+1].x,y:this.inputRoute.route[e+1].y}],strokeColor:"rgba(255, 0, 0, 0.8)",strokeDash:1===this.inputRoute.route[e].z?"5, 5":void 0,layer:`z${this.inputRoute.route[e].z.toString()}`});for(let e=0;e<this.newRoute.length;e++)e<this.newRoute.length-1&&t.lines.push({points:[{x:this.newRoute[e].x,y:this.newRoute[e].y},{x:this.newRoute[e+1].x,y:this.newRoute[e+1].y}],strokeWidth:.15,strokeColor:"rgba(0, 255, 0, 0.8)",strokeDash:1===this.newRoute[e].z?[.4,.4]:void 0,layer:`z${this.newRoute[e].z.toString()}`}),t.points.push({x:this.newRoute[e].x,y:this.newRoute[e].y,color:"rgba(0, 255, 0, 0.8)",label:`z: ${this.newRoute[e].z}`,layer:`z${this.newRoute[e].z.toString()}`});for(const e of this.newVias)t.circles.push({center:e,radius:this.inputRoute.viaDiameter/2,fill:"rgba(0, 0, 255, 0.5)"});for(const e of this.obstacles)t.rects.push({center:e.center,width:e.width,height:e.height,fill:e.layers?.includes("top")?"rgba(255, 0, 0, 0.3)":e.layers?.includes("bottom")?"rgba(0, 0, 255, 0.3)":"rgba(128, 128, 128, 0.3)"});for(const e of this.otherHdRoutes)for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeWidth:.15,strokeColor:0===e.route[n].z?"rgba(255, 0, 255, 0.5)":1===e.route[n].z?"rgba(128, 0, 128, 0.5)":"rgba(0, 0, 255, 0.5)",layer:`z${e.route[n].z.toString()}`});if("filteredObstaclePathSegments"in this){const e=this.filteredObstaclePathSegments;for(const[n,s]of e)t.lines.push({points:[n,s]})}return t}};function fl(t,e,n,s){if(L(t,e,n,s))return 0;const o=ml(t,n,s),i=ml(e,n,s),r=ml(n,t,e),a=ml(s,t,e);return Math.min(o,i,r,a)}function ml(t,e,n){const s={x:n.x-e.x,y:n.y-e.y},o=gl({x:t.x-e.x,y:t.y-e.y},s);if(o<=0)return yl(t,e);const i=gl(s,s);if(i<=o)return yl(t,n);const r=o/i;return yl(t,{x:e.x+r*s.x,y:e.y+r*s.y})}function gl(t,e){return t.x*e.x+t.y*e.y}function yl(t,e){const n=e.x-t.x,s=e.y-t.y;return Math.sqrt(n*n+s*s)}var xl=t=>({minX:Math.min(t[0].x,t[1].x),maxX:Math.max(t[0].x,t[1].x),minY:Math.min(t[0].y,t[1].y),maxY:Math.max(t[0].y,t[1].y)}),vl=class{constructor(t){this.segments=t,this.buckets=new Map;const e=new Map;for(const n of t){const t=this.getSegmentKey(n);if(e.has(t))continue;e.set(t,n);const s=xl(n),o=Math.floor(s.minX/this.CELL_SIZE),i=Math.floor(s.maxX/this.CELL_SIZE),r=Math.floor(s.minY/this.CELL_SIZE),a=Math.floor(s.maxY/this.CELL_SIZE);for(let e=o;e<=i;e++)for(let s=r;s<=a;s++){const o=`${e}x${s}`,i=this.buckets.get(o),r=[n[0],n[1],t];i?i.push(r):this.buckets.set(o,[r])}}}buckets;CELL_SIZE=.4;SEGMENT_MARGIN=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getSegmentKey(t){return`${t[0].x}-${t[0].y}-${t[0].z}-${t[1].x}-${t[1].y}-${t[1].z}`}getSegmentsThatCouldIntersect(t,e){const n=[],s=new Set,o=Math.min(t.x,e.x)-this.SEGMENT_MARGIN,i=Math.min(t.y,e.y)-this.SEGMENT_MARGIN,r=Math.max(t.x,e.x)+this.SEGMENT_MARGIN,a=Math.max(t.y,e.y)+this.SEGMENT_MARGIN,c=Math.floor(o/this.CELL_SIZE),h=Math.floor(r/this.CELL_SIZE),l=Math.floor(i/this.CELL_SIZE),d=Math.floor(a/this.CELL_SIZE);for(let t=c;t<=h;t++)for(let e=l;e<=d;e++){const o=`${t}x${e}`,i=this.buckets.get(o);if(i)for(const t of i){const e=t[2];s.has(e)||(s.add(e),n.push(t))}}return n}},bl=1e-6,Pl=(t,e,n)=>X(t,e,n)<=bl,Sl=(t,e)=>Math.abs(t.x-e.x)<=bl&&Math.abs(t.y-e.y)<=bl,Ml=(t,e)=>{if(!e||e.length<3)return!1;for(let n=0;n<e.length;n++){const s=e[n],o=e[(n+1)%e.length];if(Pl(t,s,o))return!0}let n=!1;for(let s=0,o=e.length-1;s<e.length;o=s++){const i=e[s],r=e[o];i.y>t.y!=r.y>t.y&&t.x<(r.x-i.x)*(t.y-i.y)/(r.y-i.y)+i.x&&(n=!n)}return n},Nl=class extends pl{pathSegments=[];totalPathLength=0;headDistanceAlongPath=0;tailDistanceAlongPath=0;minStepSize=.25;lastValidPath=null;lastValidPathHeadDistance=0;STEP_SIZE_REDUCTION_FACTOR=.25;maxStepSize=4;currentStepSize=this.maxStepSize;lastHeadMoveDistance=0;cachedValidPathSegments;filteredObstacles=[];filteredObstaclePathSegments=[];filteredVias=[];filteredJumperPads=[];jumperPadPointIndices=new Set;segmentTree;OBSTACLE_MARGIN=.1;TRACE_THICKNESS=.15;TAIL_JUMP_RATIO=.8;constructor(t){if(super(t),this.cachedValidPathSegments=new Set,this.inputRoute.route.length<=1)return this.newRoute=[...this.inputRoute.route],void(this.solved=!0);const e=this.inputRoute.route.reduce((t,e)=>(t.minX=Math.min(t.minX,e.x),t.maxX=Math.max(t.maxX,e.x),t.minY=Math.min(t.minY,e.y),t.maxY=Math.max(t.maxY,e.y),t),{minX:1/0,maxX:-1/0,minY:1/0,maxY:-1/0}),n={center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY};this.filteredObstacles=this.obstacles.filter(t=>!t.connectedTo.some(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t))).filter(t=>{if(t.connectedTo.some(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t)))return!1;return function(t,e){const n=z(t),s=z(e),o=Math.max(n.minX-s.maxX,s.minX-n.maxX,0),i=Math.max(n.minY-s.maxY,s.minY-n.maxY,0);return Math.hypot(o,i)}(n,t)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2}),this.filteredObstaclePathSegments=this.otherHdRoutes.flatMap(t=>{if(this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName))return[];const n=t.route,s=[];for(let t=0;t<n.length-1;t++){const o=n[t],i=n[t+1],r=Math.min(o.x,i.x),a=Math.max(o.x,i.x),c=Math.min(o.y,i.y),h=Math.max(o.y,i.y);r<=e.maxX&&a>=e.minX&&c<=e.maxY&&h>=e.minY&&s.push([o,i])}return s}),this.segmentTree=new vl(this.filteredObstaclePathSegments),this.filteredVias=this.otherHdRoutes.flatMap(t=>{if(this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName))return[];const n=t.vias,s=[];for(const o of n){const n=this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2+t.viaDiameter/2,i=o.x-n,r=o.x+n,a=o.y-n,c=o.y+n;i<=e.maxX&&r>=e.minX&&a<=e.maxY&&c>=e.minY&&s.push({...o,diameter:t.viaDiameter})}return s});const s=(t,n)=>{const s=[];for(const o of t){const t=wn[o.footprint]??wn["0603"],i=o.end.x-o.start.x,r=o.end.y-o.start.y,a=Math.abs(i)>Math.abs(r),c=a?t.padLength:t.padWidth,h=a?t.padWidth:t.padLength,l=this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2;o.start.x-c/2-l<=e.maxX&&o.start.x+c/2+l>=e.minX&&o.start.y-h/2-l<=e.maxY&&o.start.y+h/2+l>=e.minY&&s.push({center:o.start,width:c,height:h,connectionName:n}),o.end.x-c/2-l<=e.maxX&&o.end.x+c/2+l>=e.minX&&o.end.y-h/2-l<=e.maxY&&o.end.y+h/2+l>=e.minY&&s.push({center:o.end,width:c,height:h,connectionName:n})}return s};if(this.filteredJumperPads=this.otherHdRoutes.flatMap(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName)?[]:s(t.jumpers??[],t.connectionName)),this.inputRoute.jumpers&&this.inputRoute.jumpers.length>0){this.filteredJumperPads.push(...s(this.inputRoute.jumpers,this.inputRoute.connectionName));for(const t of this.inputRoute.jumpers)for(let e=0;e<this.inputRoute.route.length;e++){const n=this.inputRoute.route[e];(Math.abs(n.x-t.start.x)<.01&&Math.abs(n.y-t.start.y)<.01||Math.abs(n.x-t.end.x)<.01&&Math.abs(n.y-t.end.y)<.01)&&this.jumperPadPointIndices.add(e)}}this.computePathSegments()}computePathSegments(){let t=0;for(let e=0;e<this.inputRoute.route.length-1;e++){const n=this.inputRoute.route[e],s=this.inputRoute.route[e+1],o=Math.sqrt((s.x-n.x)**2+(s.y-n.y)**2)+e/1e4;this.pathSegments.push({start:n,end:s,length:o,startDistance:t,endDistance:t+o}),t+=o}this.totalPathLength=t}arePointsEqual(t,e){return t.x===e.x&&t.y===e.y&&t.z===e.z}getPointAtDistance(t){t=Math.max(0,Math.min(t,this.totalPathLength));const e=this.pathSegments.find(e=>t>=e.startDistance&&t<=e.endDistance);if(!e)return this.inputRoute.route[this.inputRoute.route.length-1];const n=(t-e.startDistance)/e.length;return{x:e.start.x+n*(e.end.x-e.start.x),y:e.start.y+n*(e.end.y-e.start.y),z:n<.5?e.start.z:e.end.z}}getNearestIndexForDistance(t){if(t<=0)return 0;if(t>=this.totalPathLength)return this.inputRoute.route.length-1;const e=this.pathSegments.findIndex(e=>t>=e.startDistance&&t<=e.endDistance);if(-1===e)return 0;const n=this.pathSegments[e],s=(n.startDistance+n.endDistance)/2;return t>s?e+1:e}isValidPathSegment(t,e){for(const n of this.filteredObstacles){if(!n.zLayers?.includes(t.z))continue;if(Q(t,e,n)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2)return!1}const n=this.segmentTree.getSegmentsThatCouldIntersect(t,e);for(const[s,o,i]of n)if(s.z===t.z&&o.z===t.z){if(fl({x:t.x,y:t.y},{x:e.x,y:e.y},{x:s.x,y:s.y},{x:o.x,y:o.y})<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS)return!1}for(const n of this.filteredVias)if(X(n,t,e)<this.OBSTACLE_MARGIN+n.diameter/2+this.TRACE_THICKNESS/2)return!1;for(const n of this.filteredJumperPads){if(Q(t,e,n)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2)return!1}if(this.outline&&this.outline.length>=3){const n=(({start:t,end:e,polygon:n,margin:s=.2})=>{if(!n||n.length<3)return!1;const o=Ml(t,n),i=Ml(e,n);if(!o||!i)return!0;for(let o=0;o<n.length;o++){const i=n[o],r=n[(o+1)%n.length],a=Pl(t,i,r),c=Pl(e,i,r);if(a&&c)continue;if(!L(t,e,i,r)){if(!a&&!c&&fl(t,e,i,r)<s-bl)return!0;continue}const h=$(t,e,i,r);if(!(h&&(a&&Sl(h,t)||c&&Sl(h,e))||h&&(Sl(h,t)||Sl(h,e))))return!0}return!1})({start:{x:t.x,y:t.y},end:{x:e.x,y:e.y},polygon:this.outline});if(n)return!1}return!0}isValidPath(t){if(t.length<2)return!0;for(let e=0;e<t.length-1;e++)if(t[e].z!==t[e+1].z)return!1;for(let e=0;e<t.length-1;e++)if(!this.isValidPathSegment(t[e],t[e+1]))return!1;return!0}find45DegreePath(t,e){if(this.arePointsEqual(t,e))return[t];if(t.z!==e.z)return null;const n=((t,e)=>{const n=[],s=Math.abs(e.x-t.x),o=Math.abs(e.y-t.y),i=e.x>t.x?1:-1,r=e.y>t.y?1:-1,a={x:e.x-i*Math.abs(e.y-t.y),y:t.y};(a.x-t.x)*i>=0&&(a.x-e.x)*i<=0&&n.push([t,a,e]);const c={x:t.x,y:e.y-r*Math.abs(e.x-t.x)};(c.y-t.y)*r>=0&&(c.y-e.y)*r<=0&&n.push([t,c,e]);const h=Math.min(s,o),l={x:t.x+i*h,y:t.y+r*h};return(l.x-t.x)*i>=0&&(l.x-e.x)*i<=0&&(l.y-t.y)*r>=0&&(l.y-e.y)*r<=0&&n.push([t,l,e]),n})({x:t.x,y:t.y},{x:e.x,y:e.y});for(const e of n){const n=e.map(e=>({x:e.x,y:e.y,z:t.z}));if(this.isValidPath(n))return n}return null}addPathToResult(t){if(0!==t.length){for(let e=0;e<t.length;e++)0===e&&this.newRoute.length>0&&this.arePointsEqual(this.newRoute[this.newRoute.length-1],t[e])||this.newRoute.push(t[e]);this.currentStepSize=this.maxStepSize}}moveHead(t){this.lastHeadMoveDistance=t,this.headDistanceAlongPath=Math.min(this.headDistanceAlongPath+t,this.totalPathLength)}stepBackAndReduceStepSize(){this.headDistanceAlongPath=Math.max(this.tailDistanceAlongPath,this.headDistanceAlongPath-this.lastHeadMoveDistance),this.currentStepSize=Math.max(this.minStepSize,this.currentStepSize*this.STEP_SIZE_REDUCTION_FACTOR)}_step(){const t=this.tailDistanceAlongPath>=this.totalPathLength,e=this.headDistanceAlongPath>=this.totalPathLength;if(t){const t=this.inputRoute.route[this.inputRoute.route.length-1];return 0!==this.newRoute.length&&this.arePointsEqual(this.newRoute[this.newRoute.length-1],t)||this.newRoute.push(t),void(this.solved=!0)}if(e){const t=this.getPointAtDistance(this.tailDistanceAlongPath),e=this.inputRoute.route[this.inputRoute.route.length-1],n=this.find45DegreePath(t,e);if(n)return this.addPathToResult(n),void(this.solved=!0);this.lastValidPath=null,this.tailDistanceAlongPath=this.totalPathLength,this.headDistanceAlongPath=this.totalPathLength;const s=[];for(const t of this.inputRoute.route)0!==s.length&&this.arePointsEqual(s[s.length-1],t)||s.push(t);return this.newRoute=s,this.newVias=[...this.inputRoute.vias],void(this.solved=!0)}this.moveHead(this.currentStepSize);const n=this.getPointAtDistance(this.tailDistanceAlongPath),s=this.getPointAtDistance(this.headDistanceAlongPath),o=this.getNearestIndexForDistance(this.tailDistanceAlongPath),i=this.getNearestIndexForDistance(this.headDistanceAlongPath);let r=!1,a=-1;for(let t=o;t<i;t++)if(t+1<this.inputRoute.route.length&&this.inputRoute.route[t].z!==this.inputRoute.route[t+1].z){r=!0;const e=t;a=this.pathSegments[e].startDistance;break}if(r&&this.lastHeadMoveDistance>this.minStepSize)return void this.stepBackAndReduceStepSize();let c=!1,h=-1,l=-1;for(let t=o+1;t<=i;t++)if(this.jumperPadPointIndices.has(t)){c=!0,h=t,l=t>0&&t-1<this.pathSegments.length?this.pathSegments[t-1].endDistance:this.pathSegments[0]?.startDistance??0;break}if(c&&this.lastHeadMoveDistance>this.minStepSize)return void this.stepBackAndReduceStepSize();if(c&&h>=0){const t=this.inputRoute.route[h];this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null);const e=this.newRoute[this.newRoute.length-1];return e&&e.x===t.x&&e.y===t.y||this.newRoute.push({x:t.x,y:t.y,z:t.z}),this.currentStepSize=this.maxStepSize,this.tailDistanceAlongPath=l,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,void(this.lastValidPathHeadDistance=this.tailDistanceAlongPath)}if(r&&a>0){const t=this.getNearestIndexForDistance(a)+1,e=this.inputRoute.route[t],n={x:e.x,y:e.y};this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null);const s=this.newRoute[this.newRoute.length-1];s.x===n.x&&s.y===n.y||this.newRoute.push({x:n.x,y:n.y,z:s.z}),this.newVias.push(n),this.newRoute.push({x:n.x,y:n.y,z:e.z}),this.currentStepSize=this.maxStepSize;const o=this.pathSegments.findIndex(t=>t.start===e);if(-1!==o)this.tailDistanceAlongPath=this.pathSegments[o].startDistance,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,this.lastValidPathHeadDistance=this.tailDistanceAlongPath;else if(t<this.inputRoute.route.length){if(t===this.inputRoute.route.length-1)return void(this.solved=!0);console.warn("Fallback used for tailDistanceAlongPath after layer change");const e=this.pathSegments.find(e=>e.start===this.inputRoute.route[t]);e?(this.tailDistanceAlongPath=e.startDistance,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,this.lastValidPathHeadDistance=this.tailDistanceAlongPath):(console.error(`[${this.inputRoute.connectionName}] Could not find segment start after layer change. Path might be incomplete.\n Index sought: ${t}, Point: (${this.inputRoute.route[t].x.toFixed(3)}, ${this.inputRoute.route[t].y.toFixed(3)}, z=${this.inputRoute.route[t].z})\n Route Length: ${this.inputRoute.route.length}, Path Segments: ${this.pathSegments.length}`),this.solved=!0)}else console.warn("Layer change occurred at the end of the path."),this.solved=!0;return}const d=this.find45DegreePath(n,s);if(!d&&this.lastHeadMoveDistance>this.minStepSize)this.stepBackAndReduceStepSize();else{if(!d&&!this.lastValidPath){const t=this.getPointAtDistance(this.tailDistanceAlongPath);this.tailDistanceAlongPath+=this.minStepSize,this.moveHead(this.minStepSize);const e=this.getNearestIndexForDistance(this.tailDistanceAlongPath),n=this.inputRoute.route[e],s=this.inputRoute.route[this.inputRoute.route.length-1];return void(this.arePointsEqual(t,n)||this.arePointsEqual(n,s)||this.newRoute.push(n))}if(d)return this.lastValidPath=d,void(this.lastValidPathHeadDistance=this.headDistanceAlongPath);this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null,this.tailDistanceAlongPath=this.lastValidPathHeadDistance,this.moveHead(this.minStepSize))}}visualize(){const t=this.getVisualsForNewRouteAndObstacles(),e=this.getPointAtDistance(this.tailDistanceAlongPath),n=this.getPointAtDistance(this.headDistanceAlongPath);t.points.push({x:e.x,y:e.y,color:"yellow",label:["Tail",`z: ${e.z}`].join("\n")}),t.points.push({x:n.x,y:n.y,color:"orange",label:["Head",`z: ${n.z}`].join("\n")});const s=this.getPointAtDistance(this.headDistanceAlongPath+this.currentStepSize);t.points.push({x:s.x,y:s.y,color:"red",label:["Tentative Head",`z: ${s.z}`].join("\n")});let o=0;for(;o<this.totalPathLength;){const e=this.getPointAtDistance(o);t.circles.push({center:{x:e.x,y:e.y},radius:.05,fill:"rgba(100, 100, 100, 0.5)"}),o+=this.totalPathLength/20}if(this.lastValidPath&&this.lastValidPath.length>1)for(let e=0;e<this.lastValidPath.length-1;e++)t.lines.push({points:[{x:this.lastValidPath[e].x,y:this.lastValidPath[e].y},{x:this.lastValidPath[e+1].x,y:this.lastValidPath[e+1].y}],strokeColor:"rgba(0, 255, 255, 0.9)",strokeDash:"3, 3"});return t}},Il=class extends Ln{getSolverName(){return"MultiSimplifiedPathSolver"}simplifiedHdRoutes;currentUnsimplifiedHdRouteIndex=0;activeSubSolver=null;unsimplifiedHdRoutes;obstacles;connMap;colorMap;outline;defaultViaDiameter;constructor(t){super(),this.MAX_ITERATIONS=1e8,this.unsimplifiedHdRoutes=t.unsimplifiedHdRoutes;const e=Math.max(2,...t.unsimplifiedHdRoutes.flatMap(t=>t.route.map(t=>t.z+1)))||2;this.obstacles=dl(t.obstacles,e),this.connMap=t.connMap||new An({}),this.colorMap=t.colorMap||{},this.outline=t.outline,this.defaultViaDiameter=t.defaultViaDiameter??.3,this.simplifiedHdRoutes=[]}_step(){const t=this.unsimplifiedHdRoutes[this.currentUnsimplifiedHdRouteIndex];if(!this.activeSubSolver)return t?(this.activeSubSolver=new Nl({inputRoute:t,otherHdRoutes:this.unsimplifiedHdRoutes.slice(this.currentUnsimplifiedHdRouteIndex+1).concat(this.simplifiedHdRoutes),obstacles:this.obstacles,connMap:this.connMap,colorMap:this.colorMap,outline:this.outline}),void this.currentUnsimplifiedHdRouteIndex++):void(this.solved=!0);this.activeSubSolver.step(),this.activeSubSolver.solved&&(this.simplifiedHdRoutes.push(this.activeSubSolver.simplifiedRoute),this.activeSubSolver=null)}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:"Multi Simplified Path Solver"};for(const e of this.unsimplifiedHdRoutes)if(!this.simplifiedHdRoutes.some(t=>t.connectionName===e.connectionName)){for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeColor:1===e.route[n].z?"rgba(0, 0, 255, 0.4)":"rgba(255, 0, 0, 0.4)",strokeWidth:.15,strokeDash:1===e.route[n].z?[.5,.5]:void 0});for(const n of e.vias||[])t.circles.push({center:n,radius:(e.viaDiameter??this.defaultViaDiameter)/2,fill:"rgba(0, 0, 255, 0.4)"})}for(const e of this.simplifiedHdRoutes){const n=this.colorMap?.[e.connectionName]||"rgba(128, 128, 128, 0.8)";for(let s=0;s<e.route.length-1;s++)t.lines.push({points:[{x:e.route[s].x,y:e.route[s].y},{x:e.route[s+1].x,y:e.route[s+1].y}],strokeWidth:.15,strokeColor:n,strokeDash:1===e.route[s].z?[.5,.5]:void 0,step:1});for(const n of e.vias||[])t.circles.push({center:n,radius:e.viaDiameter/2,fill:"rgba(0, 0, 255, 0.5)",step:1})}for(const e of this.unsimplifiedHdRoutes){for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeWidth:.15,strokeColor:"rgba(255, 0, 0, 0.2)",strokeDash:[.5,.5],step:0,layer:`z${e.route[n].z.toString()}`});for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 0, 0.2)",step:0})}for(const e of this.obstacles)t.rects.push({center:e.center,width:e.width,height:e.height,fill:e.layers?.includes("top")?"rgba(255, 0, 0, 0.3)":e.layers?.includes("bottom")?"rgba(0, 0, 255, 0.3)":"rgba(128, 128, 128, 0.3)"});if(this.currentUnsimplifiedHdRouteIndex<this.unsimplifiedHdRoutes.length){const e=this.unsimplifiedHdRoutes[this.currentUnsimplifiedHdRouteIndex];e.route.length>0&&t.circles.push({center:{x:e.route[0].x,y:e.route[0].y},radius:.2,fill:"yellow",label:"Current"})}return t}},_l=class extends Ln{constructor(t){super(),this.input=t,this.input={...t,obstacles:dl(t.obstacles,t.layerCount)},this.MAX_ITERATIONS=1e6,this.inputHdRoutes=this.input.inputHdRoutes,this.mergedViaHdRoutes=structuredClone(this.inputHdRoutes),this.unprocessedRoutes=[...this.input.inputHdRoutes],this.colorMap=this.input.colorMap,this.outline=this.input.outline,this.obstacles=this.input.obstacles,this.obstacleSHI=new sl("flatbush",this.input.obstacles),this.hdRouteSHI=new hl(this.inputHdRoutes),this.vias=[],this.offendingVias=[],this.connMap=t.connMap,this.viasByNet=new Map,this.rebuildVias()}getSolverName(){return"SameNetViaMergerSolver"}inputHdRoutes;mergedViaHdRoutes;unprocessedRoutes;vias;offendingVias;currentViaRoutes=[];connMap;colorMap;outline;obstacles;viasByNet;obstacleSHI=null;hdRouteSHI=null;rebuildVias(){this.vias=[],this.viasByNet=new Map;for(let t=0;t<this.mergedViaHdRoutes.length;t++){const e=this.mergedViaHdRoutes[t];for(let n=0;n<e.vias.length;n++){const s=e.vias[n],o={x:s.x,y:s.y,diameter:e.viaDiameter,net:this.connMap?.idToNetMap[e.connectionName]??"",layers:[...new Set(e.route.map(t=>t.z))],routeIndex:t};this.vias.push(o);const i=this.viasByNet.get(o.net);i?i.push(o):this.viasByNet.set(o.net,[o])}}}findNextOffendingPair(){for(let t=0;t<this.vias.length-1;t++){const e=this.vias[t],n=this.viasByNet.get(e.net);if(!n)continue;const s=n.indexOf(e);for(let t=s>=0?s+1:0;t<n.length;t++){const s=n[t],o=e.x-s.x,i=e.y-s.y,r=o*o+i*i,a=e.diameter/2+s.diameter/2;if(r<=a*a&&0!==r)return[e,s]}}return null}handleOffendingPair(t,e){const n=t.layers.length<e.layers.length?t:e,s=n===t?e:t,o=this.mergedViaHdRoutes[n.routeIndex].route;for(let t=0;t<n.layers.length;t++)for(let t=o.length-1;t>=1;t--){const e=o[t-1],i=o[t];if(i.x===n.x&&i.y===n.y){o.splice(t,0,{x:s.x,y:s.y,z:i.z}),o.splice(t,0,{x:s.x,y:s.y,z:e.z});const r=this.mergedViaHdRoutes[n.routeIndex];return r.vias=r.vias.map(t=>t.x===n.x&&t.y===n.y?{x:s.x,y:s.y}:t),void this.rebuildVias()}}this.rebuildVias()}_step(){const t=this.findNextOffendingPair();t?this.handleOffendingPair(t[0],t[1]):this.solved=!0}getMergedViaHdRoutes(){return this.mergedViaHdRoutes}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Same Net Via Merger Solver"};for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.mergedViaHdRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888";for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:0===s.z?"rgba(255, 0, 0, 0.5)":"rgba(0, 0, 255, 0.5)",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${s.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const s=Zh(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...s.rects??[]),t.lines.push(...s.lines??[])}}return this.activeSubSolver&&t.lines.push(...this.activeSubSolver.visualize().lines??[]),t}},Cl=class extends Ln{constructor(t){super(),this.simplificationConfig=t,this.simplificationConfig={...t,obstacles:dl(t.obstacles,t.layerCount)},this.hdRoutes=[...t.hdRoutes],this.MAX_ITERATIONS=1e8}getSolverName(){return"TraceSimplificationSolver"}hdRoutes=[];simplificationPipelineLoops=0;MAX_SIMPLIFICATION_PIPELINE_LOOPS=2;PHASE_ORDER=["via_removal","via_merging","path_simplification"];currentPhase="via_removal";extractResult=null;get simplifiedHdRoutes(){return this.hdRoutes}_step(){if(this.simplificationPipelineLoops>=this.MAX_SIMPLIFICATION_PIPELINE_LOOPS)this.solved=!0;else{if(this.activeSubSolver){if(this.activeSubSolver.step(),!this.activeSubSolver.failed&&!this.activeSubSolver.solved)return;if(this.activeSubSolver.solved){if(this.extractResult&&(this.hdRoutes=this.extractResult(this.activeSubSolver)),this.activeSubSolver=null,this.extractResult=null,"via_removal"===this.currentPhase?this.currentPhase="via_merging":"via_merging"===this.currentPhase?this.currentPhase="path_simplification":(this.currentPhase="via_removal",this.simplificationPipelineLoops++),this.simplificationPipelineLoops>=this.MAX_SIMPLIFICATION_PIPELINE_LOOPS)return void(this.solved=!0)}else if(this.activeSubSolver.failed)return this.failed=!0,void(this.error=this.activeSubSolver.error??"Sub-solver failed without error message")}if(!this.activeSubSolver&&!this.solved)switch(this.currentPhase){case"via_removal":this.activeSubSolver=new ul({unsimplifiedHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],colorMap:{...this.simplificationConfig.colorMap},layerCount:this.simplificationConfig.layerCount}),this.extractResult=t=>t.getOptimizedHdRoutes()??[];break;case"via_merging":this.activeSubSolver=new _l({inputHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],colorMap:{...this.simplificationConfig.colorMap},layerCount:this.simplificationConfig.layerCount,connMap:this.simplificationConfig.connMap,outline:this.simplificationConfig.outline?[...this.simplificationConfig.outline]:void 0}),this.extractResult=t=>t.getMergedViaHdRoutes()??[];break;case"path_simplification":this.activeSubSolver=new Il({unsimplifiedHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],connMap:this.simplificationConfig.connMap,colorMap:{...this.simplificationConfig.colorMap},outline:this.simplificationConfig.outline?[...this.simplificationConfig.outline]:void 0,defaultViaDiameter:this.simplificationConfig.defaultViaDiameter}),this.extractResult=t=>t.simplifiedHdRoutes;break;default:this.failed=!0,this.error=`Unknown phase: ${this.currentPhase}`}}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Trace Simplification Solver"};for(const e of this.simplificationConfig.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.hdRoutes)if(0!==e.route.length){for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:0===s.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${s.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const n=Zh(e.jumpers,{color:"orange",label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}return t}},Tl=class extends Ln{getSolverName(){return"TraceWidthSolver"}hdRoutes;hdRoutesWithWidths=[];nominalTraceWidth;minTraceWidth;obstacleMargin;TRACE_WIDTH_SCHEDULE;connectionNominalTraceWidthMap;unprocessedRoutes=[];processedRoutes=[];currentTrace=null;cursorPosition=null;currentTraceSegmentIndex=0;currentTraceSegmentT=0;currentScheduleIndex=0;currentTargetWidth=0;hasInsufficientClearance=!1;lastCollidingObstacles=[];lastCollidingRoutes=[];lastClearance=1/0;obstacles=[];obstacleSHI;hdRouteSHI;connMap;colorMap;constructor(t){super(),this.MAX_ITERATIONS=1e6,this.hdRoutes=[...t.hdRoutes],this.minTraceWidth=t.minTraceWidth,this.obstacleMargin=t.obstacleMargin??.15,this.nominalTraceWidth=0,this.TRACE_WIDTH_SCHEDULE=[],this.unprocessedRoutes=[...this.hdRoutes],this.connMap=t.connMap,this.colorMap=t.colorMap;const e=t.layerCount;this.obstacles=dl(t.obstacles??[],e),this.connectionNominalTraceWidthMap=new Map;for(const e of t.connection)void 0!==e.nominalTraceWidth&&this.connectionNominalTraceWidthMap.set(e.name,e.nominalTraceWidth);this.obstacles.length>0&&(this.obstacleSHI=new sl("flatbush",this.obstacles)),this.hdRouteSHI=new hl(this.hdRoutes)}getNominalTraceWidthForRoute(t){const e=this.connectionNominalTraceWidthMap.get(t.connectionName);return void 0!==e?e:t.rootConnectionName?this.connectionNominalTraceWidthMap.get(t.rootConnectionName):void 0}_step(){if(!this.currentTrace){const t=this.unprocessedRoutes.shift();if(!t)return this.hdRoutesWithWidths=this.processedRoutes,void(this.solved=!0);const e=this.getNominalTraceWidthForRoute(t);if(void 0===e)return this.processedRoutes.push({...t}),void(this.currentTrace=null);this.currentTrace=t,this.nominalTraceWidth=e;const n=(this.nominalTraceWidth+this.minTraceWidth)/2;return this.TRACE_WIDTH_SCHEDULE=[this.nominalTraceWidth,n],this.currentTrace.route.length<2?(this.processedRoutes.push({...this.currentTrace,traceThickness:this.minTraceWidth}),void(this.currentTrace=null)):(this.currentScheduleIndex=0,this.currentTargetWidth=this.TRACE_WIDTH_SCHEDULE[0],void this.initializeCursor())}if(!this.stepCursorForward())return void this.finalizeCurrentTrace(this.currentTargetWidth);this.getClearanceAtPosition(this.cursorPosition)<this.currentTargetWidth/2+this.obstacleMargin&&(this.hasInsufficientClearance=!0,this.currentScheduleIndex++,this.currentScheduleIndex<this.TRACE_WIDTH_SCHEDULE.length?(this.currentTargetWidth=this.TRACE_WIDTH_SCHEDULE[this.currentScheduleIndex],this.initializeCursor()):this.finalizeCurrentTrace(this.minTraceWidth))}initializeCursor(){if(!this.currentTrace)return;const t=this.currentTrace.route[0];this.cursorPosition={...t},this.currentTraceSegmentIndex=0,this.currentTraceSegmentT=0,this.hasInsufficientClearance=!1}stepCursorForward(){if(!this.currentTrace||!this.cursorPosition)return!1;const t=this.currentTrace.route;let e=.1;for(;e>0;){if(this.currentTraceSegmentIndex>=t.length-1)return!1;const n=t[this.currentTraceSegmentIndex],s=t[this.currentTraceSegmentIndex+1];if(n.insideJumperPad&&s.insideJumperPad){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const o=s.x-n.x,i=s.y-n.y,r=Math.sqrt(o*o+i*i);if(0===r){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const a=this.currentTraceSegmentT*r,c=r-a;if(e<=c){const t=a+e;return this.currentTraceSegmentT=t/r,this.cursorPosition={x:n.x+o*this.currentTraceSegmentT,y:n.y+i*this.currentTraceSegmentT,z:n.z},!0}if(e-=c,this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,this.currentTraceSegmentIndex>=t.length-1){const e=t[t.length-1];return this.cursorPosition={...e},!1}}return!0}isObstacleOwnJumperPad(t){if(!this.currentTrace?.jumpers)return!1;for(const e of this.currentTrace.jumpers){const n=Math.sqrt((t.center.x-e.start.x)**2+(t.center.y-e.start.y)**2),s=Math.sqrt((t.center.x-e.end.x)**2+(t.center.y-e.end.y)**2),o=Math.max(t.width,t.height)/2+.01;if(n<o||s<o)return!0}return!1}getClearanceAtPosition(t){if(!this.currentTrace)return 1/0;const e=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,n=2*this.nominalTraceWidth;let s=1/0;if(this.lastCollidingObstacles=[],this.lastCollidingRoutes=[],this.obstacleSHI){const o=this.obstacleSHI.searchArea(t.x,t.y,n,n);for(const n of o){if(n.zLayers&&!n.zLayers.includes(t.z))continue;if(n.connectedTo.includes(e))continue;if(n.obstacleId&&this.connMap?.areIdsConnected(e,n.obstacleId))continue;let o=!1;if(this.connMap)for(const t of n.connectedTo)if(this.connMap.areIdsConnected(e,t)){o=!0;break}if(o)continue;if(this.isObstacleOwnJumperPad(n))continue;const i=n.center.x-n.width/2,r=n.center.x+n.width/2,a=n.center.y-n.height/2,c=n.center.y+n.height/2,h=Math.max(i-t.x,0,t.x-r),l=Math.max(a-t.y,0,t.y-c),d=Math.sqrt(h*h+l*l);d<this.currentTargetWidth/2+this.obstacleMargin&&this.lastCollidingObstacles.push(n),d<s&&(s=d)}}const o=this.hdRouteSHI.getConflictingRoutesNearPoint({x:t.x,y:t.y,z:t.z},n);for(const{conflictingRoute:t,distance:n}of o){const o=t.rootConnectionName??t.connectionName;if(o===e)continue;if(this.connMap?.areIdsConnected(e,o))continue;const i=n-(t.traceThickness??.15)/2;i<this.currentTargetWidth/2+this.obstacleMargin&&this.lastCollidingRoutes.push(t),i<s&&(s=i)}return this.lastClearance=s,s}finalizeCurrentTrace(t){if(!this.currentTrace)return;const e={connectionName:this.currentTrace.connectionName,rootConnectionName:this.currentTrace.rootConnectionName,traceThickness:t,viaDiameter:this.currentTrace.viaDiameter,route:[...this.currentTrace.route],vias:[...this.currentTrace.vias],jumpers:this.currentTrace.jumpers};this.processedRoutes.push(e),this.currentTrace=null,this.cursorPosition=null,this.hasInsufficientClearance=!1}visualize(){const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:`Trace Width Solver (schedule: [${this.TRACE_WIDTH_SCHEDULE.map(t=>t.toFixed(2)).join(", ")}]mm, fallback: ${this.minTraceWidth.toFixed(2)}mm, margin: ${this.obstacleMargin.toFixed(2)}mm)`},e=new Set(this.lastCollidingObstacles.map(t=>t.obstacleId)),n=new Set(this.lastCollidingRoutes.map(t=>t.connectionName));for(const n of this.obstacles){const s=e.has(n.obstacleId),o=n.zLayers?.includes(0),i=n.zLayers?.includes(1);let r;r=s?"rgba(255, 0, 0, 0.6)":o&&i?"rgba(128, 0, 128, 0.15)":o?"rgba(255, 0, 0, 0.15)":i?"rgba(0, 0, 255, 0.15)":"rgba(128, 128, 128, 0.15)",t.rects.push({center:n.center,width:n.width,height:n.height,fill:r,stroke:s?"red":void 0,label:s?`COLLIDING: ${n.obstacleId??"obstacle"}`:`${n.obstacleId??"obstacle"} (Z: ${n.zLayers?.join(", ")})`})}for(const e of this.processedRoutes){if(0===e.route.length)continue;const n=e.traceThickness===this.nominalTraceWidth,s=e.traceThickness===this.TRACE_WIDTH_SCHEDULE[1],o=n?"green":s?"yellow":"orange";for(let n=0;n<e.route.length-1;n++){const s=e.route[n],i=e.route[n+1];s.insideJumperPad&&i.insideJumperPad||s.z===i.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:i.x,y:i.y}],strokeColor:o,strokeWidth:e.traceThickness,label:`${e.connectionName} (w=${e.traceThickness.toFixed(2)})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const n=Zh(e.jumpers,{color:o,label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}if(this.currentTrace){for(let e=0;e<this.currentTrace.route.length-1;e++){const n=this.currentTrace.route[e],s=this.currentTrace.route[e+1];n.insideJumperPad&&s.insideJumperPad||n.z===s.z&&t.lines.push({points:[{x:n.x,y:n.y},{x:s.x,y:s.y}],strokeColor:"cyan",strokeWidth:this.currentTrace.traceThickness??this.minTraceWidth,label:`Processing: ${this.currentTrace.connectionName}`})}this.cursorPosition&&(t.circles.push({center:{x:this.cursorPosition.x,y:this.cursorPosition.y},radius:this.currentTargetWidth/2,stroke:this.hasInsufficientClearance?"red":"green",fill:"none",label:`Testing width: ${this.currentTargetWidth.toFixed(2)}mm (clearance: ${this.lastClearance.toFixed(2)}mm)`}),t.points.push({x:this.cursorPosition.x,y:this.cursorPosition.y,color:"orange",label:"Cursor"}))}for(const e of this.unprocessedRoutes){if(0===e.route.length)continue;const s=n.has(e.connectionName);for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];o.z===i.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:s?"rgba(255, 0, 0, 0.8)":"rgba(128, 128, 128, 0.3)",strokeWidth:e.traceThickness??this.minTraceWidth,label:s?`COLLIDING: ${e.connectionName}`:e.connectionName})}}return t}getHdRoutesWithWidths(){return this.hdRoutesWithWidths}};function El(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var wl=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=Ph(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AutoroutingPipelineSolver2_PortPointPathing"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;inputNodeWithPortPoints=[];cacheProvider=null;pipelineDef=[El("netToPointPairsSolver",Uh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),El("nodeSolver",xe,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),El("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),El("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),El("portPointPathingSolver",Dh,t=>{this.inputNodeWithPortPoints=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle}));const e=new Map(this.inputNodeWithPortPoints.map(t=>[t.capacityMeshNodeId,t])),n=t.availableSegmentPointSolver;for(const t of n.sharedEdgeSegments)for(const n of t.portPoints){const[t,s]=n.nodeIds,o={portPointId:n.segmentPortPointId,x:n.x,y:n.y,z:n.availableZ[0]??0,connectionNodeIds:[t,s],distToCentermostPortOnZ:n.distToCentermostPortOnZ},i=e.get(t);i&&i.portPoints.push(o)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:this.inputNodeWithPortPoints,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:200,hyperParameters:{NODE_PF_MAX_PENALTY:100,FORCE_OFF_BOARD_FREQUENCY:0,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:4}}]}),El("multiSectionPortPointOptimizer",Yh,t=>{const e=t.portPointPathingSolver;return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e.inputNodes,capacityMeshNodes:t.capacityNodes,capacityMeshEdges:t.capacityEdges,colorMap:t.colorMap,initialConnectionResults:e.connectionsWithResults,initialAssignedPortPoints:e.assignedPortPoints,initialNodeAssignedPortPoints:e.nodeAssignedPortPoints,effort:t.effort}]}),El("uniformPortDistributionSolver",ze,t=>[{nodeWithPortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],inputNodesWithPortPoints:this.inputNodeWithPortPoints,minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),El("highDensityRouteSolver",ph,t=>[{nodePortPoints:t.uniformPortDistributionSolver?.getOutput()??t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,effort:t.effort}]),El("highDensityStitchSolver",tl,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),El("traceSimplificationSolver",Cl,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),El("traceWidthSolver",Tl,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),l=this.uniformPortDistributionSolver?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensityStitchSolver?.visualize(),p=this.traceSimplificationSolver?.visualize(),f=this.srj.outline,m=[];if(m.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),f&&f.length>=2){const t=f.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),m.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const g={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:m},y=[g,t,e,n,s,o,i,r,a,c,h,l,d?jn(g,d):null,u,p,this.solved?jn(g,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...y)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},Rl=wl,Ol=class extends Ln{getSolverName(){return"CapacityEdgeToPortSegmentSolver"}nodes;edges;capacityPaths;nodeMap;nodeEdgeMap;unprocessedNodeIds;nodePortSegments;colorMap;constructor({nodes:t,edges:e,capacityPaths:n,colorMap:s}){super(),this.nodes=t,this.edges=e,this.nodeMap=new Map(t.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Fn(e),this.capacityPaths=n,this.colorMap=s??{},this.unprocessedNodeIds=[...new Set(n.flatMap(t=>t.nodeIds))],this.nodePortSegments=new Map}step(){const t=this.unprocessedNodeIds.pop();if(!t)return void(this.solved=!0);const e=[];for(const n of this.capacityPaths){const s=n.nodeIds.indexOf(t);-1!==s&&e.push({path:n,indexOfNodeInPath:s})}const n=this.nodeMap.get(t),s=[];for(const{path:o,indexOfNodeInPath:i}of e){const e=o.nodeIds[i-1],r=o.nodeIds[i+1];for(const i of[e,r]){const e=this.nodeMap.get(i);if(!e)continue;const r=Al(n,e),a=e.availableZ.filter(t=>n.availableZ.includes(t));if(0===a.length)continue;const c={capacityMeshNodeId:t,start:r.start,end:r.end,connectionNames:[o.connectionName],rootConnectionNames:o.rootConnectionName?[o.rootConnectionName]:void 0,availableZ:a};s.push(c)}}const o=function(t){const e=[],n=t.map(t=>({...t,connectionNames:[...t.connectionNames],rootConnectionNames:t.rootConnectionNames?[...t.rootConnectionNames]:[],availableZ:[...t.availableZ].sort((t,e)=>t-e)}));for(;n.length>0;){const t=n.pop();let s=!1;for(let n=0;n<e.length;n++){const o=e[n],i=Dl(o.start,t.start)&&Dl(o.end,t.end)||Dl(o.start,t.end)&&Dl(o.end,t.start),r=Ll(o.availableZ,t.availableZ);if(i&&r){const e=new Set(o.connectionNames);t.connectionNames.forEach(t=>e.add(t)),o.connectionNames=Array.from(e);const n=new Set(o.rootConnectionNames||[]);t.rootConnectionNames?.forEach(t=>n.add(t)),o.rootConnectionNames=Array.from(n),s=!0;break}}s||e.push(t)}return e}(s);this.nodePortSegments.set(t,o)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};return this.nodePortSegments.forEach((e,n)=>{this.nodeMap.get(n);e.forEach(e=>{e.start.x,e.end.x;for(let s=0;s<e.connectionNames.length;s++){const o={x:.05*Math.max(...e.availableZ),y:.05*Math.max(...e.availableZ)},i={x:(e.start.x+e.end.x)/2,y:(e.start.y+e.end.y)/2},r={x:i.x+o.x,y:i.y+o.y};o.x>0&&t.lines.push({points:[i,r],strokeColor:"rgba(0, 0, 0, 0.25)",strokeDash:"5 5"}),t.points.push({x:r.x,y:r.y,label:`${n}: ${e.connectionNames.join(", ")}\navailableZ: ${e.availableZ.join(",")}\nnodePortSegmentId: ${e.nodePortSegmentId}`}),t.lines.push({points:[e.start,e.end],strokeColor:In(this.colorMap[e.connectionNames[s]],.6)})}})}),t}};function Al(t,e){const n={start:Math.max(t.center.x-t.width/2,e.center.x-e.width/2),end:Math.min(t.center.x+t.width/2,e.center.x+e.width/2)},s={start:Math.max(t.center.y-t.height/2,e.center.y-e.height/2),end:Math.min(t.center.y+t.height/2,e.center.y+e.height/2)};if(n.end-n.start<s.end-s.start){const t=(n.start+n.end)/2;return{start:{x:t,y:s.start},end:{x:t,y:s.end}}}{const t=(s.start+s.end)/2;return{start:{x:n.start,y:t},end:{x:n.end,y:t}}}}var zl=1e-9;function Dl(t,e){return Math.abs(t.x-e.x)<zl&&Math.abs(t.y-e.y)<zl}function Ll(t,e){if(t.length!==e.length)return!1;for(let n=0;n<t.length;n++)if(t[n]!==e[n])return!1;return!0}var Fl=class{constructor(t){this.targets=t,this.buckets=new Map;for(let e=0;e<t.length;e++){const n=t[e],s=Math.floor(n.bounds.minX/this.CELL_SIZE)*this.CELL_SIZE,o=Math.floor(n.bounds.minY/this.CELL_SIZE)*this.CELL_SIZE,i=n.bounds.maxX,r=n.bounds.maxY;for(let t=s;t<=i;t+=this.CELL_SIZE)for(let s=o;s<=r;s+=this.CELL_SIZE){const o=this.getBucketKey(t,s),i=this.buckets.get(o);i?i.push([n,e]):this.buckets.set(o,[[n,e]])}}}buckets;CELL_SIZE=5;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getTargetsInArea(t,e,n,s){const o=[],i=new Set,r=Math.floor((t-n/2)/this.CELL_SIZE)*this.CELL_SIZE,a=Math.floor((e-s/2)/this.CELL_SIZE)*this.CELL_SIZE,c=t+n/2,h=e+s/2;for(let t=r;t<=c;t+=this.CELL_SIZE)for(let e=a;e<=h;e+=this.CELL_SIZE){const n=this.getBucketKey(t,e),s=this.buckets.get(n)||[];for(const t of s)i.has(t[1])||(i.add(t[1]),o.push(t[0]))}return o}},Yl=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.MAX_DEPTH=e?.capacityDepth??this.MAX_DEPTH,this.MAX_ITERATIONS=1e5,this.layerCount=t.layerCount??2,this.outlinePolygon=t.outline&&t.outline.length>=3?t.outline:void 0;const n={x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},s={width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY},o=Math.max(s.width,s.height);this.unfinishedNodes=[{capacityMeshNodeId:this.getNextNodeId(),center:n,width:o,height:o,layer:"top",availableZ:Array.from({length:this.layerCount},(t,e)=>e),_depth:0,_containsTarget:!0,_containsObstacle:!0,_completelyInsideObstacle:!1}],this.finishedNodes=[],this.nodeToXYOverlappingObstaclesMap=new Map,this.obstacleZLayersByObstacle=new WeakMap;const i=dl(this.srj.obstacles,this.layerCount);for(const[t,e]of this.srj.obstacles.entries())this.obstacleZLayersByObstacle.set(e,i[t].zLayers);this.obstacleTree=new sl("flatbush",this.srj.obstacles),this.targets=this.computeTargets(),this.targetTree=new Fl(this.targets)}getSolverName(){return"CapacityMeshNodeSolver"}unfinishedNodes;finishedNodes;nodeToXYOverlappingObstaclesMap;layerCount;outlinePolygon;MAX_DEPTH=4;targets;targetTree;obstacleTree;obstacleZLayersByObstacle;computeTargets(){const t=[];for(const e of this.srj.connections)for(const n of e.pointsToConnect){const s=En(n),o=this.obstacleTree.searchArea(n.x,n.y,.01,.01).filter(t=>{const e=this.getObstacleZLayers(t);return!(!e||0===e.length)&&e.some(t=>s.some(e=>t===Rn(e,this.layerCount)))});let i={minX:n.x-.005,minY:n.y-.005,maxX:n.x+.005,maxY:n.y+.005};o.length>0&&(i={minX:Math.min(...o.map(t=>t.center.x-t.width/2)),minY:Math.min(...o.map(t=>t.center.y-t.height/2)),maxX:Math.max(...o.map(t=>t.center.x+t.width/2)),maxY:Math.max(...o.map(t=>t.center.y+t.height/2))});const r={...n,connectionName:e.name,availableZ:s.map(t=>Rn(t,this.layerCount)),bounds:i};t.push(r)}return t}getNodeBounds(t){const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,maxX:t.center.x+e,minY:t.center.y-n,maxY:t.center.y+n}}getNodeRect(t){return{center:{x:t.center.x,y:t.center.y},width:t.width,height:t.height}}_nextNodeCounter=0;getNextNodeId(){return"cn"+this._nextNodeCounter++}getCapacityFromDepth(t){return(this.MAX_DEPTH-t+1)**2}getTargetIfNodeContainsTarget(t){const e=t.width>4*this.targetTree.CELL_SIZE?this.targets:this.targetTree.getTargetsInArea(t.center.x,t.center.y,t.width,t.height);for(const n of e)if(n.bounds.minX<=t.center.x+t.width/2&&n.bounds.maxX>=t.center.x-t.width/2&&n.bounds.minY<=t.center.y+t.height/2&&n.bounds.maxY>=t.center.y-t.height/2&&n.availableZ.some(e=>t.availableZ.includes(e)))return n;return null}getXYOverlappingObstacles(t){const e=this.nodeToXYOverlappingObstaclesMap.get(t.capacityMeshNodeId);if(e)return e;const n=[],s=this.getNodeBounds(t),o=s.minX,i=s.maxX,r=s.minY,a=s.maxY,c=t._parent?this.getXYOverlappingObstacles(t._parent):this.srj.obstacles;for(const t of c){const e=t.center.x-t.width/2,s=t.center.x+t.width/2,c=t.center.y-t.height/2,h=t.center.y+t.height/2;i>=e&&o<=s&&a>=c&&r<=h?n.push(t):(o>=e&&i<=s&&r>=c&&a<=h||e>=o&&s<=i&&c>=r&&h<=a)&&n.push(t)}return this.nodeToXYOverlappingObstaclesMap.set(t.capacityMeshNodeId,n),n}getXYZOverlappingObstacles(t){const e=this.getXYOverlappingObstacles(t),n=[];for(const s of e)t.availableZ.some(t=>this.getObstacleZLayers(s).includes(t))&&n.push(s);return n}doesNodeOverlapObstacle(t){if(this.getXYZOverlappingObstacles(t).length>0)return!0;const e=this.getNodeBounds(t);if(this.outlinePolygon){const e=this.getNodeRect(t);if(!J(e,this.outlinePolygon))return!0}return e.minX<this.srj.bounds.minX||e.maxX>this.srj.bounds.maxX||e.minY<this.srj.bounds.minY||e.maxY>this.srj.bounds.maxY}isNodeCompletelyInsideObstacle(t){const e=this.getXYZOverlappingObstacles(t),n=this.getNodeBounds(t);if(this.outlinePolygon){const e=this.getNodeRect(t);if(!q(e,this.outlinePolygon))return!0}for(const t of e){const e=t.center.x-t.width/2,s=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2;if(n.minX>=e&&n.maxX<=s&&n.minY>=o&&n.maxY<=i)return!0}return!1}getChildNodes(t){if(t._depth===this.MAX_DEPTH)return[];const e=[],n={width:t.width/2,height:t.height/2},s=[{x:t.center.x-n.width/2,y:t.center.y-n.height/2},{x:t.center.x+n.width/2,y:t.center.y-n.height/2},{x:t.center.x-n.width/2,y:t.center.y+n.height/2},{x:t.center.x+n.width/2,y:t.center.y+n.height/2}];for(const o of s){const s={capacityMeshNodeId:this.getNextNodeId(),center:o,width:n.width,height:n.height,layer:t.layer,availableZ:t.availableZ,_depth:(t._depth??0)+1,_parent:t};s._containsObstacle=this.doesNodeOverlapObstacle(s);const i=this.getTargetIfNodeContainsTarget(s);i&&(s._targetConnectionName=i.connectionName,s.availableZ=i.availableZ,s._containsTarget=!0),s._containsObstacle&&(s._completelyInsideObstacle=this.isNodeCompletelyInsideObstacle(s)),s._completelyInsideObstacle&&!s._containsTarget||e.push(s)}return e}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||!(!t._containsObstacle||t._completelyInsideObstacle))}_step(){const t=this.unfinishedNodes.pop();if(!t)return void(this.solved=!0);const e=this.getChildNodes(t),n=[],s=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t);e?s.push(t):e||t._containsObstacle?!e&&t._containsTarget&&n.push(t):n.push(t)}this.unfinishedNodes.push(...s),this.finishedNodes.push(...n)}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Capacity Mesh Visualization"};if(this.outlinePolygon&&this.outlinePolygon.length>=2){const e=this.outlinePolygon.map(t=>({x:t.x,y:t.y}));e.push({...e[0]}),t.lines.push({points:e,strokeColor:"rgba(0, 136, 255, 0.95)",label:"outline"});for(const e of this.outlinePolygon)t.points.push({x:e.x,y:e.y,color:"rgba(0, 136, 255, 0.95)"})}for(const e of this.srj.obstacles){const n=this.getObstacleZLayers(e);t.rects.push({center:e.center,width:e.width,height:e.height,fill:1===n.length&&n.includes(1)?"rgba(0,0,255,0.3)":"rgba(255,0,0,0.3)",stroke:"red",label:["obstacle",`z: ${n.join(",")}`].join("\n")})}const e=[...this.finishedNodes,...this.unfinishedNodes];for(const n of e){const e=Math.min(...n.availableZ),s=this.unfinishedNodes.length>0&&n===this.unfinishedNodes[this.unfinishedNodes.length-1];t.rects.push({center:{x:n.center.x+e*n.width*.05,y:n.center.y-e*n.width*.05},width:Math.max(n.width-2,.8*n.width),height:Math.max(n.height-2,.8*n.height),fill:n._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[n.availableZ.join(",")]??"rgba(0,200,200,0.1)",stroke:s?"rgba(255,165,0,0.5)":void 0,label:[n.capacityMeshNodeId,`availableZ: ${n.availableZ.join(",")}`,`target? ${n._containsTarget??!1}`,`obs? ${n._containsObstacle??!1}`,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`capacity: ${bh(n).toFixed(2)}`].join("\n")})}return t.rects.sort((t,e)=>t.center.y-e.center.y),this.srj.connections.forEach((e,n)=>{const s=Mn[n%Mn.length];for(const o of e.pointsToConnect){const e=En(o);t.points.push({x:o.x,y:o.y,label:`conn-${n} (${e.join(",")})`,color:s})}}),t}getObstacleZLayers(t){return this.obstacleZLayersByObstacle.get(t)??[]}},Xl=class extends Yl{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e,this.VIA_DIAMETER=t.minViaDiameter??this.VIA_DIAMETER}getSolverName(){return"CapacityMeshNodeSolver2_NodeUnderObstacle"}VIA_DIAMETER=.6;OBSTACLE_MARGIN=.1;OVERLAP_THRESHOLD_FOR_SINGLE_LAYER_NODES=.2;isNodeCompletelyOutsideBounds(t){if(this.outlinePolygon){const e=this.getNodeRect(t);if(!q(e,this.outlinePolygon))return!0}return t.center.x+t.width/2<this.srj.bounds.minX||t.center.x-t.width/2>this.srj.bounds.maxX||t.center.y+t.height/2<this.srj.bounds.minY||t.center.y-t.height/2>this.srj.bounds.maxY}isNodePartiallyOutsideBounds(t){if(this.outlinePolygon){const e=this.getNodeRect(t);return!!q(e,this.outlinePolygon)&&!J(e,this.outlinePolygon)}return t.center.x-t.width/2<this.srj.bounds.minX||t.center.x+t.width/2>this.srj.bounds.maxX||t.center.y-t.height/2<this.srj.bounds.minY||t.center.y+t.height/2>this.srj.bounds.maxY}getObstacleCoveragePercentage(t){const e=this.getXYZOverlappingObstacles(t);if(0===e.length)return 0;const n=t.center.x-t.width/2,s=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2,r=t.width*t.height;let a=0;for(const t of e){const e=Math.max(n,t.center.x-t.width/2),r=Math.min(s,t.center.x+t.width/2),c=Math.max(o,t.center.y-t.height/2),h=Math.min(i,t.center.y+t.height/2);if(e<r&&c<h){a+=(r-e)*(h-c)}}return a/r}shouldFilterSingleLayerNodeForObstacle(t){if(1!==t.availableZ.length)return!1;if(!t._containsObstacle)return!1;return this.getObstacleCoveragePercentage(t)>this.OVERLAP_THRESHOLD_FOR_SINGLE_LAYER_NODES}shouldFilterNodeForObstacle(t){return!!t._containsObstacle&&(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}createChildNodeAtPosition(t,e){const n={capacityMeshNodeId:this.getNextNodeId(),center:e.center,width:e.width,height:e.height,layer:t.layer,availableZ:e.availableZ,_depth:e._depth??(t._depth??0)+1,_parent:t},s=this.getXYZOverlappingObstacles(n);n._containsObstacle=s.length>0||this.isNodePartiallyOutsideBounds(n);const o=this.getTargetIfNodeContainsTarget(n);return o&&(n._targetConnectionName=o.connectionName,n._containsTarget=!0),n._containsObstacle&&(n._completelyInsideObstacle=this.isNodeCompletelyInsideObstacle(n)),n}getZSubdivisionChildNodes(t){if(1===t.availableZ.length)return[];const e=[],n=t.availableZ.map(t=>[t]);for(const s of n){const n=this.createChildNodeAtPosition(t,{center:{...t.center},width:t.width,height:t.height,availableZ:s,_depth:t._depth});this.isNodeCompletelyOutsideBounds(n)||e.push(n)}return e}getChildNodes(t){if(t._depth>=this.MAX_DEPTH)return[];const e=[],n={width:t.width/2,height:t.height/2},s=[{x:t.center.x-n.width/2,y:t.center.y-n.height/2},{x:t.center.x+n.width/2,y:t.center.y-n.height/2},{x:t.center.x-n.width/2,y:t.center.y+n.height/2},{x:t.center.x+n.width/2,y:t.center.y+n.height/2}];for(const o of s){const s=this.createChildNodeAtPosition(t,{center:o,width:n.width,height:n.height,availableZ:t.availableZ});this.isNodeCompletelyOutsideBounds(s)||e.push(s)}return e}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||(1===t.availableZ.length&&t._depth<=this.MAX_DEPTH||!(!t._containsObstacle||t._completelyInsideObstacle)))}_step(){const t=this.unfinishedNodes.pop();if(!t)return void(this.solved=!0);const e=this.getChildNodes(t),n=[],s=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),o=t.availableZ.length>1&&!e&&(t._containsObstacle||t.width<this.VIA_DIAMETER+this.OBSTACLE_MARGIN);if(e)s.push(t);else if(e||this.shouldFilterNodeForObstacle(t)||o)if(!e&&t._containsTarget)if(o){const e=this.getZSubdivisionChildNodes(t);n.push(...e.filter(t=>t._containsTarget||!this.shouldFilterNodeForObstacle(t)))}else n.push(t);else o&&n.push(...this.getZSubdivisionChildNodes(t).filter(t=>!this.shouldFilterNodeForObstacle(t)));else n.push(t)}this.unfinishedNodes.push(...s),this.finishedNodes.push(...n)}},kl=class extends Ln{getSolverName(){return"CapacitySegmentToPointSolver"}unsolvedSegments;solvedSegments;nodeMap;colorMap;constructor({segments:t,colorMap:e,nodes:n}){super(),this.MAX_ITERATIONS=1e5,this.unsolvedSegments=t,this.solvedSegments=[],this.colorMap=e??{},this.nodeMap=Object.fromEntries(n.map(t=>[t.capacityMeshNodeId,t]))}_step(){let t=!1;const e=[...this.unsolvedSegments];for(const n of e){const e=n.connectionNames.length;if((!("assignedPoints"in n)||n.assignedPoints?.length!==e)&&1===e){const e={x:(n.start.x+n.end.x)/2,y:(n.start.y+n.end.y)/2,z:n.availableZ[0]};n.assignedPoints=[{connectionName:n.connectionNames[0],rootConnectionName:n.rootConnectionNames?.[0],point:e}],this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(n),1),this.solvedSegments.push(n),t=!0}}if(!t&&e.length>0){let n=e[0];for(const t of e)t.connectionNames.length<n.connectionNames.length&&(n=t);const s=[...n.connectionNames].sort(),o=n.end.x-n.start.x,i=n.end.y-n.start.y,r=s.length,a=[];for(let t=1;t<=r;t++){const e=t/(r+1);a.push({x:n.start.x+o*e,y:n.start.y+i*e,z:n.availableZ[0]})}n.assignedPoints=s.map((t,e)=>({connectionName:t,rootConnectionName:n.rootConnectionNames?.[n.connectionNames.indexOf(t)],point:a[e]})),this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(n),1),this.solvedSegments.push(n),t=!0}0===this.unsolvedSegments.length&&(this.solved=!0)}getNodesWithPortPoints(){if(!this.solved)throw new Error("CapacitySegmentToPointSolver not solved, can't give port points yet");const t=new Map;for(const e of this.solvedSegments){const n=e.capacityMeshNodeId,s=this.nodeMap[n];t.has(n)||t.set(n,{capacityMeshNodeId:n,portPoints:[],center:s.center,width:s.width,height:s.height}),t.get(n).portPoints.push(...e.assignedPoints.map(t=>({...t.point,connectionName:t.connectionName})))}return Array.from(t.values())}visualize(){const t={points:[],lines:this.solvedSegments.map(t=>({points:[t.start,t.end],step:4})),rects:[],circles:[],coordinateSystem:"cartesian",title:"Capacity Segment to Point Solver"};for(let e=0;e<this.solvedSegments.length;e++){const n=this.solvedSegments[e];for(let e=0;e<n.assignedPoints.length;e++){const s=n.assignedPoints[e],o={x:s.point.x,y:s.point.y},i={x:s.point.x+.05*s.point.z,y:s.point.y+.05*s.point.z};0!==s.point.z&&t.lines.push({points:[o,i],strokeColor:"rgba(0, 0, 0, 0.25)",strokeDash:"5 5",step:4}),t.points.push({x:i.x,y:i.y,label:[`${n.capacityMeshNodeId}-${s.connectionName}`,`z: ${n.availableZ.join(",")}`,`nodePortSegmentId: ${n.nodePortSegmentId}`].join("\n"),color:this.colorMap[s.connectionName],step:4})}}const e=[],n={};for(const t of this.solvedSegments){const e=t.capacityMeshNodeId;n[e]||(n[e]={});for(const s of t.assignedPoints)n[e][s.connectionName]||(n[e][s.connectionName]=[]),n[e][s.connectionName].push({x:s.point.x,y:s.point.y})}for(const t in n)for(const s in n[t]){const o=n[t][s];o.length>1&&e.push({points:o,step:4,strokeDash:"5 5",strokeColor:this.colorMap[s]||"#000"})}return t.lines.push(...e),t}},$l=(t,e={})=>{const n=Math.min(...t.availableZ);return{center:!e.rectMargin||e.zOffset?{x:t.center.x+n*t.width*(e.zOffset??.05),y:t.center.y-n*t.width*(e.zOffset??.05)}:t.center,width:e.rectMargin?t.width-2*e.rectMargin:Math.max(t.width-.5,.8*t.width),height:e.rectMargin?t.height-2*e.rectMargin:Math.max(t.height-.5,.8*t.height),fill:t._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[t.availableZ.join(",")]??"rgba(0,200,200,0.1)",layer:`z${t.availableZ.join(",")}`,label:[t.capacityMeshNodeId,`availableZ: ${t.availableZ.join(",")}`,""+(t._containsTarget?"containsTarget":""),""+(t._containsObstacle?"containsObstacle":"")].filter(Boolean).join("\n")}},Bl=class extends Ln{getSolverName(){return"CapacityPathingSolver"}connectionsWithNodes;usedNodeCapacityMap;simpleRouteJson;nodes;edges;GREEDY_MULTIPLIER=1.1;MAX_CANDIDATES_IN_MEMORY=1e5;nodeMap;nodeEdgeMap;connectionNameToGoalNodeIds;colorMap;maxDepthOfNodes;activeCandidateStraightLineDistance;debug_lastNodeCostMap;hyperParameters;constructor({simpleRouteJson:t,nodes:e,edges:n,colorMap:s,MAX_ITERATIONS:o=1e6,hyperParameters:i={}}){super(),this.MAX_ITERATIONS=o,this.simpleRouteJson=t,this.nodes=e,this.edges=n,this.colorMap=s??{};const{connectionsWithNodes:r,connectionNameToGoalNodeIds:a}=this.getConnectionsWithNodes();this.connectionsWithNodes=r,this.connectionNameToGoalNodeIds=a,this.hyperParameters=i,this.usedNodeCapacityMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,0])),this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Fn(this.edges),this.maxDepthOfNodes=Math.max(...this.nodes.map(t=>t._depth??0)),this.debug_lastNodeCostMap=new Map}getTotalCapacity(t){const e=t._depth??0;return(this.maxDepthOfNodes-e+1)**2}getConnectionsWithNodes(){const t=[],e=this.nodes.filter(t=>t._containsTarget),n=new Map;for(const s of this.simpleRouteJson.connections){const o=[];for(const t of s.pointsToConnect){let n=this.nodes[0],s=Number.MAX_VALUE;for(const o of e){const e=Math.sqrt((o.center.x-t.x)**2+(o.center.y-t.y)**2);e<s&&(s=e,n=o)}o.push(n)}if(o.length<2)throw new Error(`Not enough nodes for connection "${s.name}", only ${o.length} found`);n.set(s.name,o.map(t=>t.capacityMeshNodeId)),t.push({connection:s,nodes:o,pathFound:!1,straightLineDistance:k(o[0].center,o[o.length-1].center)})}return t.sort((t,e)=>t.straightLineDistance-e.straightLineDistance),{connectionsWithNodes:t,connectionNameToGoalNodeIds:n}}currentConnectionIndex=0;candidates;visitedNodes;computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)}getBacktrackedPath(t){const e=[];let n=t;for(;n;)e.push(n.node),n=n.prevCandidate;return e}getNeighboringNodes(t){return this.nodeEdgeMap.get(t.capacityMeshNodeId).flatMap(e=>e.nodeIds.filter(e=>e!==t.capacityMeshNodeId)).map(t=>this.nodeMap.get(t))}getCapacityPaths(){const t=[];for(const e of this.connectionsWithNodes){const n=e.path;n&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,rootConnectionName:e.connection.rootConnectionName,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}doesNodeHaveCapacityForTrace(t,e){const n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,s=this.getTotalCapacity(t);if(1===t.availableZ.length&&!t._containsTarget&&n>0)return!1;let o=0;return t.availableZ.length>1&&1===e.availableZ.length&&(o+=.5),n+o<s}canTravelThroughObstacle(t,e){const n=this.connectionNameToGoalNodeIds.get(e);return n?.includes(t.capacityMeshNodeId)??!1}getDistanceBetweenNodes(t,e){return Math.sqrt((t.center.x-e.center.x)**2+(t.center.y-e.center.y)**2)}reduceCapacityAlongPath(t){for(const e of t.path??[])this.usedNodeCapacityMap.set(e.capacityMeshNodeId,this.usedNodeCapacityMap.get(e.capacityMeshNodeId)+1)}isConnectedToEndGoal(t,e){return this.nodeEdgeMap.get(t.capacityMeshNodeId).some(t=>t.nodeIds.includes(e.capacityMeshNodeId))}_step(){const t=this.connectionsWithNodes[this.currentConnectionIndex];if(!t)return void(this.solved=!0);const[e,n]=t.nodes;this.candidates||(this.candidates=[{prevCandidate:null,node:e,f:0,g:0,h:0}],this.debug_lastNodeCostMap=new Map,this.visitedNodes=new Set([e.capacityMeshNodeId]),this.activeCandidateStraightLineDistance=k(e.center,n.center)),this.candidates.sort((t,e)=>t.f-e.f);const s=this.candidates.shift();if(this.candidates.length>this.MAX_CANDIDATES_IN_MEMORY&&this.candidates.splice(this.MAX_CANDIDATES_IN_MEMORY,this.candidates.length-this.MAX_CANDIDATES_IN_MEMORY),!s)return console.error(`Ran out of candidates on connection ${t.connection.name}`),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,void(this.failed=!0);if(this.isConnectedToEndGoal(s.node,n))return t.path=this.getBacktrackedPath({prevCandidate:s,node:n,f:0,g:0,h:0}),this.reduceCapacityAlongPath(t),this.currentConnectionIndex++,this.candidates=null,void(this.visitedNodes=null);const o=this.getNeighboringNodes(s.node);for(const t of o){if(this.visitedNodes?.has(t.capacityMeshNodeId))continue;if(!this.doesNodeHaveCapacityForTrace(t,s.node))continue;const e=this.connectionsWithNodes[this.currentConnectionIndex].connection.name;if(t._containsObstacle&&!this.canTravelThroughObstacle(t,e))continue;const o=this.computeG(s,t,n),i=this.computeH(s,t,n),r=o+i*this.GREEDY_MULTIPLIER;this.debug_lastNodeCostMap.set(t.capacityMeshNodeId,{f:r,g:o,h:i});const a={prevCandidate:s,node:t,f:r,g:o,h:i};this.candidates.push(a)}this.visitedNodes.add(s.node.capacityMeshNodeId)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(this.connectionsWithNodes)for(let e=0;e<this.connectionsWithNodes.length;e++){const n=this.connectionsWithNodes[e];if(n.path&&n.path.length>0){const s=n.path.map(({center:{x:t,y:n},width:s,availableZ:o})=>({x:t+.005*s*(e%10+e%19),y:n+.005*s*(e%10+e%19),availableZ:o}));t.lines.push({points:s,strokeColor:this.colorMap[n.connection.name]});for(let e=0;e<s.length;e++){const o=s[e];t.points.push({x:o.x,y:o.y,label:[`conn: ${n.connection.name}`,`node: ${n.path[e].capacityMeshNodeId}`,`z: ${o.availableZ.join(",")}`].join("\n")})}}}for(const e of this.nodes){const n=this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0,s=this.getTotalCapacity(e),o=this.debug_lastNodeCostMap.get(e.capacityMeshNodeId);t.rects.push({...$l(e,{rectMargin:.025,zOffset:.01}),label:[`${e.capacityMeshNodeId}`,`${n}/${s}`,`${e.width.toFixed(2)}x${e.height.toFixed(2)}`,`g: ${void 0!==o?.g?o.g.toFixed(2):"?"}`,`h: ${void 0!==o?.h?o.h.toFixed(2):"?"}`,`f: ${void 0!==o?.f?o.f.toFixed(2):"?"}`,`z: ${e.availableZ.join(", ")}`].join("\n"),stroke:n>s+.5?"red":void 0})}if(this.connectionsWithNodes)for(const e of this.connectionsWithNodes)if(e.connection?.pointsToConnect)for(const n of e.connection.pointsToConnect)t.points.push({x:n.x,y:n.y,label:[`pointsToConnect ${e.connection.name}`].join("\n")});let e=this.connectionsWithNodes[this.currentConnectionIndex];if(!this.candidates&&this.currentConnectionIndex>0&&!this.connectionsWithNodes[this.currentConnectionIndex-1].path&&(e=this.connectionsWithNodes[this.currentConnectionIndex-1]),e){const[n,s]=e.connection.pointsToConnect;t.lines.push({points:[{x:n.x,y:n.y},{x:s.x,y:s.y}],strokeColor:"red",strokeDash:"10 5"})}if(this.candidates){const e=this.candidates.slice(0,5),n=this.connectionsWithNodes[this.currentConnectionIndex].connection.name;e.forEach((e,s)=>{const o=.5*(1-s/5),i=this.getBacktrackedPath(e);t.lines.push({points:i.map(({center:{x:t,y:e}})=>({x:t,y:e})),strokeColor:In(this.colorMap[n]??"red",1-o)})})}return t}},jl=class extends Bl{getSolverName(){return"CapacityPathingSolver5"}NEGATIVE_CAPACITY_PENALTY_FACTOR=1;REDUCED_CAPACITY_PENALTY_FACTOR=1;constructor(...t){super(...t),this.GREEDY_MULTIPLIER=2.5}get maxCapacityFactor(){return this.hyperParameters.MAX_CAPACITY_FACTOR??1}getTotalCapacity(t){return bh(t,this.maxCapacityFactor)}getNodeCapacityPenalty(t){const e=t.width+t.height,n=.05,s=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0);if(s>2)return n;return(e-n)*Math.max(1,(2-s)/(e-n))+n}getDistanceBetweenNodes(t,e){const n=t.center.x-e.center.x,s=t.center.y-e.center.y;return Math.sqrt(n**2+s**2)}computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)+this.getNodeCapacityPenalty(e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)+this.getNodeCapacityPenalty(e)}},Wl=class extends jl{getSolverName(){return"CapacityPathingGreedySolver"}doesNodeHaveCapacityForTrace(t,e){return!0}getNodeCapacityPenalty(t){const e=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0)-1;if(e>0)return 0;let n=1;return 1===t.availableZ.length&&(n=10),(.05+2*Math.abs(e))*n}};function Hl(t,e,n){const s=e.x-t.x,o=e.y-t.y;if(Math.abs(s)<1e-9&&Math.abs(o)<1e-9)return t;const i=n.width/2,r=n.height/2,a=n.center.x-i,c=n.center.x+i,h=n.center.y-r,l=n.center.y+r;let d=0,u=1/0;if(Math.abs(s)>1e-9){const e=(a-t.x)/s,n=(c-t.x)/s;d=Math.max(d,Math.min(e,n)),u=Math.min(u,Math.max(e,n))}else if(t.x<a||t.x>c)return t;if(Math.abs(o)>1e-9){const e=(h-t.y)/o,n=(l-t.y)/o;d=Math.max(d,Math.min(e,n)),u=Math.min(u,Math.max(e,n))}else if(t.y<h||t.y>l)return t;if(u<d||d===1/0||d<-1e9)return t;return{x:t.x+s*d,y:t.y+o*d}}function Ul(t,e){const n=t.center,s=e.center,o=Hl(n,s,t),i=Hl(s,n,e),r=s.x-n.x,a=s.y-n.y,c=Math.sqrt(r*r+a*a);let h=o,l=i;if(c>1e-9){const n={x:r/c,y:a/c},s=.3*t.width,d=.3*e.width;s+d<Math.sqrt((i.x-o.x)**2+(i.y-o.y)**2)?(h={x:o.x+n.x*s,y:o.y+n.y*s},l={x:i.x-n.x*d,y:i.y-n.y*d}):(h=o,l=i)}return{lineStart:h,lineEnd:l}}var Vl=t=>{const{usedCapacity:e,totalCapacity:n,layerCount:s}=t;if(e<n)return 0;if(n<1&&e<=1)return 0;if(1===s&&e>1)return 1-.01**e;const o=e/n-1;return 1-Math.exp(-2*o)},Gl=(t,e,n)=>{if(n._containsTarget)return 0;if(t<=e)return 0;const s=1-Vl({usedCapacity:t,totalCapacity:e,layerCount:n.availableZ.length});return s<=0?-1e9:Math.log(s)},Zl=({totalNodeCapacityMap:t,usedNodeCapacityMap:e,nodeMap:n,sectionNodeIds:s})=>{let o=0;const i=s??new Set(e.keys());for(const s of i){if(!t.has(s))continue;const i=n.get(s);if(!i)continue;const r=t.get(s),a=e.get(s)??0;o+=Gl(a,r,i)}return o};function ql({sectionNodes:t,sectionEdges:e,sectionConnectionTerminals:n,completedPaths:s,nodeMap:o,colorMap:i,centerNodeId:r,title:a,nodeOpacity:c=.1,usedNodeCapacityMap:h,totalCapacityMap:l}){const d={points:[],lines:[],rects:[],circles:[],title:a},u=new Set(t.map(t=>t.capacityMeshNodeId));for(const e of t){let t=`rgba(128, 128, 128, ${c})`,n=`rgba(128, 128, 128, ${c})`;const s=e.availableZ??[],o=s.includes(0),i=s.includes(1);o&&i?(t=`rgba(128, 0, 128, ${c})`,n=`rgba(128, 0, 128, ${c})`):o?(t=`rgba(0, 0, 255, ${c})`,n=`rgba(0, 0, 255, ${c})`):i&&(t=`rgba(255, 0, 0, ${c})`,n=`rgba(255, 0, 0, ${c})`),r&&e.capacityMeshNodeId===r&&(t=`rgba(0, 255, 0, ${c})`,n=`rgba(0, 128, 0, ${c})`),d.rects.push({...$l(e),fill:t,stroke:n,label:`${e.capacityMeshNodeId}\n(Section Node)\nZ: ${s.join(",")}`});const a=d.rects.length-1;if(h&&l){const t=h.get(e.capacityMeshNodeId)??0,n=l.get(e.capacityMeshNodeId)??0,s=n>0?(t/n*100).toFixed(1):"N/A",o=Vl({usedCapacity:t,totalCapacity:n,layerCount:e.availableZ.length});d.rects[a].label+=`\n${t.toFixed(1)} / ${n.toFixed(1)}\n${s}% (Pf: ${(100*o).toFixed(1)}%)`,o>.2&&(d.rects[a].stroke=In("red",.7*(.8+c)))}}for(const t of e){const[e,n]=t.nodeIds,s=o.get(e),i=o.get(n);if(s&&i){const{lineStart:t,lineEnd:e}=Ul(s,i);d.lines.push({points:[t,e],strokeColor:`rgba(0, 0, 0, ${.2*Math.min(1,c/.1)})`})}}return n.forEach((t,e)=>{const n=o.get(t.startNodeId),s=o.get(t.endNodeId),r=i[t.connectionName]??"black",a=n&&u.has(n.capacityMeshNodeId),c=s&&u.has(s.capacityMeshNodeId),h=(e+e/50)%5;let l=0,p=0,f=0,m=0;if(a&&n){const e=.02*Math.min(n.width,n.height);l=e*h,p=e*h,d.points.push({x:n.center.x+l,y:n.center.y+p,color:r,label:`Start: ${t.connectionName}\n(${t.startNodeId})`}),d.lines.push({points:[{x:n.center.x,y:n.center.y},{x:n.center.x+l,y:n.center.y+p}],strokeColor:"gray",strokeDash:"2 2"})}if(c&&s){const e=.02*Math.min(s.width,s.height);f=e*h,m=e*h,d.points.push({x:s.center.x+f,y:s.center.y+m,color:r,label:`End: ${t.connectionName}\n(${t.endNodeId})`}),d.lines.push({points:[{x:s.center.x,y:s.center.y},{x:s.center.x+f,y:s.center.y+m}],strokeColor:"gray",strokeDash:"2 2"})}a&&c&&n&&s&&d.lines.push({points:[{x:n.center.x+l,y:n.center.y+p},{x:s.center.x+f,y:s.center.y+m}],strokeColor:r,strokeDash:"5 5"})}),s&&s.forEach((t,e)=>{if(t.path&&t.path.length>0){const n=i[t.connectionName]??"gray",s={x:(e+e/50)%5*.03,y:(e+e/50)%5*.03};d.lines.push({points:t.path.map(({center:{x:t,y:e}})=>({x:t+s.x,y:e+s.y})),strokeColor:In(n,.2)})}}),d}var Jl=class extends Ln{getSolverName(){return"CapacityPathingSingleSectionSolver"}GREEDY_MULTIPLIER=1.5;sectionNodes;sectionEdges;sectionConnectionTerminals;nodeMap;nodeEdgeMap;colorMap;usedNodeCapacityMap;totalNodeCapacityMap;centerNodeId;currentSectionScore=0;MAX_CANDIDATES_IN_MEMORY=1e4;currentConnectionIndex=0;candidates=null;visitedNodes=null;queuedNodes=null;activeCandidateStraightLineDistance;debug_lastNodeCostMap=new Map;maxCapacityFactor=1;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.centerNodeId=t.centerNodeId,this.sectionNodes=t.sectionNodes,this.sectionEdges=t.sectionEdges,this.sectionConnectionTerminals=t.sectionConnectionTerminals.map(t=>({...t,path:void 0})),this.nodeMap=t.nodeMap??new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=t.nodeEdgeMap??Fn(this.sectionEdges),this.colorMap=t.colorMap??{},this.usedNodeCapacityMap=new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,0])),this.totalNodeCapacityMap=new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,this.getTotalCapacity(t)]));const e=new Set(this.sectionNodes.map(t=>t.capacityMeshNodeId));this.currentSectionScore=Zl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:e}),t.hyperParameters?.SHUFFLE_SEED&&(this.sectionConnectionTerminals=Gn(this.sectionConnectionTerminals,t.hyperParameters?.SHUFFLE_SEED))}getTotalCapacity(t){return bh(t,this.maxCapacityFactor)}getNodeCapacityPenalty(t){if(!this.nodeMap.has(t.capacityMeshNodeId))return 1/0;const e=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0)-1;if(e>0)return 0;let n=1;return 1===t.availableZ.length&&(n=10),(.05+e**2*4)*n}getDistanceBetweenNodes(t,e){const n=t.center.x-e.center.x,s=t.center.y-e.center.y;return Math.sqrt(n**2+s**2)}computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)+this.getNodeCapacityPenalty(e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)+this.getNodeCapacityPenalty(e)}getBacktrackedPath(t){const e=[];let n=t;for(;n;){if(e.push(n.node),!this.nodeMap.has(n.node.capacityMeshNodeId)){console.warn("Backtracked path went outside section bounds");break}n=n.prevCandidate}return e.reverse()}getNeighboringNodes(t){return this.nodeMap.has(t.capacityMeshNodeId)?this.nodeEdgeMap.get(t.capacityMeshNodeId)?.flatMap(e=>e.nodeIds.filter(e=>e!==t.capacityMeshNodeId)).map(t=>this.nodeMap.get(t)).filter(Boolean)??[]:[]}isConnectedToEndGoal(t,e){return!(!this.nodeMap.has(t.capacityMeshNodeId)||!this.nodeMap.has(e.capacityMeshNodeId))&&(this.nodeEdgeMap.get(t.capacityMeshNodeId)??[]).some(t=>t.nodeIds.includes(e.capacityMeshNodeId))}doesNodeHaveCapacityForTrace(t,e){return!0}reduceCapacityAlongPath(t){for(const e of t)if(this.usedNodeCapacityMap.has(e.capacityMeshNodeId)){const t=e.capacityMeshNodeId,n=this.nodeMap.get(t);if(!n){console.warn(`Node ${t} from path not found in section's nodeMap during score update.`);continue}const s=this.totalNodeCapacityMap.get(t),o=this.usedNodeCapacityMap.get(t)??0,i=Gl(o,s,n);this.currentSectionScore-=i;const r=o+1;this.usedNodeCapacityMap.set(t,r);const a=Gl(r,s,n);this.currentSectionScore+=a}}getSolvedSectionScore(){return this.currentSectionScore}_step(){const t=this.sectionConnectionTerminals[this.currentConnectionIndex];if(!t)return void(this.solved=!0);const e=this.nodeMap.get(t.startNodeId),n=this.nodeMap.get(t.endNodeId);if(!e||!n)return console.error(`Start or end node not found in section for connection ${t.connectionName}`),this.currentConnectionIndex++,this.candidates=null,void(this.visitedNodes=null);this.candidates||this._setupAStar(e,n);const s=this.candidates;if(0===s.length)return void this._handleCandidatesExhausted(t);s.sort((t,e)=>t.f-e.f);const o=s.shift();if(s.length>this.MAX_CANDIDATES_IN_MEMORY&&s.splice(this.MAX_CANDIDATES_IN_MEMORY,s.length-this.MAX_CANDIDATES_IN_MEMORY),this.visitedNodes.add(o.node.capacityMeshNodeId),o.node.capacityMeshNodeId===n.capacityMeshNodeId)return void this._handleGoalReached(o,t,n);const i=this.getNeighboringNodes(o.node);for(const e of i){if(this.queuedNodes?.has(e.capacityMeshNodeId))continue;if(!this.doesNodeHaveCapacityForTrace(e,o.node))continue;if(e._containsObstacle){const n=e.capacityMeshNodeId===t.startNodeId,s=e.capacityMeshNodeId===t.endNodeId;if(!n&&!s)continue}const i=this.computeG(o,e,n),r=this.computeH(o,e,n),a=i+r*this.GREEDY_MULTIPLIER;this.debug_lastNodeCostMap.set(e.capacityMeshNodeId,{f:a,g:i,h:r});const c={prevCandidate:o,node:e,f:a,g:i,h:r};this.queuedNodes?.add(e.capacityMeshNodeId),s.push(c)}}computeProgress(){const t=this.sectionConnectionTerminals.length;if(0===t)return 1;let e=this.currentConnectionIndex/t;if(this.currentConnectionIndex<t&&this.candidates&&this.candidates.length>0&&this.activeCandidateStraightLineDistance&&this.activeCandidateStraightLineDistance>0){const n=this.candidates.reduce((t,e)=>e.f<t.f?e:t);e+=Math.max(0,Math.min(1,1-n.h/this.activeCandidateStraightLineDistance))/t}else this.solved&&(e=1);return Math.min(1,e)}_setupAStar(t,e){this.candidates=[{prevCandidate:null,node:t,f:0,g:0,h:0}],this.visitedNodes=new Set([t.capacityMeshNodeId]),this.debug_lastNodeCostMap=new Map,this.activeCandidateStraightLineDistance=k(t.center,e.center);const n=this.computeH(null,t,e);this.candidates[0].h=n,this.candidates[0].f=n*this.GREEDY_MULTIPLIER,this.debug_lastNodeCostMap.set(t.capacityMeshNodeId,{f:this.candidates[0].f,g:0,h:n}),this.queuedNodes=new Set([t.capacityMeshNodeId])}_handleCandidatesExhausted(t){console.error(`Ran out of candidates for section connection ${t.connectionName}`),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,this.queuedNodes=null}_handleGoalReached(t,e,n){const s=this.getBacktrackedPath(t);e.path=s,this.reduceCapacityAlongPath(s),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,this.queuedNodes=null}visualize(){const t=this.sectionConnectionTerminals.filter(t=>t.path&&t.path.length>0).map(t=>({connectionName:t.connectionName,path:t.path})),e=ql({sectionNodes:this.sectionNodes,sectionEdges:this.sectionEdges,sectionConnectionTerminals:this.sectionConnectionTerminals,completedPaths:t,nodeMap:this.nodeMap,colorMap:this.colorMap,centerNodeId:null,title:`Section Pathing: Conn ${this.currentConnectionIndex+1}/${this.sectionConnectionTerminals.length} (${this.sectionNodes.length} nodes)`,nodeOpacity:.1});for(const t of this.sectionNodes){const n=e.rects.findIndex(e=>e.label?.includes(t.capacityMeshNodeId));if(-1!==n){const s=this.debug_lastNodeCostMap.get(t.capacityMeshNodeId),o=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,i=this.getTotalCapacity(t),r=`${o.toFixed(1)}/${i.toFixed(1)}`,a=s?`f:${s.f.toFixed(1)} g:${s.g.toFixed(1)} h:${s.h.toFixed(1)}`:"cost:?";e.rects[n].label=[t.capacityMeshNodeId,`Cap: ${r}`,a,`Z: ${t.availableZ.join(",")}`].join("\n"),o>i&&(e.rects[n].stroke=In("red",.7))}}if(this.candidates&&this.candidates.length>0){const t=this.candidates.slice().sort((t,e)=>t.f-e.f).slice(0,5),n=this.sectionConnectionTerminals[this.currentConnectionIndex],s=n?.connectionName??"unknown",o=this.colorMap[s]??"purple";t.forEach((t,n)=>{const s=.8*(1-n/5),i=this.getBacktrackedPath(t);i.length>0&&e.lines.push({points:i.map(({center:{x:t,y:e}})=>({x:t,y:e})),strokeColor:In(o,1-s),strokeWidth:.05})})}return e}},Kl=t=>Array.from({length:t},(t,e)=>e),Ql=class extends is{getSolverName(){return"HyperCapacityPathingSingleSectionSolver"}constructorParams;constructor(t){super(),this.MAX_ITERATIONS=1e5,this.constructorParams=t}computeG(t){return-t.getSolvedSectionScore()}computeH(t){return 0}getCombinationDefs(){const t=this.constructorParams.sectionConnectionTerminals.length;return 2===t?[["orderings2_for2"]]:3===t?[["orderings6_for3"]]:4===t?[["orderings24_for4"]]:[["orderings30"]]}getFailureMessage(){return`All CapacityPathingSingleSection solvers failed for "${this.centerNodeId}"`}getHyperParameterDefs(){return[{name:"orderings2_for2",possibleValues:Kl(2).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings6_for3",possibleValues:Kl(6).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings24_for4",possibleValues:Kl(24).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings30",possibleValues:Kl(30).map(t=>({SHUFFLE_SEED:t}))}]}generateSolver(t){return new Jl({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}onSolve({solver:t}){this.winningSolver=t}get centerNodeId(){return this.constructorParams.centerNodeId}get sectionNodes(){return this.constructorParams.sectionNodes}get sectionConnectionTerminals(){return this.winningSolver?.sectionConnectionTerminals}};import td from"object-hash";var ed=t=>Math.floor(10*t)/10,nd=class extends Ql{cacheHit=!1;cacheProvider;hasAttemptedToUseCache=!1;sectionNodeIdSet;cachedSectionConnectionTerminals=null;sectionScore=0;constructor(t){t.nodeMap=t.nodeMap??new Map(t.sectionNodes.map(t=>[t.capacityMeshNodeId,t])),super(t),this.sectionNodeIdSet=new Set(t.sectionNodes.map(t=>t.capacityMeshNodeId)),this.cacheProvider=void 0===t.cacheProvider?Me():t.cacheProvider}_step(){!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync()||(super._step(),(this.solved||this.failed)&&this.cacheProvider&&this.saveToCacheSync())}_computeBfsOrderingOfNodesInSection(){const t=new Set(this.constructorParams.centerNodeId),e=[],n=[{ancestorCapacitySum:0,capacity:0,g:0,capacityMeshNodeId:this.constructorParams.centerNodeId}];for(;n.length>0;){n.sort((t,e)=>e.g-t.g);const s=n.pop();if(!s)break;e.push(s.capacityMeshNodeId);const o=this.constructorParams.nodeEdgeMap.get(s.capacityMeshNodeId).flatMap(t=>t.nodeIds).filter(e=>!t.has(e)).filter(t=>this.sectionNodeIdSet.has(t));for(const e of o){t.add(e);const o=this.constructorParams.nodeMap.get(e),i=bh(o);n.push({ancestorCapacitySum:s.g,capacity:i,g:s.g+i,capacityMeshNodeId:e})}}return e}computeCacheKeyAndTransform(){const t=this._computeBfsOrderingOfNodesInSection(),e=new Map,n=new Map;t.forEach((t,s)=>{const o=`node${s}`;e.set(t,o),n.set(o,t)});const s={};for(const n of t){const t=e.get(n),o=this.constructorParams.nodeMap.get(n),i=bh(o);s[t]=ed(i).toFixed(1)}const o=new Set,i=[];for(const n of t){const t=e.get(n),s=this.constructorParams.nodeEdgeMap.get(n)??[];for(const r of s){const s=r.nodeIds.find(t=>t!==n);if(this.sectionNodeIdSet.has(s)){const n=[t,e.get(s)].sort(),r=`${n[0]}-${n[1]}`;o.has(r)||(i.push(n),o.add(r))}}}i.sort((t,e)=>t[0]!==e[0]?t[0].localeCompare(e[0]):t[1].localeCompare(e[1]));const r={},a=new Map,c=new Map;for(const t of this.constructorParams.sectionConnectionTerminals){const n=e.get(t.startNodeId),s=e.get(t.endNodeId),[o,i]=[n,s].sort(),h=`${o}->${i}`,l=c.get(h)??0;c.set(h,l+1);const d=`${o}->${i}::${l}`;r[d]={start:o,end:i},a.set(d,t.connectionName)}const h=`capacitypathing:${td({node_capacity_map:s,node_edge_map:i,terminals:r})}`,l={cacheSpaceToRealConnectionId:a,cacheSpaceToRealNodeId:n};return this.cacheKey=h,this.cacheToSolveSpaceTransform=l,{cacheKey:h,cacheToSolveSpaceTransform:l}}applyCachedSolution(t){if(!this.cacheToSolveSpaceTransform)return console.error("Cache transform not available, cannot apply cached solution."),void(this.failed=!0);if(!t.success)return this.failed=!0,void(this.cacheHit=!0);this.cachedSectionConnectionTerminals=[];const{cacheSpaceToRealNodeId:e,cacheSpaceToRealConnectionId:n}=this.cacheToSolveSpaceTransform;for(const[s,o]of Object.entries(t.solutionPaths)){const t=n.get(s);if(!t){console.warn(`Could not find real connection name for ${s}`);continue}const i=this.constructorParams.sectionConnectionTerminals.find(e=>e.connectionName===t);if(!i){console.warn(`Could not find original terminal for connection name ${t}`);continue}const r=o.map(n=>{const s=e.get(n);if(!s)throw new Error(`Could not map cache node ID ${n} to real node ID for connection ${t}`);const o=this.constructorParams.nodeMap.get(s);if(!o)throw new Error(`Could not find node with ID ${s} in nodeMap for connection ${t}`);return o});this.cachedSectionConnectionTerminals.push({...i,path:r})}this.sectionScore=t.sectionScore,this.solved=!0,this.cacheHit=!0}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return console.log("Cache provider is not synchronous, skipping sync cache check."),!1;if(this.cacheKey||this.computeCacheKeyAndTransform(),!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(!this.cacheKey)return void console.error("Cannot save to cache without cache key.");if(!this.cacheToSolveSpaceTransform)return void console.error("Cache transform not available, cannot save solution to cache.");let t;if(this.failed)t={success:!1};else{if(!this.solved)return;{const e={},{cacheSpaceToRealNodeId:n,cacheSpaceToRealConnectionId:s}=this.cacheToSolveSpaceTransform,o=new Map;for(const[t,e]of n)o.set(e,t);const i=new Map;for(const[t,e]of s)i.set(e,t);const r=[];if(super.sectionConnectionTerminals)for(const t of super.sectionConnectionTerminals)if(t.path&&t.path.length>0){const e=t.path.map(t=>t.capacityMeshNodeId);r.push([t.connectionName,e])}for(const[t,n]of r){const s=i.get(t);if(!s){console.warn(`Could not find cache space connection ID for ${t} when saving to cache.`);continue}const r=n.map(e=>{const n=o.get(e);if(!n)throw new Error(`Could not map real node ID ${e} to cache node ID for connection ${t} when saving to cache.`);return n});e[s]=r}t={success:!0,sectionScore:this.sectionScore,solutionPaths:e}}}try{this.cacheProvider?.setCachedSolutionSync(this.cacheKey,t)}catch(t){console.error("Error saving solution to cache:",t)}}get sectionConnectionTerminals(){return this.cacheHit&&this.solved&&this.cachedSectionConnectionTerminals?(console.log("returning the cached section connection terminals"),this.cachedSectionConnectionTerminals):super.sectionConnectionTerminals}visualize(){if(!this.cacheHit)return super.visualize();return ql({sectionNodes:this.constructorParams.sectionNodes,sectionEdges:this.constructorParams.sectionEdges,sectionConnectionTerminals:this.cachedSectionConnectionTerminals,completedPaths:this.cachedSectionConnectionTerminals.map(t=>({connectionName:t.connectionName,path:t.path})),nodeMap:this.constructorParams.nodeMap,colorMap:this.constructorParams.colorMap,title:"CachedHyperCapacityPathingSingleSectionSolver"})}},sd=class extends Ln{getSolverName(){return"CapacityPathingMultiSectionSolver"}simpleRouteJson;nodes;edges;nodeEdgeMap;connectionsWithNodes=[];colorMap;initialSolver;cacheProvider;stage="initialization";nodeMap=new Map;allNodeIdsSet;usedNodeCapacityMap=new Map;totalNodeCapacityMap=new Map;nodeCapacityPercentMap=new Map;nodeOptimizationAttemptCountMap=new Map;currentSection=null;sectionSolver=null;currentScheduleIndex=0;stats;OPTIMIZATION_SCHEDULE=[{MAX_ATTEMPTS_PER_NODE:1,MAX_EXPANSION_DEGREES:3,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.05},{MAX_ATTEMPTS_PER_NODE:2,MAX_EXPANSION_DEGREES:5,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.2},{MAX_ATTEMPTS_PER_NODE:3,MAX_EXPANSION_DEGREES:7,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.9}];get currentSchedule(){return this.OPTIMIZATION_SCHEDULE[this.currentScheduleIndex]??null}constructor(t){super(),this.stats={successfulOptimizations:0,failedOptimizations:0,failedSectionSolvers:0,startingScore:0,scheduleScores:this.OPTIMIZATION_SCHEDULE.map(({MAX_EXPANSION_DEGREES:t})=>({maxExpansionDegrees:t,endingScore:0,endingHighestNodePf:0,sectionAttempts:0})),cacheHits:0,cacheMisses:0},this.MAX_ITERATIONS=t.MAX_ITERATIONS??1e7,this.cacheProvider=t.cacheProvider,this.simpleRouteJson=t.simpleRouteJson,this.nodes=t.nodes,this.edges=t.edges,this.nodeEdgeMap=Fn(this.edges),this.colorMap=t.colorMap??{},this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Fn(this.edges),this.initialSolver=t.initialPathingSolver||new Wl({simpleRouteJson:this.simpleRouteJson,nodes:this.nodes,edges:this.edges,colorMap:this.colorMap}),this.activeSubSolver=this.initialSolver;for(const t of this.nodes){const e=this.initialSolver.getTotalCapacity(t);this.totalNodeCapacityMap.set(t.capacityMeshNodeId,e)}this.allNodeIdsSet=new Set(this.nodes.map(t=>t.capacityMeshNodeId))}_stepInitialization(){if(this.initialSolver?.step(),this.initialSolver?.failed)return this.failed=!0,void(this.error=this.initialSolver.error);if(this.initialSolver?.solved){this.usedNodeCapacityMap=new Map(this.initialSolver.usedNodeCapacityMap);for(const t of this.nodes){const e=this.totalNodeCapacityMap.get(t.capacityMeshNodeId)??0,n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,s=e>0?n/e:0;this.nodeCapacityPercentMap.set(t.capacityMeshNodeId,s),this.nodeOptimizationAttemptCountMap.set(t.capacityMeshNodeId,0)}this.connectionsWithNodes=this.initialSolver.connectionsWithNodes,this.stats.startingScore=Zl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:this.allNodeIdsSet}),this.stage="section-optimization"}}_getNextNodeToOptimize(){let t=0,e=0,n=null;for(const s of this.nodes){if(s._containsTarget)continue;const o=this.nodeOptimizationAttemptCountMap.get(s.capacityMeshNodeId),i=this.totalNodeCapacityMap.get(s.capacityMeshNodeId),r=Vl({usedCapacity:this.usedNodeCapacityMap.get(s.capacityMeshNodeId)??0,totalCapacity:i,layerCount:s.availableZ.length}),a=r/(o+1);o<this.currentSchedule.MAX_ATTEMPTS_PER_NODE&&a>t&&r>this.currentSchedule.MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE&&(t=a,e=r,n=s.capacityMeshNodeId)}return n}getOverallScore(){let t=0;for(const e of this.nodes){if(e._containsTarget)continue;const n=this.totalNodeCapacityMap.get(e.capacityMeshNodeId),s=Vl({usedCapacity:this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0,totalCapacity:n,layerCount:e.availableZ.length});s>t&&(t=s)}return{highestNodePf:t,score:Zl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:this.allNodeIdsSet})}}_stepSectionOptimization(){if(!this.sectionSolver){const t=this._getNextNodeToOptimize();if(!t){const{highestNodePf:t,score:e}=this.getOverallScore();return this.stats.scheduleScores[this.currentScheduleIndex].endingHighestNodePf=t,this.stats.scheduleScores[this.currentScheduleIndex].endingScore=e,this.currentScheduleIndex++,void(this.currentSchedule||(this.solved=!0))}const e=(t=>{const{centerNodeId:e,connectionsWithNodes:n,nodeMap:s,edges:o,nodeEdgeMap:i,expansionDegrees:r}=t,a=new Set,c=[{nodeId:e,depth:0}];a.add(e);let h=0;for(;h<c.length;){const{nodeId:t,depth:e}=c[h++];if(e>=r)continue;const n=i.get(t)?.flatMap(e=>e.nodeIds.filter(e=>e!==t))??[];for(const t of n)a.has(t)||(a.add(t),c.push({nodeId:t,depth:e+1}))}const l=Array.from(a).map(t=>s.get(t)),d=o.filter(t=>{const[e,n]=t.nodeIds;return a.has(e)&&a.has(n)}),u=[];for(const t of n){if(!t.path)continue;let e=null,n=null;for(const n of t.path)if(a.has(n.capacityMeshNodeId)){e=n.capacityMeshNodeId;break}for(let e=t.path.length-1;e>=0;e--){const s=t.path[e];if(a.has(s.capacityMeshNodeId)){n=s.capacityMeshNodeId;break}}e&&n&&u.push({connectionName:t.connection.name,startNodeId:e,endNodeId:n})}return{sectionConnectionTerminals:u,sectionNodes:l,sectionEdges:d,centerNodeId:e}})({centerNodeId:t,connectionsWithNodes:this.connectionsWithNodes,nodeMap:this.nodeMap,edges:this.edges,expansionDegrees:this.currentSchedule.MAX_EXPANSION_DEGREES,nodeEdgeMap:this.nodeEdgeMap});this.stats.scheduleScores[this.currentScheduleIndex].sectionAttempts++,this.currentSection=e,this.sectionSolver=new nd({sectionNodes:this.currentSection.sectionNodes,sectionEdges:this.currentSection.sectionEdges,sectionConnectionTerminals:this.currentSection.sectionConnectionTerminals,colorMap:this.colorMap,centerNodeId:this.currentSection.centerNodeId,nodeEdgeMap:this.nodeEdgeMap,hyperParameters:{EXPANSION_DEGREES:this.currentSchedule.MAX_EXPANSION_DEGREES},cacheProvider:this.cacheProvider}),this.activeSubSolver=this.sectionSolver,this.nodeOptimizationAttemptCountMap.set(t,(this.nodeOptimizationAttemptCountMap.get(t)??0)+1)}if(this.sectionSolver.step(),(this.sectionSolver.failed||this.sectionSolver.solved)&&(this.sectionSolver.cacheHit?this.stats.cacheHits++:this.stats.cacheMisses++),this.sectionSolver.failed)return console.warn(`Section solver failed for node ${this.currentSection.centerNodeId}. Error: ${this.sectionSolver.error}`),this.stats.failedSectionSolvers++,this.stats.failedOptimizations++,this.sectionSolver=null,void(this.activeSubSolver=null);if(this.sectionSolver.solved){const t=this.sectionSolver.sectionConnectionTerminals,e=this.sectionSolver.sectionNodes,n=this.sectionSolver.centerNodeId;if(this.sectionSolver=null,this.activeSubSolver=null,!t)return void console.warn(`Pathing sub-solver for section ${this.currentSection.centerNodeId} did not complete successfully. Discarding results.`);const s=new Set(e.map(t=>t.capacityMeshNodeId)),o=Zl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:s}),i=new Map(this.usedNodeCapacityMap),r=t;for(const t of r){const e=this.connectionsWithNodes.find(e=>e.connection.name===t.connectionName);if(e?.path)for(const t of e.path)if(s.has(t.capacityMeshNodeId)){const e=i.get(t.capacityMeshNodeId)??0;i.set(t.capacityMeshNodeId,Math.max(0,e-1))}}for(const t of r)if(t.path)for(const e of t.path)s.has(e.capacityMeshNodeId)&&i.set(e.capacityMeshNodeId,(i.get(e.capacityMeshNodeId)??0)+1);Zl({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:i,nodeMap:this.nodeMap,sectionNodeIds:s})>o?(this.stats.successfulOptimizations++,this._mergeSolvedSectionPaths({centerNodeId:n,sectionConnectionTerminals:t}),this._recalculateNodeCapacityUsage()):this.stats.failedOptimizations++}}_mergeSolvedSectionPaths({centerNodeId:t,sectionConnectionTerminals:e}){for(const n of e){if(!n.path){console.warn(`No path found for connection ${n.connectionName} in section ${t}`);continue}const e=this.connectionsWithNodes.find(t=>t.connection.name===n.connectionName);if(!e||!e.path){console.warn(`Original connection or path not found for ${n.connectionName} while merging section ${t}`);continue}const s=e.path,o=n.path,i=s.findIndex(t=>t.capacityMeshNodeId===n.startNodeId),r=s.findIndex(t=>t.capacityMeshNodeId===n.endNodeId);if(-1===i||-1===r){console.warn(`Could not find start/end nodes (${n.startNodeId}/${n.endNodeId}) in original path for ${n.connectionName}`);continue}const[a,c]=i<=r?[i,r]:[r,i],h=s.slice(0,a),l=s.slice(c+1);let d=o;if(o.length>0&&s[a]&&o[0].capacityMeshNodeId!==s[a].capacityMeshNodeId){if(o[o.length-1].capacityMeshNodeId!==s[a].capacityMeshNodeId){console.warn(`New section path for ${n.connectionName} doesn't align with original path boundaries. Skipping merge for this connection.`);continue}d=[...o].reverse()}e.path=[...h,...d,...l]}}_recalculateNodeCapacityUsage(){this.usedNodeCapacityMap.clear();for(const t of this.connectionsWithNodes)if(t.path)for(const e of t.path)this.usedNodeCapacityMap.set(e.capacityMeshNodeId,(this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0)+1);for(const t of this.nodes){const e=this.totalNodeCapacityMap.get(t.capacityMeshNodeId)??0,n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,s=e>0?n/e:0;this.nodeCapacityPercentMap.set(t.capacityMeshNodeId,s)}}getCapacityPaths(){const t=[];for(const e of this.connectionsWithNodes){const n=e.path;n&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}_step(){this.iterations>=this.MAX_ITERATIONS-1?this.solved=!0:"initialization"===this.stage?this._stepInitialization():"section-optimization"===this.stage&&this._stepSectionOptimization()}visualize(){const t=this.connectionsWithNodes.filter(t=>t.path&&t.path.length>0).map(t=>({connectionName:t.connection.name,path:t.path}));return ql({nodeMap:this.nodeMap,sectionConnectionTerminals:this.connectionsWithNodes.map(t=>({connectionName:t.connection.name,startNodeId:t.path?.[0]?.capacityMeshNodeId,endNodeId:t.path?.[t.path.length-1]?.capacityMeshNodeId})),completedPaths:t,sectionNodes:this.nodes,sectionEdges:this.edges,colorMap:this.colorMap,totalCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeOpacity:.05,title:"Capacity Pathing Multi-Section Solver (Solved)"})}},od=class extends Ln{getSolverName(){return"DeadEndSolver"}removedNodeIds;targetNodeIds;leaves;leavesIndex;adjacencyList;nodeMap;nodes;edges;constructor({nodes:t,edges:e}){super(),this.MAX_ITERATIONS=t.length,this.nodes=t,this.edges=e,this.removedNodeIds=new Set,this.targetNodeIds=new Set(t.filter(t=>t._containsTarget).map(t=>t.capacityMeshNodeId)),this.adjacencyList=new Map(t.map(({capacityMeshNodeId:t})=>[t,new Set]));for(const{nodeIds:[t,n]}of e)this.adjacencyList.get(t).add(n),this.adjacencyList.get(n).add(t);this.leavesIndex=0,this.leaves=[...this.adjacencyList.entries()].filter(([t,e])=>1===e.size).filter(([t,e])=>!this.targetNodeIds.has(t)).map(([t,e])=>t)}_step(){if(this.leavesIndex===this.leaves.length)return void(this.solved=!0);const t=this.leaves[this.leavesIndex],e=this.adjacencyList.get(t);if(!e||0===e.size)return this.removedNodeIds.add(t),this.adjacencyList.delete(t),this.leavesIndex+=1,void(this.leavesIndex===this.leaves.length&&(this.solved=!0));const[n]=e,s=n?this.adjacencyList.get(n):void 0;if(!n||!s)return this.removedNodeIds.add(t),this.adjacencyList.delete(t),this.leavesIndex+=1,void(this.leavesIndex===this.leaves.length&&(this.solved=!0));s.delete(t),this.removedNodeIds.add(t),this.adjacencyList.delete(t),1!==s.size||this.targetNodeIds.has(n)||this.leaves.push(n),this.leavesIndex+=1,this.leavesIndex===this.leaves.length&&(this.solved=!0)}visualize(){if(!this.nodeMap){this.nodeMap=new Map;for(const t of this.nodes)this.nodeMap.set(t.capacityMeshNodeId,t)}const t=new Map;for(const e of this.edges)for(const n of e.nodeIds)t.set(n,1+(t.get(n)??0));const e={lines:[],points:[],rects:this.nodes.map(e=>{const n=Math.min(...e.availableZ);return{width:Math.max(e.width-2,.8*e.width),height:Math.max(e.height-2,.8*e.height),center:{x:e.center.x+n*e.width*.05,y:e.center.y-n*e.width*.05},fill:e._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[e.availableZ.join(",")]??"rgba(0,200,200,0.1)",label:[e.capacityMeshNodeId,`availableZ: ${e.availableZ.join(",")}`,`target? ${e._containsTarget??!1}`,`obs? ${e._containsObstacle??!1}`,`conn: ${t.get(e.capacityMeshNodeId)??0}`].join("\n"),layer:`z${e.availableZ.join(",")}`}}),circles:[]};for(const t of this.edges){const n=this.nodeMap.get(t.nodeIds[0]),s=this.nodeMap.get(t.nodeIds[1]);if(n?.center&&s?.center){const o=Math.min(...n.availableZ),i=Math.min(...s.availableZ),r={x:n.center.x+o*n.width*.05,y:n.center.y-o*n.width*.05},a={x:s.center.x+i*s.width*.05,y:s.center.y-i*s.width*.05},c=Array.from(new Set([...n.availableZ,...s.availableZ])).sort();e.lines.push({layer:`z${c.join(",")}`,points:[r,a],strokeDash:n.availableZ.join(",")===s.availableZ.join(",")?void 0:"10 5",strokeColor:t.nodeIds.some(t=>this.removedNodeIds.has(t))?In("black",.9):void 0})}}return e}},id=class extends tl{getSolverName(){return"NoOffBoardMultipleHighDensityRouteStitchSolver"}constructor(t){super(t),this.unsolvedRoutes=[];const e=new Map;for(const n of t.hdRoutes){const t=e.get(n.connectionName)||[];t.push(n),e.set(n.connectionName,t)}for(const[n,s]of e.entries()){const e=t.connections.find(t=>t.name===n);if(!e)continue;const o={...e.pointsToConnect[0],z:Rn(Tn(e.pointsToConnect[0]),t.layerCount)},i={...e.pointsToConnect[1],z:Rn(Tn(e.pointsToConnect[1]),t.layerCount)};this.unsolvedRoutes.push({connectionName:n,hdRoutes:s,start:o,end:i})}for(const n of t.connections)e.has(n.name)||this.unsolvedRoutes.push({connectionName:n.name,hdRoutes:[],start:{...n.pointsToConnect[0],z:Rn(Tn(n.pointsToConnect[0]),t.layerCount)},end:{...n.pointsToConnect[1],z:Rn(Tn(n.pointsToConnect[1]),t.layerCount)}})}},rd=.005,ad=class extends Ln{getSolverName(){return"SingleLayerNodeMergerSolver"}nodeMap;currentBatchNodeIds;absorbedNodeIds;nextBatchNodeIds;batchHadModifications;hasComputedAdjacentNodeIds=!1;newNodes;constructor(t){super(),this.nodeMap=new Map,this.MAX_ITERATIONS=1e5;for(const e of t)this.nodeMap.set(e.capacityMeshNodeId,e);this.newNodes=[],this.absorbedNodeIds=new Set;const e=[];for(const n of t)n.availableZ.length>1?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):e.push([n,n.width*n.height]);e.sort((t,e)=>t[1]-e[1]);for(const[t,n]of e){const e={...t,center:{...t.center}};this.nodeMap.set(t.capacityMeshNodeId,e)}this.currentBatchNodeIds=e.map(([t])=>t.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=>Math.max(...t.availableZ))),n=[];for(let s=0;s<=e;s++)n.push(new $n(t.filter(t=>t.availableZ[0]===s)));for(const e of t){const t=[],s=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of s)n._containsTarget&&n._targetConnectionName!==e._targetConnectionName||e._containsTarget&&(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId&&Xn(e,n)&&t.push(n);e._adjacentNodeIds=t.map(t=>t.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){return this.getAdjacentSameLayerUnprocessedNodes2(t)}getAdjacentSameLayerUnprocessedNodes2(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=>this.nodeMap.get(t)))).filter(e=>e&&e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=>t.width*t.height-e.width*e.height);for(const t of n)this.absorbedNodeIds.has(t.capacityMeshNodeId)||e.push(t);return e}_step(){this.hasComputedAdjacentNodeIds||(this.computeAdjacentNodeIdsForFirstBatch(this.currentBatchNodeIds.map(t=>this.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t&&this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=>{const n=this.nodeMap.get(t),s=this.nodeMap.get(e);return n.width*n.height-s.width*s.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=>this.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const s=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===s.length)return void this.nextBatchNodeIds.push(t);const o=t=>{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=>t._adjacentNodeIds??[])].filter(t=>t!==e.capacityMeshNodeId&&!this.absorbedNodeIds.has(t))))},i=s.filter(t=>t.center.x<e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(i.length>0){const{width:t,height:s}=i[0],r=i.every(e=>e.width===t&&e.height===s);Math.abs(i.reduce((t,e)=>t+e.height,0)-e.height)<rd&&r&&(e.width+=t,e.center.x=e.center.x-t/2,o(i),n=!0)}const r=s.filter(t=>t.center.x>e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(r.length>0&&!n){const{width:t,height:s}=r[0],i=r.every(e=>e.width===t&&e.height===s);Math.abs(r.reduce((t,e)=>t+e.height,0)-e.height)<rd&&i&&(e.width+=t,e.center.x=e.center.x+t/2,o(r),n=!0)}const a=s.filter(t=>t.center.y>e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(a.length>0&&!n){const{width:t,height:s}=a[0],i=a.every(e=>e.width===t&&e.height===s);Math.abs(a.reduce((t,e)=>t+e.width,0)-e.width)<rd&&i&&(e.height+=s,e.center.y=e.center.y+s/2,o(a),n=!0)}const c=s.filter(t=>t.center.y<e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(c.length>0&&!n){const{width:t,height:s}=c[0],i=c.every(e=>e.width===t&&e.height===s);Math.abs(c.reduce((t,e)=>t+e.width,0)-e.width)<rd&&i&&(e.height+=s,e.center.y=e.center.y-s/2,o(c),n=!0)}n?(this.batchHadModifications=!0,this.currentBatchNodeIds.push(t)):this.nextBatchNodeIds.unshift(t)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Same Layer Node Merger"};for(const e of this.newNodes)t.rects.push($l(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e&&(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const s of this.currentBatchNodeIds){const o=this.nodeMap.get(s);if(!this.absorbedNodeIds.has(s)&&o){const i=$l(o,{rectMargin:.01});s===e?i.stroke="rgba(0, 255, 0, 0.8)":n?.some(t=>t.capacityMeshNodeId===s)?i.stroke="rgba(128, 0, 128, 0.8)":i.stroke="rgba(255, 165, 0, 0.8)",i.layer=`z${o.availableZ.join(",")}`,i.label=`${i.label}\n(unprocessed)`,t.rects.push(i)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)&&n){const e=$l(n,{rectMargin:.01});e.layer=`z${n.availableZ.join(",")}`,e.stroke="rgba(0, 217, 255, 0.8)",e.label=`${e.label}\nx: ${n.center.x}, y: ${n.center.y}\n${n.width}x${n.height}\n(next batch)`,t.rects.push(e)}}return t}},cd=class extends Ln{getSolverName(){return"StrawSolver"}multiLayerNodes;strawNodes;skippedNodes;unprocessedNodes;strawSize;nodeIdCounter;constructor(t){super(),this.MAX_ITERATIONS=1e5,this.strawSize=t.strawSize??.5,this.multiLayerNodes=[],this.strawNodes=[],this.skippedNodes=[],this.nodeIdCounter=0,this.unprocessedNodes=[];for(const e of t.nodes)1===e.availableZ.length?this.unprocessedNodes.push(e):this.multiLayerNodes.push(e)}getCapacityOfMultiLayerNodesWithinBounds(t){let e=0;for(const n of this.multiLayerNodes){const s=n.center.x-n.width/2,o=n.center.x+n.width/2,i=n.center.y-n.height/2,r=n.center.y+n.height/2,a=Math.max(t.minX,s),c=Math.min(t.maxX,o),h=Math.max(t.minY,i),l=Math.min(t.maxY,r);if(a<c&&h<l){const t=(c-a)*(l-h)/(n.width*n.height);e+=bh(n)*t}}return e}getSurroundingCapacities(t){const e=Math.min(t.width,t.height);return{leftSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2-e,maxX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}),rightSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x+t.width/2,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}),topSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2-e,maxY:t.center.y-t.height/2}),bottomSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y+t.height/2,maxY:t.center.y+t.height/2+e})}}createStrawsForNode(t){const e=[],{leftSurroundingCapacity:n,rightSurroundingCapacity:s,topSurroundingCapacity:o,bottomSurroundingCapacity:i}=this.getSurroundingCapacities(t);if(1*(n+s)>o+i){const n=Math.floor(t.height/this.strawSize),s=t.height/n;for(let o=0;o<n;o++){const n=t.center.y-t.height/2+o*s+s/2;e.push({capacityMeshNodeId:`${t.capacityMeshNodeId}_straw${o}`,center:{x:t.center.x,y:n},width:t.width,height:s,layer:t.layer,availableZ:[...t.availableZ],_depth:t._depth,_strawNode:!0,_strawParentCapacityMeshNodeId:t.capacityMeshNodeId})}}else{const n=Math.floor(t.width/this.strawSize),s=t.width/n;for(let o=0;o<n;o++){const n=t.center.x-t.width/2+o*s+s/2;e.push({capacityMeshNodeId:`${t.capacityMeshNodeId}_straw${o}`,center:{x:n,y:t.center.y},width:s,height:t.height,layer:t.layer,availableZ:[...t.availableZ],_depth:t._depth,_strawNode:!0,_strawParentCapacityMeshNodeId:t.capacityMeshNodeId})}}return e}getResultNodes(){return[...this.multiLayerNodes,...this.strawNodes,...this.skippedNodes]}_step(){const t=this.unprocessedNodes.pop();if(!t)return void(this.solved=!0);if(t.width<this.strawSize&&t.height<this.strawSize)return void this.skippedNodes.push(t);if(t._containsTarget)return void this.skippedNodes.push(t);const e=this.createStrawsForNode(t);this.strawNodes.push(...e),0===e.length&&this.strawNodes.push(t)}visualize(){const t={rects:[],lines:[],points:[],circles:[],title:"Straw Solver"};for(const e of this.unprocessedNodes)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(200, 200, 200, 0.5)",stroke:"rgba(0, 0, 0, 0.5)",label:`${e.capacityMeshNodeId}\nUnprocessed\n${e.width}x${e.height}`});for(const e of this.strawNodes){const n=0===e.availableZ[0]?"rgba(0, 150, 255, 0.5)":"rgba(255, 100, 0, 0.5)";t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,stroke:"rgba(0, 0, 0, 0.5)",label:`${e.capacityMeshNodeId}\nLayer: ${e.availableZ[0]}\n${e.width}x${e.height}`,layer:`z${e.availableZ.join(",")}`})}for(const e of this.multiLayerNodes)t.rects.push({center:e.center,width:.9*e.width,height:.9*e.height,fill:"rgba(100, 255, 100, 0.5)",stroke:"rgba(0, 0, 0, 0.5)",layer:`z${e.availableZ.join(",")}`,label:`${e.capacityMeshNodeId}\nLayers: ${e.availableZ.join(",")}\n${e.width}x${e.height}`});return t}};function hd(t){const{nodeId:e,nodeIdToSegmentIds:n,segmentIdToNodeIds:s,hops:o}=t;if(0===o)return[e];const i=new Set([e]),r=[{nodeId:e,remainingHops:o}];for(;r.length>0;){const{nodeId:t,remainingHops:e}=r.shift();if(0===e)continue;const o=n.get(t)||[];for(const t of o){const n=s.get(t)||[];for(const t of n)i.has(t)||(i.add(t),r.push({nodeId:t,remainingHops:e-1}))}}return Array.from(i)}var ld=t=>Array.from(t.entries()).map(([t,{x:e,y:n,z:s}])=>`${t}(${e?.toFixed(3)??""},${n?.toFixed(3)??""},${s??""})`).sort().join("&"),dd=(t,e,n,s)=>{const o=Math.min(t,e),i=Math.max(t,e),r=Math.min(n,s);return o<=Math.max(n,s)&&i>=r},ud=(t,e,n,s)=>{const o=[],i=new Map(t.originalPointMap);for(const[t,e]of n.entries()){const n=i.get(t);i.set(t,{x:e.x??n.x,y:e.y??n.y,z:e.z??n.z})}for(const n of t.allNodeIds){if(!e.get(n))continue;const r=t.segmentPairsInNode.get(n);for(const t of r){const e=i.get(t[0]),s=i.get(t[1]);e.z!==s.z&&o.push({type:"transition_via",segmentPoints:t,capacityMeshNodeId:n,probabilityOfFailure:0})}for(let t=0;t<r.length;t++)for(let e=t+1;e<r.length;e++){if(s?.areIdsConnected(r[t][0],r[t][1]))continue;const a=r[t],c=r[e],h=i.get(a[0]),l=i.get(a[1]),d=i.get(c[0]),u=i.get(c[1]);if(!dd(h.z,l.z,d.z,u.z))continue;const p=L(h,l,d,u),f=h.z===l.z&&d.z===u.z&&h.z===d.z;p&&(f?o.push({type:"same_layer_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,crossingLine1:a,crossingLine2:c,probabilityOfFailure:0}):h.z===l.z&&d.z!==u.z?o.push({type:"single_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,sameLayerCrossingLine:a,transitionCrossingLine:c,probabilityOfFailure:0}):h.z!==l.z&&d.z===u.z?o.push({type:"single_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,sameLayerCrossingLine:c,transitionCrossingLine:a,probabilityOfFailure:0}):h.z!==l.z&&d.z!==u.z&&o.push({type:"double_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,crossingLine1:a,crossingLine2:c,probabilityOfFailure:0}))}}return o},pd=(t,e,n)=>{if("change_layer"===e.type)for(const n of e.segmentPointIds){const s=t.get(n)||{};t.set(n,{...s,z:e.newZ})}else if("swap_position_on_segment"===e.type){const[s,o]=e.segmentPointIds,i=n(s),r=n(o),a=t.get(s)||{},c=t.get(o)||{};t.set(s,{...a,x:r.x,y:r.y}),t.set(o,{...c,x:i.x,y:i.y})}else if("combined"===e.type)for(const s of e.operations)pd(t,s,n)},fd=(t,e)=>{const n=new Map,s=new Map,o=new Map,i=[];let r=0;for(const a of t)for(const t of a.assignedPoints){const c={segmentPointId:"SP"+r++,segmentId:a.nodePortSegmentId,capacityMeshNodeIds:e.get(a.nodePortSegmentId),connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,x:t.point.x,y:t.point.y,z:t.point.z,directlyConnectedSegmentPointIds:[]};n.set(c.segmentPointId,c);for(const t of c.capacityMeshNodeIds)s.set(t,[...s.get(t)??[],c.segmentPointId]);o.set(a.nodePortSegmentId,[...o.get(a.nodePortSegmentId)??[],c.segmentPointId]),i.push(c)}return{segmentPointMap:n,nodeToSegmentPointMap:s,segmentToSegmentPointMap:o}},md=class extends Ln{getSolverName(){return"UnravelSectionSolver"}nodeMap;dedupedSegments;dedupedSegmentMap;MUTABLE_HOPS=1;unravelSection;candidates=[];lastProcessedCandidate=null;bestCandidate=null;originalCandidate;rootNodeId;nodeIdToSegmentIds;segmentIdToNodeIds;colorMap;tunedNodeCapacityMap;MAX_CANDIDATES=500;iterationsSinceImprovement=0;hyperParameters;selectedCandidateIndex=null;queuedOrExploredCandidatePointModificationHashes=new Set;constructorParams;constructor(t){if(super(),this.constructorParams=t,this.MUTABLE_HOPS=t.MUTABLE_HOPS??this.MUTABLE_HOPS,this.MAX_ITERATIONS=5e4,this.hyperParameters={...t.hyperParameters,MAX_ITERATIONS_WITHOUT_IMPROVEMENT:200},this.nodeMap=t.nodeMap,this.dedupedSegments=t.dedupedSegments,t.dedupedSegmentMap)this.dedupedSegmentMap=t.dedupedSegmentMap;else{this.dedupedSegmentMap=new Map;for(const t of this.dedupedSegments)this.dedupedSegmentMap.set(t.nodePortSegmentId,t)}this.nodeIdToSegmentIds=t.nodeIdToSegmentIds,this.segmentIdToNodeIds=t.segmentIdToNodeIds,this.rootNodeId=t.rootNodeId,this.colorMap=t.colorMap??{},this.unravelSection=this.createUnravelSection({segmentPointMap:t.segmentPointMap,nodeToSegmentPointMap:t.nodeToSegmentPointMap,segmentToSegmentPointMap:t.segmentToSegmentPointMap}),this.tunedNodeCapacityMap=new Map;for(const t of this.unravelSection.allNodeIds)this.tunedNodeCapacityMap.set(t,bh(this.nodeMap.get(t)));this.originalCandidate=this.createInitialCandidate(),this.candidates=[this.originalCandidate]}getConstructorParams(){return{...this.constructorParams,segmentPointMap:this.unravelSection.segmentPointMap,nodeToSegmentPointMap:this.unravelSection.segmentPointsInNode,segmentToSegmentPointMap:this.unravelSection.segmentPointsInSegment}}createUnravelSection(t){const e=hd({nodeId:this.rootNodeId,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,hops:this.MUTABLE_HOPS}),n=hd({nodeId:this.rootNodeId,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,hops:this.MUTABLE_HOPS+1}),s=Array.from(new Set(n).difference(new Set(e)));t?.segmentPointMap||(t=fd(this.dedupedSegments,this.segmentIdToNodeIds));const o=new Map;for(const e of n)o.set(e,t.nodeToSegmentPointMap.get(e));const i=new Map;for(const e of n)for(const n of o.get(e)){const e=t.segmentPointMap.get(n);i.set(n,e)}const r=Array.from(i.values()),a=new Map;for(const t of r)a.set(t.segmentId,[...a.get(t.segmentId)??[],t.segmentPointId]);for(const[e,n]of o.entries())for(let e=0;e<n.length;e++){const s=t.segmentPointMap.get(n[e]);for(let o=e+1;o<n.length;o++){const e=t.segmentPointMap.get(n[o]);e.segmentPointId!==s.segmentPointId&&(e.segmentId!==s.segmentId&&e.connectionName===s.connectionName&&(e.directlyConnectedSegmentPointIds.includes(s.segmentPointId)||(s.directlyConnectedSegmentPointIds.push(e.segmentPointId),e.directlyConnectedSegmentPointIds.push(s.segmentPointId))))}}const c=new Map;for(const t of n)c.set(t,[]);for(const e of r)for(const n of e.capacityMeshNodeIds){const s=c.get(n);if(s)for(const o of e.directlyConnectedSegmentPointIds){const i=t.segmentPointMap.get(o);i.segmentPointId!==e.segmentPointId&&(i.capacityMeshNodeIds.some(t=>t===n)&&(s.some(([t,n])=>t===e.segmentPointId&&n===i.segmentPointId||t===i.segmentPointId&&n===e.segmentPointId)||s.push([e.segmentPointId,i.segmentPointId])))}}const h=new Set;for(const t of e)for(const e of this.nodeIdToSegmentIds.get(t)){this.segmentIdToNodeIds.get(e).every(t=>!this.nodeMap.get(t)._containsTarget)&&h.add(e)}const l=new Set;for(const t of r){const n=t.capacityMeshNodeIds.some(t=>e.includes(t)),s=this.dedupedSegmentMap.get(t.segmentId),o=s&&s.availableZ.length>1;(n||o)&&l.add(t.segmentPointId)}const d=new Set;for(const t of r){if(t.capacityMeshNodeIds.some(t=>this.nodeMap.get(t)?._containsTarget)){const e=this.dedupedSegmentMap.get(t.segmentId);e&&1===e.availableZ.length&&d.add(t.segmentPointId)}}return{allNodeIds:n,mutableNodeIds:e,immutableNodeIds:s,mutableSegmentIds:h,segmentPairsInNode:c,segmentPointMap:i,segmentPointsInNode:o,segmentPointsInSegment:a,originalPointMap:i,mutableSegmentPointIds:l,zLockedSegmentPointIds:d}}createInitialCandidate(){const t=new Map,e=ud(this.unravelSection,this.nodeMap,t),n=this.computeG({issues:e,originalCandidate:{},operationsPerformed:0,operation:{}});return{pointModifications:t,g:n,h:0,f:n,operationsPerformed:0,candidateHash:ld(t),issues:ud(this.unravelSection,this.nodeMap,t)}}get nextCandidate(){return this.candidates[0]??null}getPointInCandidate(t,e){const n=this.unravelSection.segmentPointMap.get(e),s=t.pointModifications.get(e);return{x:s?.x??n.x,y:s?.y??n.y,z:s?.z??n.z,segmentId:n.segmentId}}getConnectionSegmentPointIds(t){const e=[];for(const[n,s]of this.unravelSection.segmentPointMap.entries())s.connectionName===t&&e.push(n);return e}canConnectionUseLayer(t,e){for(const n of t){const t=this.unravelSection.segmentPointMap.get(n),s=this.dedupedSegmentMap.get(t.segmentId);if(!s||!s.availableZ.includes(e))return!1}return!0}getOperationsForIssue(t,e){const n=[];if("transition_via"===e.type){const[s,o]=e.segmentPoints,i=this.getPointInCandidate(t,s),r=this.getPointInCandidate(t,o),a=this.unravelSection.segmentPointMap.get(s),c=(this.unravelSection.segmentPointMap.get(o),this.dedupedSegmentMap.get(i.segmentId).availableZ),h=this.dedupedSegmentMap.get(r.segmentId).availableZ,l=this.unravelSection.zLockedSegmentPointIds.has(s),d=this.unravelSection.zLockedSegmentPointIds.has(o),u=this.getConnectionSegmentPointIds(a.connectionName);if(this.canConnectionUseLayer(u,r.z)){const t=u.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));t.length>0&&n.push({type:"change_layer",newZ:r.z,segmentPointIds:t})}if(this.canConnectionUseLayer(u,i.z)){const t=u.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));t.length>0&&n.push({type:"change_layer",newZ:i.z,segmentPointIds:t})}this.unravelSection.mutableSegmentPointIds.has(s)&&!l&&c.includes(r.z)&&n.push({type:"change_layer",newZ:r.z,segmentPointIds:[s]}),this.unravelSection.mutableSegmentPointIds.has(o)&&!d&&h.includes(i.z)&&n.push({type:"change_layer",newZ:i.z,segmentPointIds:[o]})}if("same_layer_crossing"===e.type){const[t,s]=e.crossingLine1,[o,i]=e.crossingLine2,r=[],a=this.unravelSection.segmentPointMap.get(t),c=this.unravelSection.segmentPointMap.get(s),h=this.unravelSection.segmentPointMap.get(o),l=this.unravelSection.segmentPointMap.get(i),d=this.unravelSection.mutableSegmentPointIds.has(t),u=this.unravelSection.mutableSegmentPointIds.has(s),p=this.unravelSection.mutableSegmentPointIds.has(o),f=this.unravelSection.mutableSegmentPointIds.has(i),m=this.unravelSection.zLockedSegmentPointIds.has(t),g=this.unravelSection.zLockedSegmentPointIds.has(s),y=this.unravelSection.zLockedSegmentPointIds.has(o),x=this.unravelSection.zLockedSegmentPointIds.has(i);d&&p&&a.segmentId===h.segmentId&&r.push([t,o]),d&&f&&a.segmentId===l.segmentId&&r.push([t,i]),u&&p&&c.segmentId===h.segmentId&&r.push([s,o]),u&&f&&c.segmentId===l.segmentId&&r.push([s,i]);for(const[t,e]of r)n.push({type:"swap_position_on_segment",segmentPointIds:[t,e]});const v=this.getConnectionSegmentPointIds(a.connectionName),b=this.getConnectionSegmentPointIds(h.connectionName),P=new Set;for(const t of this.unravelSection.segmentPointMap.values()){const e=this.dedupedSegmentMap.get(t.segmentId);if(e)for(const t of e.availableZ)P.add(t)}for(const t of P)if(t!==a.z&&this.canConnectionUseLayer(v,t)){const e=v.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));e.length>0&&n.push({type:"change_layer",newZ:t,segmentPointIds:e})}for(const t of P)if(t!==h.z&&this.canConnectionUseLayer(b,t)){const e=b.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));e.length>0&&n.push({type:"change_layer",newZ:t,segmentPointIds:e})}const S=this.dedupedSegmentMap.get(a.segmentId),M=this.dedupedSegmentMap.get(c.segmentId),N=this.dedupedSegmentMap.get(h.segmentId),I=this.dedupedSegmentMap.get(l.segmentId),_=(t,e)=>t.every(t=>t.availableZ.includes(e));if(d&&u&&!m&&!g){const e=0===a.z?1:0;_([S,M],e)&&n.push({type:"change_layer",newZ:e,segmentPointIds:[t,s]})}if(p&&f&&!y&&!x){const t=0===h.z?1:0;_([N,I],t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[o,i]})}if(d&&!m){const e=0===a.z?1:0;S.availableZ.includes(e)&&n.push({type:"change_layer",newZ:e,segmentPointIds:[t]})}if(u&&!g){const t=0===c.z?1:0;M.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[s]})}if(p&&!y){const t=0===h.z?1:0;N.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[o]})}if(f&&!x){const t=0===l.z?1:0;I.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[i]})}}return n}computeG(t){const{issues:e,originalCandidate:n,operationsPerformed:s,operation:o}=t,i=new Map;for(const t of e){i.has(t.capacityMeshNodeId)||i.set(t.capacityMeshNodeId,{numTransitionCrossings:0,numSameLayerCrossings:0,numEntryExitLayerChanges:0});const e=i.get(t.capacityMeshNodeId);"transition_via"===t.type?e.numTransitionCrossings++:"same_layer_crossing"===t.type?e.numSameLayerCrossings++:"double_transition_crossing"===t.type||"single_transition_crossing"===t.type?e.numEntryExitLayerChanges++:t.type}let r=0;for(const[t,{numEntryExitLayerChanges:e,numSameLayerCrossings:n,numTransitionCrossings:s}]of i){const o=this.nodeMap.get(t),i=Math.min(Sh(o,n,e,s),.999999);r+=Math.log(1-i)}var a;return(a=r)<-Math.LN2?Math.log(1-Math.exp(a)):Math.log(-Math.expm1(a))}getUnexploredNeighborByApplyingOperation(t,e){const n=new Map(t.pointModifications);pd(n,e,e=>this.getPointInCandidate(t,e));const s=ld(n);if(this.queuedOrExploredCandidatePointModificationHashes.has(s))return null;const o=ud(this.unravelSection,this.nodeMap,n),i=t.operationsPerformed+1,r=this.computeG({issues:o,originalCandidate:t,operationsPerformed:i,operation:e});return{issues:o,g:r,h:0,f:r,pointModifications:n,candidateHash:s,operationsPerformed:i}}getNeighborOperationsForCandidate(t){return t.issues.flatMap(e=>this.getOperationsForIssue(t,e))}getNeighbors(t){const e=[],n=this.getNeighborOperationsForCandidate(t);for(const s of n){const n=this.getUnexploredNeighborByApplyingOperation(t,s);n&&e.push(n)}return e}_step(){const t=this.candidates.shift();this.iterationsSinceImprovement++,this.iterationsSinceImprovement>this.hyperParameters.MAX_ITERATIONS_WITHOUT_IMPROVEMENT?this.solved=!0:t?(this.lastProcessedCandidate=t,t.f<(this.bestCandidate?.f??1/0)&&(this.bestCandidate=t,this.iterationsSinceImprovement=0),this.getNeighbors(t).forEach(t=>{this.queuedOrExploredCandidatePointModificationHashes.has(t.candidateHash)||(this.queuedOrExploredCandidatePointModificationHashes.add(t.candidateHash),this.candidates.push(t))}),this.candidates.sort((t,e)=>t.f-e.f),this.candidates.length=Math.min(this.candidates.length,this.MAX_CANDIDATES)):this.solved=!0}visualize(){const t={points:[],lines:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Unravel Section Solver"};let e=null;if(e=null!==this.selectedCandidateIndex?"best"===this.selectedCandidateIndex?this.bestCandidate:"original"===this.selectedCandidateIndex?this.originalCandidate:this.candidates[this.selectedCandidateIndex]:this.solved?this.bestCandidate:this.lastProcessedCandidate||this.candidates[0],!e)return t;const n=new Map;for(const[t,s]of this.unravelSection.segmentPointMap){const o={...s},i=e.pointModifications.get(t);i&&(void 0!==i.x&&(o.x=i.x),void 0!==i.y&&(o.y=i.y),void 0!==i.z&&(o.z=i.z)),n.set(t,o)}for(const[e,s]of n)t.points.push({x:s.x,y:s.y,label:`${e}\nSegment: ${s.segmentId} ${this.unravelSection.mutableSegmentIds.has(s.segmentId)?"MUTABLE":"IMMUTABLE"}\nLayer: ${s.z}`,color:this.colorMap[s.connectionName]||"#000"});const s=new Map;for(const t of this.unravelSection.allNodeIds)s.set(t,{numTransitionCrossings:0,numSameLayerCrossings:0,numEntryExitLayerChanges:0,estPf:0});for(const t of e.issues){const e=s.get(t.capacityMeshNodeId);"transition_via"===t.type?e.numTransitionCrossings++:"same_layer_crossing"===t.type?e.numSameLayerCrossings++:"double_transition_crossing"!==t.type&&"single_transition_crossing"!==t.type||e.numEntryExitLayerChanges++}for(const[t,e]of s.entries()){const n=this.nodeMap.get(t);e.estPf=Sh(n,e.numSameLayerCrossings,e.numEntryExitLayerChanges,e.numTransitionCrossings)}for(const e of this.unravelSection.allNodeIds){const n=this.nodeMap.get(e),o=this.unravelSection.mutableNodeIds.includes(e),i=s.get(e),r=[`${e} (${o?"MUT":"IMM"})`,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`Pf: ${i.estPf.toFixed(3)}`,`TC: ${i.numTransitionCrossings}`,`SLC: ${i.numSameLayerCrossings}`,`EELC: ${i.numEntryExitLayerChanges}`].join("\n");t.rects.push({center:n.center,label:r,color:o?"green":"red",width:n.width/8,height:n.height/8})}for(const[e,s]of this.unravelSection.segmentPointsInSegment){if(s.length<=1)continue;const o=s.map(t=>n.get(t));for(let n=0;n<o.length-1;n++)t.lines.push({points:[{x:o[n].x,y:o[n].y},{x:o[n+1].x,y:o[n+1].y}],strokeColor:this.colorMap[e]||"#000"})}for(const[e,s]of n)for(const o of s.directlyConnectedSegmentPointIds)if(e<o){const e=n.get(o);if(!e)continue;const i=s.z===e.z,r=s.z;let a;a=i?0===r?void 0:"10 5":"3 3 10",t.lines.push({points:[{x:s.x,y:s.y},{x:e.x,y:e.y}],strokeDash:a,strokeColor:this.colorMap[s.connectionName]||"#000"})}for(const s of e.issues){const e=this.nodeMap.get(s.capacityMeshNodeId);if("transition_via"===s.type)for(const o of s.segmentPoints){const s=n.get(o);t.circles.push({center:{x:s.x,y:s.y},radius:e.width/16,stroke:"#ff0000",fill:"rgba(255, 0, 0, 0.2)",label:`Via Issue\n${o}\nLayer: ${s.z}`})}else if("same_layer_crossing"===s.type)for(const[o,i]of[s.crossingLine1,s.crossingLine2]){const s=n.get(o),r=n.get(i);t.lines.push({points:[{x:s.x,y:s.y},{x:r.x,y:r.y}],strokeColor:"rgba(255,0,0,0.2)",strokeWidth:e.width/32})}}for(const[s,o]of e.pointModifications){const e=n.get(s),o=this.unravelSection.segmentPointMap.get(s);t.circles.push({center:{x:e.x,y:e.y},radius:.05,stroke:"#0000ff",fill:"rgba(0, 0, 255, 0.2)",label:`${s}\nOriginal: (${o.x.toFixed(2)}, ${o.y.toFixed(2)}, ${o.z})\nNew: (${e.x.toFixed(2)}, ${e.y.toFixed(2)}, ${e.z})`})}return t}};import gd from"object-hash";var yd=t=>(Math.round(20*t)/20).toFixed(2),xd=t=>(Math.round(1e3*t)/1e3).toFixed(3);Ne();var vd=class extends md{cacheHit=!1;cacheProvider;hasAttemptedToUseCache=!1;constructor(t){super(t),this.cacheProvider=void 0===t.cacheProvider?Se():t.cacheProvider}_step(){!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync()||(super._step(),(this.solved||this.failed)&&this.cacheProvider&&this.saveToCacheSync())}computeCacheKeyAndTransform(){const t=this.nodeMap.get(this.rootNodeId),e=y(-t.center.x,-t.center.y),n=new Map,s=new Map,o=new Map,i=new Map,r=new Map,a=new Map;let c=0,h=0,l=0;const d=[...this.unravelSection.allNodeIds].sort((t,e)=>{const n=this.nodeMap.get(t),s=this.nodeMap.get(e);return n.center.x!==s.center.x?n.center.x-s.center.x:n.center.y-s.center.y});for(const t of d){const e="node_"+c++;n.set(t,e),s.set(e,t)}const u=[...Array.from(this.unravelSection.segmentPointMap.entries()).sort(([,t],[,e])=>t.x!==e.x?t.x-e.x:t.y-e.y).map(([t])=>t)].sort();for(const t of u){const e="sp_"+l++;r.set(t,e),a.set(e,t);const n=this.unravelSection.segmentPointMap.get(t).segmentId;if(!o.has(n)){const t="seg_"+h++;o.set(n,t),i.set(t,n)}}const p={};for(const[t,s]of n.entries()){const n=this.nodeMap.get(t),o=g(e,n.center);p[s]={width:n.width,height:n.height,availableZ:n.availableZ,center:{x:yd(o.x),y:yd(o.y)}}}const f={};for(const[t,n]of r.entries()){const s=this.unravelSection.segmentPointMap.get(t),o=g(e,{x:s.x,y:s.y});f[n]={x:yd(o.x),y:yd(o.y),z:s.z}}const m={hyperParameters:this.hyperParameters,normalizedNodes:p,normalizedSegmentPoints:f,mutableHops:this.MUTABLE_HOPS},x=`unravelsec:${gd(m)}`,v={realToCacheTransform:e,nodeIdMap:n,segmentIdMap:o,segmentPointIdMap:r,reverseNodeIdMap:s,reverseSegmentIdMap:i,reverseSegmentPointIdMap:a};return this.cacheKey=x,this.cacheToSolveSpaceTransform=v,{cacheKey:x,cacheToSolveSpaceTransform:v}}applyCachedSolution(t){if(!1===t.success)return void(this.failed=!0);if(!this.cacheToSolveSpaceTransform)return void console.error("Cache transform not available to apply cached solution.");const{reverseSegmentPointIdMap:e,reverseNodeIdMap:n}=this.cacheToSolveSpaceTransform,s=new Map;for(const[n,o]of t.bestCandidatePointModificationsDelta){const t=e.get(n);if(!t){console.warn(`Could not find original ID for normalized SP ID: ${n} when applying cache.`);continue}const i=this.unravelSection.segmentPointMap.get(t);if(!i){console.warn(`Could not find original segment point for ID: ${t} when applying cache.`);continue}const r={};if(void 0!==o.dx){const t=parseFloat(o.dx);Number.isNaN(t)?console.warn(`Failed to parse cached dx coordinate: ${o.dx}`):r.x=i.x+t}if(void 0!==o.dy){const t=parseFloat(o.dy);Number.isNaN(t)?console.warn(`Failed to parse cached dy coordinate: ${o.dy}`):r.y=i.y+t}void 0!==o.dz&&(r.z=i.z+o.dz),Object.keys(r).length>0&&s.set(t,r)}const o=ud(this.unravelSection,this.nodeMap,s);this.bestCandidate={pointModifications:s,issues:o,f:t.bestCandidateF,g:t.bestCandidateF,h:0,operationsPerformed:-1,candidateHash:ld(s)},this.cacheHit=!0,this.solved=!0}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return console.log("Cache provider is not synchronous, skipping sync cache check."),!1;if(this.cacheKey||this.computeCacheKeyAndTransform(),!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(this.failed)return void this.cacheProvider?.setCachedSolutionSync(this.cacheKey,{success:!1});if(!this.bestCandidate)return;const{segmentPointIdMap:t}=this.cacheToSolveSpaceTransform,e=[];for(const[n,s]of this.bestCandidate.pointModifications.entries()){const o=t.get(n);if(!o){console.warn(`Could not find normalized ID for original SP ID: ${n} when saving to cache.`);continue}const i=this.unravelSection.segmentPointMap.get(n);if(!i){console.warn(`Could not find original segment point for ID: ${n} when saving cache.`);continue}const r={};let a=!1;if(void 0!==s.x){const t=s.x-i.x,e=xd(t);0!==parseFloat(e)&&(r.dx=e,a=!0)}if(void 0!==s.y){const t=s.y-i.y,e=xd(t);0!==parseFloat(e)&&(r.dy=e,a=!0)}if(void 0!==s.z){const t=s.z-i.z;0!==t&&(r.dz=t,a=!0)}a&&e.push([o,r])}const n={success:!0,bestCandidatePointModificationsDelta:e,bestCandidateF:this.bestCandidate.f};this.cacheProvider?.setCachedSolutionSync(this.cacheKey,n)}},bd=class extends Ln{getSolverName(){return"UnravelMultiSectionSolver"}nodeMap;dedupedSegmentMap;dedupedSegments;nodeIdToSegmentIds;segmentIdToNodeIds;nodeToSegmentPointMap;segmentToSegmentPointMap;colorMap;tunedNodeCapacityMap;MAX_NODE_ATTEMPTS=2;MUTABLE_HOPS=1;ACCEPTABLE_PF=.05;MAX_ITERATIONS_WITHOUT_IMPROVEMENT=200;nodePfMap;attemptsToFixNode;activeSubSolver=null;segmentPointMap;cacheProvider=null;constructor({assignedSegments:t,colorMap:e,nodes:n,cacheProvider:s}){super(),this.stats.successfulOptimizations=0,this.stats.failedOptimizations=0,this.stats.cacheHits=0,this.stats.cacheMisses=0,this.cacheProvider=s??null,this.MAX_ITERATIONS=1e6,this.dedupedSegments=(t=>{const e=[],n=new Map;let s=-1;for(const o of t){const t=`${o.start.x}-${o.start.y}-${o.end.x}-${o.end.y}-${o.availableZ.join(",")}`,i=n.get(t);i?o.nodePortSegmentId=i.nodePortSegmentId:(s++,o.nodePortSegmentId=`SEG${s}`,n.set(t,o),e.push(o))}return e})(t),this.dedupedSegmentMap=new Map;for(const t of this.dedupedSegments)this.dedupedSegmentMap.set(t.nodePortSegmentId,t);this.nodeMap=new Map;for(const t of n)this.nodeMap.set(t.capacityMeshNodeId,t);this.nodeIdToSegmentIds=new Map,this.segmentIdToNodeIds=new Map,this.attemptsToFixNode=new Map;for(const e of t)this.segmentIdToNodeIds.set(e.nodePortSegmentId,[...this.segmentIdToNodeIds.get(e.nodePortSegmentId)??[],e.capacityMeshNodeId]),this.nodeIdToSegmentIds.set(e.capacityMeshNodeId,[...this.nodeIdToSegmentIds.get(e.capacityMeshNodeId)??[],e.nodePortSegmentId]);this.colorMap=e??{},this.tunedNodeCapacityMap=new Map;for(const[t,e]of this.nodeMap)this.tunedNodeCapacityMap.set(t,bh(e));const{segmentPointMap:o,nodeToSegmentPointMap:i,segmentToSegmentPointMap:r}=fd(this.dedupedSegments,this.segmentIdToNodeIds);this.segmentPointMap=o,this.nodeToSegmentPointMap=i,this.segmentToSegmentPointMap=r,this.nodePfMap=this.computeInitialPfMap()}computeInitialPfMap(){const t=new Map;for(const[e,n]of this.nodeMap.entries())t.set(e,this.computeNodePf(n));return t}computeNodePf(t){const{numSameLayerCrossings:e,numEntryExitLayerChanges:n,numTransitionCrossings:s}=(t=>{let e=0,n=0,s=0;const o=new Map;for(const e of t)o.has(e.connectionName)||o.set(e.connectionName,[]),o.get(e.connectionName).push(e);const i=[],r=[];for(const[t,e]of o.entries()){if(e.length<2)continue;const s=e[0];for(let o=1;o<e.length;o++){const a=e[o],c={connectionName:t,z:s.z,points:[s,a]};s.z!==a.z?(n++,r.push({connectionName:t,points:[s,a]})):i.push(c)}}for(let t=0;t<i.length;t++)for(let n=t+1;n<i.length;n++){const s=i[t],o=i[n];s.z===o.z&&L(s.points[0],s.points[1],o.points[0],o.points[1])&&e++}for(let t=0;t<r.length;t++)for(let e=t+1;e<r.length;e++){const n=r[t],o=r[e];L(n.points[0],n.points[1],o.points[0],o.points[1])&&s++}for(let t=0;t<r.length;t++)for(let e=0;e<i.length;e++){const n=r[t],o=i[e];L(n.points[0],n.points[1],o.points[0],o.points[1])&&s++}return{numSameLayerCrossings:e,numEntryExitLayerChanges:n,numTransitionCrossings:s}})((this.nodeToSegmentPointMap.get(t.capacityMeshNodeId)??[]).map(t=>this.segmentPointMap.get(t)));return Sh(t,e,n,s)}_step(){if(this.iterations>=this.MAX_ITERATIONS-1)return void(this.solved=!0);if(!this.activeSubSolver){let t=null,e=0;for(const[n,s]of this.nodePfMap.entries()){s*(1-(this.attemptsToFixNode.get(n)??0)/this.MAX_NODE_ATTEMPTS)>e&&(e=s,t=n)}if(!t||e<this.ACCEPTABLE_PF)return void(this.solved=!0);this.attemptsToFixNode.set(t,(this.attemptsToFixNode.get(t)??0)+1),this.activeSubSolver=new vd({dedupedSegments:this.dedupedSegments,dedupedSegmentMap:this.dedupedSegmentMap,nodeMap:this.nodeMap,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,colorMap:this.colorMap,rootNodeId:t,MUTABLE_HOPS:this.MUTABLE_HOPS,segmentPointMap:this.segmentPointMap,nodeToSegmentPointMap:this.nodeToSegmentPointMap,segmentToSegmentPointMap:this.segmentToSegmentPointMap,cacheProvider:this.cacheProvider})}this.activeSubSolver.step();const{bestCandidate:t,originalCandidate:e,lastProcessedCandidate:n}=this.activeSubSolver;if(this.activeSubSolver.failed)return this.stats.failedOptimizations+=1,void(this.activeSubSolver=null);if(this.activeSubSolver.solved){this.activeSubSolver.cacheHit?this.stats.cacheHits+=1:this.stats.cacheMisses+=1;if(t&&t.g<e.g){this.stats.successfulOptimizations+=1;for(const[e,n]of t.pointModifications.entries()){const t=this.segmentPointMap.get(e);t.x=n.x??t.x,t.y=n.y??t.y,t.z=n.z??t.z}for(const t of this.activeSubSolver.unravelSection.allNodeIds)this.nodePfMap.set(t,this.computeNodePf(this.nodeMap.get(t)))}else this.stats.failedOptimizations+=1;this.activeSubSolver=null}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Unravel Multi Section Solver"};for(const[e,n]of this.nodeMap.entries()){const s=this.nodePfMap.get(e)||0,o=Math.min(s,1),i=`rgb(${Math.floor(255*o)}, ${Math.floor(255*(1-o))}, 0)`;0===(this.attemptsToFixNode.get(e)??0)&&0===o||t.rects.push({center:n.center,label:[e,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`Pf: ${s.toFixed(3)}`].join("\n"),color:i,width:n.width/8,height:n.height/8})}for(const e of this.segmentPointMap.values()){const n=this.dedupedSegmentMap.get(e.segmentId);t.points.push({x:e.x,y:e.y,label:[e.segmentPointId,e.segmentId,`z: ${e.z}`,`segment.availableZ: ${n?.availableZ.join(",")}`].join("\n"),color:this.colorMap[e.connectionName]||"#000"})}const e=new Map;for(const t of this.segmentPointMap.values())e.has(t.segmentId)||e.set(t.segmentId,[]),e.get(t.segmentId).push(t);for(const[n,s]of e.entries()){if(s.length<2)continue;const e=[...s].sort((t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y);for(let s=0;s<e.length-1;s++)t.lines.push({points:[{x:e[s].x,y:e[s].y},{x:e[s+1].x,y:e[s+1].y}],strokeColor:this.colorMap[n]||"#000"})}const n=new Set,s=Array.from(this.segmentPointMap.values());for(let e=0;e<s.length;e++){const o=s[e];for(let i=e+1;i<s.length;i++){const e=s[i];if(o.connectionName!==e.connectionName||o.segmentId===e.segmentId)continue;if(o.capacityMeshNodeIds.some(t=>e.capacityMeshNodeIds.includes(t))){const s=`${o.segmentPointId}-${e.segmentPointId}`;if(n.has(s))continue;n.add(s);const i=o.z===e.z,r=o.z;let a;a=i?0===r?void 0:"10 5":"3 3 10",t.lines.push({points:[{x:o.x,y:o.y},{x:e.x,y:e.y}],strokeDash:a,strokeColor:this.colorMap[o.connectionName]||"#666"})}}}return t}getNodesWithPortPoints(){if(!this.solved)throw new Error("CapacitySegmentToPointSolver not solved, can't give port points yet");const t=new Map;for(const e of this.dedupedSegments){const n=e.nodePortSegmentId;for(const e of this.segmentIdToNodeIds.get(n)){const n=this.nodeMap.get(e);t.has(e)||t.set(e,{capacityMeshNodeId:e,portPoints:[],center:n.center,width:n.width,height:n.height})}}for(const e of this.segmentPointMap.values())for(const n of e.capacityMeshNodeIds){const s=t.get(n);s&&s.portPoints.push({x:e.x,y:e.y,z:e.z,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName})}return Array.from(t.values())}};function Pd(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var Sd=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=Ph(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AutoroutingPipeline1_OriginalUnravel"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;initialPathingSolver;pathingOptimizer;edgeToPortSegmentSolver;colorMap;segmentToPointSolver;unravelMultiSectionSolver;segmentToPointOptimizer;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;viaDiameter;minTraceWidth;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[Pd("netToPointPairsSolver",Uh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),Pd("nodeSolver",Xl,t=>[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.finishedNodes}}),Pd("singleLayerNodeMerger",ad,t=>[t.nodeSolver?.finishedNodes],{onSolved:t=>{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),Pd("strawSolver",cd,t=>[{nodes:t.singleLayerNodeMerger?.newNodes}],{onSolved:t=>{t.capacityNodes=t.strawSolver?.getResultNodes()}}),Pd("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Pd("deadEndSolver",od,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=>{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=>!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=>t.nodeIds.every(t=>!e.has(t)))}}),Pd("initialPathingSolver",Wl,t=>[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}]),Pd("pathingOptimizer",sd,t=>[{initialPathingSolver:t.initialPathingSolver,simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,cacheProvider:t.cacheProvider,hyperParameters:{MAX_CAPACITY_FACTOR:1}}]),Pd("edgeToPortSegmentSolver",Ol,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.pathingOptimizer?.getCapacityPaths()||[],colorMap:t.colorMap}]),Pd("segmentToPointSolver",kl,t=>{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments&&t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=>{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),Pd("unravelMultiSectionSolver",bd,t=>[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),Pd("highDensityRouteSolver",ph,t=>[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),Pd("highDensityStitchSolver",id,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),Pd("traceSimplificationSolver",Cl,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.initialPathingSolver?.visualize(),c=this.pathingOptimizer?.visualize(),h=this.edgeToPortSegmentSolver?.visualize(),l=this.segmentToPointSolver?.visualize(),d=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),u=this.highDensityRouteSolver?.visualize(),p=this.highDensityStitchSolver?.visualize(),f=this.traceSimplificationSolver?.visualize(),m=this.srj.outline,g=[];if(g.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),m&&m.length>=2){const t=m.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),g.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const y={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:g},x=[y,t,e,n,s,o,i,r,a,c,h,l,d,u?jn(y,u):null,p,f,this.solved?jn(y,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...x)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path&&t.push({points:e.path.map(t=>({x:t.center.x,y:t.center.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}};function Md(t){const{pos:e,segments:n,dir:s,keepoutRadius:o}=t;let i=1/0;const r=o/4,a={x:e.x-s.x*r,y:e.y-s.y*r},c={x:e.x+s.x*r,y:e.y+s.y*r};for(const t of n){const e=K(a,c,t.start,t.end);i=Math.min(i,e)}return i}function Nd(t,e,n,s){const o=Id(n,s,t),i=Id(n,s,e),r=Id(t,e,n),a=Id(t,e,s);if((o>0&&i<0||o<0&&i>0)&&(r>0&&a<0||r<0&&a>0))return!0;const c=1e-4;return!!(Math.abs(o)<c&&_d(n,s,t))||(!!(Math.abs(i)<c&&_d(n,s,e))||(!!(Math.abs(r)<c&&_d(t,e,n))||!!(Math.abs(a)<c&&_d(t,e,s))))}function Id(t,e,n){return(n.x-t.x)*(e.y-t.y)-(e.x-t.x)*(n.y-t.y)}function _d(t,e,n){return n.x>=Math.min(t.x,e.x)-1e-4&&n.x<=Math.max(t.x,e.x)+1e-4&&n.y>=Math.min(t.y,e.y)-1e-4&&n.y<=Math.max(t.y,e.y)+1e-4}function Cd(t,e,n){for(const s of n)if(Nd(t,e,s.start,s.end))return!1;return!0}var Td=1e-4;function Ed(t){const e=t.width/2,n=t.height/2,s=t.center.x,o=t.center.y,i={x:s-e,y:o+n},r={x:s+e,y:o+n},a={x:s-e,y:o-n},c={x:s+e,y:o-n};return[{start:i,end:r},{start:r,end:c},{start:c,end:a},{start:a,end:i}]}function wd(t,e,n=.1){const s=e.x-t.x,o=e.y-t.y,i=Math.sqrt(s*s+o*o);if(0===i)return[];const r=-(o/i),a=s/i,c=n/2;return[{start:{x:t.x+r*c,y:t.y+a*c},end:{x:e.x+r*c,y:e.y+a*c}},{start:{x:t.x-r*c,y:t.y-a*c},end:{x:e.x-r*c,y:e.y-a*c}}]}function Rd(t,e,n){const s=Math.hypot(t.start.x-e.x,t.start.y-e.y),o=Math.hypot(t.end.x-e.x,t.end.y-e.y);if(s<=n||o<=n)return!0;const i=t.end.x-t.start.x,r=t.end.y-t.start.y,a=i*i+r*r;if(0===a)return!1;const c=Math.max(0,Math.min(1,((e.x-t.start.x)*i+(e.y-t.start.y)*r)/a)),h=t.start.x+c*i,l=t.start.y+c*r;return Math.hypot(h-e.x,l-e.y)<=n}function Od(t,e,n){if(!n||0===n.length)return!1;for(const s of n){const n=Math.abs(t.x-s.start.x)<Td&&Math.abs(t.y-s.start.y)<Td&&Math.abs(e.x-s.end.x)<Td&&Math.abs(e.y-s.end.y)<Td,o=Math.abs(t.x-s.end.x)<Td&&Math.abs(t.y-s.end.y)<Td&&Math.abs(e.x-s.start.x)<Td&&Math.abs(e.y-s.start.y)<Td;if(n||o)return!0}return!1}function Ad(t,e,n,s,o){const i=[];for(let r=0;r<t.length-1;r++){const a=t[r],c=t[r+1];Od(a,c,o)||Rd({start:a,end:c},n,s+e)&&i.push(...wd(a,c,e))}return i}var zd=1e-4;function Dd(t,e,n,s){const o=e.x-t.x,i=e.y-t.y,r=s.x-n.x,a=s.y-n.y,c=o*a-i*r;if(Math.abs(c)<1e-10)return null;const h=n.x-t.x,l=n.y-t.y,d=(h*a-l*r)/c,u=(h*i-l*o)/c,p=1e-6;return d>p&&d<.999999&&u>p&&u<.999999?{x:t.x+d*o,y:t.y+d*i}:null}function Ld(t,e){if(!e||0===e.length)return!1;for(const n of e)if(Math.abs(t.x-n.start.x)<zd&&Math.abs(t.y-n.start.y)<zd||Math.abs(t.x-n.end.x)<zd&&Math.abs(t.y-n.end.y)<zd)return!0;return!1}function Fd(t,e,n,s){if(!s||0===s.length)return!1;for(let o=e;o<=n;o++)if(o>=0&&o<t.length&&Ld(t[o],s))return!0;return!1}var Yd=1e-4,Xd=class extends Ln{constructor(t){super(),this.input=t;const e=t.srj?.layerCount??2;this.input={...t,obstacles:dl(t.obstacles,e)},this.MAX_ITERATIONS=1e6,this.originalHdRoutes=[...this.input.hdRoutes],this.hdRoutes=this.input.hdRoutes,this.KEEPOUT_RADIUS_SCHEDULE=t.keepoutRadiusSchedule??[.3,.5,.5],this.currentKeepoutRadius=this.KEEPOUT_RADIUS_SCHEDULE[0]??.15,this.unprocessedRoutes=[...this.hdRoutes],this.smoothedCursorRoutes=[...this.unprocessedRoutes];const n=[...this.input.obstacles,...this.getJumperPadObstacles()];this.obstacleSHI=new sl("flatbush",n),this.boardOutlineRoutes=this.createBoardOutlineRoutes(),this.hdRouteSHI=new hl([...this.hdRoutes,...this.boardOutlineRoutes]);for(const[t,e,n]of this.hdRoutes.flatMap(t=>[[t.route[0],t.connectionName,t.rootConnectionName],[t.route[t.route.length-1],t.connectionName,t.rootConnectionName]])){const s=this.obstacleSHI.searchArea(t.x,t.y,.01,.01).filter(e=>e.zLayers?.includes(t.z));if(0===s.length)continue;const o=s[0];this.input.connMap.addConnections([[e,n,...o.offBoardConnectsTo??[],o.obstacleId,...o.connectedTo].filter(Boolean)])}}getSolverName(){return"TraceKeepoutSolver"}originalHdRoutes;hdRoutes;redrawnHdRoutes=[];KEEPOUT_RADIUS_SCHEDULE;currentScheduleIndex=0;currentKeepoutRadius;unprocessedRoutes=[];smoothedCursorRoutes=[];processedRoutes=[];currentTrace=null;cursorPosition=null;lastCursorPosition=null;drawPosition=null;currentTraceSegmentIndex=0;currentTraceSegmentT=0;recordedDrawPositions=[];lastCollidingSegments=[];currentTraceJumperSegments=new Map;obstacleSHI;hdRouteSHI;boardOutlineRoutes=[];getSmoothDistance(){return this.currentKeepoutRadius}getJumperPadObstacles(){const t=[];if(!this.input.jumpers)return t;for(const e of this.input.jumpers)for(const n of e.pads)t.push({...n,zLayers:[0]});return t}buildJumperSegmentMap(t){const e=new Map;if(!t.jumpers||0===t.jumpers.length)return e;const n=t.route;for(const s of t.jumpers){let t=-1,o=1/0;for(let e=0;e<n.length-1;e++){const i=n[e],r=n[e+1],a=Math.sqrt((i.x-s.start.x)**2+(i.y-s.start.y)**2),c=Math.sqrt((r.x-s.end.x)**2+(r.y-s.end.y)**2),h=a+c,l=Math.sqrt((i.x-s.end.x)**2+(i.y-s.end.y)**2),d=Math.sqrt((r.x-s.start.x)**2+(r.y-s.start.y)**2),u=l+d,p=Math.min(h,u);(h<=u?a:l)<1&&(h<=u?c:d)<1&&p<o&&(o=p,t=e)}t>=0&&e.set(t,s)}return e}_step(){if(!this.currentTrace){const t=this.unprocessedRoutes.shift();if(!t)return this.currentScheduleIndex++,this.currentScheduleIndex<this.KEEPOUT_RADIUS_SCHEDULE.length?(this.currentKeepoutRadius=this.KEEPOUT_RADIUS_SCHEDULE[this.currentScheduleIndex],this.unprocessedRoutes=Gn([...this.processedRoutes],this.currentScheduleIndex),this.smoothedCursorRoutes=[...this.unprocessedRoutes],this.processedRoutes=[],void(this.hdRouteSHI=new hl([...this.unprocessedRoutes,...this.boardOutlineRoutes]))):(this.redrawnHdRoutes=this.processedRoutes,void(this.solved=!0));if(this.currentTrace=t,this.currentTrace.route.length<2)return this.processedRoutes.push(this.currentTrace),void(this.currentTrace=null);this.currentTraceJumperSegments=this.buildJumperSegmentMap(this.currentTrace);const e=this.currentTrace.route[0];return this.cursorPosition={...e},this.lastCursorPosition={...e},this.drawPosition={x:e.x,y:e.y},this.currentTraceSegmentIndex=0,this.currentTraceSegmentT=0,void(this.recordedDrawPositions=[{...e}])}this.lastCursorPosition={...this.cursorPosition};const t=this.stepCursorForward();if("end"===t)return void this.finalizeCurrentTrace();if("jumper"===t)return void(this.drawPosition={x:this.cursorPosition.x,y:this.cursorPosition.y});const e=this.getCollidingSegments(this.cursorPosition);this.lastCollidingSegments=e;const n=function(t){const{cursorPosition:e,lastCursorPosition:n,collidingSegments:s,keepoutRadius:o}=t;if(0===s.length)return null;const i=1e-4,r=e.x-n.x,a=e.y-n.y,c=Math.sqrt(r*r+a*a),h=c>i?{x:r/c,y:a/c}:{x:1,y:0},l=-h.y,d=h.x,u=Md({pos:e,segments:s,dir:h,keepoutRadius:o});if(u>=o)return null;for(let t=1;t<=20;t++){const n=t/20*o,i={x:e.x+l*n,y:e.y+d*n},r=Md({pos:i,segments:s,dir:h,keepoutRadius:o}),a={x:e.x-l*n,y:e.y-d*n},c=Md({pos:a,segments:s,dir:h,keepoutRadius:o}),u=r>=o&&Cd(e,i,s),p=c>=o&&Cd(e,a,s);if(u&&p)return r>=c?i:a;if(u)return i;if(p)return a}const p=o,f=[];for(let t=-60;t<=60;t++){const n=t/60*p,i={x:e.x+l*n,y:e.y+d*n},r=Md({pos:i,segments:s,dir:h,keepoutRadius:o}),a=Cd(e,i,s);f.push({pos:i,clearance:r,dist:Math.abs(n),pathClear:a,index:t})}const m=f.filter(t=>t.pathClear),g=f.findIndex(t=>0===t.index),y=g>=0?g:Math.floor(f.length/2);let x=null;for(let t=y+1;t<f.length-1;t++){const e=f[t-1],n=f[t],s=f[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){x=n;break}}let v=null;for(let t=y-1;t>0;t--){const e=f[t-1],n=f[t],s=f[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){v=n;break}}let b=null,P=null;if(m.length>0){const t=m.findIndex(t=>0===t.index),e=t>=0?t:Math.floor(m.length/2);for(let t=e+1;t<m.length-1;t++){const e=m[t-1],n=m[t],s=m[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){b=n;break}}for(let t=e-1;t>0;t--){const e=m[t-1],n=m[t],s=m[t+1];if(n.clearance>=e.clearance&&n.clearance>=s.clearance){P=n;break}}}const S=[x,v,b,P,f.find(t=>0===t.index)].filter(t=>null!=t),M=new Set,N=S.filter(t=>{const e=`${t.pos.x.toFixed(6)},${t.pos.y.toFixed(6)}`;return!M.has(e)&&(M.add(e),!0)});if(0===N.length){let t=f[0];if(!t)return null;for(const e of f)e.clearance>t.clearance&&(t=e);return Math.sqrt((t.pos.x-e.x)**2+(t.pos.y-e.y)**2)>i?t.pos:null}let I;if(u<.15*o){I=N[0];for(const t of N)t.clearance>I.clearance&&(I=t)}else{const t=N.filter(t=>t.pathClear),e=t.length>0?t:N;I=e[0];for(const t of e)t.clearance>I.clearance&&(I=t)}return Math.sqrt((I.pos.x-e.x)**2+(I.pos.y-e.y)**2)>i?I.pos:null}({cursorPosition:this.cursorPosition,lastCursorPosition:this.lastCursorPosition,collidingSegments:e,keepoutRadius:this.currentKeepoutRadius});this.drawPosition=n??{...this.cursorPosition};const s=this.recordedDrawPositions[this.recordedDrawPositions.length-1];if(s&&this.drawPosition){const t={x:s.x,y:s.y,z:s.z},e={x:this.drawPosition.x,y:this.drawPosition.y,z:this.cursorPosition.z};this.segmentIntersectsOtherRoutes(t,e)&&(this.drawPosition={...this.cursorPosition})}this.recordedDrawPositions.push({x:this.drawPosition.x,y:this.drawPosition.y,z:this.cursorPosition.z})}getStepDistance(){return this.currentKeepoutRadius/2}getJumperAtCurrentSegmentStart(){return this.currentTraceSegmentT>Yd?null:this.currentTraceJumperSegments.get(this.currentTraceSegmentIndex)??null}stepCursorForward(){if(!this.currentTrace||!this.cursorPosition)return"end";const t=this.currentTrace.route;let e=this.getStepDistance();for(;e>0;){if(this.currentTraceSegmentIndex>=t.length-1)return"end";const n=this.getJumperAtCurrentSegmentStart();if(n){const e=t[this.currentTraceSegmentIndex],s=t[this.currentTraceSegmentIndex+1],o=Math.sqrt((e.x-n.start.x)**2+(e.y-n.start.y)**2),i=Math.sqrt((e.x-n.end.x)**2+(e.y-n.end.y)**2),r=o<=i?n.start:n.end,a=o<=i?n.end:n.start;return this.recordedDrawPositions.push({x:r.x,y:r.y,z:e.z,insideJumperPad:!0}),this.recordedDrawPositions.push({x:a.x,y:a.y,z:s.z,insideJumperPad:!0}),this.cursorPosition={x:a.x,y:a.y,z:s.z},this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,"jumper"}const s=t[this.currentTraceSegmentIndex],o=t[this.currentTraceSegmentIndex+1],i=o.x-s.x,r=o.y-s.y,a=Math.sqrt(i*i+r*r);if(0===a){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const c=this.currentTraceSegmentT*a,h=a-c;if(e<=h){const t=c+e;return this.currentTraceSegmentT=t/a,this.cursorPosition={x:s.x+i*this.currentTraceSegmentT,y:s.y+r*this.currentTraceSegmentT,z:s.z},"stepped"}if(e-=h,this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,this.currentTraceSegmentIndex>=t.length-1){const e=t[t.length-1];return this.cursorPosition={...e},"end"}}return"stepped"}getCollidingSegments(t){if(!this.currentTrace)return[];const e=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,n=2*this.currentKeepoutRadius,s=[],o=this.obstacleSHI.searchArea(t.x,t.y,n,n).filter(e=>e.zLayers?.includes(t.z));for(const n of o){if(n.zLayers&&!n.zLayers.includes(t.z))continue;if(n.connectedTo.includes(e))continue;if(n.obstacleId&&this.input.connMap.areIdsConnected(e,n.obstacleId))continue;let o=!1;for(const t of n.connectedTo)if(this.input.connMap.areIdsConnected(e,t)){o=!0;break}o||s.push(...Ed(n))}const i=this.hdRouteSHI.getConflictingRoutesNearPoint({x:t.x,y:t.y,z:t.z},n);for(const{conflictingRoute:o}of i){const i=o.rootConnectionName??o.connectionName;if(i===e)continue;if(this.input.connMap.areIdsConnected(e,i))continue;const r=o.traceThickness??.15;s.push(...Ad(o.route,r,{x:t.x,y:t.y},n,o.jumpers))}return s}positionHasCollision(t,e=0){const n=this.getCollidingSegments(t);for(const s of n)if(X(t,s.start,s.end)<=this.currentKeepoutRadius+e)return!0;return!1}segmentIntersectsOtherRoutes(t,e){if(!this.currentTrace)return!1;const n=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,s=[...this.unprocessedRoutes,...this.smoothedCursorRoutes,...this.processedRoutes];for(const o of s){if((o.rootConnectionName??o.connectionName)!==n)for(let n=0;n<o.route.length-1;n++){const s=o.route[n],i=o.route[n+1];if((s.z===t.z||i.z===t.z)&&((!s.insideJumperPad||!i.insideJumperPad)&&L({x:t.x,y:t.y},{x:e.x,y:e.y},{x:s.x,y:s.y},{x:i.x,y:i.y})))return!0}}return!1}finalizeCurrentTrace(){if(!this.currentTrace)return;const t=this.currentTrace.route[this.currentTrace.route.length-1],e=this.recordedDrawPositions[this.recordedDrawPositions.length-1];e&&e.x===t.x&&e.y===t.y||this.recordedDrawPositions.push({...t});const n=function(t,e){if(t.length<4)return t;let n=[...t],s=!0;for(;s;){s=!1;for(let t=0;t<n.length-1&&!s;t++){const o=n[t],i=n[t+1];if(o.z===i.z)for(let r=t+2;r<n.length-1&&!s;r++){if(r===t+1)continue;const a=n[r],c=n[r+1];if(a.z!==c.z||o.z!==a.z)continue;const h=Dd(o,i,a,c);if(h){if(Fd(n,t+1,r,e))continue;const i=[];for(let e=0;e<=t;e++)i.push(n[e]);i.push({x:h.x,y:h.y,z:o.z});for(let t=r+1;t<n.length;t++)i.push(n[t]);n=i,s=!0}}}}return n}(this.simplifyRoute(this.recordedDrawPositions,this.currentTrace.jumpers),this.currentTrace.jumpers),s={connectionName:this.currentTrace.connectionName,rootConnectionName:this.currentTrace.rootConnectionName,traceThickness:this.currentTrace.traceThickness,viaDiameter:this.currentTrace.viaDiameter,route:n,vias:[...this.currentTrace.vias],jumpers:this.currentTrace.jumpers};this.processedRoutes.push(s),this.hdRouteSHI.removeRoute(this.currentTrace.connectionName),this.hdRouteSHI.addRoute(s),this.currentTrace=null,this.cursorPosition=null,this.lastCursorPosition=null,this.drawPosition=null,this.recordedDrawPositions=[]}isJumperEndpoint(t,e){if(!e||0===e.length)return!1;for(const n of e)if(Math.abs(t.x-n.start.x)<Yd&&Math.abs(t.y-n.start.y)<Yd||Math.abs(t.x-n.end.x)<Yd&&Math.abs(t.y-n.end.y)<Yd)return!0;return!1}simplifyRoute(t,e){if(t.length<=2)return t;const n=[t[0]];for(let s=1;s<t.length-1;s++){const o=n[n.length-1],i=t[s],r=t[s+1];if(this.isJumperEndpoint(i,e)){n.push(i);continue}if(i.z!==o.z||i.z!==r.z){n.push(i);continue}const a=i.x-o.x,c=i.y-o.y,h=r.x-i.x,l=a*(r.y-i.y)-c*h,d=1e-6;Math.abs(l)>d&&n.push(i)}return n.push(t[t.length-1]),n}createBoardOutlineRoutes(){const t=[];if(!this.input.srj)return t;const{outline:e,bounds:n}=this.input.srj;let s;s=e&&e.length>=3?e:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}];const o=this.input.srj.layerCount??2;for(let e=0;e<s.length;e++){const n=s[e],i=s[(e+1)%s.length];for(let s=0;s<o;s++)t.push({connectionName:`__board_outline___${e}_z${s}`,traceThickness:.01,viaDiameter:0,route:[{x:n.x,y:n.y,z:s},{x:i.x,y:i.y,z:s}],vias:[]})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:`Trace Keepout Solver (radius: ${this.currentKeepoutRadius.toFixed(2)})`};for(const e of this.originalHdRoutes)if(0!==e.route.length)for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:"rgba(0,0,0,0.25)",strokeWidth:1.5*(e.traceThickness??.15)})}if(this.input.jumpers)for(const e of this.input.jumpers){for(const n of e.pads){const e=n.connectedTo.length>0?n.connectedTo.join(", "):"unused",s=n.connectedTo.length>0?this.input.colorMap[n.connectedTo[0]]||"#888888":"rgba(128, 128, 128, 0.5)";t.rects.push({center:n.center,width:n.width,height:n.height,fill:s,stroke:"rgba(0, 0, 0, 0.5)",label:`Jumper pad (${e})`})}e.pads.length>=2&&t.lines.push({points:[e.pads[0].center,e.pads[1].center],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.2,label:"Jumper body"})}for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const s=e.zLayers?.includes(0),o=e.zLayers?.includes(1);s&&o?n="rgba(128, 0, 128, 0.2)":s?n="rgba(255, 0, 0, 0.2)":o&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}if(this.input.srj){const{outline:e,bounds:n}=this.input.srj;let s;s=e&&e.length>=3?e:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}];for(let e=0;e<s.length;e++){const n=s[e],o=s[(e+1)%s.length];t.lines.push({points:[{x:n.x,y:n.y},{x:o.x,y:o.y}],strokeColor:"rgba(0, 128, 0, 0.6)",strokeWidth:.1,label:"Board outline"})}}for(const e of this.processedRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888",s=new Set;if(e.jumpers&&e.jumpers.length>0)for(const t of e.jumpers)for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1],r=Math.abs(o.x-t.start.x)<Yd&&Math.abs(o.y-t.start.y)<Yd&&Math.abs(i.x-t.end.x)<Yd&&Math.abs(i.y-t.end.y)<Yd,a=Math.abs(o.x-t.end.x)<Yd&&Math.abs(o.y-t.end.y)<Yd&&Math.abs(i.x-t.start.x)<Yd&&Math.abs(i.y-t.start.y)<Yd;if(r||a){s.add(n);break}}for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];s.has(n)?t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:"rgba(128, 128, 128, 0.6)",strokeDash:"2 2",label:`${e.connectionName} (jumper segment - fixed)`}):o.z===i.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:0===o.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${o.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const s=Zh(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...s.rects??[]),t.lines.push(...s.lines??[])}}if(this.currentTrace&&this.recordedDrawPositions.length>0){this.input.colorMap[this.currentTrace.connectionName];for(let e=0;e<this.recordedDrawPositions.length-1;e++){const n=this.recordedDrawPositions[e],s=this.recordedDrawPositions[e+1];t.lines.push({points:[{x:n.x,y:n.y},{x:s.x,y:s.y}],strokeColor:"green",strokeWidth:this.currentTrace.traceThickness})}if(this.cursorPosition&&(t.circles.push({center:{x:this.cursorPosition.x,y:this.cursorPosition.y},radius:this.currentKeepoutRadius,stroke:"orange",fill:"none"}),t.points.push({x:this.cursorPosition.x,y:this.cursorPosition.y,color:"orange",label:"Cursor"}),this.lastCursorPosition)){const e=this.cursorPosition.x-this.lastCursorPosition.x,n=this.cursorPosition.y-this.lastCursorPosition.y,s=Math.sqrt(e*e+n*n),o=s>1e-4?{x:e/s,y:n/s}:{x:1,y:0},i=this.currentKeepoutRadius/4,r={x:this.cursorPosition.x-o.x*i,y:this.cursorPosition.y-o.y*i},a={x:this.cursorPosition.x+o.x*i,y:this.cursorPosition.y+o.y*i};t.lines.push({points:[r,a],strokeColor:"cyan",strokeWidth:.05,label:"Projected segment"})}this.drawPosition&&t.points.push({x:this.drawPosition.x,y:this.drawPosition.y,color:"lime",label:"Draw"});for(const e of this.lastCollidingSegments)t.lines.push({points:[{x:e.start.x,y:e.start.y},{x:e.end.x,y:e.end.y}],strokeColor:"rgba(255, 0, 255, 0.8)",strokeWidth:.02,label:"Colliding segment"})}if(!this.solved)for(const e of this.smoothedCursorRoutes)if(0!==e.route.length)for(let n=0;n<e.route.length-1;n++){const s=e.route[n],o=e.route[n+1];s.z===o.z&&t.lines.push({points:[{x:s.x,y:s.y},{x:o.x,y:o.y}],strokeColor:"gray"})}return t}getRedrawnHdRoutes(){return this.redrawnHdRoutes}},kd=class extends Ln{constructor(t){super(),this.input=t,this.unprocessedObstacles=dl(this.input.srj.obstacles,this.input.srj.layerCount).filter(t=>t.offBoardConnectsTo&&t.offBoardConnectsTo.length>0),this.unprocessedObstacles.forEach((t,e)=>{t.obstacleId=t.obstacleId??`__obs${e}`}),this.offBoardConnMap=new Vh({}),this.offBoardConnMap.addConnections(this.unprocessedObstacles.filter(t=>t.offBoardConnectsTo?.length).map(t=>[t.obstacleId,...t.offBoardConnectsTo??[]])),this.nodeTree=new $n(this.input.capacityMeshNodes)}getSolverName(){return"RelateNodesToOffBoardConnectionsSolver"}unprocessedObstacles;nodeTree;offBoardConnMap;nodesInNet=new Map;lastProcessedObstacle;_step(){const t=this.unprocessedObstacles.pop();if(this.lastProcessedObstacle=t,!t)return void(this.solved=!0);const e=this.offBoardConnMap.getNetConnectedToId(t.obstacleId),n=this.nodeTree.getNodesInArea(t.center.x,t.center.y,.01,.01).filter(e=>e.availableZ.some(e=>t.zLayers?.includes(e))).filter(e=>Math.abs(e.center.x-t.center.x)<.01&&Math.abs(e.center.y-t.center.y)<.01),s=n.map(t=>t.capacityMeshNodeId),o=this.nodesInNet.get(e)??[],i=[...o.map(t=>t.capacityMeshNodeId),...s];for(const t of o)t._offBoardConnectedCapacityMeshNodeIds=i;for(const t of n)t._offBoardConnectedCapacityMeshNodeIds=i,t._offBoardConnectionId=e;this.nodesInNet.set(e,[...o,...n])}getOutput(){return{capacityNodes:this.input.capacityMeshNodes}}visualize(){const t={rects:[],lines:[],points:[],circles:[]},e=new Set;for(const[t,n]of this.nodesInNet)for(const t of n)e.add(t.capacityMeshNodeId);for(const n of this.input.capacityMeshNodes)e.has(n.capacityMeshNodeId)||t.rects.push({center:n.center,width:n.width-.1,height:n.height-.1,fill:"rgba(0, 0, 0, 0.2)"});this.lastProcessedObstacle&&t.rects.push({center:this.lastProcessedObstacle.center,width:this.lastProcessedObstacle.width,height:this.lastProcessedObstacle.height,fill:"rgba(255, 0, 0, 0.5)"});for(const[e,n]of this.nodesInNet.entries()){for(const s of n)t.rects.push({center:s.center,width:s.width,height:s.height,fill:_n(e,.2),label:`OffBoardConn: ${e}`});for(const s of n)for(const o of n)s.capacityMeshNodeId!==o.capacityMeshNodeId&&t.lines.push({points:[s.center,o.center],strokeColor:_n(e,1)})}return t}},$d=.1,Bd=.1;function jd(t,e,n,s,o,i){return(o-t)*(s-e)-(i-e)*(n-t)}function Wd(t,e,n,s,o,i){return Math.min(t,n)<=o&&o<=Math.max(t,n)&&Math.min(e,s)<=i&&i<=Math.max(e,s)}function Hd(t,e,n,s,o,i,r,a){const c=jd(o,i,r,a,t,e),h=jd(o,i,r,a,n,s),l=jd(t,e,n,s,o,i),d=jd(t,e,n,s,r,a);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)||(!(0!==c||!Wd(o,i,r,a,t,e))||(!(0!==h||!Wd(o,i,r,a,n,s))||(!(0!==l||!Wd(t,e,n,s,o,i))||!(0!==d||!Wd(t,e,n,s,r,a)))))}function Ud(t,e,n,s,o,i){const r=o-n,a=i-s,c=t-n,h=e-s,l=r*r+a*a;if(0===l){return{x:n,y:s,distSq:c*c+h*h}}let d=(c*r+h*a)/l;d=Math.max(0,Math.min(1,d));const u=n+d*r,p=s+d*a,f=t-u,m=e-p;return{x:u,y:p,distSq:f*f+m*m}}var Vd=class extends Ln{getSolverName(){return"SimpleHighDensitySolver"}unsolvedNodes;allNodes;routes;colorMap;traceWidth;viaDiameter;numMovablePoints;currentNode=null;lastNode=null;currentNodeStep=0;routesInProgress=[];pushMargin;currentNodeBounds=null;constructor({nodePortPoints:t,colorMap:e,traceWidth:n=.1,viaDiameter:s=.3,pushMargin:o=.3,numMovablePoints:i=2}){if(super(),i<1||i>3)throw new Error(`numMovablePoints must be 1, 2, or 3, got ${i}`);this.allNodes=[...t],this.unsolvedNodes=[...t],this.colorMap=e??{},this.routes=[],this.traceWidth=n,this.viaDiameter=s,this.numMovablePoints=i,this.pushMargin=o,this.MAX_ITERATIONS=10*t.length+1}_step(){if(null===this.currentNode){if(0===this.unsolvedNodes.length)return void(this.solved=!0);this.lastNode=this.currentNode,this.currentNode=this.unsolvedNodes.pop(),this.currentNodeStep=0,this.routesInProgress=[],this._initializeRoutesForCurrentNode()}this.currentNodeStep>0&&this._runForceDirectedStep(),this.currentNodeStep++,this.currentNodeStep>=10&&(this._finalizeRoutesForCurrentNode(),this.lastNode=this.currentNode,this.currentNode=null)}_initializeRoutesForCurrentNode(){const t=this.currentNode,e=t.center.x-t.width/2,n=t.center.x+t.width/2,s=t.center.y-t.height/2,o=t.center.y+t.height/2;this.currentNodeBounds={minX:e,maxX:n,minY:s,maxY:o};const i=new Map;for(const e of t.portPoints)i.has(e.connectionName)||i.set(e.connectionName,[]),i.get(e.connectionName).push({x:e.x,y:e.y,z:e.z,rootConnectionName:e.rootConnectionName});for(const[t,e]of i){if(e.length<2)continue;const n=e[0],s=e[e.length-1],o=n.z,i=s.x-n.x,r=s.y-n.y,a=Math.sqrt(i*i+r*r),c=a>0?i/a:0,h=a>0?r/a:0,l=[];this.numMovablePoints>=1&&l.push({x:n.x+c*Bd,y:n.y+h*Bd,z:o,rootConnectionName:n.rootConnectionName,connectionName:t}),this.numMovablePoints>=2&&l.push({x:s.x-c*Bd,y:s.y-h*Bd,z:o,rootConnectionName:n.rootConnectionName,connectionName:t}),this.numMovablePoints>=3&&l.push({x:n.x+i/2,y:n.y+r/2,z:o,rootConnectionName:n.rootConnectionName,connectionName:t}),this.routesInProgress.push({connectionName:t,rootConnectionName:n.rootConnectionName,startPoint:{x:n.x,y:n.y,z:o},endPoint:{x:s.x,y:s.y,z:o},movablePoints:l})}}_runForceDirectedStep(){const t=this.currentNodeBounds,e=[];for(const t of this.routesInProgress)e.push(...t.movablePoints);const n=new Map;for(const t of e)n.set(t,{fx:0,fy:0});const s=.3+this.pushMargin,o=new Map;for(const t of this.routesInProgress){const e=[{x:t.startPoint.x,y:t.startPoint.y,movablePoint:null}];1===t.movablePoints.length?e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}):2===t.movablePoints.length?(e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}),e.push({x:t.movablePoints[1].x,y:t.movablePoints[1].y,movablePoint:t.movablePoints[1]})):3===t.movablePoints.length&&(e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}),e.push({x:t.movablePoints[2].x,y:t.movablePoints[2].y,movablePoint:t.movablePoints[2]}),e.push({x:t.movablePoints[1].x,y:t.movablePoints[1].y,movablePoint:t.movablePoints[1]})),e.push({x:t.endPoint.x,y:t.endPoint.y,movablePoint:null}),o.set(t,e)}for(const i of e){const e=n.get(i),r=i.x-t.minX,a=t.maxX-i.x,c=t.maxY-i.y,h=i.y-t.minY;r<s&&(e.fx+=$d*(s-r)),a<s&&(e.fx-=$d*(s-a)),h<s&&(e.fy+=$d*(s-h)),c<s&&(e.fy-=$d*(s-c));for(const t of this.routesInProgress){if(t.rootConnectionName===i.rootConnectionName)continue;const r=o.get(t);for(let t=0;t<r.length-1;t++){const o=r[t],a=r[t+1],c=Ud(i.x,i.y,o.x,o.y,a.x,a.y),h=Math.sqrt(c.distSq);if(h>0&&h<2*s){const t=i.x-c.x,s=i.y-c.y,r=.002/c.distSq,h=r*t,l=r*s;e.fx+=h,e.fy+=l;const d=o.movablePoint,u=a.movablePoint;if(d&&u){const t=n.get(d),e=n.get(u);t.fx-=h/2,t.fy-=l/2,e.fx-=h/2,e.fy-=l/2}else if(d){const t=n.get(d);t.fx-=h,t.fy-=l}else if(u){const t=n.get(u);t.fx-=h,t.fy-=l}}}}}const i=t=>t.movablePoint?{x:t.movablePoint.x,y:t.movablePoint.y}:{x:t.x,y:t.y},r=t=>{let e=null;for(const n of this.routesInProgress)if(n.movablePoints.includes(t)){e=n;break}if(!e)return!1;const n=o.get(e);let s=-1;for(let e=0;e<n.length;e++)if(n[e].movablePoint===t){s=e;break}if(-1===s)return!1;const r=[];if(s>0){const e=i(n[s-1]);r.push({ax:e.x,ay:e.y,bx:t.x,by:t.y})}if(s<n.length-1){const e=i(n[s+1]);r.push({ax:t.x,ay:t.y,bx:e.x,by:e.y})}for(const t of this.routesInProgress){if(t.rootConnectionName===e.rootConnectionName)continue;const n=o.get(t);for(let t=0;t<n.length-1;t++){const e=i(n[t]),s=i(n[t+1]);for(const t of r)if(Hd(t.ax,t.ay,t.bx,t.by,e.x,e.y,s.x,s.y))return!0}}return!1};for(const s of e){const e=n.get(s);s.forceX=e.fx,s.forceY=e.fy;const o=s.x,i=s.y;s.x+=e.fx,s.y+=e.fy,s.x=Math.max(t.minX,Math.min(t.maxX,s.x)),s.y=Math.max(t.minY,Math.min(t.maxY,s.y)),r(s)&&(s.x=o,s.y=i)}}_finalizeRoutesForCurrentNode(){for(const t of this.routesInProgress){const{connectionName:e,rootConnectionName:n,startPoint:s,endPoint:o,movablePoints:i}=t,r=[{x:s.x,y:s.y,z:s.z}];1===i.length?r.push({x:i[0].x,y:i[0].y,z:i[0].z}):2===i.length?(r.push({x:i[0].x,y:i[0].y,z:i[0].z}),r.push({x:i[1].x,y:i[1].y,z:i[1].z})):3===i.length&&(r.push({x:i[0].x,y:i[0].y,z:i[0].z}),r.push({x:i[2].x,y:i[2].y,z:i[2].z}),r.push({x:i[1].x,y:i[1].y,z:i[1].z})),r.push({x:o.x,y:o.y,z:o.z});const a={connectionName:e,rootConnectionName:n,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:r,vias:[]};this.routes.push(a)}this.routesInProgress=[]}_getNodeBounds(t){return{minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.unsolvedNodes){if(e===this.currentNode)continue;const n=this._getNodeBounds(e);t.rects.push({center:{x:(n.minX+n.maxX)/2,y:(n.minY+n.maxY)/2},width:n.maxX-n.minX,height:n.maxY-n.minY,fill:"rgba(0, 0, 0, 0.08)",stroke:"rgba(0, 0, 0, 0.2)",label:e.capacityMeshNodeId})}if(this.lastNode){const e=this._getNodeBounds(this.lastNode);t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(0, 200, 0, 0.15)",stroke:"rgba(0, 0, 255, 0.6)"})}if(this.currentNode){const e=this._getNodeBounds(this.currentNode);t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(0, 200, 0, 0.15)",stroke:"rgba(0, 200, 0, 0.6)"})}for(const e of this.unsolvedNodes){const n=new Map;for(const t of e.portPoints)n.has(t.connectionName)||n.set(t.connectionName,[]),n.get(t.connectionName).push({x:t.x,y:t.y});for(const[e,s]of n)s.length<2||t.lines.push({points:s.map(t=>({x:t.x,y:t.y})),label:e,strokeColor:"gray",strokeWidth:this.traceWidth})}for(const e of this.routes){const n=Wn(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const s of n)t.lines.push({points:s.points,label:s.connectionName,strokeColor:0===s.z?s.color:In(s.color,.75),layer:`z${s.z}`,strokeWidth:e.traceThickness,strokeDash:0!==s.z?"10, 5":void 0});const s=e.route;for(let e=0;e<s.length;e++){const n=s[e],o=0===e,i=e===s.length-1,r=!o&&!i;let a;a=o?"start":i?"end":`M${e}`,t.points.push({x:n.x,y:n.y,label:a,color:r?"orange":"blue"})}}for(const e of this.routesInProgress){const{startPoint:n,endPoint:s,movablePoints:o,connectionName:i}=e,r=this.colorMap[i]??"gray",a=[{x:n.x,y:n.y}];1===o.length?a.push({x:o[0].x,y:o[0].y}):2===o.length?(a.push({x:o[0].x,y:o[0].y}),a.push({x:o[1].x,y:o[1].y})):3===o.length&&(a.push({x:o[0].x,y:o[0].y}),a.push({x:o[2].x,y:o[2].y}),a.push({x:o[1].x,y:o[1].y})),a.push({x:s.x,y:s.y}),t.lines.push({points:a,label:i,strokeColor:r,strokeWidth:this.traceWidth}),t.points.push({x:n.x,y:n.y,label:"start",color:"blue"});for(let e=0;e<o.length;e++){const n=o[e];if(t.points.push({x:n.x,y:n.y,label:`M${e+1}`,color:"orange"}),void 0!==n.forceX&&void 0!==n.forceY){if(Math.sqrt(n.forceX*n.forceX+n.forceY*n.forceY)>.001){const s=5;t.lines.push({points:[{x:n.x,y:n.y},{x:n.x+n.forceX*s,y:n.y+n.forceY*s}],strokeColor:"red",strokeWidth:.02,label:`F${e+1}`});const o=.05,i=n.x+n.forceX*s,r=n.y+n.forceY*s,a=Math.atan2(n.forceY,n.forceX);t.lines.push({points:[{x:i,y:r},{x:i-o*Math.cos(a-Math.PI/6),y:r-o*Math.sin(a-Math.PI/6)}],strokeColor:"red",strokeWidth:.02}),t.lines.push({points:[{x:i,y:r},{x:i-o*Math.cos(a+Math.PI/6),y:r-o*Math.sin(a+Math.PI/6)}],strokeColor:"purple",strokeWidth:.02})}}}t.points.push({x:s.x,y:s.y,label:"end",color:"blue"})}return t}},Gd=({connMap:t,connectionsWithResults:e,inputNodes:n,obstacles:s})=>{const o=s.filter(t=>t.offBoardConnectsTo?.length);if(0===o.length)return;const i=new An({});i.addConnections(o.map((t,e)=>[t.obstacleId??`__obs${e}`,...t.offBoardConnectsTo??[]]));const r=new Map(n.map(t=>[t.capacityMeshNodeId,t]));for(const n of e){if(!n.path)continue;const e=n.connection.rootConnectionName??n.connection.name,s=new Set;for(const t of n.path){const e=r.get(t.currentNodeId);if(e?._offBoardConnectionId&&s.add(e._offBoardConnectionId),t.throughNodeId){const e=r.get(t.throughNodeId);e?._offBoardConnectionId&&s.add(e._offBoardConnectionId)}}for(const n of s){const s=i.getIdsConnectedToNet(n);s?.length&&t.addConnections([[e,...s]])}}};function Zd(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var qd=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=Ph(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline2"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;relateNodesToOffBoardConnections;colorMap;highDensityRouteSolver;simpleHighDensityRouteSolver;highDensitySolver;highDensityStitchSolver;singleLayerNodeMerger;offboardPathFragmentSolver;strawSolver;deadEndSolver;traceSimplificationSolver;traceKeepoutSolver;traceWidthSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[Zd("netToPointPairsSolver",Hh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),Zd("nodeSolver",xe,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),Zd("relateNodesToOffBoardConnections",kd,t=>[{capacityMeshNodes:t.capacityNodes,srj:t.srj}],{onSolved:t=>{t.capacityNodes=t.relateNodesToOffBoardConnections?.getOutput().capacityNodes}}),Zd("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Zd("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),Zd("portPointPathingSolver",Dh,t=>{const e=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle,_offBoardConnectionId:t._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t._offBoardConnectedCapacityMeshNodeIds})),n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),s=t.availableSegmentPointSolver;for(const t of s.sharedEdgeSegments)for(const e of t.portPoints){const[s,o]=e.nodeIds,i={portPointId:e.segmentPortPointId,x:e.x,y:e.y,z:e.availableZ[0]??0,connectionNodeIds:[s,o],distToCentermostPortOnZ:e.distToCentermostPortOnZ,connectsToOffBoardNode:t.nodeIds.some(t=>n.get(t)?._offBoardConnectionId)},r=n.get(s);r&&r.portPoints.push(i)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:100*t.effort,hyperParameters:{JUMPER_PF_FN_ENABLED:!1,NODE_PF_FACTOR:100,NODE_PF_MAX_PENALTY:100,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,FORCE_CENTER_FIRST:!0}}]},{onSolved:t=>{const e=t.portPointPathingSolver;e&&Gd({connMap:t.connMap,connectionsWithResults:e.connectionsWithResults,inputNodes:e.inputNodes,obstacles:t.srj.obstacles})}}),Zd("multiSectionPortPointOptimizer",Yh,t=>{const e=t.portPointPathingSolver;return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e.inputNodes,capacityMeshNodes:t.capacityNodes,capacityMeshEdges:t.capacityEdges,colorMap:t.colorMap,initialConnectionResults:e.connectionsWithResults,initialAssignedPortPoints:e.assignedPortPoints,initialNodeAssignedPortPoints:e.nodeAssignedPortPoints}]}),Zd("highDensitySolver",Vd,t=>[{nodePortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,connMap:t.connMap}]),Zd("highDensityStitchSolver",tl,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensitySolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),Zd("traceSimplificationSolver",Cl,t=>[{hdRoutes:t.highDensityStitchSolver?.mergedHdRoutes??t.highDensitySolver?.routes??t.highDensityRouteSolver?.routes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),Zd("traceKeepoutSolver",Xd,t=>[{hdRoutes:t.traceSimplificationSolver?.simplifiedHdRoutes??[],obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,srj:t.srj}]),Zd("traceWidthSolver",Tl,t=>[{hdRoutes:t.traceKeepoutSolver?.redrawnHdRoutes??[],connection:t.srj.connections,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.offboardPathFragmentSolver?.visualize(),h=this.portPointPathingSolver?.visualize(),l=this.multiSectionPortPointOptimizer?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensitySolver?.visualize(),p=this.simpleHighDensityRouteSolver?.visualize(),f=this.highDensityStitchSolver?.visualize(),m=this.traceSimplificationSolver?.visualize(),g=this.traceKeepoutSolver?.visualize(),y=this.traceWidthSolver?.visualize(),x=this.srj.outline,v=[];if(v.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),x&&x.length>=2){const t=x.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const b={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:["obstacle",t.offBoardConnectsTo?`offboardConnections: ${t.offBoardConnectsTo?.join(", ")}`:"",t.layers?.join(", ")].filter(Boolean).join("\n")}))],lines:v},P=[b,t,e,n,s,o,i,r,a,c,h,l,d?jn(b,d):null,u?jn(b,u):null,p?jn(b,p):null,f,m,g,y,this.solved?jn(b,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...P)}preview(){const t=this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes;if(t){const e=[];for(let n=t.length-1;n>=0;n--){const s=t[n];if(e.push({points:s.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[s.connectionName]}),e.length>200)break}return{lines:e}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.hdRoutesWithWidths??this.traceKeepoutSolver?.redrawnHdRoutes??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver?.mergedHdRoutes??this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes}getConnectedOffboardObstacles(){const t={},e=new Set(this.srj.connections.map(t=>t.rootConnectionName??t.name));for(const[n,s]of this.srj.obstacles.entries()){if(!s.offBoardConnectsTo?.length)continue;const o=s.obstacleId??`__obs${n}`,i=this.connMap.getNetConnectedToId(o);if(!i)continue;const r=this.connMap.getIdsConnectedToNet(i).find(t=>e.has(t));r&&(t[o]=r)}return t}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver&&!this.simpleHighDensityRouteSolver&&!this.highDensitySolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},Jd=class extends Ln{getSolverName(){return"MultipleHighDensityRouteStitchSolver2"}unsolvedRoutes;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;constructor(t){super(),this.colorMap=t.colorMap??{};const e=t.hdRoutes[0];this.defaultTraceThickness=e?.traceThickness??.15,this.defaultViaDiameter=e?.viaDiameter??t.defaultViaDiameter??.3;const n=new Map;for(const e of t.connectionPathResults)n.set(e.connection.name,e);const s=new Map;for(const e of t.hdRoutes){const t=s.get(e.connectionName);t?t.push(e):s.set(e.connectionName,[e])}this.unsolvedRoutes=[];for(const[e,o]of s.entries()){const s=t.connections.find(t=>t.name===e);if(!s)continue;const i=n.get(e);let r=[];i?.path&&(r=i.path.map(t=>t.currentNodeId));const a={...s.pointsToConnect[0],z:Rn(Tn(s.pointsToConnect[0]),t.layerCount)},c={...s.pointsToConnect[1],z:Rn(Tn(s.pointsToConnect[1]),t.layerCount)};this.unsolvedRoutes.push({connectionName:e,hdRoutes:o,nodeOrder:r,start:a,end:c})}this.MAX_ITERATIONS=1e5}_step(){const t=this.unsolvedRoutes.pop();if(!t)return void(this.solved=!0);const e=this.stitchOrderedRoutes(t);this.mergedHdRoutes.push(e)}stitchOrderedRoutes(t){const{connectionName:e,hdRoutes:n,nodeOrder:s,start:o,end:i}=t;if(0===n.length)return{connectionName:e,traceThickness:this.defaultTraceThickness,viaDiameter:this.defaultViaDiameter,route:[o,i],vias:[],jumpers:[]};let r;r=s.length>0?this.orderRoutesByNodePath(n,s,o,e):this.orderRoutesByProximity(n,o);const a=[],c=[],h=[];a.push({x:o.x,y:o.y,z:o.z});for(let t=0;t<r.length;t++){const e=r[t],n=a[a.length-1],s=e.route[0],o=e.route[e.route.length-1],i=k(n,s),l=k(n,o),d=Math.min(i,l);if(t>0&&d>1)continue;let u;u=i<=l?[...e.route]:[...e.route].reverse();const p=.001;u.length>0&&k(n,u[0])<p&&(u=u.slice(1)),a.push(...u),c.push(...e.vias),e.jumpers&&h.push(...e.jumpers)}const l=k(a[a.length-1],i);return l>.001&&l<5&&a.push({x:i.x,y:i.y,z:i.z}),{connectionName:e,rootConnectionName:n[0]?.rootConnectionName,traceThickness:n[0]?.traceThickness??this.defaultTraceThickness,viaDiameter:n[0]?.viaDiameter??this.defaultViaDiameter,route:a,vias:c,jumpers:h}}orderRoutesByNodePath(t,e,n,s){if(0===t.length)return[];const o=new Set(t);let i=null,r=1/0;for(const t of o){const e=t.route[0],s=t.route[t.route.length-1],o=Math.min(k(n,e),k(n,s));o<r&&(r=o,i=t)}if(!i)return[];o.delete(i);const a=i.route[0],c=i.route[i.route.length-1];let h,l;k(n,a)<=k(n,c)?(h=a,l=c):(h=c,l=a);const d=(t,e)=>{let n=0;for(const s of o){if(s===e)continue;const o=s.route[0],i=s.route[s.route.length-1];(k(t,o)<10||k(t,i)<10)&&n++}return n},u=[i];let p=l;for(;o.size>0;){let t=null,e=1/0,n=-1;for(const s of o){const o=s.route[0],i=s.route[s.route.length-1],r=k(p,o),a=k(p,i),c=Math.min(r,a);if(c>=10)continue;const h=d(r<=a?i:o,s),l=0===h,u=0===n,f=c-e;let m=!1;m=null===t||(!!(!l&&u&&f<5)||!(l&&!u&&f>-5)&&c<e),m&&(e=c,t=s,n=h)}if(!t)break;{u.push(t),o.delete(t);const e=t.route[0],n=t.route[t.route.length-1];p=k(p,e)<=k(p,n)?n:e}}const f=[];for(p=h;o.size>0;){let t=null,e=1/0,s=-1;const i=k(p,n);for(const r of o){const o=r.route[0],a=r.route[r.route.length-1],c=k(p,o),h=k(p,a),l=Math.min(c,h);if(l>=10)continue;const u=c<=h?a:o;if(k(u,n)>i+2)continue;const f=d(u,r),m=0===f,g=0===s,y=l-e;let x=!1;x=null===t||(!!(!m&&g&&y<5)||!(m&&!g&&y>-5)&&l<e),x&&(e=l,t=r,s=f)}if(!t)break;{f.unshift(t),o.delete(t);const e=t.route[0],n=t.route[t.route.length-1];p=k(p,e)<=k(p,n)?n:e}}const m=[...f,...u];if(o.size>0){const e=[...o].map(t=>{const e=t.route[0],n=t.route[t.route.length-1];return`start=(${e.x.toFixed(2)},${e.y.toFixed(2)}) end=(${n.x.toFixed(2)},${n.y.toFixed(2)})`});console.warn(`[StitchSolver] Skipped ${o.size} routes for connection ${t[0]?.connectionName??"?"}, skipped routes: ${e.join("; ")}`)}return m}orderRoutesByProximity(t,e){const n=new Set(t),s=[];let o=e;for(;n.size>0;){let t=null,e=1/0,i=!1;for(const s of n){const n=s.route[0],r=s.route[s.route.length-1],a=k(o,n),c=k(o,r);a<e&&(e=a,t=s,i=!1),c<e&&(e=c,t=s,i=!0)}if(!t)break;{s.push(t),n.delete(t);const e=t.route[0],r=t.route[t.route.length-1];o=i?e:r}}return s}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Multiple High Density Route Stitch Solver 2"};for(const[e,n]of this.mergedHdRoutes.entries()){const s=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1],r=0!==o.z?In(s,.5):s;t.lines?.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:r,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?In(s,.5):s;t.points?.push({x:e.x,y:e.y,color:n})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:s});if(n.jumpers&&n.jumpers.length>0){const e=Zh(n.jumpers,{color:s,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.unsolvedRoutes){const n=this.colorMap[e.connectionName]??"gray";t.points?.push({x:e.start.x,y:e.start.y,color:n,label:`${e.connectionName} Start`},{x:e.end.x,y:e.end.y,color:n,label:`${e.connectionName} End`});for(let s=0;s<e.hdRoutes.length;s++){const o=e.hdRoutes[s];if(o.route.length>1&&t.lines?.push({points:o.route.map(t=>({x:t.x,y:t.y})),strokeColor:In(n,.5),strokeDash:"10 5",label:`segment ${s}`}),o.jumpers&&o.jumpers.length>0){const e=Zh(o.jumpers,{color:n,label:o.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}}return t}},Kd=Object.create,Qd=Object.defineProperty,tu=Object.getOwnPropertyDescriptor,eu=Object.getOwnPropertyNames,nu=Object.getPrototypeOf,su=Object.prototype.hasOwnProperty,ou=(t,e)=>function(){return e||(0,t[eu(t)[0]])((e={exports:{}}).exports,e),e.exports},iu=(t,e,n)=>(n=null!=t?Kd(nu(t)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of eu(e))su.call(t,o)||o===n||Qd(t,o,{get:()=>e[o],enumerable:!(s=tu(e,o))||s.enumerable});return t})(!e&&t&&t.__esModule?n:Qd(n,"default",{value:t,enumerable:!0}),t)),ru=ou({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),au=ou({"node_modules/kind-of/index.js"(t,e){var n=ru(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),cu=ou({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),hu=ou({"node_modules/deep-rename-keys/index.js"(t,e){var n=au(),s=cu();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),lu=ou({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),du=ou({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=lu(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),uu=ou({"node_modules/xml-reader/dist/reader.js"(t,e){var n=lu(),s=du(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}}),{cos:pu,sin:fu,PI:mu}=Math,{tan:gu}=Math,yu=(iu(hu()),iu(uu()),class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.constructor.name} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.constructor.name} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}}),xu=t=>t?`hsl(${(t=>{let e=0;for(let n=0;n<t.length;n++)e=779*t.charCodeAt(n)+((e<<5)-e);return e})(t)%360}, 100%, 50%)`:"rgba(0, 0, 0, 0.5)",vu=t=>[[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY}],[{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY}],[{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],[{x:t.minX,y:t.maxY},{x:t.minX,y:t.minY}]];function bu(t,e){const{minX:n,maxX:s,minY:o,maxY:i}=e,r=s-n,a=i-o,c=1e-6;return Math.abs(t.y-i)<c?t.x-n:Math.abs(t.x-s)<c?r+(i-t.y):Math.abs(t.y-o)<c?r+a+(s-t.x):Math.abs(t.x-n)<c?2*r+a+(t.y-o):0}function Pu(t,e){const{minX:n,maxX:s,minY:o,maxY:i}=e,r=1e-6,a=Math.abs(t.y-i)<r,c=Math.abs(t.y-o)<r,h=Math.abs(t.x-s)<r,l=Math.abs(t.x-n)<r;if(a&&h)return{x:-Math.SQRT1_2,y:-Math.SQRT1_2};if(a&&l)return{x:Math.SQRT1_2,y:-Math.SQRT1_2};if(c&&h)return{x:-Math.SQRT1_2,y:Math.SQRT1_2};if(c&&l)return{x:Math.SQRT1_2,y:Math.SQRT1_2};if(a)return{x:0,y:-1};if(c)return{x:0,y:1};if(h)return{x:-1,y:0};if(l)return{x:1,y:0};const d=(o+i)/2,u=(n+s)/2-t.x,p=d-t.y,f=Math.hypot(u,p);return f>0?{x:u/f,y:p/f}:{x:0,y:-1}}function Su(t,e,n,s,o,i,r,a,c,h){for(let l=0;l<=h;l++){const d=l/h,u=1-d,p=u*u,f=p*u,m=d*d,g=m*d,y=2*l;c[y]=f*t+3*p*d*n+3*u*m*o+g*r,c[y+1]=f*e+3*p*d*s+3*u*m*i+g*a}}function Mu(t,e,n,s,o){const i=[];for(let r=0;r<=o;r++){const a=r/o,c=1-a,h=c*c,l=h*c,d=a*a,u=d*a;i.push({x:l*t.x+3*h*a*e.x+3*c*d*n.x+u*s.x,y:l*t.y+3*h*a*e.y+3*c*d*n.y+u*s.y})}return i}function Nu(t,e,n,s,o,i){const r=o-n,a=i-s,c=r*r+a*a;if(0===c){const o=t-n,i=e-s;return o*o+i*i}const h=Math.max(0,Math.min(1,((t-n)*r+(e-s)*a)/c)),l=t-(n+h*r),d=e-(s+h*a);return l*l+d*d}function Iu(t,e,n,s,o,i,r,a){const c=(r-o)*(e-i)-(a-i)*(t-o),h=(r-o)*(s-i)-(a-i)*(n-o),l=(n-t)*(i-e)-(s-e)*(o-t),d=(n-t)*(a-e)-(s-e)*(r-t);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)?0:Math.min(Nu(t,e,o,i,r,a),Nu(n,s,o,i,r,a),Nu(o,i,t,e,n,s),Nu(r,a,t,e,n,s))}function _u(t,e,n,s,o,i,r,a){const c=(r-o)*(e-i)-(a-i)*(t-o),h=(r-o)*(s-i)-(a-i)*(n-o),l=(n-t)*(i-e)-(s-e)*(o-t),d=(n-t)*(a-e)-(s-e)*(r-t);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)}function Cu(t,e,n,s,o){const i=t=>(t%o+o)%o,r=i(t),a=i(e),c=i(n),h=i(s),[l,d]=r<a?[r,a]:[a,r];return c>l&&c<d&&h>l&&h<d}function Tu(t,e){let n=1/0,s=-1/0,o=1/0,i=-1/0;for(let r=0;r<e;r++){const e=t[2*r],a=t[2*r+1];e<n&&(n=e),e>s&&(s=e),a<o&&(o=a),a>i&&(i=a)}return{minX:n,maxX:s,minY:o,maxY:i}}var Eu=class extends yu{constructor(t){super(),this.problem=t;for(const t of this.problem.obstacles)t.outerSegments=vu(t);this.precomputeObstacles()}outputTraces=[];traces=[];optimizationStep=0;maxOptimizationSteps=100;sampledPoints=[];traceBounds=[];obstacleSegments=new Float64Array(0);obstacleNetworkIds=[];numObstacleSegments=0;collisionPairs=[];lastCost=1/0;stagnantSteps=0;effectiveTraceToTraceSpacing=0;getConstructorParams(){return this.problem}precomputeObstacles(){const{obstacles:t}=this.problem;let e=0;for(const n of t)n.outerSegments&&(e+=n.outerSegments.length);this.obstacleSegments=new Float64Array(4*e),this.obstacleNetworkIds=[],this.numObstacleSegments=e;let n=0;for(const e of t)if(e.outerSegments)for(const t of e.outerSegments)this.obstacleSegments[n++]=t[0].x,this.obstacleSegments[n++]=t[0].y,this.obstacleSegments[n++]=t[1].x,this.obstacleSegments[n++]=t[1].y,this.obstacleNetworkIds.push(e.networkId)}initializeTraces(){const{bounds:t,waypointPairs:e}=this.problem,{minX:n,maxX:s,minY:o,maxY:i}=t,r=s-n,a=i-o,c=2*r+2*a,h=function(t){return{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}}(t),l=e.map((e,n)=>({pair:e,t1:bu(e.start,t),t2:bu(e.end,t),idx:n})),d=l.map(()=>[]),u=l.map(()=>[]);for(const t of l)for(const e of l)if(t.idx!==e.idx){if(t.pair.networkId&&e.pair.networkId&&t.pair.networkId===e.pair.networkId)continue;Cu(e.t1,e.t2,t.t1,t.t2,c)&&(d[t.idx].push(e.idx),u[e.idx].push(t.idx))}const p=d.map(t=>t.length),f=Math.max(...p,1);this.traces=l.map(({pair:e,t1:n,t2:s,idx:o})=>{const i=Pu(e.start,t),c=Pu(e.end,t),l=Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),m=p[o]/f,g=(e.start.x+e.end.x)/2,y=(e.start.y+e.end.y)/2,x=l*(.25+.15*(1-Math.hypot(g-h.x,y-h.y)/Math.hypot(r/2,a/2)))*(1-.3*m),v=.05*Math.min(r,a),b=Math.max(v,x),P=Math.max(v,x);return{waypointPair:e,ctrl1:{x:e.start.x+b*i.x,y:e.start.y+b*i.y},ctrl2:{x:e.end.x+P*c.x,y:e.end.y+P*c.y},networkId:e.networkId,t1:n,t2:s,perpDir1:i,perpDir2:c,d1:b,d2:P,containedBy:d[o],contains:u[o]}}),this.sampledPoints=this.traces.map(()=>new Float64Array(12)),this.traceBounds=this.traces.map(()=>({minX:0,maxX:0,minY:0,maxY:0})),this.updateSampledTraces(),this.updateCollisionPairs()}updateSampledTraces(){for(let t=0;t<this.traces.length;t++){const e=this.traces[t];Su(e.waypointPair.start.x,e.waypointPair.start.y,e.ctrl1.x,e.ctrl1.y,e.ctrl2.x,e.ctrl2.y,e.waypointPair.end.x,e.waypointPair.end.y,this.sampledPoints[t],5),this.traceBounds[t]=Tu(this.sampledPoints[t],6)}}updateSingleTraceSample(t){const e=this.traces[t];Su(e.waypointPair.start.x,e.waypointPair.start.y,e.ctrl1.x,e.ctrl1.y,e.ctrl2.x,e.ctrl2.y,e.waypointPair.end.x,e.waypointPair.end.y,this.sampledPoints[t],5),this.traceBounds[t]=Tu(this.sampledPoints[t],6)}updateControlPointsFromDistances(t){const e=this.traces[t],{minX:n,maxX:s,minY:o,maxY:i}=this.problem.bounds,r=1e-6;let a=e.waypointPair.start.x+e.d1*e.perpDir1.x,c=e.waypointPair.start.y+e.d1*e.perpDir1.y,h=e.waypointPair.end.x+e.d2*e.perpDir2.x,l=e.waypointPair.end.y+e.d2*e.perpDir2.y;const d=e.waypointPair.start;Math.abs(d.x-n)<r&&(a=Math.max(a,n)),Math.abs(d.x-s)<r&&(a=Math.min(a,s)),Math.abs(d.y-o)<r&&(c=Math.max(c,o)),Math.abs(d.y-i)<r&&(c=Math.min(c,i));const u=e.waypointPair.end;Math.abs(u.x-n)<r&&(h=Math.max(h,n)),Math.abs(u.x-s)<r&&(h=Math.min(h,s)),Math.abs(u.y-o)<r&&(l=Math.max(l,o)),Math.abs(u.y-i)<r&&(l=Math.min(l,i)),a=Math.max(n,Math.min(s,a)),c=Math.max(o,Math.min(i,c)),h=Math.max(n,Math.min(s,h)),l=Math.max(o,Math.min(i,l)),e.ctrl1.x=a,e.ctrl1.y=c,e.ctrl2.x=h,e.ctrl2.y=l}updateCollisionPairs(){const t=this.effectiveTraceToTraceSpacing;this.collisionPairs=[];for(let e=0;e<this.traces.length;e++)for(let n=e+1;n<this.traces.length;n++){const s=this.traces[e],o=this.traces[n];if(s.networkId&&o.networkId&&s.networkId===o.networkId)continue;const i=this.traceBounds[e],r=this.traceBounds[n];i.maxX+t>=r.minX&&r.maxX+t>=i.minX&&i.maxY+t>=r.minY&&r.maxY+t>=i.minY&&this.collisionPairs.push([e,n])}}computeTotalCost(){const{preferredObstacleToTraceSpacing:t}=this.problem,e=this.effectiveTraceToTraceSpacing,n=e**2,s=t**2;let o=0;for(const[t,s]of this.collisionPairs){const i=this.sampledPoints[t],r=this.sampledPoints[s];for(let t=0;t<5;t++){const s=i[2*t],a=i[2*t+1],c=i[2*(t+1)],h=i[2*(t+1)+1];for(let t=0;t<5;t++){const i=Iu(s,a,c,h,r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1]);if(i<n){o+=(e-Math.sqrt(i))**2,i<1e-18&&(o+=20*n)}}}}for(let e=0;e<this.traces.length;e++){const n=this.traces[e],i=this.sampledPoints[e],r=this.traceBounds[e];for(let e=0;e<this.numObstacleSegments;e++){if(n.networkId&&this.obstacleNetworkIds[e]&&n.networkId===this.obstacleNetworkIds[e])continue;const a=4*e,c=this.obstacleSegments[a],h=this.obstacleSegments[a+1],l=this.obstacleSegments[a+2],d=this.obstacleSegments[a+3],u=Math.min(c,l),p=Math.max(c,l),f=Math.min(h,d),m=Math.max(h,d);if(!(r.maxX+t<u||p+t<r.minX||r.maxY+t<f||m+t<r.minY))for(let e=0;e<5;e++){const n=Iu(i[2*e],i[2*e+1],i[2*(e+1)],i[2*(e+1)+1],c,h,l,d);if(n<s){o+=(t-Math.sqrt(n))**2,n<1e-18&&(o+=20*s)}}}}return o}computeCostForTrace(t){const{preferredObstacleToTraceSpacing:e}=this.problem,n=this.effectiveTraceToTraceSpacing,s=n**2,o=e**2,i=this.traces[t],r=this.sampledPoints[t],a=this.traceBounds[t];let c=0;for(let e=0;e<this.traces.length;e++){if(e===t)continue;const o=this.traces[e];if(i.networkId&&o.networkId&&i.networkId===o.networkId)continue;const h=this.traceBounds[e];if(a.maxX+n<h.minX||h.maxX+n<a.minX||a.maxY+n<h.minY||h.maxY+n<a.minY)continue;const l=this.sampledPoints[e];for(let t=0;t<5;t++){const e=r[2*t],o=r[2*t+1],i=r[2*(t+1)],a=r[2*(t+1)+1];for(let t=0;t<5;t++){const r=Iu(e,o,i,a,l[2*t],l[2*t+1],l[2*(t+1)],l[2*(t+1)+1]);if(r<s){c+=(n-Math.sqrt(r))**2,r<1e-18&&(c+=20*s)}}}}for(let t=0;t<this.numObstacleSegments;t++){if(i.networkId&&this.obstacleNetworkIds[t]&&i.networkId===this.obstacleNetworkIds[t])continue;const n=4*t,s=this.obstacleSegments[n],h=this.obstacleSegments[n+1],l=this.obstacleSegments[n+2],d=this.obstacleSegments[n+3],u=Math.min(s,l),p=Math.max(s,l),f=Math.min(h,d),m=Math.max(h,d);if(!(a.maxX+e<u||p+e<a.minX||a.maxY+e<f||m+e<a.minY))for(let t=0;t<5;t++){const n=Iu(r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1],s,h,l,d);if(n<o){c+=(e-Math.sqrt(n))**2,n<1e-18&&(c+=20*o)}}}return c}tracesIntersect(t,e){const n=this.traces[t],s=this.traces[e],o=15,i=new Float64Array(32),r=new Float64Array(32);Su(n.waypointPair.start.x,n.waypointPair.start.y,n.ctrl1.x,n.ctrl1.y,n.ctrl2.x,n.ctrl2.y,n.waypointPair.end.x,n.waypointPair.end.y,i,o),Su(s.waypointPair.start.x,s.waypointPair.start.y,s.ctrl1.x,s.ctrl1.y,s.ctrl2.x,s.ctrl2.y,s.waypointPair.end.x,s.waypointPair.end.y,r,o);for(let t=0;t<o;t++){const e=i[2*t],n=i[2*t+1],s=i[2*(t+1)],a=i[2*(t+1)+1];for(let t=0;t<o;t++){if(_u(e,n,s,a,r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1]))return!0}}return!1}findIntersectingPairs(){const t=[];for(let e=0;e<this.traces.length;e++)for(let n=e+1;n<this.traces.length;n++){const s=this.traces[e],o=this.traces[n];if(s.networkId&&o.networkId&&s.networkId===o.networkId)continue;const i=this.traceBounds[e],r=this.traceBounds[n];i.maxX<r.minX||r.maxX<i.minX||i.maxY<r.minY||r.maxY<i.minY||this.tracesIntersect(e,n)&&t.push([e,n])}return t}resolveIntersections(){const{bounds:t,preferredTraceToTraceSpacing:e}=this.problem,{minX:n,maxX:s,minY:o,maxY:i}=t,r=Math.min(s-n,i-o),a=.02*r,c=1.5*r,h=this.findIntersectingPairs();if(0===h.length)return 0;let l=0;for(const[t,n]of h){const s=this.traces[t],o=this.traces[n];if(!this.tracesIntersect(t,n))continue;let i,r;if(s.containedBy.includes(n))i=n,r=t;else if(o.containedBy.includes(t))i=t,r=n;else{(s.d1+s.d2)/2<(o.d1+o.d2)/2?(i=t,r=n):(i=n,r=t)}const h=this.traces[i],d=this.traces[r],u=h.d1,p=h.d2,f=d.d1,m=d.d2,g=2*e,y=[{innerMult:1,outerMult:0},{innerMult:0,outerMult:1},{innerMult:.5,outerMult:.5},{innerMult:2,outerMult:0},{innerMult:1,outerMult:1},{innerMult:3,outerMult:0},{innerMult:2,outerMult:1},{innerMult:4,outerMult:0}];let x=this.computeTotalCost(),v=null;for(const t of y)if(h.d1=u,h.d2=p,d.d1=f,d.d2=m,d.d1=Math.min(c,f+g*t.innerMult),d.d2=Math.min(c,m+g*t.innerMult),h.d1=Math.max(a,u-g*t.outerMult),h.d2=Math.max(a,p-g*t.outerMult),this.updateControlPointsFromDistances(r),this.updateControlPointsFromDistances(i),this.updateSingleTraceSample(r),this.updateSingleTraceSample(i),!this.tracesIntersect(i,r)){const e=this.computeTotalCost();(null===v||e<x)&&(x=e,v=t)}v?(d.d1=Math.min(c,f+g*v.innerMult),d.d2=Math.min(c,m+g*v.innerMult),h.d1=Math.max(a,u-g*v.outerMult),h.d2=Math.max(a,p-g*v.outerMult),this.updateControlPointsFromDistances(r),this.updateControlPointsFromDistances(i),this.updateSingleTraceSample(r),this.updateSingleTraceSample(i),l++):(h.d1=u,h.d2=p,d.d1=f,d.d2=m,this.updateControlPointsFromDistances(i),this.updateControlPointsFromDistances(r),this.updateSingleTraceSample(i),this.updateSingleTraceSample(r))}return l}optimizeStep(){const{bounds:t}=this.problem,{minX:e,maxX:n,minY:s,maxY:o}=t,i=Math.min(n-e,o-s),r=this.effectiveTraceToTraceSpacing,a=4*(1-this.optimizationStep/this.maxOptimizationSteps)+.5,c=.02*i,h=1.5*i,l=[];for(let t=0;t<this.traces.length;t++)l.push({idx:t,cost:this.computeCostForTrace(t)});l.sort((t,e)=>e.cost-t.cost);for(const{idx:t,cost:e}of l){if(0===e)continue;const n=this.traces[t],s=e>100?2:1,o=[a*s,1.5*a*s,.5*a];for(const s of o){const o=e>100?[s,-s,2*s,2*-s,3*s,3*-s,2*r,2*-r]:[s,-s,2*s,2*-s];let i=this.computeCostForTrace(t),a=n.d1,l=n.d2;const d=n.d1,u=n.d2;for(const e of o){n.d1=Math.max(c,Math.min(h,d+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const s=this.computeCostForTrace(t);s<i&&(i=s,a=n.d1,l=u),n.d1=d,this.updateControlPointsFromDistances(t),n.d2=Math.max(c,Math.min(h,u+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const o=this.computeCostForTrace(t);o<i&&(i=o,a=d,l=n.d2),n.d2=u,this.updateControlPointsFromDistances(t),n.d1=Math.max(c,Math.min(h,d+e)),n.d2=Math.max(c,Math.min(h,u+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const r=this.computeCostForTrace(t);r<i&&(i=r,a=n.d1,l=n.d2),n.d1=d,n.d2=u,this.updateControlPointsFromDistances(t),n.d1=Math.max(c,Math.min(h,d+e)),n.d2=Math.max(c,Math.min(h,u-e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const p=this.computeCostForTrace(t);p<i&&(i=p,a=n.d1,l=n.d2),n.d1=d,n.d2=u,this.updateControlPointsFromDistances(t)}if(n.d1=a,n.d2=l,this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t),i<.9*e)break}}this.optimizationStep%10==0&&this.updateCollisionPairs()}buildOutputTraces(){this.outputTraces=this.traces.map(t=>({waypointPair:t.waypointPair,points:Mu(t.waypointPair.start,t.ctrl1,t.ctrl2,t.waypointPair.end,20),networkId:t.networkId}))}_step(){if(0===this.traces.length&&(this.effectiveTraceToTraceSpacing=3*this.problem.preferredTraceToTraceSpacing,this.initializeTraces(),this.lastCost=this.computeTotalCost(),this.stagnantSteps=0),this.optimizationStep<this.maxOptimizationSteps){const t=3,e=t+(1-t)*(this.optimizationStep/this.maxOptimizationSteps);if(this.effectiveTraceToTraceSpacing=this.problem.preferredTraceToTraceSpacing*e,this.optimizeStep(),this.optimizationStep++,this.optimizationStep%10==0){this.resolveIntersections()>0&&this.updateCollisionPairs()}const n=this.computeTotalCost();if(0===n)this.optimizationStep=this.maxOptimizationSteps;else if(n>=.99*this.lastCost){if(this.stagnantSteps++,this.stagnantSteps>10){this.resolveIntersections()>0?(this.updateCollisionPairs(),this.stagnantSteps=0):this.stagnantSteps>15&&(this.optimizationStep=this.maxOptimizationSteps)}}else this.stagnantSteps=0;this.lastCost=n}this.optimizationStep>=this.maxOptimizationSteps&&(this.resolveIntersections(),this.buildOutputTraces(),this.solved=!0)}visualize(){return this.traces.length>0&&this.buildOutputTraces(),((t,e=[])=>{const n={arrows:[],circles:[],lines:[],rects:[],coordinateSystem:"cartesian",points:[],texts:[],title:"Curvy Trace Problem"};n.lines.push({points:[{x:t.bounds.minX,y:t.bounds.minY},{x:t.bounds.maxX,y:t.bounds.minY},{x:t.bounds.maxX,y:t.bounds.maxY},{x:t.bounds.minX,y:t.bounds.maxY},{x:t.bounds.minX,y:t.bounds.minY}],strokeColor:"rgba(0, 0, 0, 0.1)"});for(const e of t.waypointPairs)n.points.push({...e.start,label:`start ${e.networkId??""}`,color:xu(e.networkId)}),n.points.push({...e.end,label:`end ${e.networkId??""}`,color:xu(e.networkId)});for(const e of t.obstacles)n.rects.push({center:e.center,width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(128, 128, 128, 0.3)",stroke:"rgba(128, 128, 128, 0.8)",label:`netId: ${e.networkId}`});for(const t of e)n.lines.push({points:t.points,strokeColor:xu(t.networkId)});return n})(this.problem,this.outputTraces)}},wu=class extends Ln{getSolverName(){return"CurvyIntraNodeSolver"}nodeWithPortPoints;colorMap;traceWidth;viaDiameter;adjacentObstacles;routes=[];curvyTraceSolver;phase="initializing";constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.viaDiameter=t.viaDiameter??.3,this.adjacentObstacles=t.adjacentObstacles??[],this.MAX_ITERATIONS=1e3}_step(){switch(this.phase){case"initializing":this._initializeCurvySolver();break;case"solving":this._stepCurvySolver();break;case"done":this.solved=!0}}_initializeCurvySolver(){const t=this.nodeWithPortPoints,e={minX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxX:t.center.x+t.width/2,maxY:t.center.y+t.height/2},n=new Map;for(const e of t.portPoints)n.has(e.connectionName)||n.set(e.connectionName,[]),n.get(e.connectionName).push(e);const s=[];for(const[t,e]of n){if(e.length<2)continue;const n=e[0],o=e[e.length-1];s.push({start:{x:n.x,y:n.y},end:{x:o.x,y:o.y},networkId:t})}if(0===s.length)return void(this.phase="done");const o={bounds:e,waypointPairs:s,obstacles:this.adjacentObstacles.map(t=>({minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},networkId:t.networkId})),preferredTraceToTraceSpacing:2*this.traceWidth,preferredObstacleToTraceSpacing:2*this.traceWidth};this.curvyTraceSolver=new Eu(o),this.phase="solving"}_stepCurvySolver(){this.curvyTraceSolver?(this.activeSubSolver=this.curvyTraceSolver,this.curvyTraceSolver.step(),this.curvyTraceSolver.solved?(this._convertOutputTraces(),this.phase="done"):this.curvyTraceSolver.failed&&(this.error=this.curvyTraceSolver.error,this.failed=!0)):this.phase="done"}_convertOutputTraces(){if(!this.curvyTraceSolver)return;const t=this.nodeWithPortPoints,e=new Map;for(const n of t.portPoints){const t=n.connectionName;e.has(t)||e.set(t,{connectionName:n.connectionName,rootConnectionName:n.rootConnectionName,z:n.z})}for(const t of this.curvyTraceSolver.outputTraces){const n=t.networkId??"",s=e.get(n);if(!s)continue;const o={connectionName:s.connectionName,rootConnectionName:s.rootConnectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:t.points.map(t=>({x:t.x,y:t.y,z:s.z})),vias:[]};this.routes.push(o)}}getConstructorParams(){return{nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:this.adjacentObstacles}}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=this.nodeWithPortPoints;t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(0, 200, 0, 0.1)",stroke:"rgba(0, 200, 0, 0.5)",label:e.capacityMeshNodeId});for(const e of this.adjacentObstacles)t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(255, 0, 0, 0.1)",stroke:"rgba(255, 0, 0, 0.3)",label:`obstacle: ${e.networkId??""}`});if(this.curvyTraceSolver){const e=this.curvyTraceSolver.visualize();e.lines&&t.lines.push(...e.lines),e.points&&t.points.push(...e.points),e.rects&&t.rects.push(...e.rects),e.circles&&t.circles.push(...e.circles)}for(const e of this.routes){const n=this.colorMap[e.connectionName]??"gray";t.lines.push({points:e.route.map(t=>({x:t.x,y:t.y})),strokeColor:n,strokeWidth:this.traceWidth,label:e.connectionName})}for(const n of e.portPoints){const e=this.colorMap[n.connectionName]??"gray";t.points.push({x:n.x,y:n.y,color:e,label:n.connectionName})}return t}},Ru=Object.create,Ou=Object.defineProperty,Au=Object.getOwnPropertyDescriptor,zu=Object.getOwnPropertyNames,Du=Object.getPrototypeOf,Lu=Object.prototype.hasOwnProperty,Fu=(t,e)=>function(){return e||(0,t[zu(t)[0]])((e={exports:{}}).exports,e),e.exports},Yu=(t,e,n)=>(n=null!=t?Ru(Du(t)):{},((t,e,n,s)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let o of zu(e))Lu.call(t,o)||o===n||Ou(t,o,{get:()=>e[o],enumerable:!(s=Au(e,o))||s.enumerable});return t})(!e&&t&&t.__esModule?n:Ou(n,"default",{value:t,enumerable:!0}),t)),Xu=Fu({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),ku=Fu({"node_modules/kind-of/index.js"(t,e){var n=Xu(),s=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=s.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),$u=Fu({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var s in t)Object.prototype.hasOwnProperty.call(t,s)&&(n[e(s,t[s])||s]=t[s]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),Bu=Fu({"node_modules/deep-rename-keys/index.js"(t,e){var n=ku(),s=$u();e.exports=function t(e,o){var i=n(e);if("object"!==i&&"array"!==i)throw new Error("expected an object");var r=[];for(var a in"object"===i&&(e=s(e,o),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,o):r[a]=c}return r}}}),ju=Fu({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,s="~";function o(){}function i(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new o,this._eventsCount=0}Object.create&&(o.prototype=Object.create(null),(new o).__proto__||(s=!1)),r.prototype.eventNames=function(){var t,e,o=[];if(0===this._eventsCount)return o;for(e in t=this._events)n.call(t,e)&&o.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?o.concat(Object.getOwnPropertySymbols(t)):o},r.prototype.listeners=function(t,e){var n=s?s+t:t,o=this._events[n];if(e)return!!o;if(!o)return[];if(o.fn)return[o.fn];for(var i=0,r=o.length,a=new Array(r);i<r;i++)a[i]=o[i].fn;return a},r.prototype.emit=function(t,e,n,o,i,r){var a=s?s+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,o),!0;case 5:return l.fn.call(l.context,e,n,o,i),!0;case 6:return l.fn.call(l.context,e,n,o,i,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,o);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var o=new i(e,n||this),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.once=function(t,e,n){var o=new i(e,n||this,!0),r=s?s+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],o]:this._events[r].push(o):(this._events[r]=o,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,i){var r=s?s+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new o:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||i&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new o:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||i&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new o:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=s?s+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new o:delete this._events[e])):(this._events=new o,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=s,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),Wu=Fu({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var s=ju(),o=function(){},i={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:i,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,m,g,y;t=Object.assign({debug:!1},t);var x=new s,v=i.data,b="",P="",S="",M="",N="",I="",_=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var s={type:e,value:n};t.debug&&console.log("emit:",s),x.emit("data",s)}};x.stateMachine=(n(y={},i.data,(n(e={},r.lt,function(){b.trim()&&_(a.text,b),P="",N=!1,v=i.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,i.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(_(a.text,b.slice(0,-3)),b="",v=i.data)})),n(y,i.tagBegin,(n(h={},r.space,o),n(h,r.char,function(t){P=t,v=i.tagName}),n(h,r.slash,function(){P="",N=!0}),h)),n(y,i.tagName,(n(l={},r.space,function(){N?v=i.tagEnd:(v=i.attributeNameStart,_(a.openTag,P))}),n(l,r.gt,function(){_(N?a.closeTag:a.openTag,P),b="",v=i.data}),n(l,r.slash,function(){v=i.tagEnd,_(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=i.cdata,b="",P="")}),l)),n(y,i.tagEnd,(n(d={},r.gt,function(){_(a.closeTag,P),b="",v=i.data}),n(d,r.char,o),d)),n(y,i.attributeNameStart,(n(u={},r.char,function(t){S=t,v=i.attributeName}),n(u,r.gt,function(){b="",v=i.data}),n(u,r.space,o),n(u,r.slash,function(){N=!0,v=i.tagEnd}),u)),n(y,i.attributeName,(n(p={},r.space,function(){v=i.attributeNameEnd}),n(p,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(p,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(p,r.slash,function(){N=!0,M="",_(a.attributeName,S),_(a.attributeValue,M),v=i.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,i.attributeNameEnd,(n(f={},r.space,o),n(f,r.equal,function(){_(a.attributeName,S),v=i.attributeValueBegin}),n(f,r.gt,function(){M="",_(a.attributeName,S),_(a.attributeValue,M),b="",v=i.data}),n(f,r.char,function(t){M="",_(a.attributeName,S),_(a.attributeValue,M),S=t,v=i.attributeName}),f)),n(y,i.attributeValueBegin,(n(m={},r.space,o),n(m,r.quote,function(t){I=t,M="",v=i.attributeValue}),n(m,r.gt,function(){_(a.attributeValue,M=""),b="",v=i.data}),n(m,r.char,function(t){I="",M=t,v=i.attributeValue}),m)),n(y,i.attributeValue,(n(g={},r.space,function(t){I?M+=t:(_(a.attributeValue,M),v=i.attributeNameStart)}),n(g,r.quote,function(t){I===t?(_(a.attributeValue,M),v=i.attributeNameStart):M+=t}),n(g,r.gt,function(t){I?M+=t:(_(a.attributeValue,M),b="",v=i.data)}),n(g,r.slash,function(t){I?M+=t:(_(a.attributeValue,M),N=!0,v=i.tagEnd)}),n(g,r.char,function(t){M+=t}),g)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],s=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];s(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),Hu=Fu({"node_modules/xml-reader/dist/reader.js"(t,e){var n=ju(),s=Wu(),o=s.Type,i={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:i.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case o.openTag:if(null===c)(c=a).name=n.value;else{var s=r({name:n.value,parent:c});c.children.push(s),c=s}break;case o.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case o.text:c&&c.children.push(r({type:i.text,value:n.value,parent:t.parentNodes?c:null}));break;case o.attributeName:h=n.value,c.attributes[h]="";break;case o.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=s.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),s=void 0;return n.on("done",function(t){s=t}),n.parse(t),s},create:a,NodeType:i}}}),{cos:Uu,sin:Vu,PI:Gu}=Math,{tan:Zu}=Math;Yu(Bu()),Yu(Hu());function qu(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.infiniteLines)for(const n of t.infiniteLines)n.step=e;if(t.polygons)for(const n of t.polygons)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var Ju=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function Ku(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var Qu=class extends Ju{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,s=this.firstIterationOfStage[e.solverName]||0,o=this.iterations,i=e.solverName===this.getCurrentStageName()?o-s:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:i,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(qu(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const s=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const s=this[e.solverName],o=s?.visualize();return o?(qu(o,n+t),o):null}).filter(Boolean));return 0===s.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(qu(n,s.length+t+1),s.push(n)),1===s.length?s[0]:{points:s.flatMap(t=>t.points||[]),rects:s.flatMap(t=>t.rects||[]),lines:s.flatMap(t=>t.lines||[]),circles:s.flatMap(t=>t.circles||[]),texts:s.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},tp=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),ep=(t,e)=>{const n=[...new Set(t)].map(t=>{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=>null!==t);if(n.sort((t,e)=>t.x-e.x||t.y-e.y),n.length<=2)return n.map(t=>t.i);const s=[],o=[];for(const t of n){for(;s.length>=2;){const e=s[s.length-2],n=s[s.length-1];if(!e||!n||tp(e,n,t)>1e-10)break;s.pop()}s.push(t)}for(let t=n.length-1;t>=0;t--){const e=n[t];if(e){for(;o.length>=2;){const t=o[o.length-2],n=o[o.length-1];if(!t||!n||tp(t,n,e)>1e-10)break;o.pop()}o.push(e)}}return s.pop(),o.pop(),s.concat(o).map(t=>t.i)},np=t=>void 0!==t,sp=class extends Ju{input;output=null;constructor(t){super(),this.input=t}_step(){const{regions:t,hulls:e}={regions:(n=this.input).cells.map(t=>t.map(t=>n.pts[t]).filter(np)),hulls:n.cells.map(t=>ep(t,n.pts).map(t=>n.pts[t]).filter(np))};var n;this.output={pts:this.input.pts,validTris:this.input.validTris,regions:t,hulls:e,depths:this.input.depths},this.stats={regions:t.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output;return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.regions.flatMap(t=>t.flatMap((e,n)=>{const s=t[(n+1)%t.length];return s?[{points:[e,s],strokeColor:"#0f766e"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`regions: ${t.regions.length}`,color:"#1f2937"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},op=(t,e,n)=>{const s=Math.cos(n.ccwRotation),o=Math.sin(n.ccwRotation);return{x:n.center.x+t*s-e*o,y:n.center.y+t*o+e*s}},ip=(t,e=[],n,s=[])=>{const o=[],{minX:i,maxX:r,minY:a,maxY:c}=t;o.push({x:i,y:a},{x:r,y:a},{x:r,y:c},{x:i,y:c});for(let t=1;t<10;t++){const e=t/10;o.push({x:i+e*(r-i),y:a}),o.push({x:r,y:a+e*(c-a)}),o.push({x:r-e*(r-i),y:c}),o.push({x:i,y:c-e*(c-a)})}for(const t of e){const e=t.diameter/2+n;for(let n=0;n<24;n++){const s=2*Math.PI*n/24;o.push({x:t.center.x+e*Math.cos(s),y:t.center.y+e*Math.sin(s)})}}for(const t of s){const e=t.width/2+n,s=t.height/2+n,i=Math.max(2,Math.ceil(Math.max(2*e,2*s)/20));for(let n=0;n<i;n++){const r=n/i;o.push(op(2*r*e-e,-s,t)),o.push(op(e,2*r*s-s,t)),o.push(op(e-2*r*e,s,t)),o.push(op(-e,s-2*r*s,t))}}return o.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))},rp=class extends Ju{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[];this.output={pts:ip(this.input.bounds,t,this.input.clearance,e)},this.stats={points:this.output.pts.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=(this.output?.pts??[]).map(t=>({x:t.x,y:t.y,color:"#2563eb"}));return{points:t,lines:[],rects:[],circles:(this.input.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2+this.input.clearance,stroke:"#ef4444"})),texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`sample points: ${t.length}`,color:"#1f2937"}]}}},ap=(t,e,n)=>{const s=n.x-e.x,o=n.y-e.y,i=s*s+o*o;if(i<1e-10)return Math.hypot(t.x-e.x,t.y-e.y);let r=((t.x-e.x)*s+(t.y-e.y)*o)/i;return r=Math.max(0,Math.min(1,r)),Math.hypot(t.x-e.x-r*s,t.y-e.y-r*o)},cp=(t,e)=>{if(t.length<=3)return 0;const n=ep(t,e),s=new Set(n),o=n.map(t=>e[t]).filter(t=>Boolean(t));let i=0;for(const n of t){if(s.has(n))continue;const t=e[n];if(!t)continue;let r=Number.POSITIVE_INFINITY;for(let e=0;e<o.length;e++){const n=o[e],s=o[(e+1)%o.length];n&&s&&(r=Math.min(r,ap(t,n,s)))}i=Math.max(i,r)}return i},hp=(t,e)=>t<e?1e5*t+e:1e5*e+t,lp=(t,e)=>{const n=t.map((e,n)=>[e,t[(n+1)%t.length]]),s=e.map((t,n)=>[t,e[(n+1)%e.length]]),o=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,i]of s)void 0!==i&&t===i&&e===n&&o.add(hp(t,e));if(0===o.size)return null;const i=[];for(const[t,e]of n)void 0!==e&&(o.has(hp(t,e))||i.push([t,e]));for(const[t,e]of s)void 0!==e&&(o.has(hp(t,e))||i.push([t,e]));if(0===i.length)return null;const r=new Map;for(const[t,e]of i)r.set(t,e);const a=i[0]?.[0];if(void 0===a)return null;const c=[a];let h=r.get(a),l=0;for(;void 0!==h&&h!==a&&l++<i.length+5;)c.push(h),h=r.get(h);return h!==a||c.length!==i.length?null:c},dp=(t,e)=>t<e?1e5*t+e:1e5*e+t,up=class extends Ju{input;output=null;constructor(t){super(),this.input=t}_step(){const t=((t,e,n)=>{if(!t.length)return{cells:[],depths:[]};const s=t.map(([t,n,s])=>{const o=e[t],i=e[n],r=e[s];return o&&i&&r&&tp(o,i,r)<0?[t,s,n]:[t,n,s]});let o=!0,i=0;for(;o&&i++<800;){o=!1;const t=new Map,i=s.map(()=>new Set);for(let e=0;e<s.length;e++){const n=s[e];if(n)for(let s=0;s<n.length;s++){const o=n[s],r=n[(s+1)%n.length];if(void 0===o||void 0===r)continue;const a=dp(o,r);if(t.has(a)){const n=t.get(a);void 0!==n&&(i[e]?.add(n),i[n]?.add(e))}else t.set(a,e)}}let r=-1,a=-1,c=null,h=Number.POSITIVE_INFINITY;for(let t=0;t<s.length;t++){const o=i[t];if(o)for(const i of o){if(i<=t)continue;const o=lp(s[t]??[],s[i]??[]);if(!o)continue;const l=cp(o,e);l<=n+1e-6&&l<h&&(h=l,r=t,a=i,c=o)}}if(r<0||a<0||!c)break;s[r]=c,s.splice(a,1),o=!0}const r=s.map(t=>cp(t,e));return{cells:s,depths:r}})(this.input.validTris,this.input.pts,this.input.concavityTolerance);this.output={pts:this.input.pts,validTris:this.input.validTris,cells:t.cells,depths:t.depths},this.stats={mergedCells:t.cells.length,maxDepth:t.depths.length?Math.max(...t.depths):0},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.cells??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.flatMap(t=>t.flatMap((e,n)=>{const s=this.input.pts[e],o=t[(n+1)%t.length],i=void 0===o?void 0:this.input.pts[o];return s&&i?[{points:[s,i],strokeColor:"#10b981"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`merged cells: ${t.length}`,color:"#1f2937"}]}}},pp=(t,e,n)=>{const s=2*(t.x*(e.y-n.y)+e.x*(n.y-t.y)+n.x*(t.y-e.y));if(Math.abs(s)<1e-10)return{x:0,y:0,r2:1e18};const o=t.x*t.x+t.y*t.y,i=e.x*e.x+e.y*e.y,r=n.x*n.x+n.y*n.y,a=(o*(e.y-n.y)+i*(n.y-t.y)+r*(t.y-e.y))/s,c=(o*(n.x-e.x)+i*(t.x-n.x)+r*(e.x-t.x))/s;return{x:a,y:c,r2:(t.x-a)**2+(t.y-c)**2}},fp=(t,e,n)=>[t.a,t.b,t.c].includes(e)&&[t.a,t.b,t.c].includes(n),mp=(t,e,n,s=[],o,i=[])=>t.filter(([t,r,a])=>{const c=e[t],h=e[r],l=e[a];if(!c||!h||!l)return!1;return((t,e,n,s=[],o,i=[])=>{const{minX:r,maxX:a,minY:c,maxY:h}=n;if(t<r-.1||t>a+.1||e<c-.1||e>h+.1)return!1;for(const n of s){const s=n.diameter/2+o;if((t-n.center.x)**2+(e-n.center.y)**2<s*s-.1)return!1}for(const n of i){const s=n.width/2+o,i=n.height/2+o,r=t-n.center.x,a=e-n.center.y,c=Math.cos(n.ccwRotation),h=Math.sin(n.ccwRotation),l=r*c+a*h,d=-r*h+a*c;if(Math.abs(l)<s-.1&&Math.abs(d)<i-.1)return!1}return!0})((c.x+h.x+l.x)/3,(c.y+h.y+l.y)/3,n,s,o,i)}),gp=class extends Ju{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=(t=>{const e=t.map((t,e)=>({...t,i:e}));if(e.length<3)return[];let n=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),s=Math.min(s,t.y),o=Math.max(o,t.x),i=Math.max(i,t.y);const r=Math.max(o-n,i-s)||1,a=(n+o)/2,c=(s+i)/2,h={x:a-30*r,y:c-r,i:-1},l={x:a,y:c+30*r,i:-2},d={x:a+30*r,y:c-r,i:-3};let u=[{a:h,b:l,c:d,cc:pp(h,l,d)}];for(const t of e){const e=u.filter(e=>{const n=t.x-e.cc.x,s=t.y-e.cc.y;return n*n+s*s<e.cc.r2+1e-6}),n=new Set(e),s=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[o,i]of n){let n=!1;for(const s of e)if(s!==t&&fp(s,o,i)){n=!0;break}n||s.push([o,i])}}u=u.filter(t=>!n.has(t));for(const[e,n]of s)u.push({a:e,b:n,c:t,cc:pp(e,n,t)})}return u.filter(t=>t.a.i>=0&&t.b.i>=0&&t.c.i>=0).map(t=>[t.a.i,t.b.i,t.c.i])})(this.input.pts),s=mp(n,this.input.pts,this.input.bounds,t,this.input.clearance,e);this.output={pts:this.input.pts,validTris:s},this.stats={candidateTriangles:n.length,validTriangles:s.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.validTris??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#2563eb"})),lines:t.flatMap(([t,e,n])=>{const s=this.input.pts[t],o=this.input.pts[e],i=this.input.pts[n];return s&&o&&i?[{points:[s,o],strokeColor:"#64748b"},{points:[o,i],strokeColor:"#64748b"},{points:[i,s],strokeColor:"#64748b"}]:[]}),rects:[],circles:[],texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`valid triangles: ${t.length}`,color:"#1f2937"}]}}},yp=class extends Qu{pipelineDef=[Ku("generatePoints",rp,t=>[t.inputProblem]),Ku("triangulate",gp,t=>{const e=t.getStageOutput("generatePoints");if(!e)throw new Error("generatePoints output missing");return[{pts:e.pts,bounds:t.inputProblem.bounds,vias:t.inputProblem.vias,rects:t.inputProblem.rects,clearance:t.inputProblem.clearance}]}),Ku("mergeCells",up,t=>{const e=t.getStageOutput("triangulate");if(!e)throw new Error("triangulate output missing");return[{pts:e.pts,validTris:e.validTris,concavityTolerance:t.inputProblem.concavityTolerance}]}),Ku("buildRegions",sp,t=>{const e=t.getStageOutput("mergeCells");if(!e)throw new Error("mergeCells output missing");return[e]})];getConstructorParams(){return[this.inputProblem]}getOutput(){return this.getStageOutput("buildRegions")??null}visualize(){const t=this.getOutput();return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#38b6ff"})),lines:t.regions.flatMap(t=>t.map((e,n)=>{const s=t[(n+1)%t.length]??e;return{points:[{x:e.x,y:e.y},{x:s.x,y:s.y}],strokeColor:"#4ecb82"}})),rects:[],circles:(this.inputProblem.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2,stroke:"#ff6b6b"})),texts:[{x:this.inputProblem.bounds.minX+8,y:this.inputProblem.bounds.minY+16,text:`regions=${t.regions.length}`,color:"#ffffff"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},xp=1e-9,vp=(t,e)=>{const n=[zp(t)],s=[];let o=e.maxSplitsPerRegion??32;for(;n.length>0;){const t=n.pop();if(!t)continue;if(t.length<4){s.push(t);continue}const i=bp(t,e);if(!i||o<=0){s.push(t);continue}const[r,a]=Sp(t,i.i,i.j);o-=1,n.push(r,a)}return s},bp=(t,e)=>{const n=Np(t);if(!n)return null;const{triangles:s}=n,o=wp(t);if(o<=xp)return null;const i=Math.sqrt(o),r=s.map(e=>Rp(t[e[0]],t[e[1]],t[e[2]]));let a=null;for(const c of n.internalEdges){const{i:h,j:l,triA:d,triB:u}=c,p=Op(t[h],t[l])/i;if(p>e.maxNeckRatio)continue;const f=Pp(d,u,s.length,n.triangleAdjacency,r),m=o-f,g=Math.min(f,m)/o;if(g<e.minSplitBalanceRatio)continue;const y=p/Math.max(g,xp);(!a||y<a.score)&&(a={i:h,j:l,score:y})}return a?{i:a.i,j:a.j}:null},Pp=(t,e,n,s,o)=>{const i=new Array(n).fill(!1),r=[t];i[e]=!0;let a=0;for(;r.length>0;){const t=r.pop();if(void 0===t||i[t])continue;i[t]=!0,a+=o[t]??0;const e=s[t]??[];for(const t of e)i[t]||r.push(t)}return a},Sp=(t,e,n)=>[Mp(t,e,n),Mp(t,n,e)],Mp=(t,e,n)=>{const s=[],o=t.length;let i=e;for(s.push(t[i]);i!==n;)i=(i+1)%o,s.push(t[i]);return zp(s)},Np=t=>{const e=t.length;if(e<3)return null;const n=new Set;for(let t=0;t<e;t++){const s=(t+1)%e;n.add(Ap(t,s))}const s=Ip(t);if(!s||0===s.length)return null;const o=new Map;s.forEach((t,e)=>{for(let n=0;n<3;n++){const s=t[n],i=t[(n+1)%3],r=Ap(s,i),a=o.get(r);a?a.push(e):o.set(r,[e])}});const i=Array.from({length:s.length},()=>[]),r=[];for(const[t,e]of o.entries()){if(n.has(t))continue;if(2!==e.length)continue;const[s,o]=t.split("_"),a=Number(s),c=Number(o),h=e[0],l=e[1];r.push({i:a,j:c,triA:h,triB:l});const d=i[h],u=i[l];d&&d.push(l),u&&u.push(h)}return{triangles:s,internalEdges:r,triangleAdjacency:i}},Ip=t=>{const e=t.length;if(e<3)return null;const n=Math.sign(Ep(t));if(0===n)return null;const s=[...Array(e).keys()];n<0&&s.reverse();const o=[];let i=0;for(;s.length>3&&i<e*e;){let e=!1;for(let n=0;n<s.length;n++){const i=s[(n-1+s.length)%s.length],r=s[n],a=s[(n+1)%s.length];if(void 0===i||void 0===r||void 0===a)continue;const c=t[i],h=t[r],l=t[a];if(!c||!h||!l)continue;if(!_p(c,h,l))continue;let d=!1;for(const e of s){if(e===i||e===r||e===a)continue;const n=t[e];if(n&&Cp(n,c,h,l)){d=!0;break}}if(!d){o.push([i,r,a]),s.splice(n,1),e=!0;break}}if(!e)return null;i+=1}if(3===s.length){const[t,e,n]=s;void 0!==t&&void 0!==e&&void 0!==n&&o.push([t,e,n])}return o},_p=(t,e,n)=>Tp(t,e,n)>xp,Cp=(t,e,n,s)=>{const o=Tp(e,n,t),i=Tp(n,s,t),r=Tp(s,e,t);return o>=-1e-9&&i>=-1e-9&&r>=-1e-9},Tp=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Ep=t=>{let e=0;for(let n=0;n<t.length;n++){const s=t[n],o=t[(n+1)%t.length];s&&o&&(e+=s.x*o.y-o.x*s.y)}return e/2},wp=t=>Math.abs(Ep(t)),Rp=(t,e,n)=>Math.abs(Tp(t,e,n))/2,Op=(t,e)=>Math.hypot(t.x-e.x,t.y-e.y),Ap=(t,e)=>t<e?`${t}_${e}`:`${e}_${t}`,zp=t=>{if(t.length<2)return t;const e=t[0],n=t[t.length-1];return e&&n&&e.x===n.x&&e.y===n.y?t.slice(0,-1):t},Dp={pattern:"grid",pitchX:2.2,pitchY:1.8,staggerAxis:"x",staggerOffset:1.1,staggerOffsetX:1.1,padWidth:.9,padHeight:1,padGap:.35,viaDiameter:.3,clearance:.2,concavityTolerance:.3,boundsPadding:1.2,orientation:"horizontal",portSpacing:.25,maxNeckRatio:0,minSplitBalanceRatio:.2},Lp=(t,e)=>{let n=Number.POSITIVE_INFINITY,s=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const r of t)for(const t of r.padCenters){const r="horizontal"===e.orientation?e.padWidth/2:e.padHeight/2,a="horizontal"===e.orientation?e.padHeight/2:e.padWidth/2;t.x-r<n&&(n=t.x-r),t.y-a<s&&(s=t.y-a),t.x+r>o&&(o=t.x+r),t.y+a>i&&(i=t.y+a)}return{minX:n-e.boundsPadding,minY:s-e.boundsPadding,maxX:o+e.boundsPadding,maxY:i+e.boundsPadding}},Fp=t=>"staggered"===t.pattern?(t=>{const e=[],n=[],s=t.padGap/2+t.padWidth/2,o=-(t.cols-1)*t.pitchX/2,i=-(t.rows-1)*t.pitchY/2;for(let r=0;r<t.rows;r++){const a="x"===t.staggerAxis&&r%2==1?t.staggerOffset:0;for(let c=0;c<t.cols;c++){const h="y"===t.staggerAxis&&c%2==1?t.staggerOffset:0,l={x:o+c*t.pitchX+a,y:i+r*t.pitchY+h},d="horizontal"===t.orientation?{x:l.x-s,y:l.y}:{x:l.x,y:l.y-s},u="horizontal"===t.orientation?{x:l.x+s,y:l.y}:{x:l.x,y:l.y+s};e.push({jumperId:`jumper_r${r}_c${c}`,center:l,orientation:t.orientation,padCenters:[d,u]}),n.push({center:d,diameter:t.viaDiameter},{center:u,diameter:t.viaDiameter})}}return{jumpers:e,vias:n,bounds:Lp(e,t)}})(t):(t=>{const e=[],n=[],s=t.padGap/2+t.padWidth/2,o=-(t.cols-1)*t.pitchX/2,i=-(t.rows-1)*t.pitchY/2;for(let r=0;r<t.rows;r++)for(let a=0;a<t.cols;a++){const c={x:o+a*t.pitchX,y:i+r*t.pitchY},h="horizontal"===t.orientation?{x:c.x-s,y:c.y}:{x:c.x,y:c.y-s},l="horizontal"===t.orientation?{x:c.x+s,y:c.y}:{x:c.x,y:c.y+s},d=`jumper_r${r}_c${a}`;e.push({jumperId:d,center:c,orientation:t.orientation,padCenters:[h,l]}),n.push({center:h,diameter:t.viaDiameter},{center:l,diameter:t.viaDiameter})}return{jumpers:e,vias:n,bounds:{minX:o-s-t.padWidth/2-t.boundsPadding,maxX:o+(t.cols-1)*t.pitchX+s+t.padWidth/2+t.boundsPadding,minY:i-s-t.padHeight/2-t.boundsPadding,maxY:i+(t.rows-1)*t.pitchY+s+t.padHeight/2+t.boundsPadding}}})(t),Yp=t=>({x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}),Xp=t=>[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],kp=(t,e,n)=>Math.abs(t-e)<=n,$p=(t,e,n)=>kp(t.x,e.x,n)&&kp(t.y,e.y,n),Bp=t=>t.map((t,e)=>{const n=(t=>{let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,o=Number.NEGATIVE_INFINITY;for(const i of t)i.x<e&&(e=i.x),i.y<n&&(n=i.y),i.x>s&&(s=i.x),i.y>o&&(o=i.y);return{minX:e,minY:n,maxX:s,maxY:o}})(t);return{regionId:`top_${e}`,ports:[],d:{bounds:n,center:Yp(n),polygon:t,isPad:!1}}}),jp=t=>{const e=t.end.x-t.start.x,n=t.end.y-t.start.y;return Math.hypot(e,n)},Wp=(t,e)=>({x:t.start.x+(t.end.x-t.start.x)*e,y:t.start.y+(t.end.y-t.start.y)*e}),Hp=(t,e,n)=>{const s=[];if(!t.d.polygon||!e.d.polygon)return s;for(let o=0;o<t.d.polygon.length;o++){const i=t.d.polygon[o],r=t.d.polygon[(o+1)%t.d.polygon.length];if(i&&r)for(let t=0;t<e.d.polygon.length;t++){const o=e.d.polygon[t],a=e.d.polygon[(t+1)%e.d.polygon.length];if(!o||!a)continue;const c=Zp({start:i,end:r},{start:o,end:a},n);if(!c)continue;s.some(t=>Gp(t,c,n))||s.push(c)}}return s},Up=(t,e)=>{const n=[];for(const s of t){let t=s,o=!0;for(;o;){o=!1;for(let s=0;s<n.length;s++){const i=n[s];if(!i)continue;const r=Vp(t,i,e);if(r){t=r,n.splice(s,1),o=!0;break}}}n.push(t)}return n},Vp=(t,e,n)=>{const s=t.end.x-t.start.x,o=t.end.y-t.start.y,i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=s**2+o**2;if(a<=n**2)return null;if(!kp(s*r-o*i,0,n))return null;const c=e.start.x-t.start.x,h=e.start.y-t.start.y,l=e.end.x-t.start.x,d=e.end.y-t.start.y,u=s*d-o*l;if(!kp(s*h-o*c,0,n)||!kp(u,0,n))return null;const p=(c*s+h*o)/a,f=(l*s+d*o)/a,m=Math.min(p,f),g=Math.max(p,f),y=n/Math.sqrt(a);if(m>1+y||g<0-y)return null;const x=Math.min(0,m),v=Math.max(1,g);return{start:Wp(t,x),end:Wp(t,v)}},Gp=(t,e,n)=>$p(t.start,e.start,n)&&$p(t.end,e.end,n)||$p(t.start,e.end,n)&&$p(t.end,e.start,n),Zp=(t,e,n)=>{const s=t.end.x-t.start.x,o=t.end.y-t.start.y,i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=s**2+o**2;if(a<=n**2)return null;if(!kp(s*r-o*i,0,n))return null;const c=e.start.x-t.start.x,h=e.start.y-t.start.y,l=e.end.x-t.start.x,d=e.end.y-t.start.y,u=s*d-o*l;if(!kp(s*h-o*c,0,n)||!kp(u,0,n))return null;const p=(c*s+h*o)/a,f=(l*s+d*o)/a,m=Math.max(0,Math.min(p,f)),g=Math.min(1,Math.max(p,f));return g-m<=n/Math.sqrt(a)?null:{start:Wp(t,m),end:Wp(t,g)}},qp=(t,e,n)=>{const s=Math.max(t.minX,e.minX),o=Math.min(t.maxX,e.maxX),i=Math.max(t.minY,e.minY),r=Math.min(t.maxY,e.maxY);return o<s-n||r<i-n?null:{minX:s,maxX:o,minY:i,maxY:r}},Jp=t=>{const e=(t=>{const e=t.orientation??Dp.orientation,n=t.staggerAxis??Dp.staggerAxis,s=t.padWidth??Dp.padWidth,o=t.padHeight??Dp.padHeight,i=t.padGap??Dp.padGap,r=t.clearance??Dp.clearance,a=t.colSpacing??t.pitchX??Dp.pitchX,c=t.rowSpacing??t.pitchY??Dp.pitchY,h=(l=s,d=o,u=i,"horizontal"===e?{x:u+2*l,y:d}:{x:d,y:u+2*l});var l,d,u;const p=r,f=((t,e,n,s,o)=>"horizontal"===t?"x"===e?o+2*n:s:"x"===e?s:o+2*n)(e,n,s,o,i)/2,m=t.staggerOffset??t.staggerOffsetX??f,g={...Dp,...t,orientation:e,staggerAxis:n,pitchX:Math.max(a,h.x+p),pitchY:Math.max(c,h.y+p),padWidth:s,padHeight:o,padGap:i,staggerOffset:m,staggerOffsetX:m,concavityTolerance:t.concavityTolerance??Dp.concavityTolerance,clearance:r,portSpacing:t.portSpacing??Dp.portSpacing,maxNeckRatio:t.maxNeckRatio??Dp.maxNeckRatio,minSplitBalanceRatio:t.minSplitBalanceRatio??Dp.minSplitBalanceRatio};if(g.cols<=0||g.rows<=0)throw new Error("rows and cols must be > 0");if(!Number.isFinite(g.portSpacing)||g.portSpacing<=0)throw new Error("portSpacing must be > 0");if(!Number.isFinite(g.maxNeckRatio)||g.maxNeckRatio<0)throw new Error("maxNeckRatio must be >= 0");if(!Number.isFinite(g.minSplitBalanceRatio)||g.minSplitBalanceRatio<0||g.minSplitBalanceRatio>.5)throw new Error("minSplitBalanceRatio must be between 0 and 0.5");return g})(t),n=Fp(e),s="horizontal"===e.orientation?e.padWidth:e.padHeight,o="horizontal"===e.orientation?e.padHeight:e.padWidth,i=n.jumpers.flatMap(t=>t.padCenters.map(t=>({center:t,width:s,height:o,ccwRotation:0}))),r=new yp({bounds:n.bounds,rects:i,clearance:0,concavityTolerance:e.concavityTolerance});r.solve();const a=r.getOutput();if(!a)throw new Error(r.error??"ConvexRegionsSolver failed");const c=((t,e)=>{if(e.maxNeckRatio<=0)return t;const n=[];for(const s of t)n.push(...vp(s,e));return n})(a.regions,{maxNeckRatio:e.maxNeckRatio,minSplitBalanceRatio:e.minSplitBalanceRatio}),h=Bp(c),l=((t,e)=>t.flatMap(t=>{const[n,s]=t.padCenters,o="horizontal"===e.orientation?e.padWidth/2:e.padHeight/2,i="horizontal"===e.orientation?e.padHeight/2:e.padWidth/2,r={minX:n.x-o,maxX:n.x+o,minY:n.y-i,maxY:n.y+i},a={minX:s.x-o,maxX:s.x+o,minY:s.y-i,maxY:s.y+i},c=o/2,h=i/2,l="horizontal"===e.orientation?{minX:Math.min(n.x,s.x),maxX:Math.max(n.x,s.x),minY:t.center.y-h,maxY:t.center.y+h}:{minX:t.center.x-c,maxX:t.center.x+c,minY:Math.min(n.y,s.y),maxY:Math.max(n.y,s.y)};return[{regionId:`${t.jumperId}_pad1`,ports:[],d:{bounds:r,center:n,polygon:Xp(r),isPad:!0,isThroughJumper:!1}},{regionId:`${t.jumperId}_bridge`,ports:[],d:{bounds:l,center:t.center,polygon:Xp(l),isPad:!1,isThroughJumper:!0}},{regionId:`${t.jumperId}_pad2`,ports:[],d:{bounds:a,center:s,polygon:Xp(a),isPad:!0,isThroughJumper:!1}}]}))(n.jumpers,{orientation:e.orientation,padWidth:e.padWidth,padHeight:e.padHeight}),d=((t,e,n=1e-5)=>{const s=[];let o=0;for(let i=0;i<t.length;i++){const r=t[i];if(r?.d.polygon)for(let a=i+1;a<t.length;a++){const i=t[a];if(!i?.d.polygon)continue;const c=Hp(r,i,n);for(const t of c){const n=jp(t),a=Math.floor(n/e),c=Math.max(1,a-1);for(let e=0;e<c;e++){const n=Wp(t,(e+1)/(c+1));s.push({portId:"tp_"+o++,region1:r,region2:i,d:{x:n.x,y:n.y}})}}}}return s})(h,e.portSpacing),u=((t,e,n=1e-5)=>{const s=[];let o=0,i=0;const r=t.filter(t=>t.d.isPad),a=t.filter(t=>t.d.isThroughJumper&&!t.d.isPad);for(const t of r)for(const i of e){const e=Hp(t,i,n),r=Up(e,n);for(const e of r){const n=Wp(e,.5);s.push({portId:"jp_"+o++,region1:t,region2:i,d:{x:n.x,y:n.y}})}}for(const t of a)for(const e of r){const o=qp(t.d.bounds,e.d.bounds,n);if(!o)continue;const r=Yp(o);s.push({portId:"jip_"+i++,region1:e,region2:t,d:{x:r.x,y:r.y}})}return s})(l,h),p=[...d,...u];return(t=>{for(const e of t)e.region1.ports.push(e),e.region2.ports.push(e)})(p),{regions:[...h,...l],ports:p,jumperLocations:n.jumpers.map((t,e)=>({center:t.center,orientation:t.orientation,padRegions:[l[3*e],l[3*e+2]].filter(t=>Boolean(t))})),topLayerRegions:h,jumperRegions:l,jumpers:n.jumpers,vias:n.vias,bounds:n.bounds}},Kp=class extends Ln{getSolverName(){return"JumperPrepatternSolver2_HyperGraph"}constructorParams;nodeWithPortPoints;colorMap;traceWidth;obstacleMargin;hyperParameters;jumperGraphSolver=null;xyConnections=[];graphBounds=null;jumperLocations=[];solvedRoutes=[];jumpers=[];phase="jumperGraph";curvySolvers=[];currentCurvySolverIndex=0;routeInfos=[];regionCurvedPaths=new Map;constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.obstacleMargin=t.obstacleMargin??.15,this.hyperParameters=t.hyperParameters??{},this.MAX_ITERATIONS=1e6,0===Object.keys(this.colorMap).length&&(this.colorMap=this._buildColorMap())}getConstructorParams(){return this.constructorParams}_buildColorMap(){const t=["#e6194b","#3cb44b","#ffe119","#4363d8","#f58231","#911eb4","#46f0f0","#f032e6","#bcf60c","#fabebe"],e={},n=new Set;for(const t of this.nodeWithPortPoints.portPoints)n.add(t.connectionName);let s=0;for(const o of Array.from(n))e[o]=t[s%t.length],s++;return e}_normalizeRegionPolygonsToBounds(t){for(const e of t.regions){const t=e.d,n=t?.polygon,s=t?.bounds;if(!n||0===n.length||!s)continue;let o=1/0,i=1/0;for(const t of n)o=Math.min(o,t.x),i=Math.min(i,t.y);const r=s.minX-o,a=s.minY-i;(Math.abs(r)>1e-12||Math.abs(a)>1e-12)&&(t.polygon=n.map(t=>({x:t.x+r,y:t.y+a}))),t.polygonPerimeterCache&&(t.polygonPerimeterCache=void 0)}return t}_getPatternConfig(){return{cols:this.hyperParameters.COLS??1,rows:this.hyperParameters.ROWS??1}}_generate0603Grid(t,e,n,s){const o="horizontal"===e?t.rows:t.cols,i="horizontal"===e?t.cols:t.rows,r=s.maxX-s.minX,a=s.maxY-s.minY,c=.35,h=this.hyperParameters.TRACE_CHANNELS_BETWEEN_JUMPERS??1,l=this.traceWidth*h+2*this.obstacleMargin,d="horizontal"===e?2.15:1,u="horizontal"===e?1:2.15,p="horizontal"===e?"x":"y",f="staggered"===n,m=f&&"x"===p?d/2:f?u/2:0,g=Math.max(0,r-1),x=Math.max(0,a-1),v=Math.max(0,g-(f&&"x"===p?m:0)),b=Math.max(0,x-(f&&"y"===p?m:0)),P=o>1?Math.max(d+l,(v-d)/(o-1)):d,S=i>1?Math.max(u+l,(b-u)/(i-1)):u,M=Jp({cols:o,rows:i,orientation:e,pattern:n,staggerAxis:p,colSpacing:P,rowSpacing:S,padWidth:.9,padHeight:1,padGap:c,clearance:l,boundsPadding:0,maxNeckRatio:.4,minSplitBalanceRatio:.2}),N=M.bounds,I=(N.minX+N.maxX)/2,_=(N.minY+N.maxY)/2,C=y((s.minX+s.maxX)/2-I,(s.minY+s.maxY)/2-_);return this._normalizeRegionPolygonsToBounds(Eo(M,C))}_initializeGraph(){const t=this.nodeWithPortPoints,e=this._getPatternConfig(),n=this.hyperParameters.ORIENTATION??"vertical",s=this.hyperParameters.JUMPER_TYPE??"1206x4",o=this.hyperParameters.PATTERN??"grid",i={minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2};let r;if(this.graphBounds=i,"0603"===s){const t=this._generate0603Grid(e,n,o,i);if(!t)return this.error=`0603 grid (${e.cols}x${e.rows}) is too large to fit in node bounds`,this.failed=!0,!1;r=t}else r=ai({cols:e.cols,rows:e.rows,marginX:Math.max(1.2,.3*e.cols),marginY:Math.max(1.2,.3*e.rows),outerPaddingX:.4,outerPaddingY:.4,parallelTracesUnderJumperCount:2,innerColChannelPointCount:3,innerRowChannelPointCount:3,outerChannelXPointCount:3,outerChannelYPointCount:3,regionsBetweenPads:!0,orientation:n,bounds:i});if(r.regions.length>0){let t=1/0,e=-1/0,n=1/0,o=-1/0;for(const s of r.regions){if(!s.d?.isPad)continue;const i=s.d?.bounds;i&&(t=Math.min(t,i.minX),e=Math.max(e,i.maxX),n=Math.min(n,i.minY),o=Math.max(o,i.maxY))}const a="0603"===s?.5:1;if(t-a<i.minX||e+a>i.maxX||n-a<i.minY||o+a>i.maxY)return this.error=`baseGraph bounds (${t.toFixed(2)}, ${n.toFixed(2)}, ${e.toFixed(2)}, ${o.toFixed(2)}) exceed node bounds (${i.minX.toFixed(2)}, ${i.minY.toFixed(2)}, ${i.maxX.toFixed(2)}, ${i.maxY.toFixed(2)})`,this.failed=!0,!1}this.jumperLocations=r.jumperLocations?.map(t=>({center:t.center,orientation:t.orientation,padRegions:t.padRegions}))??[];const a=new Map;for(const e of t.portPoints){const t=a.get(e.connectionName);t?t.points.push(e):a.set(e.connectionName,{points:[e],rootConnectionName:e.rootConnectionName})}this.xyConnections=[];for(const[t,e]of Array.from(a.entries()))e.points.length<2||this.xyConnections.push({start:{x:e.points[0].x,y:e.points[0].y},end:{x:e.points[1].x,y:e.points[1].y},connectionId:t});if(0===this.xyConnections.length)return this.solved=!0,!0;const c=((t,e)=>{const n=[...t.regions],s=[...t.ports],o=[],i=Co(t.regions);for(const r of e){const{start:e,end:a,connectionId:c}=r,h=Qo(`conn:${c}:start`,e.x,e.y);n.push(h);const l=Qo(`conn:${c}:end`,a.x,a.y);n.push(l);const d=ii(e.x,e.y,t.regions,i);if(d){const t=Ko(`conn:${c}:start-port`,h,d.region,d.portPosition);s.push(t)}const u=ii(a.x,a.y,t.regions,i);if(u){const t=Ko(`conn:${c}:end-port`,l,u.region,u.portPosition);s.push(t)}const p={connectionId:c,mutuallyConnectedNetworkId:c,startRegion:h,endRegion:l};o.push(p)}return{regions:n,ports:s,connections:o}})(r,this.xyConnections);return this.jumperGraphSolver=new Jo({inputGraph:{regions:c.regions,ports:c.ports},inputConnections:c.connections}),this.jumperGraphSolver.MAX_ITERATIONS*=3,!0}_step(){switch(this.phase){case"jumperGraph":this._stepJumperGraph();break;case"curvyTrace":this._stepCurvyTrace();break;case"done":this.solved=!0}}_stepJumperGraph(){if(!this.jumperGraphSolver){if(this._initializeGraph(),this.solved)return;if(!this.jumperGraphSolver)return void(this.failed=!0)}this.activeSubSolver=this.jumperGraphSolver,this.jumperGraphSolver.step(),this.jumperGraphSolver.solved?(this._initializeCurvyTraceSolvers(),this.curvySolvers.length>0?this.phase="curvyTrace":(this._finalizeCurvyTraceResults(),this.phase="done",this.solved=!0)):this.jumperGraphSolver.failed&&(this.error=this.jumperGraphSolver.error,this.failed=!0)}_stepCurvyTrace(){if(this.currentCurvySolverIndex>=this.curvySolvers.length)return this._finalizeCurvyTraceResults(),this.phase="done",void(this.solved=!0);const t=this.curvySolvers[this.currentCurvySolverIndex],e=t.solver;if(this.activeSubSolver=e,e.step(),e.solved){const n=t.regionId;this.regionCurvedPaths.has(n)||this.regionCurvedPaths.set(n,new Map);for(const t of e.outputTraces){const e=t.networkId??"",s=t.points.map(t=>({x:t.x,y:t.y})),o={path:s,start:s[0]??{x:0,y:0},end:s[s.length-1]??{x:0,y:0}};this.regionCurvedPaths.get(n).has(e)||this.regionCurvedPaths.get(n).set(e,[]),this.regionCurvedPaths.get(n).get(e).push(o)}this.currentCurvySolverIndex++}else e.failed&&this.currentCurvySolverIndex++}_initializeCurvyTraceSolvers(){if(!this.jumperGraphSolver)return;const t=new Set,e=[];for(const t of this.jumperLocations)for(const n of t.padRegions){const t=n.d.bounds,s=n.d.center;e.push({minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:{x:s.x,y:s.y},networkIds:[]})}const n=new Map;for(let e=0;e<this.jumperGraphSolver.solvedRoutes.length;e++){const s=this.jumperGraphSolver.solvedRoutes[e],o=s.connection.connectionId,i=this.nodeWithPortPoints.portPoints.find(t=>t.connectionName===o)?.rootConnectionName,r=[],a=[];let c=null,h=null;for(let l=0;l<s.path.length;l++){const d=s.path[l],u=d.port,p=d.lastRegion,f=u.region1,m=u.region2;let g;if(p)f&&f.regionId!==p.regionId?g=f:m&&m.regionId!==p.regionId&&(g=m);else{const t=s.path[l+1],e=t?.lastRegion;if(e&&(f&&f.regionId===e.regionId?g=f:m&&m.regionId===e.regionId&&(g=m)),!g){const t=t=>t?.regionId?.startsWith("conn:");g=!f||t(f)||f.d?.isPad||f.d?.isThroughJumper?!m||t(m)||m.d?.isPad||m.d?.isThroughJumper?!f||f.d?.isPad||f.d?.isThroughJumper?(!m||m.d?.isPad||m.d?.isThroughJumper)&&f||m:f:m:f}}if(g&&(!c||g.regionId!==c.regionId)){if(c&&h){a.push({regionId:c.regionId,region:c,entryPort:h,exitPort:u});const t=c.regionId;n.has(t)||n.set(t,[]),n.get(t).push({regionId:c.regionId,region:c,routeIndex:e,connectionName:o,rootConnectionName:i,entryPort:h,exitPort:u})}c=g,h=u}if(p?.d?.isThroughJumper&&!t.has(p.regionId)){t.add(p.regionId);const e=p.d.bounds,n=p.d.center,s=e.maxX-e.minX>e.maxY-e.minY,o="0603"===(this.hyperParameters.JUMPER_TYPE??"1206x4")?"0603":"1206x4_pair";s?r.push({route_type:"jumper",start:{x:e.minX,y:n.y},end:{x:e.maxX,y:n.y},footprint:o}):r.push({route_type:"jumper",start:{x:n.x,y:e.minY},end:{x:n.x,y:e.maxY},footprint:o})}}if(c&&h){const t=s.path[s.path.length-1];a.push({regionId:c.regionId,region:c,entryPort:h,exitPort:t?.port||null})}this.routeInfos.push({connectionId:o,rootConnectionName:i,jumpers:r,traversals:a})}for(let t=0;t<this.routeInfos.length;t++){const n=this.routeInfos[t],s=n.rootConnectionName??n.connectionId;for(const t of n.jumpers){const n=[t.start,t.end];for(const t of n)for(const n of e){const e=Math.abs(n.center.x-t.x),o=Math.abs(n.center.y-t.y);e<.1&&o<.1&&(n.networkIds.includes(s)||n.networkIds.push(s))}}}for(const[t,s]of n){if(0===s.length)continue;const n=s[0].region;if(n.d.isPad||n.d.isThroughJumper)continue;const o=n.d.bounds,i=[];for(const t of s)i.push({start:{x:t.entryPort.d.x,y:t.entryPort.d.y},end:{x:t.exitPort.d.x,y:t.exitPort.d.y},networkId:t.rootConnectionName??t.connectionName});const r=.01,a=e.filter(t=>t.minX<=o.maxX+r&&t.maxX>=o.minX-r&&t.minY<=o.maxY+r&&t.maxY>=o.minY-r).map(t=>{const e=s.map(t=>t.rootConnectionName??t.connectionName),n=t.networkIds.find(t=>e.includes(t));return{minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:t.center,networkId:n}}),c={bounds:o,waypointPairs:i,obstacles:a,preferredTraceToTraceSpacing:2*this.traceWidth,preferredObstacleToTraceSpacing:2*this.traceWidth},h=new Eu(c);this.curvySolvers.push({solver:h,regionId:t,traversals:s.map(t=>({routeIndex:t.routeIndex,connectionName:t.connectionName,rootConnectionName:t.rootConnectionName}))})}}_finalizeCurvyTraceResults(){const t=(t,e)=>Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2);for(let e=0;e<this.routeInfos.length;e++){const n=this.routeInfos[e],s=[];for(const e of n.traversals){const o=e.regionId,i=n.rootConnectionName??n.connectionId,r=this.regionCurvedPaths.get(o)?.get(i);let a=null;if(r&&r.length>0){const n={x:e.entryPort.d.x,y:e.entryPort.d.y},s=e.exitPort?{x:e.exitPort.d.x,y:e.exitPort.d.y}:null;let o=null,i=1/0;for(const e of r){const r=t(e.start,n)+(s?t(e.end,s):0);r<i&&(i=r,o=e)}o&&i<.5&&(a=o.path)}if(a&&a.length>0){for(let t=s.length>0?1:0;t<a.length;t++)s.push({x:a[t].x,y:a[t].y,z:0})}else 0===s.length&&s.push({x:e.entryPort.d.x,y:e.entryPort.d.y,z:0}),e.exitPort&&s.push({x:e.exitPort.d.x,y:e.exitPort.d.y,z:0})}this.solvedRoutes.push({connectionName:n.connectionId,rootConnectionName:n.rootConnectionName,traceThickness:this.traceWidth,route:s,jumpers:n.jumpers})}}getOutput(){return this.solvedRoutes}getOutputJumpers(){if(this.jumpers.length>0)return this.jumpers;const t=new Map;for(const e of this.solvedRoutes)for(const n of e.jumpers){const s=[n.start,n.end];for(const n of s){const s=`${n.x.toFixed(3)},${n.y.toFixed(3)}`,o=t.get(s)??[];e.rootConnectionName&&!o.includes(e.rootConnectionName)&&o.push(e.rootConnectionName),o.includes(e.connectionName)||o.push(e.connectionName),t.set(s,o)}}const e=this.hyperParameters.JUMPER_TYPE??"1206x4",n=wn["0603"===e?"0603":"1206x4_pair"];for(const s of this.jumperLocations){const o="horizontal"===s.orientation,i=s.padRegions.map(e=>{const n=e.d.bounds,s=e.d.center,o=n.maxX-n.minX,i=n.maxY-n.minY,r=`${s.x.toFixed(3)},${s.y.toFixed(3)}`;return{type:"rect",center:s,width:o,height:i,layers:["top"],connectedTo:[...t.get(r)??[]]}}),r={jumper_footprint:e,center:s.center,orientation:s.orientation,width:o?n.length:n.width,height:o?n.width:n.length,pads:i};this.jumpers.push(r)}return this.jumpers=this.jumpers.filter(t=>t.pads.some(t=>t.connectedTo.length>0)),this.jumpers}visualize(){if(this.jumperGraphSolver&&!this.solved)return this.jumperGraphSolver.visualize();const t={lines:[],points:[],rects:[],circles:[]},e=this.nodeWithPortPoints,n={minX:e.center.x-e.width/2,maxX:e.center.x+e.width/2,minY:e.center.y-e.height/2,maxY:e.center.y+e.height/2};t.lines.push({points:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY},{x:n.minX,y:n.minY}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"});for(const n of e.portPoints)t.points.push({x:n.x,y:n.y,label:n.connectionName,color:this.colorMap[n.connectionName]??"blue"});for(const e of this.solvedRoutes){const n=this.colorMap[e.connectionName]??"blue";for(let s=0;s<e.route.length-1;s++){const o=e.route[s],i=e.route[s+1];t.lines.push({points:[o,i],strokeColor:In(n,.2),strokeWidth:e.traceThickness,layer:"route-layer-0"})}for(const s of e.jumpers)this._drawJumperPads(t,s,In(n,.5))}return t}_drawJumperPads(t,e,n){const s=wn[e.footprint],o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=Math.abs(o)>Math.abs(i),a=r?s.padLength:s.padWidth,c=r?s.padWidth:s.padLength;t.rects.push({center:{x:e.start.x,y:e.start.y},width:a,height:c,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:a,height:c,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*s.padWidth,layer:"jumper-body"})}},Qp=class extends is{constructorParams;nodeWithPortPoints;colorMap;traceWidth;obstacleMargin;connMap;baseHyperParameters;availableJumperTypes;solvedRoutes=[];jumpers=[];constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.obstacleMargin=t.obstacleMargin??.15,this.connMap=t.connMap,this.baseHyperParameters=t.hyperParameters??{},this.availableJumperTypes=t.availableJumperTypes??["0603"],this.MAX_ITERATIONS=1e6,this.GREEDY_MULTIPLIER=1,this.MIN_SUBSTEPS=1e3}getConstructorParams(){return this.constructorParams}getHyperParameterDefs(){const t=[],e=this.nodeWithPortPoints,n=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",1);t.push({name:"0603_max_rows_and_cols_vert_1trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:n.cols,ROWS:n.rows,ORIENTATION:"vertical",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const s=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",1,"staggered");t.push({name:"0603_max_rows_and_cols_vert_1trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:s.cols,ROWS:s.rows,ORIENTATION:"vertical",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const o=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",2);t.push({name:"0603_max_rows_and_cols_vert_2trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:o.cols,ROWS:o.rows,ORIENTATION:"vertical",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const i=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",2,"staggered");t.push({name:"0603_max_rows_and_cols_vert_2trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:i.cols,ROWS:i.rows,ORIENTATION:"vertical",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const r=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",1);t.push({name:"0603_max_rows_and_cols_horz_1trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:r.cols,ROWS:r.rows,ORIENTATION:"horizontal",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const a=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",1,"staggered");t.push({name:"0603_max_rows_and_cols_horz_1trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:a.cols,ROWS:a.rows,ORIENTATION:"horizontal",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const c=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",2);t.push({name:"0603_max_rows_and_cols_horz_2trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:c.cols,ROWS:c.rows,ORIENTATION:"horizontal",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const h=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",2,"staggered");t.push({name:"0603_max_rows_and_cols_horz_2trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:h.cols,ROWS:h.rows,ORIENTATION:"horizontal",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]}),t.push({name:"1206x4",possibleValues:[{JUMPER_TYPE:"1206x4"}]});return t.push({name:"1206x4_cols",possibleValues:[1,2,3,4,6,8,10].map(t=>({COLS:t}))}),t.push({name:"1206x4_rows",possibleValues:[1,2,3,4,8].map(t=>({ROWS:t}))}),t.push({name:"orientation",possibleValues:[{ORIENTATION:"vertical"},{ORIENTATION:"horizontal"}]}),t}isValidCombination(t){const{JUMPER_TYPE:e,COLS:n,ROWS:s}=t,o=[1,2,4,6,8],i=[1,2,3,4,6,8,10],r=[1,2,3,4,8];return"0603"===e?o.includes(n)&&o.includes(s):"1206x4"===e&&(i.includes(n)&&r.includes(s))}getCombinationDefs(){return[["0603_max_rows_and_cols_vert_1trace_grid"],["0603_max_rows_and_cols_vert_1trace_staggered"],["0603_max_rows_and_cols_horz_1trace_grid"],["0603_max_rows_and_cols_horz_1trace_staggered"],["0603_max_rows_and_cols_vert_2trace_grid"],["0603_max_rows_and_cols_vert_2trace_staggered"],["0603_max_rows_and_cols_horz_2trace_grid"],["0603_max_rows_and_cols_horz_2trace_staggered"],["1206x4","1206x4_cols","1206x4_rows","orientation"]]}calculateMax0603ConfigWithTraceChannels(t,e,n,s,o="grid"){const i=this.traceWidth*s+2*this.obstacleMargin,r="horizontal"===n?2.15:1,a="horizontal"===n?1:2.15,c="horizontal"===n?"x":"y",h="staggered"===o&&"x"===c?r/2:"staggered"===o?a/2:0,l=Math.max(0,t-1),d=Math.max(0,e-1),u=Math.max(0,l-("staggered"===o&&"x"===c?h:0)),p=Math.max(0,d-("staggered"===o&&"y"===c?h:0)),f=r+i,m=a+i,g=Math.max(1,Math.floor(1+(u-r)/f)),y=Math.max(1,Math.floor(1+(p-a)/m));return"vertical"===n?{cols:g,rows:y}:{cols:y,rows:g}}initializeSolvers(){const t=this.getHyperParameterDefs(),e=this.getCombinationDefs();this.supervisedSolvers=[];for(const n of e){const e=n.some(t=>t.startsWith("0603_max_rows_and_cols_")),s=n.includes("1206x4");if(e&&!this.availableJumperTypes.includes("0603"))continue;if(s&&!this.availableJumperTypes.includes("1206x4"))continue;const o=this.getHyperParameterCombinations(t.filter(t=>n.includes(t.name)));for(const t of o){const e=this.generateSolver(t),n=this.computeG(e);this.supervisedSolvers.push({hyperParameters:t,solver:e,h:0,g:n,f:n})}}}generateSolver(t){return new Kp({nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,traceWidth:this.traceWidth,hyperParameters:{COLS:t.COLS,ROWS:t.ROWS,ORIENTATION:t.ORIENTATION,JUMPER_TYPE:t.JUMPER_TYPE,PATTERN:t.PATTERN,TRACE_CHANNELS_BETWEEN_JUMPERS:t.TRACE_CHANNELS_BETWEEN_JUMPERS},obstacleMargin:this.obstacleMargin})}computeG(t){const e=t.hyperParameters.COLS*t.hyperParameters.ROWS;return t.iterations/1e4+.25*e}computeH(t){return 1-(t.progress||0)}onSolve(t){this.solvedRoutes=t.solver.solvedRoutes,this.jumpers=t.solver.getOutputJumpers()}getOutput(){return this.solvedRoutes}getOutputJumpers(){return this.jumpers}visualize(){return this.winningSolver?this.winningSolver.visualize():super.visualize()}};function tf(t){return{connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,traceThickness:t.traceThickness,viaDiameter:0,route:t.route,vias:[],jumpers:t.jumpers}}var ef=class extends Ln{getSolverName(){return"JumperHighDensitySolver"}allNodes;nodeAnalyses;routes;colorMap;traceWidth;obstacleMargin;viaDiameter;connMap;hyperParameters;availableJumperTypes;capacityMeshNodes;capacityMeshEdges;capacityMeshNodeMap;nodeAdjacencyMap;nodesWithoutCrossings;nodesWithCrossings;curvyIntraNodeSolvers;currentCurvySolverIndex;jumperSolvers;currentJumperSolverIndex;phase;jumpers=[];constructor({nodePortPoints:t,colorMap:e,traceWidth:n=.15,obstacleMargin:s=.15,viaDiameter:o=.3,connMap:i,hyperParameters:r,capacityMeshNodes:a=[],capacityMeshEdges:c=[],availableJumperTypes:h}){super(),this.allNodes=[...t],this.colorMap=e??{},this.routes=[],this.traceWidth=n,this.obstacleMargin=s,this.viaDiameter=o,this.connMap=i,this.hyperParameters=r,this.capacityMeshNodes=a,this.capacityMeshEdges=c,this.availableJumperTypes=h??["0603"],this.capacityMeshNodeMap=new Map(a.map(t=>[t.capacityMeshNodeId,t])),this.nodeAdjacencyMap=this._buildNodeAdjacencyMap(),this.nodesWithoutCrossings=[],this.nodesWithCrossings=[],this.nodeAnalyses=[],this.curvyIntraNodeSolvers=[],this.currentCurvySolverIndex=0,this.jumperSolvers=[],this.currentJumperSolverIndex=0,this.phase="analyzing",this._analyzeNodes();const l=1e3*this.nodesWithoutCrossings.length,d=1e5*this.nodesWithCrossings.length;this.MAX_ITERATIONS=l+d+100}_buildNodeAdjacencyMap(){const t=new Map;for(const e of this.capacityMeshEdges){const[n,s]=e.nodeIds;t.has(n)||t.set(n,new Set),t.has(s)||t.set(s,new Set),t.get(n).add(s),t.get(s).add(n)}return t}_analyzeNodes(){for(const t of this.allNodes){const e=vh(t),n={node:t,hasCrossings:e.numSameLayerCrossings>0,numSameLayerCrossings:e.numSameLayerCrossings};this.nodeAnalyses.push(n),e.numSameLayerCrossings>0?this.nodesWithCrossings.push(t):this.nodesWithoutCrossings.push(t)}this.nodesWithoutCrossings.length>0?(this.phase="curvy",this._initializeCurvySolvers()):this.nodesWithCrossings.length>0?(this.phase="jumpers",this._initializeJumperSolvers()):this.phase="done"}_step(){switch(this.phase){case"analyzing":this.nodesWithoutCrossings.length>0?(this.phase="curvy",this._initializeCurvySolvers()):this.nodesWithCrossings.length>0?(this.phase="jumpers",this._initializeJumperSolvers()):this.phase="done";break;case"curvy":this._stepCurvySolvers();break;case"jumpers":this._stepJumperSolvers();break;case"done":this.solved=!0}}_getAdjacentObstacles(t){const e=[],n=this.nodeAdjacencyMap.get(t.capacityMeshNodeId);if(!n||0===n.size)return e;const s=new Map(this.allNodes.map(t=>[t.capacityMeshNodeId,t]));for(const t of n){const n=this.capacityMeshNodeMap.get(t);if(!n)continue;if(!n._containsObstacle&&!n._containsTarget)continue;const o=n.center.x-n.width/2,i=n.center.y-n.height/2,r=n.center.x+n.width/2,a=n.center.y+n.height/2;let c;if(n._containsTarget)if(n._targetConnectionName)c=n._targetConnectionName;else{const e=s.get(t);e&&e.portPoints.length>0&&(c=e.portPoints[0].rootConnectionName??e.portPoints[0].connectionName)}e.push({minX:o,minY:i,maxX:r,maxY:a,networkId:c})}return e}_initializeCurvySolvers(){for(const t of this.nodesWithoutCrossings){const e=this._getAdjacentObstacles(t),n=new wu({nodeWithPortPoints:t,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:e});this.curvyIntraNodeSolvers.push(n)}}_stepCurvySolvers(){if(0===this.curvyIntraNodeSolvers.length)return this.phase=this.nodesWithCrossings.length>0?"jumpers":"done",void("jumpers"===this.phase&&this._initializeJumperSolvers());const t=this.curvyIntraNodeSolvers[this.currentCurvySolverIndex];if(this.activeSubSolver=t,!t)return this.phase=this.nodesWithCrossings.length>0?"jumpers":"done",void("jumpers"===this.phase&&this._initializeJumperSolvers());if(t.step(),t.solved){this.routes.push(...t.routes),this.currentCurvySolverIndex++;for(let t=this.currentCurvySolverIndex;t<this.curvyIntraNodeSolvers.length;t++){this.curvyIntraNodeSolvers[t];const e=this.nodesWithoutCrossings[t],n=this._getAdjacentObstacles(e),s=new wu({nodeWithPortPoints:e,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:n});this.curvyIntraNodeSolvers[t]=s}this.currentCurvySolverIndex>=this.curvyIntraNodeSolvers.length&&(this.phase=this.nodesWithCrossings.length>0?"jumpers":"done","jumpers"===this.phase&&this._initializeJumperSolvers())}else t.failed&&(this.error=`CurvyIntraNodeSolver failed for node: ${t.nodeWithPortPoints.capacityMeshNodeId}: ${t.error}`,this.failed=!0)}_initializeJumperSolvers(){for(const t of this.nodesWithCrossings){const e=new Qp({nodeWithPortPoints:t,colorMap:this.colorMap,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,connMap:this.connMap,availableJumperTypes:this.availableJumperTypes});this.jumperSolvers.push(e)}}_stepJumperSolvers(){if(0===this.jumperSolvers.length)return this.phase="done",void(this.solved=!0);const t=this.jumperSolvers[this.currentJumperSolverIndex];if(this.activeSubSolver=t,!t)return this.phase="done",void(this.solved=!0);if(t.step(),t.solved){for(const e of t.solvedRoutes)this.routes.push(tf(e));this.jumpers.push(...t.getOutputJumpers()),this.currentJumperSolverIndex++,this.currentJumperSolverIndex>=this.jumperSolvers.length&&(this.phase="done",this.solved=!0)}else t.failed&&(this.error=`HyperJumperPrepatternSolver2 failed for node: ${t.nodeWithPortPoints.capacityMeshNodeId}: ${t.error}`,this.failed=!0)}computeProgress(){const t=this.allNodes.length;if(0===t)return 1;let e=0;e+=this.currentCurvySolverIndex;const n=this.curvyIntraNodeSolvers[this.currentCurvySolverIndex];n&&(e+=n.progress),e+=this.currentJumperSolverIndex;const s=this.jumperSolvers[this.currentJumperSolverIndex];return s&&(e+=s.progress),e/t}getConstructorParams(){return{nodePortPoints:this.allNodes,colorMap:this.colorMap,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,viaDiameter:this.viaDiameter,connMap:this.connMap,hyperParameters:this.hyperParameters,capacityMeshNodes:this.capacityMeshNodes,capacityMeshEdges:this.capacityMeshEdges,availableJumperTypes:this.availableJumperTypes}}getOutputJumpers(){return this.jumpers}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(this.failed&&this.activeSubSolver)return this.activeSubSolver.visualize();if("curvy"===this.phase&&this.curvyIntraNodeSolvers[this.currentCurvySolverIndex])return this.curvyIntraNodeSolvers[this.currentCurvySolverIndex].visualize();if("jumpers"===this.phase&&this.jumperSolvers[this.currentJumperSolverIndex])return this.jumperSolvers[this.currentJumperSolverIndex].visualize();for(const e of this.routes){const n=e.rootConnectionName??e.connectionName,s=Wn(e.route,e.connectionName,this.colorMap[n]);for(const n of s)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:In(n.color??"gray",.75),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?"10, 5":void 0});for(const s of e.vias)t.circles.push({center:s,radius:e.viaDiameter/2,fill:In(this.colorMap[n]??"gray",.5),layer:"via"});if("jumpers"in e&&e.jumpers)for(const s of e.jumpers){const e=this.colorMap[n]??"gray",o=s.footprint??"1206",i=wn[o],r=s.end.x-s.start.x,a=s.end.y-s.start.y,c=Math.abs(r)>Math.abs(a),h=c?i.padLength:i.padWidth,l=c?i.padWidth:i.padLength;t.rects.push({center:s.start,width:h,height:l,fill:In(e,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:s.end,width:h,height:l,fill:In(e,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[s.start,s.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*i.padWidth,layer:"jumper-body"})}}for(const e of this.nodeAnalyses){const n=e.node;n.center.x,n.width,n.center.x,n.width,n.center.y,n.height,n.center.y,n.height;t.rects.push({center:n.center,width:n.width,height:n.height,fill:e.hasCrossings?"rgba(255, 200, 0, 0.1)":"rgba(0, 200, 0, 0.1)",stroke:e.hasCrossings?"rgba(255, 150, 0, 0.5)":"rgba(0, 150, 0, 0.5)",label:[n.capacityMeshNodeId,e.hasCrossings?`crossings: ${e.numSameLayerCrossings}`:"no crossings"].join("\n")})}return t}};function nf(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var sf=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=Ph(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline3"}netToPointPairsSolver;traceKeepoutSolver;nodeSolver;nodeTargetMerger;edgeSolver;relateNodesToOffBoardConnections;colorMap;highDensityRouteSolver;simpleHighDensityRouteSolver;highDensitySolver;highDensityStitchSolver;singleLayerNodeMerger;offboardPathFragmentSolver;strawSolver;deadEndSolver;traceSimplificationSolver;traceWidthSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[nf("netToPointPairsSolver",Hh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),nf("nodeSolver",xe,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),nf("relateNodesToOffBoardConnections",kd,t=>[{capacityMeshNodes:t.capacityNodes,srj:t.srj}],{onSolved:t=>{t.capacityNodes=t.relateNodesToOffBoardConnections?.getOutput().capacityNodes}}),nf("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),nf("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),nf("portPointPathingSolver",Dh,t=>{const e=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle,_offBoardConnectionId:t._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t._offBoardConnectedCapacityMeshNodeIds})),n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),s=t.availableSegmentPointSolver;for(const t of s.sharedEdgeSegments)for(const e of t.portPoints){const[s,o]=e.nodeIds,i={portPointId:e.segmentPortPointId,x:e.x,y:e.y,z:e.availableZ[0]??0,connectionNodeIds:[s,o],distToCentermostPortOnZ:e.distToCentermostPortOnZ,connectsToOffBoardNode:t.nodeIds.some(t=>n.get(t)?._offBoardConnectionId)},r=n.get(s);r&&r.portPoints.push(i)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:10*t.effort,hyperParameters:{JUMPER_PF_FN_ENABLED:!0,NODE_PF_FACTOR:100,MAX_RIPS:100*t.effort,RIPPING_ENABLED:!0,MAX_RIPPING_PF_THRESHOLD:.9,MIN_RIPPING_PF_THRESHOLD:.1,RANDOM_RIP_FRACTION:.05,NODE_PF_MAX_PENALTY:1e3,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:0,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,FORCE_CENTER_FIRST:!0}}]},{onSolved:t=>{const e=t.portPointPathingSolver;e&&Gd({connMap:t.connMap,connectionsWithResults:e.connectionsWithResults,inputNodes:e.inputNodes,obstacles:t.srj.obstacles})}}),nf("highDensitySolver",ef,t=>[{nodePortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,connMap:t.connMap,capacityMeshNodes:t.capacityNodes??[],capacityMeshEdges:t.capacityEdges??[],availableJumperTypes:t.srj.availableJumperTypes}]),nf("highDensityStitchSolver",Jd,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensitySolver.routes,connectionPathResults:t.multiSectionPortPointOptimizer?.connectionResults??t.portPointPathingSolver?.connectionsWithResults??[],colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),nf("traceKeepoutSolver",Xd,t=>[{hdRoutes:t.traceSimplificationSolver?.simplifiedHdRoutes??t.highDensityStitchSolver?.mergedHdRoutes??[],obstacles:t.srj.obstacles,jumpers:t.highDensitySolver?.getOutputJumpers()??[],connMap:t.connMap,colorMap:t.colorMap,srj:t.srj}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.traceKeepoutSolver?.visualize(),a=this.deadEndSolver?.visualize(),c=this.availableSegmentPointSolver?.visualize(),h=this.offboardPathFragmentSolver?.visualize(),l=this.portPointPathingSolver?.visualize(),d=this.multiSectionPortPointOptimizer?.visualize(),u=this.highDensityRouteSolver?.visualize(),p=this.highDensitySolver?.visualize(),f=this.simpleHighDensityRouteSolver?.visualize(),m=this.highDensityStitchSolver?.visualize(),g=this.traceSimplificationSolver?.visualize(),y=this.traceWidthSolver?.visualize(),x=this.srj.outline,v=[];if(v.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),x&&x.length>=2){const t=x.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const b={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:["obstacle",t.offBoardConnectsTo?`offboardConnections: ${t.offBoardConnectsTo?.join(", ")}`:"",t.layers?.join(", ")].filter(Boolean).join("\n")}))],lines:v},P=[b,t,e,n,s,o,i,a,c,h,l,d,u?jn(b,u):null,p?jn(b,p):null,f?jn(b,f):null,m,g,r,y,this.solved?jn(b,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...P)}preview(){const t=this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes;if(t){const e=[];for(let n=t.length-1;n>=0;n--){const s=t[n];if(e.push({points:s.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[s.connectionName]}),e.length>200)break}return{lines:e}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.hdRoutesWithWidths??this.traceKeepoutSolver?.redrawnHdRoutes??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver?.mergedHdRoutes??this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes}getConnectedOffboardObstacles(){const t={},e=new Set(this.srj.connections.map(t=>t.rootConnectionName??t.name));for(const[n,s]of this.srj.obstacles.entries()){if(!s.offBoardConnectsTo?.length)continue;const o=s.obstacleId??`__obs${n}`;s.obstacleId=o;const i=this.connMap.getNetConnectedToId(o);if(!i)continue;const r=this.connMap.getIdsConnectedToNet(i).find(t=>e.has(t));r&&(t[o]=r)}return t}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver&&!this.simpleHighDensityRouteSolver&&!this.highDensitySolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputJumpers(){return this.highDensitySolver?this.highDensitySolver.getOutputJumpers():[]}getOutputSimpleRouteJson(){const t=this.getOutputJumpers();return{...this.srj,traces:this.getOutputSimplifiedPcbTraces(),jumpers:t.length>0?t:void 0}}},of=t=>{const{candidates:e,mapOfCapacityMeshNodeIdToRef:n}=t;let s=!0;for(const t of e){let e=!1;t.port.nodeIds.forEach(t=>{const s=n.get(t);if(!s)throw new Error(`Could not find capacity mesh node for id ${t}`);s._containsObstacle&&(e=!0)}),e||(s=!1)}return s},rf=t=>t.depth+1e3*t.countOfCrampedPortPointsInPath,af=class extends N{constructor(t){if(super(),this.input=t,this.input.depthLimit<1)throw new Error("Depth limit must be at least 1");this._setup()}queue=[];resultExploredPortPoints=[];currentExploredPortPoints=null;visitedExploredPortPoints=new Map;getSolverName(){return"singleTargetNecessaryCrampedPortPointSolver"}_setup(){const t=this.input.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(this.input.target.capacityMeshNodeId)??[];for(const e of t){if(this.input.shouldIgnoreCrampedPortPoints&&e.cramped)continue;const t={port:e,depth:1,parent:null,countOfCrampedPortPointsInPath:e.cramped?1:0},n=this.visitedExploredPortPoints.get(e);(!n||this.getCandidateCost(t)<this.getCandidateCost(n))&&(this.visitedExploredPortPoints.set(e,t),this.queue.push(t))}}_step(){if(0===this.queue.length)return this.currentExploredPortPoints=null,void(this.solved=!0);for(;this.queue.length>0;){this.currentExploredPortPoints=this.queue.shift();if(this.visitedExploredPortPoints.get(this.currentExploredPortPoints.port)!==this.currentExploredPortPoints)continue;if(this.currentExploredPortPoints.depth===this.input.depthLimit){this.resultExploredPortPoints.push(this.currentExploredPortPoints);continue}const t=this.currentExploredPortPoints.port.nodeIds.map(t=>{const e=this.input.mapOfCapacityMeshNodeIdToRef.get(t);if(!e)throw new Error(`Could not find capacity mesh node for id ${t}`);return e}).flatMap(t=>this.input.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(t.capacityMeshNodeId)??[]);for(const e of t){if(this.input.shouldIgnoreCrampedPortPoints&&e.cramped)continue;const t={port:e,depth:this.currentExploredPortPoints.depth+1,parent:this.currentExploredPortPoints,countOfCrampedPortPointsInPath:this.currentExploredPortPoints.countOfCrampedPortPointsInPath+(e.cramped?1:0)},n=this.visitedExploredPortPoints.get(e);n&&this.getCandidateCost(n)<=this.getCandidateCost(t)||(this.visitedExploredPortPoints.set(e,t),this.queue.push(t))}}this.solved=!0}getCandidateCost(t){return t.depth+1e3*t.countOfCrampedPortPointsInPath}getOutput(){return this.resultExploredPortPoints}visualize(){const t={points:[],rects:[]};for(const e of this.visitedExploredPortPoints.keys())t.points.push({...e,color:e.cramped?"blue":"green"});return t}},cf=class extends N{constructor(t){super(),this.input=t,this._setup()}unprocessedTargets=[];targetNode=[];currentTarget;crampedPortPointsToKeep=new Set;candidatesAtDepth=[];isRunningCrampedPass=!1;activeSubSolver=null;nodeMap=new Map;mapOfCapacityMeshNodeIdToSegmentPortPoints=new Map;getSolverName(){return"multiTargetNecessaryCrampedPortPointSolver"}_setup(){this.targetNode=this.input.capacityMeshNodes.filter(t=>t._containsObstacle);const t=this.input.simpleRouteJson.connections.flatMap(t=>t.pointsToConnect);this.targetNode=this.targetNode.filter(e=>{let n=!1;return t.forEach(t=>{B(t,e)<=0&&(n=!0)}),n}),this.unprocessedTargets=[...this.targetNode],this.unprocessedTargets.sort((t,e)=>t.center.x-e.center.x);for(const t of this.input.capacityMeshNodes)this.nodeMap.set(t.capacityMeshNodeId,t);for(const t of this.input.sharedEdgeSegments)for(const e of t.portPoints){const t=e.nodeIds;for(const n of t){if(!this.nodeMap.get(n))throw new Error(`Could not find capacity mesh node for id ${n}`);const t=this.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(n)||[];this.mapOfCapacityMeshNodeIdToSegmentPortPoints.set(n,[...t,e])}}}_step(){if(this.activeSubSolver){if(this.activeSubSolver._step(),!this.activeSubSolver.solved)return;if(this.activeSubSolver.failed)return this.failed=!0,void(this.error=this.activeSubSolver.error);if(this.candidatesAtDepth=this.activeSubSolver.getOutput(),this.activeSubSolver=null,!this.currentTarget)return this.failed=!0,void(this.error="Missing current capacity mesh node while finishing BFS");if(!this.isRunningCrampedPass){return of({candidates:this.candidatesAtDepth,mapOfCapacityMeshNodeIdToRef:this.nodeMap})||0===this.candidatesAtDepth.length?(this.isRunningCrampedPass=!0,void(this.activeSubSolver=new af({target:this.currentTarget,depthLimit:2,shouldIgnoreCrampedPortPoints:!1,mapOfCapacityMeshNodeIdToSegmentPortPoints:this.mapOfCapacityMeshNodeIdToSegmentPortPoints,mapOfCapacityMeshNodeIdToRef:this.nodeMap}))):void(this.currentTarget=void 0)}let t=this.candidatesAtDepth.filter(t=>{const e=t.port;return e.nodeIds.map(t=>{const e=this.nodeMap.get(t);if(!e)throw this.failed=!0,this.error=`Could not find capacity mesh node for id ${t}`,new Error(`Could not find capacity mesh node for id ${t}`);return e}).every(t=>!t._containsObstacle)&&e.cramped});of({candidates:t,mapOfCapacityMeshNodeIdToRef:this.nodeMap})&&(this.error=`All candidates are blocked by obstacles even after including cramped port points for capacity mesh node ${this.currentTarget.capacityMeshNodeId}`),this.candidatesAtDepth=[...t].sort((t,e)=>rf(t)-rf(e));const e=this.candidatesAtDepth[0];return e&&0!==t.length?this.crampedPortPointsToKeep.add(e.port):this.error=`No candidates found for capacity mesh node ${this.currentTarget.capacityMeshNodeId} even after including cramped port points`,this.isRunningCrampedPass=!1,void(this.currentTarget=void 0)}if(!this.currentTarget)return this.currentTarget=this.unprocessedTargets.shift(),this.currentTarget?(this.isRunningCrampedPass=!1,this.candidatesAtDepth=[],void(this.activeSubSolver=new af({target:this.currentTarget,depthLimit:2,shouldIgnoreCrampedPortPoints:!0,mapOfCapacityMeshNodeIdToSegmentPortPoints:this.mapOfCapacityMeshNodeIdToSegmentPortPoints,mapOfCapacityMeshNodeIdToRef:this.nodeMap}))):void(this.solved=!0)}getOutput(){return this.input.sharedEdgeSegments.map(t=>({...t,portPoints:t.portPoints.filter(t=>!t.cramped||this.crampedPortPointsToKeep.has(t))}))}visualize(){const t={rects:[],points:[]};for(const e of this.targetNode)t.rects.push({...e,fill:this.currentTarget?.capacityMeshNodeId===e.capacityMeshNodeId?"rgba(255, 0, 0, 0.5)":"rgba(255, 0, 0, 0.2)"});for(const e of this.candidatesAtDepth)t.points.push({...e.port,color:e.port.cramped?"blue":"green"});for(const e of this.crampedPortPointsToKeep)t.points.push({...e,color:"blue"});return this.activeSubSolver?M(t,this.activeSubSolver.visualize()):t}};function hf(t,e){if(null==t)throw new Error(e)}function lf(t){if(0===B(t.point,t.region.d)){if(function(t,e){const n=[];for(const s of t)e.includes(s)&&n.push(s);return n}(("layers"in t.point?t.point.layers:[t.point.layer]).map(e=>Rn(e,t.layerCount)),t.region.d.availableZ).length>0)return!0}return!1}function df(t,e){const n={lines:[],points:[]};if(!t)return n;let s=t.shift();if(!s)return n;const o=[];n.points.push({...s.port.d,color:"rgb(255, 50, 50)",label:`g: ${s.g}\nh: ${s.h}\nf: ${s.f}\nripRequired: ${s.ripRequired}`});do{o.push({x:s.port.d.x,y:s.port.d.y,z:s.port.d.z}),s=s.parent}while(s);o.reverse();const i=o[0]?.z??0;o.unshift({x:e.x,y:e.y,z:i});for(let t=0;t<o.length-1;t++){const e=o[t],s=o[t+1];let i;i=e.z===s.z?0===e.z?void 0:"10 5":"3 3 10",n.lines.push({points:[{x:e.x,y:e.y},{x:s.x,y:s.y}],strokeColor:"rgba(255, 250, 50, 1)",strokeWidth:.1,strokeDash:i})}for(const e of t)n.points.push({...e.port.d,color:"rgb(0, 64, 255)",label:`${e.port.portId}\ng: ${e.g}\nh: ${e.h}\nf: ${e.f}\nripRequired: ${e.ripRequired}`});return n}function uf(t,e){const n={lines:[],points:[]};for(const s of t){const t=e[s.connection.connectionId]??"rgba(255, 50, 50, 1)",o=[{x:s.connection.startRegion.d.center.x,y:s.connection.startRegion.d.center.y,z:s.connection.startRegion.d.availableZ[0]??0}];for(const t of s.path)o.push({x:t.port.d.x,y:t.port.d.y,z:t.port.d.z});o.push({x:s.connection.endRegion.d.center.x,y:s.connection.endRegion.d.center.y,z:s.connection.endRegion.d.availableZ[0]??0});for(let e=0;e<o.length-1;e++){const s=o[e],i=o[e+1];let r;r=s.z===i.z?0===s.z?void 0:"10 5":"3 3 10";const a={points:[{x:s.x,y:s.y},{x:i.x,y:i.y}],strokeColor:t,strokeWidth:.1,strokeDash:r};n.lines.push(a)}}return n}function pf(t,e){const n={lines:[],points:[]};for(const s of t){const t=s.startRegion.d.center,o=s.endRegion.d.center,i=(t.x+o.x)/2,r=(t.y+o.y)/2,a=e[s.connectionId]??"rgba(255, 50, 150, 0.8)";n.points.push({x:i,y:r,color:a,label:s.connectionId}),n.lines.push({points:[t,o],strokeColor:a,strokeWidth:.05,strokeDash:0===(s.startRegion.d.availableZ[0]??0)?void 0:"10 5"})}return n}function ff(t){const e={rects:[],points:[]};for(const n of t.regions)e.rects.push({center:n.d.center,width:n.d.width,height:n.d.height,fill:"rgba(200, 200, 200, 0.5)",label:n.regionId});for(const n of t.ports)e.points.push({x:n.d.x,y:n.d.y,color:"rgba(4, 90, 20, 0.3)",label:n.portId});return e}var mf=class extends xo{constructor(t){super({inputConnections:t.connections,inputGraph:t.graph,greedyMultiplier:t.weights.GREEDY_MULTIPLIER,ripCost:t.weights.RIPPING_PF_COST,rippingEnabled:t.flags.RIPPING_ENABLED}),this.params=t,this.regionMemoryPfMap=t.opts?.regionMemoryPfMap??new Map,this.baseRegionFailureCostMap=new Map,this.regionRipCountMap=new Map,this.totalRipCount=0,t.weights.MAX_ITERATIONS_PER_PATH>0&&(this.MAX_ITERATIONS=t.weights.MAX_ITERATIONS_PER_PATH*t.effort)}regionMemoryPfMap;baseRegionFailureCostMap;regionRipCountMap;totalRipCount;estimateCostToEnd(t){const e=this.currentEndRegion;return hf(e,"Current end region is undefined"),k(t.d,e.d.center)}computeH(t){const e=t,n=this.computeDistanceTraveled(e);if(this.params.weights.RANDOM_WALK_DISTANCE>0&&n<this.params.weights.RANDOM_WALK_DISTANCE)return 0;const s=this.estimateCostToEnd(t.port),o=(t.port.d.distToCentermostPortOnZ-this.params.weights.CENTER_OFFSET_FOCUS_SHIFT)*this.params.weights.CENTER_OFFSET_DIST_PENALTY_FACTOR,i=t.nextRegion?.regionId??t.lastRegion?.regionId,r=i?this.regionMemoryPfMap.get(i)??0:0;return s+o+this.computeMemoryPfPenalty(r)+this.computeDeviation(t)*this.params.weights.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){const s=this.currentConnection;hf(s,"Current connection is undefined");const o=this.getBaseRegionFailureCost(t),i=this.computeRegionPfWithAdditionalSegment(t,e,n,s.connectionId,s.mutuallyConnectedNetworkId);if(i>=this.NODE_MAX_PF)return this.params.weights.NODE_PF_MAX_PENALTY;const r=this.pfToFailureCost(i),a=Math.max(0,r-o);return Math.min(this.params.weights.NODE_PF_MAX_PENALTY,a*this.params.weights.NODE_PF_FACTOR)}computeG(t){const e=t;let n=super.computeG(t);return e.lastPort&&e.lastPort.d.z!==e.port.d.z&&(n+=this.params.weights.LAYER_CHANGE_COST),e.nextRegion!==this.currentEndRegion?n:n+this.computeEndRegionCloseCost(e)}getPortUsagePenalty(t){const e=t.assignment;if(!e)return 0;const n=this.currentConnection?.mutuallyConnectedNetworkId;return e.connection.mutuallyConnectedNetworkId===n?0:.5*Math.max(1,this.params.weights.NODE_PF_FACTOR)+this.params.weights.BASE_CANDIDATE_COST}getRipsRequiredForPortUsage(t,e,n){const s=t.assignments??[];if(0===s.length)return[];return s.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection?.mutuallyConnectedNetworkId&&(t.regionPort1!==e&&t.regionPort2!==e&&(t.regionPort1!==n&&t.regionPort2!==n&&L(t.regionPort1.d,t.regionPort2.d,e.d,n.d))))}selectCandidatesForEnteringRegion(t){const e=this.currentConnection?.startRegion,n=this.currentConnection?.endRegion;hf(e,"Current connection or start region is undefined"),hf(n,"Current connection or end region is undefined");const s=t.filter(t=>{const s=t.nextRegion;return!s?.d._containsObstacle||(s===e||s===n)});let o=this.params.flags.FORCE_CENTER_FIRST?this.getCenterFirstEnteringRegionCandidates(s):s;const i=-this.params.weights.MIN_ALLOWED_BOARD_SCORE;if(i>0){const t=o.filter(t=>t.g+t.h<=i);t.length>0&&(o=t)}return o}routeSolvedHook(t){this.baseRegionFailureCostMap.clear();const e=new Set;for(const n of t.path){const t=n.lastRegion;t&&e.add(t)}for(const t of e){const e=this.computeRegionPfFromAssignments(t);this.regionMemoryPfMap.set(t.regionId,e)}if(!t.requiredRip)return;if(this.unprocessedConnections.length<2)return;const[n,...s]=this.unprocessedConnections;this.unprocessedConnections=[...s,n]}computeRoutesToRip(t){const e=super.computePortOverlapRoutes(t),n=new Set(e),s=new Map;t.path.map(t=>{if(!t.lastPort||!t.lastRegion)return;const e=this.getRipsRequiredForPortUsage(t.lastRegion,t.lastPort,t.port);if(0===e.length)return null;const n=s.get(t.lastRegion)??new Set;for(const t of e)n.add(t.solvedRoute);s.set(t.lastRegion,n)});const o=t.path.flatMap(t=>t.lastRegion?[t.lastRegion]:[]),i=Array.from(new Set([...s.keys(),...o])),r=this.params.weights.SHUFFLE_SEED+this.iterations+this.solvedRoutes.length+this.totalRipCount,a=Gn(i,r);for(const e of a){if(this.totalRipCount>=this.params.weights.MAX_RIPS)break;const s=this.getRegionRippingPfThreshold(e.regionId);let o=this.computeRegionPf({region:e,newlySolvedRoute:t,routesToRip:n});if(this.regionMemoryPfMap.set(e.regionId,o),o<=s)continue;const i=new Set;let a=0;for(;o>s&&!(this.totalRipCount>=this.params.weights.MAX_RIPS);){if(!e.assignments||0===e.assignments.length)throw new Error("We are trying to rip a region with no assignments, this should not happen");const s=e.assignments.map(e=>{const s=e.solvedRoute;return e.connection.connectionId===t.connection.connectionId?null:n.has(s)?void 0:s}).filter(t=>!!t);if(0===s.length)break;const c=Gn(s,r+a+i.size)[0];if(!c)break;i.add(c.connection),n.add(c),this.totalRipCount++,a++,this.regionRipCountMap.set(e.regionId,(this.regionRipCountMap.get(e.regionId)??0)+1),o=this.computeRegionPf({region:e,newlySolvedRoute:t,routesToRip:n}),this.regionMemoryPfMap.set(e.regionId,o)}}if(n.size>e.size){if(this.totalRipCount>=this.params.weights.MAX_RIPS)return n;const e=this.solvedRoutes.filter(e=>!n.has(e)&&e.connection.connectionId!==t.connection.connectionId);if(0===e.length)return n;const s=Math.max(1,Math.floor(this.params.weights.RANDOM_RIP_FRACTION*e.length)),o=Gn(e,r);let i=0;for(const t of o){if(i>=s)break;if(this.totalRipCount>=this.params.weights.MAX_RIPS)break;n.has(t)||(n.add(t),i++,this.totalRipCount++)}}return n}computeDeviation(t){const e=this.currentConnection?.startRegion.d.center,n=this.currentConnection?.endRegion.d.center;hf(e,"Current connection or start region is undefined"),hf(n,"Current connection or end region is undefined");return X(t.port.d,e,n)}computeDistanceTraveled(t){let e=0,n=t;for(;n?.parent;)e+=k(n.parent.port.d,n.port.d),n=n.parent;return e}computeMemoryPfPenalty(t){const e=Math.min(Math.max(t,0),.999999),n=Math.min(this.params.weights.NODE_PF_MAX_PENALTY,-Math.log(1-e));return n*this.params.weights.MEMORY_PF_FACTOR+n*this.params.weights.NODE_PF_FACTOR*.01}computeEndRegionCloseCost(t){const e=this.currentConnection,n=this.currentEndRegion;hf(e,"Current connection is undefined"),hf(n,"Current end region is undefined");const s=e.endRegion.d.center,o={portId:`end-target:${e.connectionId}`,region1:n,region2:n,d:{portId:`end-target:${e.connectionId}`,x:s.x,y:s.y,z:t.port.d.z,distToCentermostPortOnZ:0,regions:[n,n]}};return this.computeIncreasedRegionCostIfPortsAreUsed(n,t.port,o)}getCenterFirstEnteringRegionCandidates(t){const e=new Map;for(const n of t){const t=n.port.d.z,s=e.get(t)??[];s.push(n),e.set(t,s)}const n=[];for(const t of e.values()){const e=t.sort((t,e)=>t.port.d.distToCentermostPortOnZ-e.port.d.distToCentermostPortOnZ)[0];if(!e)continue;if(this.isPortAvailableForCurrentNet(e.port)){n.push(e);continue}const s=t.sort((t,e)=>t.port.d.x!==e.port.d.x?t.port.d.x-e.port.d.x:t.port.d.y-e.port.d.y),o=[];let i=[];for(const t of s)this.isPortAvailableForCurrentNet(t.port)?i.push(t):i.length>0&&(o.push(i),i=[]);i.length>0&&o.push(i);for(const t of o)n.push(t[Math.floor(t.length/2)])}return n}isPortAvailableForCurrentNet(t){const e=t.assignment;if(!e)return!0;const n=this.currentConnection?.mutuallyConnectedNetworkId;return e.connection.mutuallyConnectedNetworkId===n}computeRegionPfFromAssignments(t){const e=this.getRegionAssignedPortPoints(t),n={...t.d,portPoints:e},s=vh(n),o=t.d;return Sh(o,s.numSameLayerCrossings,s.numEntryExitLayerChanges,s.numTransitionPairCrossings)}clampPf(t){return Math.min(Math.max(t,0),.999999)}get NODE_MAX_PF(){return Math.min(.99999,1-Math.exp(-this.params.weights.NODE_PF_MAX_PENALTY))}pfToFailureCost(t){const e=this.clampPf(t);return e>=this.NODE_MAX_PF?this.params.weights.NODE_PF_MAX_PENALTY:-Math.log(1-e)}getBaseRegionFailureCost(t){const e=this.baseRegionFailureCostMap.get(t.regionId);if(null!=e)return e;const n=this.computeRegionPfFromAssignments(t),s=this.pfToFailureCost(n);return this.baseRegionFailureCostMap.set(t.regionId,s),s}getRegionAssignedPortPoints(t){return(t.assignments??[]).flatMap(t=>{const e=t.regionPort1.d,n=t.regionPort2.d,s=t.connection.connectionId,o=t.connection.mutuallyConnectedNetworkId;return[{x:e.x,y:e.y,z:e.z,connectionName:s,rootConnectionName:o},{x:n.x,y:n.y,z:n.z,connectionName:s,rootConnectionName:o}]})}computeRegionPfWithAdditionalSegment(t,e,n,s,o){const i=this.getRegionAssignedPortPoints(t),r=[{x:e.d.x,y:e.d.y,z:e.d.z,connectionName:s,rootConnectionName:o},{x:n.d.x,y:n.d.y,z:n.d.z,connectionName:s,rootConnectionName:o}],a={...t.d,portPoints:[...i,...r]},c=vh(a);return Sh(t.d,c.numSameLayerCrossings,c.numEntryExitLayerChanges,c.numTransitionPairCrossings)}getRegionRippingPfThreshold(t){const e=this.regionRipCountMap.get(t)??0,n=Math.max(1,Math.floor(this.params.weights.MAX_RIPS/10)),s=Math.min(1,e/n);return(this.params.weights.START_RIPPING_PF_THRESHOLD||.3)*(1-s)+(this.params.weights.END_RIPPING_PF_THRESHOLD||1)*s}computeRegionPf({region:t,newlySolvedRoute:e,routesToRip:n}){const s=[...(t.assignments??[]).filter(t=>!n.has(t.solvedRoute)).flatMap(t=>{const e=t.regionPort1,n=t.regionPort2,s=t.connection.connectionId,o=t.connection.mutuallyConnectedNetworkId;return[{x:e.d.x,y:e.d.y,z:e.d.z,connectionName:s,rootConnectionName:o},{x:n.d.x,y:n.d.y,z:n.d.z,connectionName:s,rootConnectionName:o}]}),...e.path.flatMap(n=>{if(!n.lastPort||n.lastRegion!==t)return[];const s=n.lastPort,o=n.port;return[{x:s.d.x,y:s.d.y,z:s.d.z,connectionName:e.connection.connectionId,rootConnectionName:e.connection.mutuallyConnectedNetworkId},{x:o.d.x,y:o.d.y,z:o.d.z,connectionName:e.connection.connectionId,rootConnectionName:e.connection.mutuallyConnectedNetworkId}]})],o={capacityMeshNodeId:t.d.capacityMeshNodeId,center:t.d.center,width:t.d.width,height:t.d.height,portPoints:s,availableZ:t.d.availableZ},i=vh(o),r=t.d;return Sh(r,i.numSameLayerCrossings,i.numEntryExitLayerChanges,i.numTransitionPairCrossings)}getOutput(){new Map(this.params.graph.regions.map(t=>[t.regionId,t]));const t=new Set;for(const e of this.params.connections)t.add(e.startRegion.regionId),t.add(e.endRegion.regionId);const e=new Map;for(const t of this.solvedRoutes){const n=t.path;if(0===n.length)continue;const s=n[0]?.port,o=n[n.length-1]?.port;if(!s||!o)continue;const i=t.connection.connectionId,r=t.connection.mutuallyConnectedNetworkId,a=t.connection.startRegion.regionId,c=t.connection.endRegion.regionId,h=e.get(a)??[];h.push({portPointId:s.d.portId,x:s.d.x,y:s.d.y,z:s.d.z,connectionName:i,rootConnectionName:r}),e.set(a,h);const l=e.get(c)??[];l.push({portPointId:o.d.portId,x:o.d.x,y:o.d.y,z:o.d.z,connectionName:i,rootConnectionName:r}),e.set(c,l)}const n=[],s=[];for(const o of this.params.graph.regions){const i=(o.assignments??[]).flatMap(t=>{const e=t.connection.connectionId,n=t.connection.mutuallyConnectedNetworkId;return[{portPointId:t.regionPort1.d.portId,x:t.regionPort1.d.x,y:t.regionPort1.d.y,z:t.regionPort1.d.z,connectionName:e,rootConnectionName:n},{portPointId:t.regionPort2.d.portId,x:t.regionPort2.d.x,y:t.regionPort2.d.y,z:t.regionPort2.d.z,connectionName:e,rootConnectionName:n}]}),r=[];if(o.d._containsObstacle&&t.has(o.regionId)){const t=e.get(o.regionId)??[],n=[];for(const e of t){i.some(t=>t.connectionName===e.connectionName&&t.rootConnectionName===e.rootConnectionName&&t.portPointId===e.portPointId)||n.push(e)}i.push(...n);const s=new Map;for(const t of i){const e=`${t.connectionName}::${t.rootConnectionName??""}`,n=s.get(e)??[];n.push(t),s.set(e,n)}for(const[t,e]of s.entries()){const[n,s=""]=t.split("::"),i=e[0];i&&r.push({portPointId:`center:${o.regionId}:${n}:${s}`,x:o.d.center.x,y:o.d.center.y,z:i.z,connectionName:n,rootConnectionName:s||void 0})}}const a=[...i,...r];a.length>0&&n.push({capacityMeshNodeId:o.d.capacityMeshNodeId,center:o.d.center,width:o.d.width,height:o.d.height,portPoints:a,availableZ:o.d.availableZ});const c=o.ports.map(t=>{const e=t.d.regions.some(t=>Boolean(t.d._offBoardConnectionId));return{portPointId:t.d.portId,x:t.d.x,y:t.d.y,z:t.d.z,connectionNodeIds:t.d.regions.map(t=>t.regionId),distToCentermostPortOnZ:t.d.distToCentermostPortOnZ,connectsToOffBoardNode:e}});s.push({capacityMeshNodeId:o.d.capacityMeshNodeId,center:o.d.center,width:o.d.width,height:o.d.height,portPoints:c,availableZ:o.d.availableZ,_containsObstacle:o.d._containsObstacle,_containsTarget:o.d._containsTarget,_offBoardConnectionId:o.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:o.d._offBoardConnectedCapacityMeshNodeIds})}return{nodesWithPortPoints:n,inputNodeWithPortPoints:s}}visualize(){return function(t){let e={};return e=t.reduce((t,e)=>t&&e?M(t,e):{},e),e||{}}([ff(this.params.graph),pf(this.params.connections,this.params.colorMap??{}),df(this.candidateQueue.peekMany(100),this.currentConnection?.startRegion.d.center),uf(this.solvedRoutes,this.params.colorMap??{})])}};function gf(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var yf=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=Ph(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[gf("netToPointPairsSolver",Uh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),gf("nodeSolver",xe,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),gf("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),gf("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),gf("necessaryCrampedPortPointSolver",cf,t=>[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),gf("portPointPathingSolver",mf,t=>{const{graph:e,connections:n}=function(t){const e={ports:[],regions:[]},n=[];for(const n of t.capacityMeshNodes)e.regions.push({regionId:n.capacityMeshNodeId,d:n,ports:[]});for(const n of t.segmentPortPoints){const[t,s]=n.nodeIds,o=e.regions.find(e=>e.regionId===t),i=e.regions.find(t=>t.regionId===s);hf(o,`Could not find region with id ${t} for segment port point ${n.segmentPortPointId}`),hf(i,`Could not find region with id ${s} for segment port point ${n.segmentPortPointId}`);for(const t of n.availableZ){const s={portId:`${n.segmentPortPointId}::${t}`,x:n.x,y:n.y,z:t,distToCentermostPortOnZ:n.distToCentermostPortOnZ,regions:[o,i]},r={portId:n.segmentPortPointId,d:s,region1:o,region2:i};e.ports.push(r),o.ports.push(r),i.ports.push(r)}}for(const s of t.simpleRouteJsonConnections){const[o,i]=s.pointsToConnect,r=e.regions.find(e=>lf({point:o,region:e,layerCount:t.layerCount})),a=e.regions.find(e=>lf({point:i,region:e,layerCount:t.layerCount}));hf(r,`Could not find start region for connection "${s.name}"`),hf(a,`Could not find end region for connection "${s.name}"`),n.push({connectionId:s.name,mutuallyConnectedNetworkId:s.rootConnectionName??s.name,startRegion:r,endRegion:a,simpleRouteConnection:s})}return{graph:e,connections:n}}({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,segmentPortPoints:t.availableSegmentPointSolver.getOutput().flatMap(t=>t.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:e,connections:n,layerCount:t.srj.layerCount,effort:t.effort,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,START_RIPPING_PF_THRESHOLD:.3,END_RIPPING_PF_THRESHOLD:1,MAX_RIPS:1e3,RANDOM_RIP_FRACTION:.3,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:4,GREEDY_MULTIPLIER:.7,MIN_ALLOWED_BOARD_SCORE:-1e4}}]}),gf("uniformPortDistributionSolver",ze,t=>[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),gf("highDensityRouteSolver",ph,t=>[{nodePortPoints:t.uniformPortDistributionSolver?.getOutput()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),gf("highDensityStitchSolver",tl,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),gf("traceSimplificationSolver",Cl,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),gf("traceWidthSolver",Tl,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.singleLayerNodeMerger?.visualize(),o=this.strawSolver?.visualize(),i=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),l=this.uniformPortDistributionSolver?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensityStitchSolver?.visualize(),p=this.traceSimplificationSolver?.visualize(),f=this.necessaryCrampedPortPointSolver?.visualize(),m=this.srj.outline,g=[];if(g.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),m&&m.length>=2){const t=m.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),g.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const y={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:g},x=[y,t,e,n,s,o,i,r,a,f,c,h,l,d?jn(y,d):null,u,p,this.solved?jn(y,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...x)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const s=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,o=e.filter(t=>t.connectionName===n.name);for(let e=0;e<o.length;e++){const i=o[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:s??n.rootConnectionName??n.name,route:Le(i,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},xf=class extends Xl{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e}MAX_SIZE_FOR_SINGLE_LAYER_NODES=2;isObstacleAssignable(t){return Boolean(t?.netIsAssignable)}getOverlappingAssignableObstacles(t){return this.getXYZOverlappingObstacles(t).filter(t=>this.isObstacleAssignable(t))}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||(!(!t._containsObstacle||t._completelyInsideObstacle)||1===t.availableZ.length&&(t.width>this.MAX_SIZE_FOR_SINGLE_LAYER_NODES||t.height>this.MAX_SIZE_FOR_SINGLE_LAYER_NODES)))}shouldFilterNodeForObstacle(t){if(!t._containsObstacle)return!1;return!(this.getOverlappingAssignableObstacles(t).length>0)&&(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}insertAssignableObstaclesAsNodes(){const t=this.srj.obstacles.filter(t=>this.isObstacleAssignable(t)),e=new Map;for(const n of t){const t=[];for(const e of this.finishedNodes){this.getXYZOverlappingObstacles(e).some(t=>t===n)&&t.push(e)}e.set(n,t)}const n=new Set;for(const t of e.values())for(const e of t)n.add(e);this.finishedNodes=this.finishedNodes.filter(t=>!n.has(t));for(const n of t){const t=e.get(n)||[],s=n.layers&&n.layers.length>0?Array.from(new Set(n.layers.map(t=>Rn(t,this.srj.layerCount)))).sort((t,e)=>t-e):Array.from({length:this.srj.layerCount},(t,e)=>this.srj.layerCount-e-1);let o=n.center.x-n.width/2,i=n.center.x+n.width/2,r=n.center.y-n.height/2,a=n.center.y+n.height/2;for(const e of t){const t=e.center.x-e.width/2,n=e.center.x+e.width/2,s=e.center.y-e.height/2,c=e.center.y+e.height/2;o=Math.min(o,t),i=Math.max(i,n),r=Math.min(r,s),a=Math.max(a,c)}const c=i-o,h=a-r,l=(o+i)/2,d=(r+a)/2;let u=!1;for(const t of this.srj.connections){for(const e of t.pointsToConnect)if(e.x>=o&&e.x<=i&&e.y>=r&&e.y<=a){u=!0;break}if(u)break}const p={capacityMeshNodeId:`assignable_via_${n.center.x}_${n.center.y}`,center:{x:l,y:d},width:c,height:h,layer:1===s.length?`z${s[0]}`:`z${s.join(",")}`,availableZ:s,_depth:0,_containsTarget:u,_containsObstacle:!1,_completelyInsideObstacle:!1};p._assignedViaObstacle=n,this.finishedNodes.push(p)}}_step(){const t=this.unfinishedNodes.pop();if(!t)return this.insertAssignableObstaclesAsNodes(),void(this.solved=!0);const e=this.getChildNodes(t),n=[],s=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),o=t.availableZ.length>1&&!e;if(e)s.push(t);else{if(o){const e=this.getZSubdivisionChildNodes(t);for(const t of e)!t._containsTarget&&this.shouldFilterNodeForObstacle(t)||(this.shouldNodeBeXYSubdivided(t)?s.push(t):(t._containsObstacle=!1,n.push(t)));continue}this.shouldFilterNodeForObstacle(t)&&!t._containsTarget||n.push(t)}}this.unfinishedNodes.push(...s),this.finishedNodes.push(...n)}},vf=.005,bf=class extends Ln{getSolverName(){return"SingleLayerNodeMergerSolver_OnlyMergeTargets"}nodeMap;currentBatchNodeIds;absorbedNodeIds;nextBatchNodeIds;batchHadModifications;hasComputedAdjacentNodeIds=!1;newNodes;constructor(t){super(),this.nodeMap=new Map,this.MAX_ITERATIONS=1e5;for(const e of t)this.nodeMap.set(e.capacityMeshNodeId,e);this.newNodes=[],this.absorbedNodeIds=new Set;const e=[];for(const n of t)n._assignedViaObstacle?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):n._containsTarget?n.availableZ.length>1?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):e.push([n,n.width*n.height]):(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId));e.sort((t,e)=>t[1]-e[1]);for(const[t,n]of e){const e={...t,center:{...t.center}};this.nodeMap.set(t.capacityMeshNodeId,e)}this.currentBatchNodeIds=e.map(([t])=>t.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=>Math.max(...t.availableZ))),n=[];for(let s=0;s<=e;s++)n.push(new $n(t.filter(t=>t.availableZ[0]===s)));for(const e of t){const t=[],s=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of s)n._containsTarget&&n._targetConnectionName!==e._targetConnectionName||e._containsTarget&&(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId&&Xn(e,n)&&t.push(n);e._adjacentNodeIds=t.map(t=>t.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=>this.nodeMap.get(t)))).filter(e=>e&&e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=>t.width*t.height-e.width*e.height);for(const t of n)this.absorbedNodeIds.has(t.capacityMeshNodeId)||e.push(t);return e}_step(){this.hasComputedAdjacentNodeIds||(this.computeAdjacentNodeIdsForFirstBatch(this.currentBatchNodeIds.map(t=>this.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t&&this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=>{const n=this.nodeMap.get(t),s=this.nodeMap.get(e);return n.width*n.height-s.width*s.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=>this.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const s=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===s.length)return void this.nextBatchNodeIds.push(t);const o=t=>{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=>t._adjacentNodeIds??[])].filter(t=>t!==e.capacityMeshNodeId&&!this.absorbedNodeIds.has(t))))},i=s.filter(t=>t.center.x<e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(i.length>0){const{width:t,height:s}=i[0],r=i.every(e=>e.width===t&&e.height===s);Math.abs(i.reduce((t,e)=>t+e.height,0)-e.height)<vf&&r&&(e.width+=t,e.center.x=e.center.x-t/2,o(i),n=!0)}const r=s.filter(t=>t.center.x>e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(r.length>0&&!n){const{width:t,height:s}=r[0],i=r.every(e=>e.width===t&&e.height===s);Math.abs(r.reduce((t,e)=>t+e.height,0)-e.height)<vf&&i&&(e.width+=t,e.center.x=e.center.x+t/2,o(r),n=!0)}const a=s.filter(t=>t.center.y>e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(a.length>0&&!n){const{width:t,height:s}=a[0],i=a.every(e=>e.width===t&&e.height===s);Math.abs(a.reduce((t,e)=>t+e.width,0)-e.width)<vf&&i&&(e.height+=s,e.center.y=e.center.y+s/2,o(a),n=!0)}const c=s.filter(t=>t.center.y<e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(c.length>0&&!n){const{width:t,height:s}=c[0],i=c.every(e=>e.width===t&&e.height===s);Math.abs(c.reduce((t,e)=>t+e.width,0)-e.width)<vf&&i&&(e.height+=s,e.center.y=e.center.y-s/2,o(c),n=!0)}n?(this.batchHadModifications=!0,this.currentBatchNodeIds.push(t)):this.nextBatchNodeIds.unshift(t)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Single Layer Node Merger (Only Merge Targets)"};for(const e of this.newNodes)t.rects.push($l(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e&&(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const s of this.currentBatchNodeIds){const o=this.nodeMap.get(s);if(!this.absorbedNodeIds.has(s)&&o){const i=$l(o,{rectMargin:.01});s===e?i.stroke="rgba(0, 255, 0, 0.8)":n?.some(t=>t.capacityMeshNodeId===s)?i.stroke="rgba(128, 0, 128, 0.8)":i.stroke="rgba(255, 165, 0, 0.8)",i.layer=`z${o.availableZ.join(",")}`,i.label=`${i.label}\n(unprocessed)`,t.rects.push(i)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)&&n){const e=$l(n,{rectMargin:.01});e.layer=`z${n.availableZ.join(",")}`,e.stroke="rgba(0, 217, 255, 0.8)",e.label=`${e.label}\nx: ${n.center.x}, y: ${n.center.y}\n${n.width}x${n.height}\n(next batch)`,t.rects.push(e)}}return t}},Pf=class extends Ln{getSolverName(){return"AssignableViaNodeMergerSolver"}newNodes;obstacleToNodesMap;obstaclesToProcess;mergedNodeIds;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.newNodes=[],this.obstacleToNodesMap=new Map,this.mergedNodeIds=new Set;for(const e of t){const t=e._assignedViaObstacle;if(t){const n=this.obstacleToNodesMap.get(t)||[];n.push(e),this.obstacleToNodesMap.set(t,n)}else this.newNodes.push(e)}this.obstaclesToProcess=Array.from(this.obstacleToNodesMap.keys())}_step(){const t=this.obstaclesToProcess.pop();if(!t)return void(this.solved=!0);const e=this.obstacleToNodesMap.get(t);if(!e||0===e.length)return;let n=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;const r=new Set;let a=!1;for(const t of e){const e=t.center.x-t.width/2,c=t.center.x+t.width/2,h=t.center.y-t.height/2,l=t.center.y+t.height/2;n=Math.min(n,e),s=Math.max(s,c),o=Math.min(o,h),i=Math.max(i,l);for(const e of t.availableZ)r.add(e);t._containsTarget&&(a=!0)}const c=s-n,h=i-o,l=(n+s)/2,d=(o+i)/2,u=Array.from(r).sort((t,e)=>t-e),p={capacityMeshNodeId:`merged_via_${t.center.x}_${t.center.y}`,center:{x:l,y:d},width:c,height:h,layer:1===u.length?`z${u[0]}`:`z${u.join(",")}`,availableZ:u,_containsTarget:a,_containsObstacle:!1,_completelyInsideObstacle:!1};p._assignedViaObstacle=t;for(const t of e)this.mergedNodeIds.add(t.capacityMeshNodeId);this.newNodes.push(p)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Assignable Via Node Merger"};for(const e of this.newNodes){const n=$l(e);e._assignedViaObstacle&&(n.stroke="rgba(255, 0, 255, 0.8)",n.label=`${n.label||""}\n(merged via)`),t.rects.push(n)}const e=this.obstaclesToProcess[this.obstaclesToProcess.length-1];if(e){const n=this.obstacleToNodesMap.get(e)||[];for(const e of n){const n=$l(e,{rectMargin:.01});n.stroke="rgba(0, 255, 0, 0.8)",n.label=`${n.label||""}\n(to be merged)`,t.rects.push(n)}}return t}},Sf=class extends Ln{constructor(t){const{simpleRouteJson:e,nodes:n,edges:s,colorMap:o,MAX_ITERATIONS:i=1e6,hyperParameters:r={}}=t;super(),this.inputParams=t,this.hyperParameters=r,this.MAX_ITERATIONS=i,this.simpleRouteJson=e,this.nodes=n,this.edges=s,this.colorMap=o??{},this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Fn(this.edges);const a=this.nodes.filter(t=>t._containsTarget);this.unprocessedConnectionPairs=Gn(this.simpleRouteJson.connections.map(t=>{const[e,n]=t.pointsToConnect;return{start:a.find(t=>k(t.center,e)<t.width/2),end:a.find(t=>k(t.center,n)<t.width/2),connection:t}}),this.hyperParameters.SHUFFLE_SEED??0),this.viaNodes=this.nodes.filter(t=>t.availableZ.length>1)}getSolverName(){return"AssignableViaCapacityPathingSolver_DirectiveSubOptimal"}GREEDY_MULTIPLIER=1.5;simpleRouteJson;nodes;edges;colorMap;MAX_ITERATIONS;hyperParameters;usedNodeMap=new Map;nodeMap;nodeEdgeMap;unprocessedConnectionPairs;solvedRoutes=[];activeConnectionPair=null;ogUnprocessedSubpaths=null;unprocessedSubpaths=null;solvedSubpaths=null;activeSubpath=null;viaNodes=[];closestViaForConnectionStartMap=new Map;closestViaForConnectionEndMap=new Map;getConstructorParams(){return this.inputParams}lastStepOperation="none";computeClosestViaForAllConnections(){this.closestViaForConnectionStartMap.clear(),this.closestViaForConnectionEndMap.clear();for(const t of this.unprocessedConnectionPairs){const e=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId));if(e.length>0){const n=e.reduce((e,n)=>{const s=this._dist(e,t.start);return this._dist(n,t.start)<s?n:e});this.closestViaForConnectionStartMap.set(t,n);const s=e.reduce((e,n)=>{const s=this._dist(e,t.end);return this._dist(n,t.end)<s?n:e});this.closestViaForConnectionEndMap.set(t,s)}}}_step(){if(!this.activeConnectionPair)return this.activeConnectionPair=this.unprocessedConnectionPairs.shift(),this.activeConnectionPair?(this.computeClosestViaForAllConnections(),void(this.lastStepOperation="dequeueConnectionPair")):void(this.solved=!0);if(this.activeConnectionPair&&!this.unprocessedSubpaths)return this.unprocessedSubpaths=this.breakConnectionPairIntoSubpaths(this.activeConnectionPair),this.ogUnprocessedSubpaths=this.unprocessedSubpaths.slice(),this.solvedSubpaths=[],void(this.lastStepOperation="breakConnectionPairIntoSubpaths");if(this.activeSubpath){if(this.activeSubpath&&(this.stepSolveSubpath(this.activeSubpath),this.activeSubpath.solved))return this.solvedSubpaths.push(this.activeSubpath),this.activeSubpath=null,this.clearCandidateNodes(),void(this.lastStepOperation="finishedSolvingSubpath");this.lastStepOperation="stepSolveSubpath"}else{if(this.activeSubpath=this.unprocessedSubpaths.shift(),!this.activeSubpath){const t=this.activeConnectionPair;return this.activeConnectionPair=null,this.unprocessedSubpaths=null,this.ogUnprocessedSubpaths=null,this.activeSubpath=null,this.solvedRoutes.push(this.createSolvedRoute(this.solvedSubpaths,t)),void(this.lastStepOperation="finishedSolvingConnectionPair")}this.lastStepOperation="dequeueSubpath"}}queuedCandidateNodes=[];visitedNodes=new Set;_dist(t,e){return Math.hypot(t.center.x-e.center.x,t.center.y-e.center.y)}stepSolveSubpath(t){const{start:e,end:n}=t;if(e.capacityMeshNodeId===n.capacityMeshNodeId)return t.path=[e],t.solved=!0,void this.usedNodeMap.set(e.capacityMeshNodeId,!0);if(0===this.queuedCandidateNodes.length&&0===this.visitedNodes.size){const t=this._dist(e,n),s={prevCandidate:null,node:e,g:0,h:t,f:this.GREEDY_MULTIPLIER*t};this.queuedCandidateNodes.push(s)}let s;for(this.queuedCandidateNodes.sort((t,e)=>t.f-e.f);this.queuedCandidateNodes.length&&!s;){const t=this.queuedCandidateNodes.shift();this.visitedNodes.has(t.node.capacityMeshNodeId)||(s=t)}if(!s)return this.failed=!0,void(this.error="No viable candidates left");if(this.visitedNodes.add(s.node.capacityMeshNodeId),s.node.capacityMeshNodeId===n.capacityMeshNodeId){const e=[];let n=s;for(;n;)e.unshift(n.node),this.usedNodeMap.set(n.node.capacityMeshNodeId,!0),n=n.prevCandidate;return t.path=e,void(t.solved=!0)}const o=this.getNeighbors(s.node);for(const t of o){const e=t.capacityMeshNodeId;if(this.visitedNodes.has(e))continue;const o=this.computeG(s,t,n),i=this.computeH(s,t,n),r=o+this.GREEDY_MULTIPLIER*i,a=this.queuedCandidateNodes.findIndex(t=>t.node.capacityMeshNodeId===e);if(a>=0){if(this.queuedCandidateNodes[a].g<=o)continue;this.queuedCandidateNodes.splice(a,1)}this.queuedCandidateNodes.push({prevCandidate:s,node:t,g:o,h:i,f:r})}}getNeighbors(t){const e=new Set,n=this.nodeEdgeMap.get(t.capacityMeshNodeId)??[];for(const s of n){const[n,o]=s.nodeIds,i=n===t.capacityMeshNodeId?o:n,r=this.nodeMap.get(i);r&&e.add(r)}const s=this.activeSubpath?.layer;return Array.from(e).filter(t=>!(t.capacityMeshNodeId!==this.activeSubpath?.end.capacityMeshNodeId)||!t._containsObstacle&&(!t._containsTarget&&(!this.usedNodeMap.has(t.capacityMeshNodeId)&&!(void 0!==s&&!t.availableZ.includes(s)))))}clearCandidateNodes(){this.queuedCandidateNodes=[],this.visitedNodes=new Set}computeG(t,e,n){const s=this._dist(t.node,e);return t.g+s}computeH(t,e,n){return this._dist(e,n)}createSolvedRoute(t,e){const n=[];for(let e=0;e<t.length;e++){const s=t[e];s.path?0===e?n.push(...s.path):n.push(...s.path.slice(1)):(0===e&&n.push(s.start),e===t.length-1&&n.push(s.end))}return{connection:e.connection,path:n}}breakConnectionPairIntoSubpaths(t){var e,n;if(!(e=[this.hyperParameters.DIRECTIVE_SEED??0,this.solvedRoutes.length],n=this.hyperParameters.FORCE_VIA_TRAVEL_CHANCE??0,Un(e.reduce((t,e)=>t+16807*e%2147483647,0))()<n))return[{start:t.start,end:t.end,solved:!1,layer:t.start.availableZ[0]??0}];const s=this.getClosestVia(t.start),o=this.getFarVia(s,t.end),i=t.start.availableZ[0]??0,r=t.end.availableZ[0]??0,a=[];return a.push({start:t.start,end:s,solved:!1,layer:i}),i===r?(a.push({start:s,end:o,solved:!1,layer:0===i?1:0}),a.push({start:o,end:t.end,solved:!1,layer:r})):a.push({start:s,end:t.end,solved:!1,layer:r}),a}getClosestVia(t){if(0===this.viaNodes.length)return t;const e=new Set;for(const[t,n]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair&&e.add(n.capacityMeshNodeId);for(const[t,n]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair&&e.add(n.capacityMeshNodeId);const n=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId)).filter(t=>!e.has(t.capacityMeshNodeId));if(0===n.length){const e=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId));return 0===e.length?t:(e.sort((e,n)=>this._dist(e,t)-this._dist(n,t)),e[0])}n.sort((e,n)=>this._dist(e,t)-this._dist(n,t));const s=this.hyperParameters.MAX_CLOSEST_VIA_SKIP??0;if(s>0&&n.length>1){const t=Un((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length),e=Math.floor(t()*(s+1));return n[Math.min(e,n.length-1)]}return n[0]}getFarVia(t,e){if(0===this.viaNodes.length)return t;const n=null!=this.hyperParameters.FAR_VIA_MIN_DISTANCE?this.hyperParameters.FAR_VIA_MIN_DISTANCE:50,s=new Set;for(const[t,e]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair&&s.add(e.capacityMeshNodeId);for(const[t,e]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair&&s.add(e.capacityMeshNodeId);const o=this.viaNodes.filter(e=>!this.usedNodeMap.has(e.capacityMeshNodeId)&&e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!s.has(e.capacityMeshNodeId)&&this._dist(e,t)>=n);if(0===o.length){const s=this.viaNodes.filter(e=>e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!this.usedNodeMap.has(e.capacityMeshNodeId)&&this._dist(e,t)>=n).sort((t,n)=>this._dist(t,e)-this._dist(n,e));if(s.length>0)return s[0];return this.viaNodes.filter(e=>e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!this.usedNodeMap.has(e.capacityMeshNodeId)).sort((t,n)=>this._dist(t,e)-this._dist(n,e))[0]??t}o.sort((t,n)=>this._dist(t,e)-this._dist(n,e));const i=this.hyperParameters.MAX_FURTHEST_VIA_SKIP??0;if(i>0&&o.length>1){const t=Un((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length+1e3),e=Math.floor(t()*(i+1));return o[Math.min(e,o.length-1)]}return o[0]}getCapacityPaths(){const t=[];for(const e of this.solvedRoutes){const n=e.path;n&&n.length>0&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=t=>!!t&&"number"==typeof t.x&&"number"==typeof t.y&&!Number.isNaN(t.x)&&!Number.isNaN(t.y)&&Number.isFinite(t.x)&&Number.isFinite(t.y),n=t=>"number"==typeof t&&!Number.isNaN(t)&&Number.isFinite(t);for(const s of this.nodes){const o=this.queuedCandidateNodes.some(t=>t.node.capacityMeshNodeId===s.capacityMeshNodeId),i=this.queuedCandidateNodes.find(t=>t.node.capacityMeshNodeId===s.capacityMeshNodeId);if(e(s.center)&&n(s.width)&&n(s.height)){const e=$l(s,{rectMargin:.025,zOffset:.01});t.rects.push({...e,fill:o?"rgba(255, 128, 255, 0.5)":s._containsTarget?"rgba(0, 150, 255, 0.15)":s._containsObstacle?"rgba(255, 0, 0, 0.1)":"rgba(200, 200, 200, 0.05)",label:[`ID: ${s.capacityMeshNodeId}`,`Size: ${s.width.toFixed(2)}x${s.height.toFixed(2)}`,`Z: ${s.availableZ.join(", ")}`,i?`g: ${i.g.toFixed(2)}`:"",i?`h: ${i.h.toFixed(2)}`:"",i?`f: ${i.f.toFixed(2)}`:"",s._containsTarget?"TARGET":"",s._containsObstacle?"OBSTACLE":""].filter(t=>t).join("\n")})}}for(const n of this.edges){const[s,o]=n.nodeIds,i=this.nodeMap.get(s),r=this.nodeMap.get(o);i?.center&&r?.center&&e(i.center)&&e(r.center)&&t.lines.push({points:[i.center,r.center],strokeColor:"rgba(150, 150, 150, 0.2)"})}for(let n=0;n<this.solvedRoutes.length;n++){const s=this.solvedRoutes[n],o=s.path,i="blue";for(let s=0;s<o.length-1;s++){const r=o[s],a=o[s+1];if(r?.center&&a?.center&&e(r.center)&&e(a.center)){const e=r.availableZ.includes(1)&&a.availableZ.includes(1),s=n%5*.02;t.lines.push({points:[{x:r.center.x+s,y:r.center.y+s},{x:a.center.x+s,y:a.center.y+s}],strokeColor:i,strokeDash:e?"5 5":void 0})}}if(o.length>0){const n=o[0],i=o[o.length-1];n?.center&&e(n.center)&&t.points.push({x:n.center.x,y:n.center.y,label:`START: ${s.connection.name}`}),i?.center&&e(i.center)&&t.points.push({x:i.center.x,y:i.center.y,label:`END: ${s.connection.name}`})}}if(this.solvedSubpaths)for(let n=0;n<this.solvedSubpaths.length;n++){const s=this.solvedSubpaths[n];if(s.path&&s.path.length>1)for(let n=0;n<s.path.length-1;n++){const o=s.path[n],i=s.path[n+1];o?.center&&i?.center&&e(o.center)&&e(i.center)&&t.lines.push({points:[o.center,i.center],strokeColor:"green",strokeDash:1===s.layer?"3 3":void 0})}}if(this.activeSubpath){const n=this.activeSubpath.start?.center,s=this.activeSubpath.end?.center;n&&s&&e(n)&&e(s)&&(t.lines.push({points:[n,s],strokeColor:"orange",strokeDash:"5 5"}),t.points.push({x:n.x,y:n.y,label:"ACTIVE START"}),t.points.push({x:s.x,y:s.y,label:"ACTIVE END"}))}const s=this.queuedCandidateNodes.slice(0,10).sort((t,e)=>t.f-e.f);for(let n=0;n<s.length;n++){const o=.6*(1-n/10),i=[];let r=s[n];for(;r;)i.push(r.node),r=r.prevCandidate;if(i.reverse(),i.length>1){const n=i.map(t=>t.center).filter(t=>e(t));n.length>1&&t.lines.push({points:n,strokeColor:In("purple",1-o),strokeDash:1===this.activeSubpath?.layer?"4 2":void 0})}}if(this.activeConnectionPair){const n=this.activeConnectionPair.start?.center,s=this.activeConnectionPair.end?.center;n&&s&&e(n)&&e(s)&&t.lines.push({points:[n,s],strokeColor:"cyan",strokeDash:"20 5"})}if(this.ogUnprocessedSubpaths&&3===this.ogUnprocessedSubpaths.length){const[,s]=this.ogUnprocessedSubpaths;if(s.start?.center&&e(s.start.center)){const e=Math.max(s.start.width||0,s.start.height||0);n(e)&&e>0&&(t.circles.push({center:s.start.center,radius:e,stroke:"blue"}),t.points.push({x:s.start.center.x,y:s.start.center.y,label:"DIRECTIVE VIA 1"}))}if(s.end?.center&&e(s.end.center)){const e=Math.max(s.end.width||0,s.end.height||0);n(e)&&e>0&&(t.circles.push({center:s.end.center,radius:e,stroke:"purple"}),t.points.push({x:s.end.center.x,y:s.end.center.y,label:"DIRECTIVE VIA 2"}))}}if(this.queuedCandidateNodes.length>0)for(const n of this.queuedCandidateNodes){const s=n.node;s?.center&&e(s.center)&&t.circles.push({center:s.center,radius:.05,fill:"rgba(255, 255, 0, 0.6)",stroke:"yellow"})}if(this.visitedNodes.size>0)for(const n of this.visitedNodes){const s=this.nodeMap.get(n);s?.center&&e(s.center)&&t.circles.push({center:s.center,radius:.08,fill:"rgba(128, 128, 128, 0.5)",stroke:"gray"})}return t}},Mf=class extends is{getSolverName(){return"HyperAssignableViaCapacityPathingSolver"}constructorParams;constructor(t){super(),this.constructorParams=t,this.MAX_ITERATIONS=t.MAX_ITERATIONS??12e4,this.MIN_SUBSTEPS=5,this.GREEDY_MULTIPLIER=1.35}getHyperParameterDefs(){return[{name:"traceOrderingSeed",possibleValues:[{SHUFFLE_SEED:0},{SHUFFLE_SEED:1},{SHUFFLE_SEED:2},{SHUFFLE_SEED:3},{SHUFFLE_SEED:4},{SHUFFLE_SEED:5},{SHUFFLE_SEED:6},{SHUFFLE_SEED:7},{SHUFFLE_SEED:8},{SHUFFLE_SEED:9}]},{name:"forceViaTravelChance",possibleValues:[{FORCE_VIA_TRAVEL_CHANCE:.6},{FORCE_VIA_TRAVEL_CHANCE:.8},{FORCE_VIA_TRAVEL_CHANCE:.9}]}]}computeG(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length,s=e>0?n/e:0;return t.iterations/t.MAX_ITERATIONS+(1-s)}computeH(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length;return e>0?1-n/e:0}generateSolver(t){return new Sf({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}};function Nf(t){const e=new Map;for(const n of t)e.set(n.capacityMeshNodeId,n);return e}function If(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var _f=class extends Ln{getSolverName(){return"OffboardCapacityNodeSolver"}capacityNodes;capacityEdges;enhancedEdges=[];animationState="showing_nodes";assignableNodes=[];shownNodes=[];pendingEdges=[];createdEdges=[];nextEdgeId=0;nodeMap=new Map;constructor(t){super(),this.capacityNodes=t.capacityNodes,this.capacityEdges=t.capacityEdges,this.nodeMap=Nf(this.capacityNodes),this.enhancedEdges=[...this.capacityEdges],this.initializeAssignableNodes(),this.initializePendingEdges(),this.MAX_ITERATIONS=this.assignableNodes.length+this.pendingEdges.length+10}initializeAssignableNodes(){for(const t of this.capacityNodes){const e=t._assignedViaObstacle;e?.offBoardConnectsTo&&e.offBoardConnectsTo.length>0&&this.assignableNodes.push(t)}}initializePendingEdges(){const t=new Map;for(const e of this.assignableNodes){const n=e._assignedViaObstacle;if(n?.offBoardConnectsTo)for(const s of n.offBoardConnectsTo)t.has(s)||t.set(s,[]),t.get(s).push(e)}this.pendingEdges=[];for(const[e,n]of t)if(n.length>1)for(let t=0;t<n.length;t++)for(let s=t+1;s<n.length;s++)this.pendingEdges.push({node1:n[t],node2:n[s],netName:e})}_step(){switch(this.animationState){case"showing_nodes":if(this.assignableNodes.length>0){const t=this.assignableNodes.shift();this.shownNodes.push(t)}else this.animationState="showing_edges";break;case"showing_edges":if(this.pendingEdges.length>0){const{node1:t,node2:e,netName:n}=this.pendingEdges.shift(),s=this.createOffboardEdge(t,e,n);this.enhancedEdges.push(s),this.createdEdges.push(s)}else this.animationState="done",this.solved=!0;break;case"done":this.solved=!0}}createOffboardEdge(t,e,n){return{capacityMeshEdgeId:"offboard_"+this.nextEdgeId++,nodeIds:[t.capacityMeshNodeId,e.capacityMeshNodeId],isOffboardEdge:!0,offboardNetName:n}}visualize(){const t=[],e=[],n=[],s=new Set(this.shownNodes.map(t=>t.capacityMeshNodeId));for(const e of this.capacityEdges){if(e.isOffboardEdge)continue;if(s.has(e.nodeIds[0])||s.has(e.nodeIds[1])){const n=this.nodeMap.get(e.nodeIds[0]),s=this.nodeMap.get(e.nodeIds[1]);n&&s&&t.push({points:[n.center,s.center],strokeColor:"rgba(0, 200, 0, 0.5)",strokeWidth:.05})}}for(let t=0;t<this.shownNodes.length;t++){const s=this.shownNodes[t],o=s._assignedViaObstacle,i=t===this.shownNodes.length-1&&"showing_nodes"===this.animationState;n.push({center:s.center,width:s.width,height:s.height,fill:i?"rgba(255, 165, 0, 0.5)":"rgba(173, 216, 230, 0.5)",stroke:i?"orange":"blue",strokeWidth:i?.15:.1}),e.push({x:s.center.x,y:s.center.y,color:i?"orange":"blue",label:`${i?"NEW: ":""}${s.capacityMeshNodeId}\n${o?.offBoardConnectsTo?.join(", ")||""}`})}for(let n=0;n<this.createdEdges.length;n++){const s=this.createdEdges[n],o=n===this.createdEdges.length-1&&"showing_edges"===this.animationState,i=this.nodeMap.get(s.nodeIds[0]),r=this.nodeMap.get(s.nodeIds[1]);if(i&&r){t.push({points:[i.center,r.center],strokeColor:o?"red":"orange",strokeWidth:o?.2:.1,strokeDasharray:"0.3,0.15"});const n=If(i.center,r.center);e.push({x:n.x,y:n.y,color:o?"red":"orange",label:`${o?"NEW: ":""}⚡ ${s.offboardNetName}`})}}let o="Offboard Capacity Node Solver";switch(this.animationState){case"showing_nodes":o+=` - Showing nodes (${this.shownNodes.length}/${this.shownNodes.length+this.assignableNodes.length})`;break;case"showing_edges":o+=` - Creating edges (${this.createdEdges.length}/${this.createdEdges.length+this.pendingEdges.length})`;break;case"done":o+=` - Done (${this.shownNodes.length} nodes, ${this.createdEdges.length} edges)`}return{lines:t,points:e,rects:n,title:o}}getVirtualOffboardNodes(){return[]}getOffboardEdges(){return this.enhancedEdges.filter(t=>t.isOffboardEdge)}};function Cf(t,e){return t.x>=e.center.x-e.width/2&&t.x<=e.center.x+e.width/2&&t.y>=e.center.y-e.height/2&&t.y<=e.center.y+e.height/2}var Tf=class extends Ln{getSolverName(){return"OffboardPathFragmentSolver"}inputPaths;capacityEdges;originalConnections;fragmentedPaths=[];fragmentedConnections=[];fragmentedOriginalConnectionNames=new Set;nextFragmentId=0;animationState="showing_original_path";currentPath=null;currentFragments=[];currentFragmentIndex=0;nodeMap=new Map;constructor({capacityPaths:t,capacityEdges:e,capacityNodes:n,connections:s}){super(),this.inputPaths=[...t],this.capacityEdges=e,this.originalConnections=s,this.nodeMap=Nf(n)}_step(){switch(this.animationState){case"showing_original_path":if(0===this.inputPaths.length)return this.animationState="done",void(this.solved=!0);this.currentPath=this.inputPaths.shift(),this.currentFragments=this.splitPath(this.currentPath),this.currentFragmentIndex=0;this.currentFragments.some(t=>t.isFragmentedPath)?this.animationState="showing_fragment":this.fragmentedPaths.push(...this.currentFragments);break;case"showing_fragment":if(this.currentFragmentIndex<this.currentFragments.length){const t=this.currentFragments[this.currentFragmentIndex];this.fragmentedPaths.push(t),this.currentFragmentIndex++}else this.currentPath&&(this.fragmentedOriginalConnectionNames.add(this.currentPath.connectionName),this.createFragmentConnections(this.currentPath,this.currentFragments)),this.currentPath=null,this.currentFragments=[],this.currentFragmentIndex=0,this.animationState="showing_original_path";break;case"done":this.solved=!0}}createFragmentConnections(t,e){const n=this.originalConnections.find(e=>e.name===t.connectionName);if(n)for(let t=0;t<e.length;t++){const s=e[t];if(!s.isFragmentedPath)continue;const o=n.pointsToConnect.filter(t=>{for(const e of s.nodeIds){const n=this.nodeMap.get(e);if(n&&Cf(t,n))return!0}return!1}),i=0===t,r=i?s.nodeIds[s.nodeIds.length-1]:s.nodeIds[0],a=this.nodeMap.get(r);if(o.length>0&&a){const t=o[0],e={x:a.center.x,y:a.center.y,layer:Tn(t)},r=i?[...o,e]:[e,...o];this.fragmentedConnections.push({name:s.connectionName,pointsToConnect:r,netConnectionName:n.netConnectionName,rootConnectionName:n.rootConnectionName})}}}splitPath(t){const{nodeIds:e}=t;if(e.length<2)return[t];const n=[];for(let t=0;t<e.length-1;t++){const s=this.capacityEdges.find(n=>n.nodeIds[0]===e[t]&&n.nodeIds[1]===e[t+1]||n.nodeIds[0]===e[t+1]&&n.nodeIds[1]===e[t]);s&&s.isOffboardEdge&&n.push(t)}if(0===n.length)return[t];const s=[];let o=0,i=0;for(const r of n){const n=e.slice(o,r+1);if(n.length>=1){const e=this.nextFragmentId++;s.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${i++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}o=r+1}if(o<e.length){const n=e.slice(o);if(n.length>=1){const e=this.nextFragmentId++;s.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${i++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}}return s.length>0?s:[t]}getFragmentedPaths(){return this.fragmentedPaths}getFragmentedConnections(){return this.fragmentedConnections}getFragmentedOriginalConnectionNames(){return this.fragmentedOriginalConnectionNames}visualize(){const t=[],e=[],n=[];if("showing_original_path"===this.animationState&&this.currentPath&&this.drawPath({path:this.currentPath,color:"gray",lines:t,points:e,rects:n,labelPrefix:"Original: "}),this.fragmentedPaths.forEach((s,o)=>{if(s.isFragmentedPath){const i=o%2==0?"blue":"red";this.drawPath({path:s,color:i,lines:t,points:e,rects:n,labelPrefix:`Frag ${o}: `})}else this.drawPath({path:s,color:"green",lines:t,points:e,rects:n,labelPrefix:""})}),"showing_fragment"===this.animationState&&this.currentFragmentIndex>0){const s=this.fragmentedPaths.length-1;if(s>=0){const o=this.fragmentedPaths[s];o.isFragmentedPath&&this.drawPath({path:o,color:"orange",lines:t,points:e,rects:n,labelPrefix:"NEW: "})}}for(const e of this.capacityEdges)if(e.isOffboardEdge){const n=this.nodeMap.get(e.nodeIds[0]),s=this.nodeMap.get(e.nodeIds[1]);n&&s&&t.push({points:[n.center,s.center],strokeColor:"orange",strokeWidth:.15,strokeDasharray:"0.3,0.15"})}let s="Offboard Path Fragment Solver";return"showing_original_path"===this.animationState?s+=" - Analyzing path...":"showing_fragment"===this.animationState?s+=` - Fragment ${this.currentFragmentIndex}/${this.currentFragments.length}`:s+=` - Done (${this.fragmentedPaths.filter(t=>t.isFragmentedPath).length} fragments)`,{lines:t,points:e,rects:n,title:s}}drawPath(t){const{path:e,color:n,lines:s,points:o,rects:i,labelPrefix:r}=t,a=[];for(let t=0;t<e.nodeIds.length;t++){const s=e.nodeIds[t],c=this.nodeMap.get(s);c&&(a.push(c.center),i.push({center:c.center,width:.8*c.width,height:.8*c.height,stroke:n,strokeWidth:.05,fill:`${n}33`}),0!==t&&t!==e.nodeIds.length-1||o.push({x:c.center.x,y:c.center.y,color:n,label:`${r}${e.connectionName}\n${s}`}))}a.length>1&&s.push({points:a,strokeColor:n,strokeWidth:.1})}};function Ef(t,e,n,s={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:s.onSolved}}var wf=class extends Ln{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8;const n=this.opts;if(void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,s=t.bounds.maxY-t.bounds.minY,o=Math.max(e,s),i=n.targetMinCapacity??.5;n.capacityDepth=Ph(o,i)}this.connMap=Dn(t),this.colorMap=Nn(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Me():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline1Solver"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;initialPathingSolver;initialPathingHyperSolver;pathingOptimizer;edgeToPortSegmentSolver;colorMap;segmentToPointSolver;unravelMultiSectionSolver;segmentToPointOptimizer;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;mergeAssignableViaNodes;offboardCapacityNodeSolver;offboardPathFragmentSolver;strawSolver;deadEndSolver;uselessViaRemovalSolver1;uselessViaRemovalSolver2;multiSimplifiedPathSolver1;multiSimplifiedPathSolver2;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[Ef("netToPointPairsSolver",Hh,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=Nn(t.srjWithPointPairs,this.connMap),t.connMap=Dn(t.srjWithPointPairs)}}),Ef("nodeSolver",xf,t=>[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.finishedNodes}}),Ef("mergeAssignableViaNodes",Pf,t=>[t.nodeSolver?.finishedNodes],{onSolved:t=>{t.capacityNodes=t.mergeAssignableViaNodes?.newNodes}}),Ef("singleLayerNodeMerger",bf,t=>[t.capacityNodes],{onSolved:t=>{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),Ef("edgeSolver",Bn,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Ef("offboardCapacityNodeSolver",_f,t=>[{capacityNodes:t.capacityNodes,capacityEdges:t.capacityEdges||[]}],{onSolved:t=>{t.capacityEdges=t.offboardCapacityNodeSolver?.enhancedEdges||t.capacityEdges}}),Ef("deadEndSolver",od,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=>{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=>!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=>t.nodeIds.every(t=>!e.has(t)))}}),Ef("initialPathingHyperSolver",Mf,t=>[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}],{onSolved:t=>{const e=t.initialPathingHyperSolver?.winningSolver;e&&(t.initialPathingSolver=e)}}),Ef("offboardPathFragmentSolver",Tf,t=>[{capacityPaths:t.initialPathingSolver?.getCapacityPaths()||[],capacityEdges:t.capacityEdges||[],capacityNodes:t.capacityNodes||[],connections:t.srjWithPointPairs?.connections||[]}],{onSolved:t=>{const e=t.offboardPathFragmentSolver;if(!e)return;const n=e.getFragmentedPaths();for(const e of n)if(e.isFragmentedPath&&e.mstPairConnectionName){const n=t.colorMap[e.mstPairConnectionName];n&&!t.colorMap[e.connectionName]&&(t.colorMap[e.connectionName]=n)}const s=e.getFragmentedOriginalConnectionNames(),o=e.getFragmentedConnections();s.size>0&&t.srjWithPointPairs&&(t.srjWithPointPairs={...t.srjWithPointPairs,connections:[...t.srjWithPointPairs.connections.filter(t=>!s.has(t.name)),...o]},t.connMap=Dn(t.srjWithPointPairs))}}),Ef("edgeToPortSegmentSolver",Ol,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.offboardPathFragmentSolver?.getFragmentedPaths()||t.initialPathingSolver?.getCapacityPaths()||[],colorMap:t.colorMap}]),Ef("segmentToPointSolver",kl,t=>{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments&&t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=>{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),Ef("unravelMultiSectionSolver",bd,t=>[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),Ef("highDensityRouteSolver",ph,t=>[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap}]),Ef("highDensityStitchSolver",tl,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Ef("uselessViaRemovalSolver1",ul,t=>[{unsimplifiedHdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Ef("multiSimplifiedPathSolver1",Il,t=>[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver1?.getOptimizedHdRoutes()||t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}]),Ef("uselessViaRemovalSolver2",ul,t=>[{unsimplifiedHdRoutes:t.multiSimplifiedPathSolver1.simplifiedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Ef("multiSimplifiedPathSolver2",Il,t=>[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver2?.getOptimizedHdRoutes(),obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),s=this.mergeAssignableViaNodes?.visualize(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),r=this.edgeSolver?.visualize(),a=(this.offboardCapacityNodeSolver?.visualize(),this.deadEndSolver?.visualize()),c=this.initialPathingSolver?.visualize(),h=this.offboardPathFragmentSolver?.visualize(),l=this.pathingOptimizer?.visualize(),d=this.edgeToPortSegmentSolver?.visualize(),u=this.segmentToPointSolver?.visualize(),p=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),f=this.highDensityRouteSolver?.visualize(),m=this.highDensityStitchSolver?.visualize(),g=this.uselessViaRemovalSolver1?.visualize(),y=this.uselessViaRemovalSolver2?.visualize(),x=this.multiSimplifiedPathSolver1?.visualize(),v=this.multiSimplifiedPathSolver2?.visualize(),b=this.srj.outline,P=[];if(P.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),b&&b.length>=2){const t=b.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),P.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const S={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:P},M=[S,t,e,n,s,o,i,r,a,c,h,l,d,u,p,f?jn(S,f):null,m,g,x,y,v,this.solved?jn(S,On(this.getOutputSimpleRouteJson())):null].filter(Boolean);return jn(...M)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path&&t.push({points:e.path.map(t=>({x:t.center.x,y:t.center.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.multiSimplifiedPathSolver2?.simplifiedHdRoutes??this.uselessViaRemovalSolver2?.getOptimizedHdRoutes()??this.multiSimplifiedPathSolver1?.simplifiedHdRoutes??this.uselessViaRemovalSolver1?.getOptimizedHdRoutes()??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes(),n=this.srjWithPointPairs?.connections??[];for(const s of n){const n=s.netConnectionName,o=s.rootConnectionName,i=e.filter(t=>t.connectionName===s.name);for(let e=0;e<i.length;e++){const r=i[e],a={type:"pcb_trace",pcb_trace_id:`${s.name}_${e}`,connection_name:n??o??s.name,route:Le(r,this.srj.layerCount)};t.push(a)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},Rf=1.8,Of=.95,Af=.8,zf=.95,Df=class extends Ln{getSolverName(){return"SingleHighDensityRouteWithJumpersSolver"}obstacleRoutes;bounds;boundsSize;boundsCenter;A;B;roundedGoalPosition;straightLineDistance;traceThickness;obstacleMargin;minCellSize=.05;cellStep=.05;GREEDY_MULTIPLER=1.1;numRoutes;JUMPER_PENALTY_FACTOR;FUTURE_CONNECTION_START_END_PENALTY;FUTURE_CONNECTION_START_END_PROXIMITY;FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY;FUTURE_CONNECTION_JUMPER_PAD_PENALTY;JUMPER_JUMPER_PAD_PROXIMITY;JUMPER_JUMPER_PAD_PENALTY;FUTURE_CONNECTION_LINE_PROXIMITY;FUTURE_CONNECTION_LINE_PENALTY;OBSTACLE_PROX_PENALTY_FACTOR;OBSTACLE_PROX_SIGMA;EDGE_PROX_PENALTY_FACTOR;EDGE_PROX_SIGMA;ALLOW_DIAGONAL;MIN_TRAVEL_BEFORE_JUMPER;CELL_SIZE_FACTOR;exploredNodes;candidates;connectionName;rootConnectionName;solvedPath=null;futureConnections;hyperParameters;connMap;debug_exploredNodesOrdered;debug_exploredNodeValues;debug_nodesTooCloseToObstacle;debug_nodePathToParentIntersectsObstacle;debugEnabled=!0;initialNodeGridOffset;existingJumpers;constructor(t){super(),this.bounds=t.bounds,this.connMap=t.connMap,this.hyperParameters=t.hyperParameters??{};const e=Math.sqrt((t.bounds.maxX-t.bounds.minX)**2+(t.bounds.maxY-t.bounds.minY)**2);this.CELL_SIZE_FACTOR=this.hyperParameters.CELL_SIZE_FACTOR??1,this.JUMPER_PENALTY_FACTOR=.2,this.FUTURE_CONNECTION_START_END_PROXIMITY??=8,this.FUTURE_CONNECTION_START_END_PENALTY??=3,this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY=this.hyperParameters.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY??e/4,this.FUTURE_CONNECTION_JUMPER_PAD_PENALTY=this.hyperParameters.FUTURE_CONNECTION_JUMPER_PAD_PENALTY??1e3,this.JUMPER_JUMPER_PAD_PROXIMITY=this.hyperParameters.JUMPER_JUMPER_PAD_PROXIMITY??5,this.JUMPER_JUMPER_PAD_PENALTY=this.hyperParameters.JUMPER_JUMPER_PAD_PENALTY??0,this.FUTURE_CONNECTION_LINE_PROXIMITY=this.hyperParameters.FUTURE_CONNECTION_LINE_PROXIMITY??10,this.FUTURE_CONNECTION_LINE_PENALTY=this.hyperParameters.FUTURE_CONNECTION_LINE_PENALTY??5,this.OBSTACLE_PROX_PENALTY_FACTOR=this.hyperParameters.OBSTACLE_PROX_PENALTY_FACTOR??2,this.OBSTACLE_PROX_SIGMA=this.hyperParameters.OBSTACLE_PROX_SIGMA??2,this.EDGE_PROX_PENALTY_FACTOR=this.hyperParameters.EDGE_PROX_PENALTY_FACTOR??1,this.EDGE_PROX_SIGMA=this.hyperParameters.EDGE_PROX_SIGMA??1,this.ALLOW_DIAGONAL=this.hyperParameters.ALLOW_DIAGONAL??!0,this.MIN_TRAVEL_BEFORE_JUMPER??=3,this.boundsSize={width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY},this.boundsCenter={x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},this.connectionName=t.connectionName,this.rootConnectionName=t.rootConnectionName,this.obstacleRoutes=t.obstacleRoutes,this.A={...t.A,z:0},this.B={...t.B,z:0},this.traceThickness=t.traceThickness??.15,this.obstacleMargin=t.obstacleMargin??.2,this.exploredNodes=new Set,this.straightLineDistance=k(this.A,this.B),this.futureConnections=t.futureConnections??[],this.MAX_ITERATIONS=1e4,this.debug_exploredNodesOrdered=[],this.debug_exploredNodeValues=new Map,this.debug_nodesTooCloseToObstacle=new Set,this.debug_nodePathToParentIntersectsObstacle=new Set,this.numRoutes=this.obstacleRoutes.length+this.futureConnections.length,this.existingJumpers=[];for(const t of this.obstacleRoutes)t.jumpers&&this.existingJumpers.push(...t.jumpers);const n=Math.ceil(5*(this.numRoutes+1));let s=this.boundsSize.width/this.cellStep,o=this.boundsSize.height/this.cellStep;for(;s*o>n**2&&!(this.cellStep>t.minDistBetweenEnteringPoints);)this.cellStep*=2,s=this.boundsSize.width/this.cellStep,o=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const i=Math.abs(this.A.x-this.bounds.minX)<.001&&Math.abs(this.B.x-this.bounds.minX)<.001||Math.abs(this.A.x-this.bounds.maxX)<.001&&Math.abs(this.B.x-this.bounds.maxX)<.001||Math.abs(this.A.y-this.bounds.minY)<.001&&Math.abs(this.B.y-this.bounds.minY)<.001||Math.abs(this.A.y-this.bounds.maxY)<.001&&Math.abs(this.B.y-this.bounds.maxY)<.001;this.futureConnections&&0===this.futureConnections.length&&0===this.obstacleRoutes.length&&!i&&this.handleSimpleCases();const r={x:t.A.x,y:t.A.y};this.initialNodeGridOffset={x:r.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:r.y-Math.round(t.A.y/this.cellStep)*this.cellStep},this.roundedGoalPosition={x:Math.round(t.B.x/this.cellStep)*this.cellStep,y:Math.round(t.B.y/this.cellStep)*this.cellStep,z:0};const a={distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},c={distanceToGoal:0,obstacleProximity:0,edgeProximity:0,futureConnectionStartEndProximityPenalty:0,futureConnectionLine:0,total:0,obstacleProximityRate:0,edgeProximityRate:0,futureConnectionStartEndProximityRate:0,futureConnectionLineRate:0};this.candidates=new qn([{...t.A,...r,z:0,g:0,h:0,f:0,jumperCount:0,gComponents:a,hComponents:c,parent:{...t.A,z:0,g:0,h:0,f:0,gComponents:a,hComponents:c,parent:null}}])}handleSimpleCases(){this.solved=!0;const{A:t,B:e}=this;this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,route:[{x:t.x,y:t.y,z:0},{x:e.x,y:e.y,z:0}],traceThickness:this.traceThickness,jumpers:[]}}get jumperPenaltyDistance(){return Rf+this.straightLineDistance*this.JUMPER_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e){e??=this.obstacleMargin;for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!s){const s=Lf(n);for(const n of s)if(X(t,n.A,n.B)<this.traceThickness+e)return!0}for(const s of n.jumpers||[])if(this.isNodeTooCloseToJumper(t,s,e))return!0}return!1}isNodeTooCloseToJumper(t,e,n){const s=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.abs(s)>Math.abs(o),r=(i?Af:zf)/2+n,a=(i?zf:Af)/2+n;return Math.abs(t.x-e.start.x)<r&&Math.abs(t.y-e.start.y)<a||Math.abs(t.x-e.end.x)<r&&Math.abs(t.y-e.end.y)<a}isNodeTooCloseToEdge(t){const e=t.gComponents?.distFromStart??0<this.obstacleMargin/2?-this.obstacleMargin/2:this.obstacleMargin/2,n=t.x<this.bounds.minX+e||t.x>this.bounds.maxX-e||t.y<this.bounds.minY+e||t.y>this.bounds.maxY-e;return(!n||!(k(t,this.B)<2*e||k(t,this.A)<2*e))&&n}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!s){for(const s of Lf(n))if(L(t,e,s.A,s.B))return!0;for(const s of n.jumpers||[])if(this.doesSegmentIntersectJumperPads(t,e,s))return!0}}return!1}doesSegmentIntersectJumperPads(t,e,n){const s=this.obstacleMargin,o=n.end.x-n.start.x,i=n.end.y-n.start.y,r=Math.abs(o)>Math.abs(i),a=(r?Af:zf)/2+s,c=(r?zf:Af)/2+s;return!!this.doesSegmentIntersectRect(t,e,n.start,a,c)||!!this.doesSegmentIntersectRect(t,e,n.end,a,c)}doesSegmentIntersectRect(t,e,n,s,o){const i=n.x-s,r=n.x+s,a=n.y-o,c=n.y+o;if(t.x>=i&&t.x<=r&&t.y>=a&&t.y<=c)return!0;if(e.x>=i&&e.x<=r&&e.y>=a&&e.y<=c)return!0;const h=[{A:{x:i,y:a},B:{x:r,y:a}},{A:{x:r,y:a},B:{x:r,y:c}},{A:{x:r,y:c},B:{x:i,y:c}},{A:{x:i,y:c},B:{x:i,y:a}}];for(const n of h)if(L(t,e,n.A,n.B))return!0;return!1}findObstaclesBetween(t,e){const n=[];for(const s of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,s.connectionName);if(!o)for(const o of Lf(s))L(t,e,o.A,o.B)&&n.push({A:o.A,B:o.B})}return n}computeHComponents(t){const e=k(t,this.roundedGoalPosition),n=this.getObstacleProximityPenalty(t),s=this.getEdgeProximityPenalty(t),o=this.getFutureConnectionStartEndPenalty(t),i=this.getFutureConnectionLinePenalty(t),r=t.parent,a=r?.hComponents,c=r?k(t,r):0,h=(t,n)=>{if(void 0===n||c<1e-9||e<1e-9)return t;const s=(t-n)/c;return(t+Math.max(0,t+s*e))/2},l=h(n,a?.obstacleProximityRate),d=h(s,a?.edgeProximityRate),u=h(o,a?.futureConnectionStartEndProximityRate),p=h(i,a?.futureConnectionLineRate),f=l*e,m=d*e,g=u*e,y=p*e;return{distanceToGoal:e,obstacleProximity:f,edgeProximity:m,futureConnectionStartEndProximityPenalty:g,futureConnectionLine:y,total:e+f+m+g+y,obstacleProximityRate:n,edgeProximityRate:s,futureConnectionStartEndProximityRate:o,futureConnectionLineRate:i}}computeH(t){return this.computeHComponents(t).total}computeGComponents(t){const e=t.parent,n=e?k(t,e):0,s=e?.gComponents??{distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},o=s.distFromStart+n,i=s.weightedMmNearObstacle+this.getObstacleProximityPenalty(t)*n,r=s.weightedMmNearEdge+this.getEdgeProximityPenalty(t)*n,a=s.weightedMmNearFutureConnectionStartEnd+this.getFutureConnectionStartEndPenalty(t)*n,c=s.weightedMmNearFutureConnectionLine+this.getFutureConnectionLinePenalty(t)*n;let h=s.jumperPenalty,l=s.jumperPadFutureConnectionPenalty;t.isJumperExit&&(h+=this.jumperPenaltyDistance,l+=this.getJumperPadFutureConnectionPenalty(t));return{distFromStart:o,weightedMmNearObstacle:i,weightedMmNearEdge:r,weightedMmNearFutureConnectionStartEnd:a,weightedMmNearFutureConnectionLine:c,jumperPenalty:h,jumperPadFutureConnectionPenalty:l,total:o+i+r+a+c+h+l}}computeG(t){return this.computeGComponents(t).total}computeF(t,e){return t+e*this.GREEDY_MULTIPLER}getClosestFutureConnectionPoint(t){let e=1/0,n=null;for(const s of this.futureConnections)for(const o of s.points){const s=k(t,o);s<e&&(e=s,n=o)}return n}getFutureConnectionStartEndPenalty(t){let e=0;const n=this.getClosestFutureConnectionPoint(t);if(n){const s=k(t,n);if(s>this.FUTURE_CONNECTION_START_END_PROXIMITY)return 0;const o=s/this.FUTURE_CONNECTION_START_END_PROXIMITY;e=this.FUTURE_CONNECTION_START_END_PENALTY*(1-o)**2}return e}getFutureConnectionLinePenalty(t){if(0===this.futureConnections.length)return 0;let e=1/0;const n=Math.min(1,(t.hComponents?.distanceToGoal??0)/this.FUTURE_CONNECTION_LINE_PROXIMITY)**2;for(const n of this.futureConnections){if(n.points.length<2)continue;const s=X(t,n.points[0],n.points[n.points.length-1]);e=Math.min(e,s)}if(e*=n,e<this.FUTURE_CONNECTION_LINE_PROXIMITY){const t=Math.max(.1,e/this.FUTURE_CONNECTION_LINE_PROXIMITY);return this.FUTURE_CONNECTION_LINE_PENALTY*(1-t)**2}return 0}getJumperPadFutureConnectionPenalty(t){if(!t.isJumperExit||!t.jumperEntry)return 0;const e=t.jumperEntry,n={x:t.x,y:t.y};let s=1/0;for(const t of this.futureConnections)for(const o of t.points){const t=k(e,o),i=k(n,o),r=Math.min(t,i);s=Math.min(s,r)}if(s<this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY){const t=s/this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY;return this.FUTURE_CONNECTION_JUMPER_PAD_PENALTY*(1-t)}return 0}getClearanceToObstacles(t){let e=1/0;for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!s){for(const s of Lf(n))e=Math.min(e,X(t,s.A,s.B));for(const s of n.jumpers||[])e=Math.min(e,this.distanceToJumperPads(t,s))}}return e}distanceToJumperPads(t,e){const n=e.end.x-e.start.x,s=e.end.y-e.start.y,o=Math.abs(n)>Math.abs(s),i=(o?Af:zf)/2,r=(o?zf:Af)/2;return Math.min(this.pointToRectDistance(t,e.start,i,r),this.pointToRectDistance(t,e.end,i,r))}pointToRectDistance(t,e,n,s){const o=Math.max(Math.abs(t.x-e.x)-n,0),i=Math.max(Math.abs(t.y-e.y)-s,0);return Math.hypot(o,i)}getClearanceToEdge(t){return Math.min(t.x-this.bounds.minX,this.bounds.maxX-t.x,t.y-this.bounds.minY,this.bounds.maxY-t.y)}getObstacleProximityPenalty(t){const e=this.getClearanceToObstacles(t),n=Math.max(0,e-(this.traceThickness+this.obstacleMargin)),s=this.OBSTACLE_PROX_SIGMA;return this.OBSTACLE_PROX_PENALTY_FACTOR*Math.exp(-n/s)}getEdgeProximityPenalty(t){const e=this.getClearanceToEdge(t),n=this.EDGE_PROX_SIGMA;if(e>2*this.EDGE_PROX_SIGMA)return 0;const s=k(t,this.B),o=Math.min(1,s/(2*this.EDGE_PROX_SIGMA));return this.EDGE_PROX_PENALTY_FACTOR*Math.exp(-e/n)*o}getNodeKey(t){const e=t.isJumperExit?"_j":"";return`${Math.round(t.x/this.cellStep)*this.cellStep},${Math.round(t.y/this.cellStep)*this.cellStep},${t.z}${e}`}getJumperNeighbors(t){const e=[];if((t.gComponents?.distFromStart??0)<this.MIN_TRAVEL_BEFORE_JUMPER)return e;const n=[{dx:1,dy:0},{dx:-1,dy:0},{dx:0,dy:1},{dx:0,dy:-1}];for(const s of n){const n=2*Rf,o=t.x+s.dx*n,i=t.y+s.dy*n,r=this.findObstaclesBetween(t,{x:o,y:i});if(r.length>0)for(const n of r){const o=this.calculateJumperExit(t,n,s);o&&!this.exploredNodes.has(this.getNodeKey(o))&&(this.isNodeTooCloseToObstacle(o)||this.isNodeTooCloseToEdge(o)||!this.isJumperPlacementValid(t,o)||(o.gComponents=this.computeGComponents(o),o.hComponents=this.computeHComponents(o),o.g=o.gComponents.total,o.h=o.hComponents.total,o.f=this.computeF(o.g,o.h),e.push(o)))}}return e}calculateJumperExit(t,e,n){const s=Rf,o=Math.sqrt(n.dx*n.dx+n.dy*n.dy),i=n.dx/o,r=n.dy/o,a=t.x+i*s,c=t.y+r*s;return a<this.bounds.minX||a>this.bounds.maxX||c<this.bounds.minY||c>this.bounds.maxY?null:{x:a,y:c,z:0,parent:t,g:0,h:0,f:0,jumperEntry:{x:t.x,y:t.y},isJumperExit:!0,jumperCount:(t.jumperCount??0)+1}}isJumperTooCloseToTraces(t,e){const n=e.x-t.x,s=e.y-t.y,o=Math.abs(n)>Math.abs(s),i=(o?Af:zf)/2,r=(o?zf:Af)/2,a=this.obstacleMargin,c=[t,e];for(const t of c){const e=[t,{x:t.x-i,y:t.y-r},{x:t.x+i,y:t.y-r},{x:t.x-i,y:t.y+r},{x:t.x+i,y:t.y+r},{x:t.x-i,y:t.y},{x:t.x+i,y:t.y},{x:t.x,y:t.y-r},{x:t.x,y:t.y+r}];for(const n of this.obstacleRoutes){const s=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(s)continue;const o=Lf(n);for(const n of o){for(const t of e)if(X(t,n.A,n.B)<this.traceThickness+a)return!0;if(this.doesSegmentIntersectRect(n.A,n.B,t,i+a,r+a))return!0}}}return!1}isJumperPlacementValid(t,e){if(this.isJumperTooCloseToTraces(t,e))return!1;const n={route_type:"jumper",start:{x:t.x,y:t.y},end:{x:e.x,y:e.y},footprint:"0603"};for(const t of this.existingJumpers)if(this.doJumpersOverlap(n,t))return!1;const s=this.getJumpersInPath(t);for(const t of s)if(this.doJumpersOverlap(n,t))return!1;return!0}doJumpersOverlap(t,e){const n=this.obstacleMargin,s=Math.min(t.start.x,t.end.x)-Of/2-n,o=Math.max(t.start.x,t.end.x)+Of/2+n,i=Math.min(t.start.y,t.end.y)-Of/2-n,r=Math.max(t.start.y,t.end.y)+Of/2+n,a=Math.min(e.start.x,e.end.x)-Of/2-n,c=Math.max(e.start.x,e.end.x)+Of/2+n,h=Math.min(e.start.y,e.end.y)-Of/2-n,l=Math.max(e.start.y,e.end.y)+Of/2+n;return!(o<a||s>c||r<h||i>l)}getJumpersInPath(t){const e=[];let n=t;for(;n&&n.parent;)n.isJumperExit&&n.jumperEntry&&e.push({route_type:"jumper",start:n.jumperEntry,end:{x:n.x,y:n.y},footprint:"0603"}),n=n.parent;return e}getNeighbors(t){const e=[],{maxX:n,minX:s,maxY:o,minY:i}=this.bounds;for(let r=-1;r<=1;r++)for(let a=-1;a<=1;a++){if(0===r&&0===a)continue;if(!this.ALLOW_DIAGONAL&&0!==r&&0!==a)continue;const c=t.x+r*this.cellStep,h=t.y+a*this.cellStep,l=Ff(c,s,n),d=Ff(h,i,o),u={...t,parent:t,x:l,y:d,isJumperExit:!1,jumperEntry:void 0,jumperCount:t.jumperCount??0},p=this.getNodeKey(u);this.exploredNodes.has(p)||(this.isNodeTooCloseToObstacle(u)?(this.debug_nodesTooCloseToObstacle.add(p),this.exploredNodes.add(p)):this.isNodeTooCloseToEdge(u)?this.debug_nodesTooCloseToObstacle.add(p):this.doesPathToParentIntersectObstacle(u)?(this.debug_nodePathToParentIntersectsObstacle.add(p),this.exploredNodes.add(p)):(u.gComponents=this.computeGComponents(u),u.hComponents=this.computeHComponents(u),u.g=u.gComponents.total,u.h=u.hComponents.total,u.f=this.computeF(u.g,u.h),e.push(u)))}const r=this.getJumperNeighbors(t);return e.push(...r),e}getNodePath(t){const e=[];let n=t;for(;n;)e.push(n),n=n.parent;return e}setSolvedPath(t){const e=this.getNodePath(t);e.reverse();const n=[];for(let t=0;t<e.length;t++){const s=e[t];s.isJumperExit&&s.jumperEntry&&n.push({route_type:"jumper",start:s.jumperEntry,end:{x:s.x,y:s.y},footprint:"0603"})}this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,traceThickness:this.traceThickness,route:e.map(t=>({x:t.x,y:t.y,z:0})).concat([{x:this.B.x,y:this.B.y,z:0}]),jumpers:n}}computeProgress(t,e){const n=1-e/this.straightLineDistance;return Math.max(this.progress||0,2/Math.PI*Math.atan(.112*n/(1-n)))}_step(){let t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;for(;t&&e&&this.exploredNodes.has(e);)t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;if(!t||!e)return this.failed=!0,void(this.error="Ran out of candidate nodes to explore");this.exploredNodes.add(e),this.debug_exploredNodesOrdered.push(e),this.debug_exploredNodeValues.set(e,{g:t.g,h:t.h,f:t.f,gComponents:t.gComponents,hComponents:t.hComponents});const n=k(t,this.roundedGoalPosition);this.progress=this.computeProgress(t,n),n<=this.cellStep*Math.SQRT2&&!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})&&(this.solved=!0,this.setSolvedPath(t));const s=this.getNeighbors(t);for(const t of s)this.candidates.enqueue(t)}drawJumperPads(t,e,n,s,o){const i=e.end.x-e.start.x,r=e.end.y-e.start.y,a=Af,c=zf,h=Math.abs(i)>Math.abs(r),l=h?a:c,d=h?c:a;t.rects.push({center:{x:e.start.x,y:e.start.y},width:l,height:d,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:s??"jumper",step:o}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:l,height:d,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:s??"jumper",step:o}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*c,layer:s??"jumper-body",step:o})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:`Input A\nz: ${this.A.z}`,color:"orange"}),t.points.push({x:this.B.x,y:this.B.y,label:`Input B\nz: ${this.B.z}`,color:"orange"}),t.lines.push({points:[this.A,this.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:"Direct Input Connection"});for(let e=0;e<this.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let s=0;s<n.route.length-1;s++)t.lines.push({points:[n.route[s],n.route[s+1]],strokeColor:"rgba(255, 0, 0, 0.75)",strokeWidth:n.traceThickness,label:"Obstacle Route",layer:`obstacle${e.toString()}`});for(const s of n.jumpers||[])this.drawJumperPads(t,s,"rgba(255, 0, 0, 0.5)",`obstacle-jumper-${e}`)}for(let e=0;e<this.futureConnections.length;e++){const n=this.futureConnections[e];if(n.points.length<2)continue;const s=n.points[0],o=n.points[n.points.length-1];t.lines.push({points:[s,o],strokeColor:"rgba(0, 100, 255, 0.6)",strokeWidth:this.traceThickness,label:`Future: ${n.connectionName}`,layer:`future-connection-${e}`})}for(let e=0;e<this.debug_exploredNodesOrdered.length;e++){const n=this.debug_exploredNodesOrdered[e];if(this.debug_nodesTooCloseToObstacle.has(n))continue;if(this.debug_nodePathToParentIntersectsObstacle.has(n))continue;const[s,o]=n.split(",").map(Number),i=n.endsWith("_j"),r=this.debug_exploredNodeValues.get(n),a=r?.gComponents,c=r?.hComponents,h=c?.distanceToGoal??0,l=[i?"Explored (jumper)":"Explored"];l.push(`g.distFromStart: ${a?.distFromStart.toFixed(2)??"?"}`),l.push(`g.nearObstacle: ${a?.weightedMmNearObstacle.toFixed(2)??"?"}`),l.push(`g.nearEdge: ${a?.weightedMmNearEdge.toFixed(2)??"?"}`),l.push(`g.nearFutStrtEnd: ${a?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??"?"}`),l.push(`g.nearFutLine: ${a?.weightedMmNearFutureConnectionLine.toFixed(2)??"?"}`),l.push(`g.jumper: ${a?.jumperPenalty.toFixed(2)??"?"}`),l.push(`g.jumperPadFutPenalty: ${a?.jumperPadFutureConnectionPenalty.toFixed(2)??"?"}`),l.push(`h.goalDist: ${h.toFixed(2)}`),l.push(`h.obstacleProx: ${c?.obstacleProximity.toFixed(2)??"?"} (${h>0?((c?.obstacleProximity??0)/h).toFixed(3):0}/mm)`),l.push(`h.edgeProx: ${c?.edgeProximity.toFixed(2)??"?"} (${h>0?((c?.edgeProximity??0)/h).toFixed(3):0}/mm)`),l.push(`h.futureConnPt: ${c?.futureConnectionStartEndProximityPenalty.toFixed(2)??"?"} (${h>0?((c?.futureConnectionStartEndProximityPenalty??0)/h).toFixed(3):0}/mm)`),l.push(`h.futureConnLine: ${c?.futureConnectionLine.toFixed(2)??"?"} (${h>0?((c?.futureConnectionLine??0)/h).toFixed(3):0}/mm)`),l.push(`g: ${r?.g.toFixed(2)??"?"}`),l.push(`h: ${r?.h.toFixed(2)??"?"}`),l.push(`f: ${r?.f.toFixed(2)??"?"}`);const d=l.join("\n");t.rects.push({center:{x:s+this.initialNodeGridOffset.x,y:o+this.initialNodeGridOffset.y},fill:i?`rgba(0,255,255,${.4-e/this.debug_exploredNodesOrdered.length*.3})`:`rgba(255,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`,width:.9*this.cellStep,height:.9*this.cellStep,label:d})}if(this.candidates.peek()){const e=this.candidates.peek();t.rects.push({center:{x:e.x,y:e.y},fill:"rgba(0, 255, 0, 0.8)",width:.9*this.cellStep,height:.9*this.cellStep,label:"Next"})}const e=this.candidates.getTopN(5);for(let n=0;n<e.length;n++){const s=e[n],o=s.isJumperExit??!1,i=s.gComponents,r=s.hComponents,a=r?.distanceToGoal??0,c=[`Candidate #${n+1}${o?" (jumper)":""}`];c.push(`g.distFromStart: ${i?.distFromStart.toFixed(2)??"?"}`),c.push(`g.nearObstacle: ${i?.weightedMmNearObstacle.toFixed(2)??"?"}`),c.push(`g.nearEdge: ${i?.weightedMmNearEdge.toFixed(2)??"?"}`),c.push(`g.nearFutureConnPt: ${i?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??"?"}`),c.push(`g.nearFutureConnLine: ${i?.weightedMmNearFutureConnectionLine.toFixed(2)??"?"}`),c.push(`g.jumper: ${i?.jumperPenalty.toFixed(2)??"?"}`),c.push(`g.jumperPadFutureConn: ${i?.jumperPadFutureConnectionPenalty.toFixed(2)??"?"}`),c.push(`g: ${s.g.toFixed(2)}`),c.push(`h.goalDist: ${a.toFixed(2)}`),c.push(`h.obstacleProx: ${r?.obstacleProximity.toFixed(2)??"?"} (${a>0?((r?.obstacleProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.edgeProx: ${r?.edgeProximity.toFixed(2)??"?"} (${a>0?((r?.edgeProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnPt: ${r?.futureConnectionStartEndProximityPenalty.toFixed(2)??"?"} (${a>0?((r?.futureConnectionStartEndProximityPenalty??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnLine: ${r?.futureConnectionLine.toFixed(2)??"?"} (${a>0?((r?.futureConnectionLine??0)/a).toFixed(3):0}/mm)`),c.push(`h: ${s.h.toFixed(2)}`),c.push(`f: ${s.f.toFixed(2)}`);const h=c.join("\n");t.points.push({x:s.x,y:s.y,color:"gray",label:h})}if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:"green",label:"Solved Route",strokeWidth:this.traceThickness});for(const e of this.solvedPath.jumpers)this.drawJumperPads(t,e,"rgba(0, 200, 0, 0.8)","solved-jumper")}const{minX:n,minY:s,maxX:o,maxY:i}=this.bounds;return t.lines.push({points:[{x:n,y:s},{x:o,y:s},{x:o,y:i},{x:n,y:i},{x:n,y:s}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}};function Lf(t){const e=[];for(let n=0;n<t.route.length-1;n++)if(t.route[n].z===t.route[n+1].z){const s=t.route[n],o=t.route[n+1],i=t.jumpers?.some(t=>{const e=Math.abs(t.start.x-s.x)<.001&&Math.abs(t.start.y-s.y)<.001&&Math.abs(t.end.x-o.x)<.001&&Math.abs(t.end.y-o.y)<.001,n=Math.abs(t.start.x-o.x)<.001&&Math.abs(t.start.y-o.y)<.001&&Math.abs(t.end.x-s.x)<.001&&Math.abs(t.end.y-s.y)<.001;return e||n});i||e.push({z:s.z,A:s,B:o})}return e}function Ff(t,e,n){return Math.max(e,Math.min(t,n))}var Yf=.8,Xf=.95,kf=class extends Ln{getSolverName(){return"IntraNodeSolverWithJumpers"}nodeWithPortPoints;colorMap;unsolvedConnections;totalConnections;solvedRoutes;failedSubSolvers;hyperParameters;minDistBetweenEnteringPoints;traceWidth;activeSubSolver=null;lastActiveSubSolver=null;connMap;get failedSolvers(){return this.failedSubSolvers}get activeSolver(){return this.activeSubSolver}constructor(t){const{nodeWithPortPoints:e,colorMap:n}=t;super(),this.nodeWithPortPoints=e,this.colorMap=n??{},this.solvedRoutes=[],this.hyperParameters=t.hyperParameters??{},this.failedSubSolvers=[],this.connMap=t.connMap,this.traceWidth=t.traceWidth??.15;const s=new Map;for(const{connectionName:t,rootConnectionName:n,x:o,y:i}of e.portPoints){const e=s.get(t);s.set(t,{rootConnectionName:e?.rootConnectionName??n,points:[...e?.points??[],{x:o,y:i,z:0}]})}this.unsolvedConnections=Array.from(s.entries().map(([t,{rootConnectionName:e,points:n}])=>({connectionName:t,rootConnectionName:e,points:n}))),this.hyperParameters.SHUFFLE_SEED&&(this.unsolvedConnections=Gn(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=>({...e,points:Gn(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Zn(this.nodeWithPortPoints)}getConstructorParams(){return{nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,hyperParameters:this.hyperParameters,connMap:this.connMap,traceWidth:this.traceWidth}}computeProgress(){return(this.solvedRoutes.length+(this.activeSubSolver?.progress||0))/this.totalConnections}_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),this.progress=this.computeProgress(),void(this.activeSubSolver.solved?(this.solvedRoutes.push(this.activeSubSolver.solvedPath),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSubSolvers.push(this.activeSubSolver),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=>t.error).join("\n"),this.failed=!0));const t=this.unsolvedConnections.pop();if(this.progress=this.computeProgress(),!t)return void(this.solved=0===this.failedSubSolvers.length);if(1===t.points.length)return;if(2===t.points.length){const[e,n]=t.points,s=Math.abs(e.x-n.x)<1e-6,o=Math.abs(e.y-n.y)<1e-6;if(s&&o)return}const{connectionName:e,rootConnectionName:n,points:s}=t;this.activeSubSolver=new Df({connectionName:e,rootConnectionName:n,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:Ie(this.nodeWithPortPoints),A:{x:s[0].x,y:s[0].y,z:0},B:{x:s[s.length-1].x,y:s[s.length-1].y,z:0},obstacleRoutes:this.solvedRoutes.filter(t=>(!n||t.rootConnectionName!==n)&&!this.connMap?.areIdsConnected(t.connectionName,e)),futureConnections:this.unsolvedConnections,hyperParameters:this.hyperParameters,connMap:this.connMap,traceThickness:this.traceWidth})}drawJumperPads(t,e,n,s){const o=e.end.x-e.start.x,i=e.end.y-e.start.y,r=Yf,a=Xf,c=Math.abs(o)>Math.abs(i),h=c?r:a,l=c?a:r;t.rects.push({center:{x:e.start.x,y:e.start.y},width:h,height:l,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:h,height:l,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*a,layer:"jumper-body"})}visualize(){if(this.activeSubSolver&&!this.solved)return this.activeSubSolver.visualize();if(this.failed&&this.lastActiveSubSolver)return this.lastActiveSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:[e.connectionName,"layer: 0 (single-layer)"].join("\n"),color:this.colorMap[e.connectionName]??"blue"});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length>0){const s=this.colorMap[n.connectionName]??"blue";for(let e=0;e<n.route.length-1;e++){const o=n.route[e],i=n.route[e+1];t.lines.push({points:[o,i],strokeColor:In(s,.2),layer:"route-layer-0",strokeWidth:n.traceThickness})}for(const o of n.jumpers)this.drawJumperPads(t,o,In(s,.5),e)}}const e=Ie(this.nodeWithPortPoints),{minX:n,minY:s,maxX:o,maxY:i}=e;return t.lines.push({points:[{x:n,y:s},{x:o,y:s},{x:o,y:i},{x:n,y:i},{x:n,y:s}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}};export{wf as AssignableAutoroutingPipeline1Solver,qd as AssignableAutoroutingPipeline2,sf as AssignableAutoroutingPipeline3,Sd as AutoroutingPipeline1_OriginalUnravel,wl as AutoroutingPipelineSolver,yf as AutoroutingPipelineSolver3_HgPortPointPathing,Rl as CapacityMeshSolver,wu as CurvyIntraNodeSolver,ef as HighDensitySolver,ve as InMemoryCache,kf as IntraNodeSolverWithJumpers,Pe as LocalStorageCache,Df as SingleHighDensityRouteWithJumpersSolver,Ph as calculateOptimalCapacityDepth,On as convertSrjToGraphicsObject,Me as getGlobalInMemoryCache,Se as getGlobalLocalStorageCache,bh as getTunedTotalCapacity1,Ne as setupGlobalCaches};
1
+ var t=Object.create,e=Object.defineProperty,n=Object.getOwnPropertyDescriptor,o=Object.getOwnPropertyNames,i=Object.getPrototypeOf,s=Object.prototype.hasOwnProperty,r=(t,e)=>function(){return e||(0,t[o(t)[0]])((e={exports:{}}).exports,e),e.exports},a=(r,a,c)=>(c=null!=r?t(i(r)):{},((t,i,r,a)=>{if(i&&"object"==typeof i||"function"==typeof i)for(let c of o(i))s.call(t,c)||c===r||e(t,c,{get:()=>i[c],enumerable:!(a=n(i,c))||a.enumerable});return t})(!a&&r&&r.__esModule?c:e(c,"default",{value:r,enumerable:!0}),r)),c=r({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),h=r({"node_modules/kind-of/index.js"(t,e){var n=c(),o=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=o.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),l=r({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(n[e(o,t[o])||o]=t[o]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),d=r({"node_modules/deep-rename-keys/index.js"(t,e){var n=h(),o=l();e.exports=function t(e,i){var s=n(e);if("object"!==s&&"array"!==s)throw new Error("expected an object");var r=[];for(var a in"object"===s&&(e=o(e,i),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,i):r[a]=c}return r}}}),u=r({"node_modules/xml-reader/node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,o="~";function i(){}function s(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(o=!1)),r.prototype.eventNames=function(){var t,e,i=[];if(0===this._eventsCount)return i;for(e in t=this._events)n.call(t,e)&&i.push(o?e.slice(1):e);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},r.prototype.listeners=function(t,e){var n=o?o+t:t,i=this._events[n];if(e)return!!i;if(!i)return[];if(i.fn)return[i.fn];for(var s=0,r=i.length,a=new Array(r);s<r;s++)a[s]=i[s].fn;return a},r.prototype.emit=function(t,e,n,i,s,r){var a=o?o+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,i),!0;case 5:return l.fn.call(l.context,e,n,i,s),!0;case 6:return l.fn.call(l.context,e,n,i,s,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,i);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var i=new s(e,n||this),r=o?o+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],i]:this._events[r].push(i):(this._events[r]=i,this._eventsCount++),this},r.prototype.once=function(t,e,n){var i=new s(e,n||this,!0),r=o?o+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],i]:this._events[r].push(i):(this._events[r]=i,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,s){var r=o?o+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new i:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||s&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new i:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||s&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new i:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=o?o+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new i:delete this._events[e])):(this._events=new i,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=o,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),p=r({"node_modules/xml-lexer/node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,o="~";function i(){}function s(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(o=!1)),r.prototype.eventNames=function(){var t,e,i=[];if(0===this._eventsCount)return i;for(e in t=this._events)n.call(t,e)&&i.push(o?e.slice(1):e);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},r.prototype.listeners=function(t,e){var n=o?o+t:t,i=this._events[n];if(e)return!!i;if(!i)return[];if(i.fn)return[i.fn];for(var s=0,r=i.length,a=new Array(r);s<r;s++)a[s]=i[s].fn;return a},r.prototype.emit=function(t,e,n,i,s,r){var a=o?o+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,i),!0;case 5:return l.fn.call(l.context,e,n,i,s),!0;case 6:return l.fn.call(l.context,e,n,i,s,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,i);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var i=new s(e,n||this),r=o?o+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],i]:this._events[r].push(i):(this._events[r]=i,this._eventsCount++),this},r.prototype.once=function(t,e,n){var i=new s(e,n||this,!0),r=o?o+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],i]:this._events[r].push(i):(this._events[r]=i,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,s){var r=o?o+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new i:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||s&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new i:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||s&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new i:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=o?o+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new i:delete this._events[e])):(this._events=new i,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=o,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),f=r({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var o=p(),i=function(){},s={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:s,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,g,m,y;t=Object.assign({debug:!1},t);var x=new o,v=s.data,b="",P="",S="",I="",M="",_="",N=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var o={type:e,value:n};t.debug&&console.log("emit:",o),x.emit("data",o)}};x.stateMachine=(n(y={},s.data,(n(e={},r.lt,function(){b.trim()&&N(a.text,b),P="",M=!1,v=s.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,s.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(N(a.text,b.slice(0,-3)),b="",v=s.data)})),n(y,s.tagBegin,(n(h={},r.space,i),n(h,r.char,function(t){P=t,v=s.tagName}),n(h,r.slash,function(){P="",M=!0}),h)),n(y,s.tagName,(n(l={},r.space,function(){M?v=s.tagEnd:(v=s.attributeNameStart,N(a.openTag,P))}),n(l,r.gt,function(){N(M?a.closeTag:a.openTag,P),b="",v=s.data}),n(l,r.slash,function(){v=s.tagEnd,N(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=s.cdata,b="",P="")}),l)),n(y,s.tagEnd,(n(d={},r.gt,function(){N(a.closeTag,P),b="",v=s.data}),n(d,r.char,i),d)),n(y,s.attributeNameStart,(n(u={},r.char,function(t){S=t,v=s.attributeName}),n(u,r.gt,function(){b="",v=s.data}),n(u,r.space,i),n(u,r.slash,function(){M=!0,v=s.tagEnd}),u)),n(y,s.attributeName,(n(p={},r.space,function(){v=s.attributeNameEnd}),n(p,r.equal,function(){N(a.attributeName,S),v=s.attributeValueBegin}),n(p,r.gt,function(){I="",N(a.attributeName,S),N(a.attributeValue,I),b="",v=s.data}),n(p,r.slash,function(){M=!0,I="",N(a.attributeName,S),N(a.attributeValue,I),v=s.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,s.attributeNameEnd,(n(f={},r.space,i),n(f,r.equal,function(){N(a.attributeName,S),v=s.attributeValueBegin}),n(f,r.gt,function(){I="",N(a.attributeName,S),N(a.attributeValue,I),b="",v=s.data}),n(f,r.char,function(t){I="",N(a.attributeName,S),N(a.attributeValue,I),S=t,v=s.attributeName}),f)),n(y,s.attributeValueBegin,(n(g={},r.space,i),n(g,r.quote,function(t){_=t,I="",v=s.attributeValue}),n(g,r.gt,function(){N(a.attributeValue,I=""),b="",v=s.data}),n(g,r.char,function(t){_="",I=t,v=s.attributeValue}),g)),n(y,s.attributeValue,(n(m={},r.space,function(t){_?I+=t:(N(a.attributeValue,I),v=s.attributeNameStart)}),n(m,r.quote,function(t){_===t?(N(a.attributeValue,I),v=s.attributeNameStart):I+=t}),n(m,r.gt,function(t){_?I+=t:(N(a.attributeValue,I),b="",v=s.data)}),n(m,r.slash,function(t){_?I+=t:(N(a.attributeValue,I),M=!0,v=s.tagEnd)}),n(m,r.char,function(t){I+=t}),m)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],o=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];o(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),g=r({"node_modules/xml-reader/dist/reader.js"(t,e){var n=u(),o=f(),i=o.Type,s={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:s.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case i.openTag:if(null===c)(c=a).name=n.value;else{var o=r({name:n.value,parent:c});c.children.push(o),c=o}break;case i.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case i.text:c&&c.children.push(r({type:s.text,value:n.value,parent:t.parentNodes?c:null}));break;case i.attributeName:h=n.value,c.attributes[h]="";break;case i.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=o.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),o=void 0;return n.on("done",function(t){o=t}),n.parse(t),o},create:a,NodeType:s}}});function m(t,e){return Array.isArray(e)?[t.a*e[0]+t.c*e[1]+t.e,t.b*e[0]+t.d*e[1]+t.f]:{x:t.a*e.x+t.c*e.y+t.e,y:t.b*e.x+t.d*e.y+t.f}}function y(t,e=0){return{a:1,c:0,e:t,b:0,d:1,f:e}}var{cos:x,sin:v,PI:b}=Math,{tan:P}=Math;a(d()),a(g());function S(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var I=(t,e)=>({...t,rects:[...t.rects??[],...e.rects??[]],points:[...t.points??[],...e.points??[]],lines:[...t.lines??[],...e.lines??[]],circles:[...t.circles??[],...e.circles??[]],arrows:[...t.arrows??[],...e.arrows??[]],texts:[...t.texts??[],...e.texts??[]]}),M=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function _(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var N=class extends M{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,o=this.firstIterationOfStage[e.solverName]||0,i=this.iterations,s=e.solverName===this.getCurrentStageName()?i-o:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:s,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(S(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const o=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const o=this[e.solverName],i=o?.visualize();return i?(S(i,n+t),i):null}).filter(Boolean));return 0===o.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(S(n,o.length+t+1),o.push(n)),1===o.length?o[0]:{points:o.flatMap(t=>t.points||[]),rects:o.flatMap(t=>t.rects||[]),lines:o.flatMap(t=>t.lines||[]),circles:o.flatMap(t=>t.circles||[]),texts:o.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},C=class{constructor(){this.ids=[],this.values=[],this.length=0}clear(){this.length=0}push(t,e){let n=this.length++;for(;n>0;){const t=n-1>>1,o=this.values[t];if(e>=o)break;this.ids[n]=this.ids[t],this.values[n]=o,n=t}this.ids[n]=t,this.values[n]=e}pop(){if(0===this.length)return;const t=this.ids,e=this.values,n=t[0],o=--this.length;if(o>0){const n=t[o],i=e[o];let s=0;const r=o>>1;for(;s<r;){const n=1+(s<<1),r=n+1,a=n+(+(r<o)&+(e[r]<e[n]));if(e[a]>=i)break;t[s]=t[a],e[s]=e[a],s=a}t[s]=n,e[s]=i}return n}peek(){return this.length>0?this.ids[0]:void 0}peekValue(){return this.length>0?this.values[0]:void 0}shrink(){this.ids.length=this.values.length=this.length}},T=[Int8Array,Uint8Array,Uint8ClampedArray,Int16Array,Uint16Array,Int32Array,Uint32Array,Float32Array,Float64Array],E=class t{static from(e,n=0){if(n%8!=0)throw new Error("byteOffset must be 8-byte aligned.");if(!e||void 0===e.byteLength||e.buffer)throw new Error("Data must be an instance of ArrayBuffer or SharedArrayBuffer.");const[o,i]=new Uint8Array(e,n+0,2);if(251!==o)throw new Error("Data does not appear to be in a Flatbush format.");const s=i>>4;if(3!==s)throw new Error(`Got v${s} data when expected v3.`);const r=T[15&i];if(!r)throw new Error("Unrecognized array type.");const[a]=new Uint16Array(e,n+2,1),[c]=new Uint32Array(e,n+4,1);return new t(c,a,r,void 0,e,n)}constructor(t,e=16,n=Float64Array,o=ArrayBuffer,i,s=0){if(void 0===t)throw new Error("Missing required argument: numItems.");if(isNaN(t)||t<=0)throw new Error(`Unexpected numItems value: ${t}.`);this.numItems=+t,this.nodeSize=Math.min(Math.max(+e,2),65535),this.byteOffset=s;let r=t,a=r;this._levelBounds=[4*r];do{r=Math.ceil(r/this.nodeSize),a+=r,this._levelBounds.push(4*a)}while(1!==r);this.ArrayType=n,this.IndexArrayType=a<16384?Uint16Array:Uint32Array;const c=T.indexOf(n),h=4*a*n.BYTES_PER_ELEMENT;if(c<0)throw new Error(`Unexpected typed array class: ${n}.`);if(i)this.data=i,this._boxes=new n(i,s+8,4*a),this._indices=new this.IndexArrayType(i,s+8+h,a),this._pos=4*a,this.minX=this._boxes[this._pos-4],this.minY=this._boxes[this._pos-3],this.maxX=this._boxes[this._pos-2],this.maxY=this._boxes[this._pos-1];else{const i=this.data=new o(8+h+a*this.IndexArrayType.BYTES_PER_ELEMENT);this._boxes=new n(i,8,4*a),this._indices=new this.IndexArrayType(i,8+h,a),this._pos=0,this.minX=1/0,this.minY=1/0,this.maxX=-1/0,this.maxY=-1/0,new Uint8Array(i,0,2).set([251,48+c]),new Uint16Array(i,2,1)[0]=e,new Uint32Array(i,4,1)[0]=t}this._queue=new C}add(t,e,n=t,o=e){const i=this._pos>>2,s=this._boxes;return this._indices[i]=i,s[this._pos++]=t,s[this._pos++]=e,s[this._pos++]=n,s[this._pos++]=o,t<this.minX&&(this.minX=t),e<this.minY&&(this.minY=e),n>this.maxX&&(this.maxX=n),o>this.maxY&&(this.maxY=o),i}finish(){if(this._pos>>2!==this.numItems)throw new Error(`Added ${this._pos>>2} items when expected ${this.numItems}.`);const t=this._boxes;if(this.numItems<=this.nodeSize)return t[this._pos++]=this.minX,t[this._pos++]=this.minY,t[this._pos++]=this.maxX,void(t[this._pos++]=this.maxY);const e=this.maxX-this.minX||1,n=this.maxY-this.minY||1,o=new Uint32Array(this.numItems);for(let i=0,s=0;i<this.numItems;i++){const r=t[s++],a=t[s++],c=t[s++],h=t[s++],l=Math.floor(65535*((r+c)/2-this.minX)/e),d=Math.floor(65535*((a+h)/2-this.minY)/n);o[i]=O(l,d)}!function(t,e,n,o,i,s){const r=[o,i];for(;r.length;){const o=r.pop()||0,i=r.pop()||0;if(o-i<=s&&Math.floor(i/s)>=Math.floor(o/s))continue;const a=t[i],c=t[i+o>>1],h=t[o],l=a>c!=a>h?a:c<a!=c<h?c:h;let d=i-1,u=o+1;for(;;){do{d++}while(t[d]<l);do{u--}while(t[u]>l);if(d>=u)break;R(t,e,n,d,u)}r.push(i,u,u+1,o)}}(o,t,this._indices,0,this.numItems-1,this.nodeSize);for(let e=0,n=0;e<this._levelBounds.length-1;e++){const o=this._levelBounds[e];for(;n<o;){const e=n;let i=t[n++],s=t[n++],r=t[n++],a=t[n++];for(let e=1;e<this.nodeSize&&n<o;e++)i=Math.min(i,t[n++]),s=Math.min(s,t[n++]),r=Math.max(r,t[n++]),a=Math.max(a,t[n++]);this._indices[this._pos>>2]=e,t[this._pos++]=i,t[this._pos++]=s,t[this._pos++]=r,t[this._pos++]=a}}}search(t,e,n,o,i){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let s=this._boxes.length-4;const r=[],a=[];for(;void 0!==s;){const c=Math.min(s+4*this.nodeSize,w(s,this._levelBounds));for(let h=s;h<c;h+=4){const c=this._boxes[h];if(n<c)continue;const l=this._boxes[h+1];if(o<l)continue;const d=this._boxes[h+2];if(t>d)continue;const u=this._boxes[h+3];if(e>u)continue;const p=0|this._indices[h>>2];s>=4*this.numItems?r.push(p):(void 0===i||i(p,c,l,d,u))&&a.push(p)}s=r.pop()}return a}neighbors(t,e,n=1/0,o=1/0,i){if(this._pos!==this._boxes.length)throw new Error("Data not yet indexed - call index.finish().");let s=this._boxes.length-4;const r=this._queue,a=[],c=o*o;t:for(;void 0!==s;){const o=Math.min(s+4*this.nodeSize,w(s,this._levelBounds));for(let n=s;n<o;n+=4){const o=0|this._indices[n>>2],a=this._boxes[n],h=this._boxes[n+1],l=this._boxes[n+2],d=this._boxes[n+3],u=t<a?a-t:t>l?t-l:0,p=e<h?h-e:e>d?e-d:0,f=u*u+p*p;f>c||(s>=4*this.numItems?r.push(o<<1,f):(void 0===i||i(o))&&r.push(1+(o<<1),f))}for(;r.length&&1&r.peek();){if(r.peekValue()>c)break t;if(a.push(r.pop()>>1),a.length===n)break t}s=r.length?r.pop()>>1:void 0}return r.clear(),a}};function w(t,e){let n=0,o=e.length-1;for(;n<o;){const i=n+o>>1;e[i]>t?o=i:n=i+1}return e[n]}function R(t,e,n,o,i){const s=t[o];t[o]=t[i],t[i]=s;const r=4*o,a=4*i,c=e[r],h=e[r+1],l=e[r+2],d=e[r+3];e[r]=e[a],e[r+1]=e[a+1],e[r+2]=e[a+2],e[r+3]=e[a+3],e[a]=c,e[a+1]=h,e[a+2]=l,e[a+3]=d;const u=n[o];n[o]=n[i],n[i]=u}function O(t,e){let n=t^e,o=65535^n,i=65535^(t|e),s=t&(65535^e),r=n|o>>1,a=n>>1^n,c=i>>1^o&s>>1^i,h=n&i>>1^s>>1^s;n=r,o=a,i=c,s=h,r=n&n>>2^o&o>>2,a=n&o>>2^o&(n^o)>>2,c^=n&i>>2^o&s>>2,h^=o&i>>2^(n^o)&s>>2,n=r,o=a,i=c,s=h,r=n&n>>4^o&o>>4,a=n&o>>4^o&(n^o)>>4,c^=n&i>>4^o&s>>4,h^=o&i>>4^(n^o)&s>>4,n=r,o=a,i=c,s=h,c^=n&i>>8^o&s>>8,h^=o&i>>8^(n^o)&s>>8,n=c^c>>1,o=h^h>>1;let l=t^e,d=o|65535^(l|n);return l=16711935&(l|l<<8),l=252645135&(l|l<<4),l=858993459&(l|l<<2),l=1431655765&(l|l<<1),d=16711935&(d|d<<8),d=252645135&(d|d<<4),d=858993459&(d|d<<2),d=1431655765&(d|d<<1),(d<<1|l)>>>0}function A(t){const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,maxX:t.center.x+e,minY:t.center.y-n,maxY:t.center.y+n}}function z(t,e,n){return Math.max(e,Math.min(n,t))}function D(t,e,n,o){const i=L(t,e,n),s=L(t,e,o),r=L(n,o,t),a=L(n,o,e);return i!==s&&r!==a||(!(0!==i||!Y(t,n,e))||(!(0!==s||!Y(t,o,e))||(!(0!==r||!Y(n,t,o))||!(0!==a||!Y(n,e,o)))))}function L(t,e,n){const o=(e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y);return 0===o?0:o>0?1:2}function Y(t,e,n){return e.x<=Math.max(t.x,n.x)&&e.x>=Math.min(t.x,n.x)&&e.y<=Math.max(t.y,n.y)&&e.y>=Math.min(t.y,n.y)}function X(t,e,n){const o=(n.x-e.x)**2+(n.y-e.y)**2;if(0===o)return F(t,e);let i=((t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y))/o;i=Math.max(0,Math.min(1,i));return F(t,{x:e.x+i*(n.x-e.x),y:e.y+i*(n.y-e.y)})}function F(t,e){const n=t.x-e.x,o=t.y-e.y;return Math.sqrt(n*n+o*o)}function k(t,e,n,o){const i=e.x-t.x,s=e.y-t.y,r=o.x-n.x,a=o.y-n.y,c=t.x-n.x,h=t.y-n.y,l=i*a-s*r;if(Math.abs(l)<1e-10)return null;const d=(h*r-c*a)/l,u=(i*h-s*c)/l,p=1e-9;if(d>=-1e-9&&d<=1+p&&u>=-1e-9&&u<=1+p){return{x:t.x+d*i,y:t.y+d*s}}return null}function $(t,e){const n=e.width/2,o=e.height/2,i=e.center.x-n,s=e.center.x+n,r=e.center.y-o,a=e.center.y+o;if(t.x>=i&&t.x<=s&&t.y>=r&&t.y<=a)return 0;return F(t,{x:z(t.x,i,s),y:z(t.y,r,a)})}function B(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var j=t=>{if("minX"in t)return t;const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,minY:t.center.y-n,maxX:t.center.x+e,maxY:t.center.y+n}},W=t=>[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],V=t=>{const e=[];for(let n=0;n<t.length;n++){const o=t[n],i=t[(n+1)%t.length];e.push([o,i])}return e},H=(t,e,n)=>{const o=(t.y-e.y)*(n.x-e.x)-(t.x-e.x)*(n.y-e.y);if(Math.abs(o)>1e-9)return!1;const i=(t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y);if(i<0)return!1;return!(i>(n.x-e.x)**2+(n.y-e.y)**2)},U=(t,e)=>{if(e.length<3)return!1;const n=V(e);for(const[e,o]of n)if(H(t,e,o))return!0;let o=!1;for(let n=0,i=e.length-1;n<e.length;i=n++){const s=e[n].x,r=e[n].y,a=e[i].x,c=e[i].y;r>t.y!=c>t.y&&t.x<(a-s)*(t.y-r)/(c-r)+s&&(o=!o)}return o},G=(t,e)=>{const n=W(t),o=[[n[0],n[1]],[n[1],n[2]],[n[2],n[3]],[n[3],n[0]]],i=V(e);for(const[t,e]of i)for(const[n,i]of o)if(D(t,e,n,i))return!0;return!1},Z=(t,e)=>((t,e)=>!(e.length<3)&&(!!e.some(e=>((t,e)=>t.x>=e.minX&&t.x<=e.maxX&&t.y>=e.minY&&t.y<=e.maxY)(e,t))||(!!W(t).some(t=>U(t,e))||G(t,e))))(j(t),e),q=(t,e)=>((t,e)=>!(e.length<3)&&(!!W(t).every(t=>U(t,e))&&!G(t,e)))(j(t),e);function J(t,e,n,o){if(t.x===e.x&&t.y===e.y)return X(t,n,o);if(n.x===o.x&&n.y===o.y)return X(n,t,e);if(D(t,e,n,o))return 0;const i=[X(t,n,o),X(e,n,o),X(n,t,e),X(o,t,e)];return Math.min(...i)}function K(t,e,n){const o=n.width/2,i=n.height/2;return function(t,e,n){const o={x:n.minX,y:n.minY},i={x:n.maxX,y:n.minY},s={x:n.minX,y:n.maxY},r={x:n.maxX,y:n.maxY};if(D(t,e,o,i)||D(t,e,i,r)||D(t,e,r,s)||D(t,e,s,o))return 0;if(t.x>=n.minX&&t.x<=n.maxX&&t.y>=n.minY&&t.y<=n.maxY&&e.x>=n.minX&&e.x<=n.maxX&&e.y>=n.minY&&e.y<=n.maxY)return 0;const a=[X(o,t,e),X(i,t,e),X(s,t,e),X(r,t,e)];if(t.x>=n.minX&&t.x<=n.maxX&&t.y>=n.minY&&t.y<=n.maxY)return 0;if(e.x>=n.minX&&e.x<=n.maxX&&e.y>=n.minY&&e.y<=n.maxY)return 0;if(t.x<n.minX||t.x>n.maxX||t.y<n.minY||t.y>n.maxY){const e=z(t.x,n.minX,n.maxX),o=z(t.y,n.minY,n.maxY);a.push(F(t,{x:e,y:o}))}if(e.x<n.minX||e.x>n.maxX||e.y<n.minY||e.y>n.maxY){const t=z(e.x,n.minX,n.maxX),o=z(e.y,n.minY,n.maxY);a.push(F(e,{x:t,y:o}))}return Math.min(...a)}(t,e,{minX:n.center.x-o,maxX:n.center.x+o,minY:n.center.y-i,maxY:n.center.y+i})}function Q(t,e,n){const o=n.x-e.x,i=n.y-e.y,s=o*o+i*i;if(0===s)return{x:e.x,y:e.y};let r=((t.x-e.x)*o+(t.y-e.y)*i)/s;r=Math.max(0,Math.min(1,r));return{x:e.x+r*o,y:e.y+r*i}}function tt(t,e,n=0,o=t.length-1,i=nt){for(;o>n;){if(o-n>600){const s=o-n+1,r=e-n+1,a=Math.log(s),c=.5*Math.exp(2*a/3),h=.5*Math.sqrt(a*c*(s-c)/s)*(r-s/2<0?-1:1);tt(t,e,Math.max(n,Math.floor(e-r*c/s+h)),Math.min(o,Math.floor(e+(s-r)*c/s+h)),i)}const s=t[e];let r=n,a=o;for(et(t,n,e),i(t[o],s)>0&&et(t,n,o);r<a;){for(et(t,r,a),r++,a--;i(t[r],s)<0;)r++;for(;i(t[a],s)>0;)a--}0===i(t[n],s)?et(t,n,a):(a++,et(t,a,o)),a<=e&&(n=a+1),e<=a&&(o=a-1)}}function et(t,e,n){const o=t[e];t[e]=t[n],t[n]=o}function nt(t,e){return t<e?-1:t>e?1:0}var ot=class{constructor(t=9){this._maxEntries=Math.max(4,t),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()}all(){return this._all(this.data,[])}search(t){let e=this.data;const n=[];if(!gt(t,e))return n;const o=this.toBBox,i=[];for(;e;){for(let s=0;s<e.children.length;s++){const r=e.children[s],a=e.leaf?o(r):r;gt(t,a)&&(e.leaf?n.push(r):ft(t,a)?this._all(r,n):i.push(r))}e=i.pop()}return n}collides(t){let e=this.data;if(!gt(t,e))return!1;const n=[];for(;e;){for(let o=0;o<e.children.length;o++){const i=e.children[o],s=e.leaf?this.toBBox(i):i;if(gt(t,s)){if(e.leaf||ft(t,s))return!0;n.push(i)}}e=n.pop()}return!1}load(t){if(!t||!t.length)return this;if(t.length<this._minEntries){for(let e=0;e<t.length;e++)this.insert(t[e]);return this}let e=this._build(t.slice(),0,t.length-1,0);if(this.data.children.length)if(this.data.height===e.height)this._splitRoot(this.data,e);else{if(this.data.height<e.height){const t=this.data;this.data=e,e=t}this._insert(e,this.data.height-e.height-1,!0)}else this.data=e;return this}insert(t){return t&&this._insert(t,this.data.height-1),this}clear(){return this.data=mt([]),this}remove(t,e){if(!t)return this;let n=this.data;const o=this.toBBox(t),i=[],s=[];let r,a,c;for(;n||i.length;){if(n||(n=i.pop(),a=i[i.length-1],r=s.pop(),c=!0),n.leaf){const o=it(t,n.children,e);if(-1!==o)return n.children.splice(o,1),i.push(n),this._condense(i),this}c||n.leaf||!ft(n,o)?a?(r++,n=a.children[r],c=!1):n=null:(i.push(n),s.push(r),r=0,a=n,n=n.children[0])}return this}toBBox(t){return t}compareMinX(t,e){return t.minX-e.minX}compareMinY(t,e){return t.minY-e.minY}toJSON(){return this.data}fromJSON(t){return this.data=t,this}_all(t,e){const n=[];for(;t;)t.leaf?e.push(...t.children):n.push(...t.children),t=n.pop();return e}_build(t,e,n,o){const i=n-e+1;let s,r=this._maxEntries;if(i<=r)return s=mt(t.slice(e,n+1)),st(s,this.toBBox),s;o||(o=Math.ceil(Math.log(i)/Math.log(r)),r=Math.ceil(i/Math.pow(r,o-1))),s=mt([]),s.leaf=!1,s.height=o;const a=Math.ceil(i/r),c=a*Math.ceil(Math.sqrt(r));yt(t,e,n,c,this.compareMinX);for(let i=e;i<=n;i+=c){const e=Math.min(i+c-1,n);yt(t,i,e,a,this.compareMinY);for(let n=i;n<=e;n+=a){const i=Math.min(n+a-1,e);s.children.push(this._build(t,n,i,o-1))}}return st(s,this.toBBox),s}_chooseSubtree(t,e,n,o){for(;o.push(e),!e.leaf&&o.length-1!==n;){let n,o=1/0,i=1/0;for(let s=0;s<e.children.length;s++){const r=e.children[s],a=lt(r),c=ut(t,r)-a;c<i?(i=c,o=a<o?a:o,n=r):c===i&&a<o&&(o=a,n=r)}e=n||e.children[0]}return e}_insert(t,e,n){const o=n?t:this.toBBox(t),i=[],s=this._chooseSubtree(o,this.data,e,i);for(s.children.push(t),at(s,o);e>=0&&i[e].children.length>this._maxEntries;)this._split(i,e),e--;this._adjustParentBBoxes(o,i,e)}_split(t,e){const n=t[e],o=n.children.length,i=this._minEntries;this._chooseSplitAxis(n,i,o);const s=this._chooseSplitIndex(n,i,o),r=mt(n.children.splice(s,n.children.length-s));r.height=n.height,r.leaf=n.leaf,st(n,this.toBBox),st(r,this.toBBox),e?t[e-1].children.push(r):this._splitRoot(n,r)}_splitRoot(t,e){this.data=mt([t,e]),this.data.height=t.height+1,this.data.leaf=!1,st(this.data,this.toBBox)}_chooseSplitIndex(t,e,n){let o,i=1/0,s=1/0;for(let r=e;r<=n-e;r++){const e=rt(t,0,r,this.toBBox),a=rt(t,r,n,this.toBBox),c=pt(e,a),h=lt(e)+lt(a);c<i?(i=c,o=r,s=h<s?h:s):c===i&&h<s&&(s=h,o=r)}return o||n-e}_chooseSplitAxis(t,e,n){const o=t.leaf?this.compareMinX:ct,i=t.leaf?this.compareMinY:ht;this._allDistMargin(t,e,n,o)<this._allDistMargin(t,e,n,i)&&t.children.sort(o)}_allDistMargin(t,e,n,o){t.children.sort(o);const i=this.toBBox,s=rt(t,0,e,i),r=rt(t,n-e,n,i);let a=dt(s)+dt(r);for(let o=e;o<n-e;o++){const e=t.children[o];at(s,t.leaf?i(e):e),a+=dt(s)}for(let o=n-e-1;o>=e;o--){const e=t.children[o];at(r,t.leaf?i(e):e),a+=dt(r)}return a}_adjustParentBBoxes(t,e,n){for(let o=n;o>=0;o--)at(e[o],t)}_condense(t){for(let e,n=t.length-1;n>=0;n--)0===t[n].children.length?n>0?(e=t[n-1].children,e.splice(e.indexOf(t[n]),1)):this.clear():st(t[n],this.toBBox)}};function it(t,e,n){if(!n)return e.indexOf(t);for(let o=0;o<e.length;o++)if(n(t,e[o]))return o;return-1}function st(t,e){rt(t,0,t.children.length,e,t)}function rt(t,e,n,o,i){i||(i=mt(null)),i.minX=1/0,i.minY=1/0,i.maxX=-1/0,i.maxY=-1/0;for(let s=e;s<n;s++){const e=t.children[s];at(i,t.leaf?o(e):e)}return i}function at(t,e){return t.minX=Math.min(t.minX,e.minX),t.minY=Math.min(t.minY,e.minY),t.maxX=Math.max(t.maxX,e.maxX),t.maxY=Math.max(t.maxY,e.maxY),t}function ct(t,e){return t.minX-e.minX}function ht(t,e){return t.minY-e.minY}function lt(t){return(t.maxX-t.minX)*(t.maxY-t.minY)}function dt(t){return t.maxX-t.minX+(t.maxY-t.minY)}function ut(t,e){return(Math.max(e.maxX,t.maxX)-Math.min(e.minX,t.minX))*(Math.max(e.maxY,t.maxY)-Math.min(e.minY,t.minY))}function pt(t,e){const n=Math.max(t.minX,e.minX),o=Math.max(t.minY,e.minY),i=Math.min(t.maxX,e.maxX),s=Math.min(t.maxY,e.maxY);return Math.max(0,i-n)*Math.max(0,s-o)}function ft(t,e){return t.minX<=e.minX&&t.minY<=e.minY&&e.maxX<=t.maxX&&e.maxY<=t.maxY}function gt(t,e){return e.minX<=t.maxX&&e.minY<=t.maxY&&e.maxX>=t.minX&&e.maxY>=t.minY}function mt(t){return{children:t,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function yt(t,e,n,o,i){const s=[e,n];for(;s.length;){if((n=s.pop())-(e=s.pop())<=o)continue;const r=e+Math.ceil((n-e)/o/2)*o;tt(t,r,e,n,i),s.push(e,r,r,n)}}var xt=1e-4;var vt=[{facingDirection:"x-",dx:-1,dy:0,startX:-.5,startY:.5,endX:-.5,endY:-.5},{facingDirection:"x+",dx:1,dy:0,startX:.5,startY:.5,endX:.5,endY:-.5},{facingDirection:"y-",dx:0,dy:-1,startX:-.5,startY:-.5,endX:.5,endY:-.5},{facingDirection:"y+",dx:0,dy:1,startX:.5,startY:.5,endX:-.5,endY:.5}],bt={"x-":vt.find(t=>"x-"===t.facingDirection),"x+":vt.find(t=>"x+"===t.facingDirection),"y-":vt.find(t=>"y-"===t.facingDirection),"y+":vt.find(t=>"y+"===t.facingDirection)},Pt={"x-":{x:-1,y:0},"x+":{x:1,y:0},"y-":{x:0,y:-1},"y+":{x:0,y:1}},St=(t,e)=>{const{dir:n,amt:o}=e,i=Pt[n];return t.map(t=>({x:t.x+i.x*o,y:t.y+i.y*o}))},It=1e-4,Mt=class extends M{constructor(t){super(),this.input=t;for(const t of this.input.meshNodes)for(const e of vt){let n={x:t.center.x+t.width*e.startX,y:t.center.y+t.height*e.startY},o={x:t.center.x+t.width*e.endX,y:t.center.y+t.height*e.endY};n.x>o.x&&([n,o]=[o,n]),Math.abs(n.x-o.x)<It&&n.y>o.y&&([n,o]=[o,n]);for(const i of t.availableZ)this.unprocessedEdges.push({parent:t,start:n,end:o,facingDirection:e.facingDirection,z:i})}this.allEdges=[...this.unprocessedEdges],this.edgeSpatialIndex=new E(this.allEdges.length);for(const t of this.allEdges)this.edgeSpatialIndex.add(t.start.x,t.start.y,t.end.x,t.end.y);this.edgeSpatialIndex.finish()}allEdges;unprocessedEdges=[];segmentsWithAdjacentEmptySpace=[];edgeSpatialIndex;lastCandidateEdge=null;lastOverlappingEdges=null;lastUncoveredSegments=null;_step(){if(0===this.unprocessedEdges.length)return this.solved=!0,this.lastCandidateEdge=null,this.lastOverlappingEdges=null,void(this.lastUncoveredSegments=null);const t=this.unprocessedEdges.shift();this.lastCandidateEdge=t;const e=this.edgeSpatialIndex.search(t.start.x-It,t.start.y-It,t.end.x+It,t.end.y+It).map(t=>this.allEdges[t]).filter(e=>e.z===t.z);this.lastOverlappingEdges=e;const n=function(t,e){const n=Math.abs(t.start.y-t.end.y)<xt,o=Math.abs(t.start.x-t.end.x)<xt;if(!n&&!o)return[];const i=n?"x":"y",s=n?"y":"x",r=t.start[s],a=t.start[i],c=t.end[i],h=Math.min(a,c),l=Math.max(a,c),d=t=>Math.max(h,Math.min(l,t)),u=[];for(const n of e){if(n===t)continue;const e=Math.abs(n.start.y-n.end.y)<xt,o=Math.abs(n.start.x-n.end.x)<xt;if("x"===i&&!e)continue;if("y"===i&&!o)continue;if(Math.abs(n.start[s]-r)>xt)continue;const a=Math.min(n.start[i],n.end[i]),c=Math.max(n.start[i],n.end[i]),h=d(a),l=d(c);l-h>xt&&u.push({s:h,e:l})}if(0===u.length)return[{...t,start:{...t.start},end:{...t.end}}];u.sort((t,e)=>t.s-e.s);const p=[];for(const t of u){const e=p[p.length-1];!e||t.s>e.e+xt?p.push({...t}):e.e=Math.max(e.e,t.e)}const f=[];let g=h;for(const t of p)if(t.s>g+xt&&f.push({s:g,e:t.s}),g=Math.max(g,t.e),g>=l-xt)break;return l>g+xt&&f.push({s:g,e:l}),0===f.length?[]:f.filter(t=>t.e-t.s>xt).map(e=>{const n="x"===i?{x:e.s,y:r}:{x:r,y:e.s},o="x"===i?{x:e.e,y:r}:{x:r,y:e.e};return{parent:t.parent,facingDirection:t.facingDirection,start:n,end:o,z:t.z}})}(t,e);this.lastUncoveredSegments=n,this.segmentsWithAdjacentEmptySpace.push(...n)}getOutput(){return{segmentsWithAdjacentEmptySpace:this.segmentsWithAdjacentEmptySpace}}visualize(){const t={title:"FindSegmentsWithAdjacentEmptySpace",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.input.meshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.1)"});for(const e of this.unprocessedEdges)t.lines.push({points:St([e.start,e.end],{dir:e.facingDirection,amt:-.1}),strokeColor:"rgba(0, 0, 255, 0.5)",strokeDash:"5 5"});for(const e of this.segmentsWithAdjacentEmptySpace)t.lines.push({points:[e.start,e.end],strokeColor:"rgba(0,255,0, 0.5)"});if(this.lastCandidateEdge&&t.lines.push({points:[this.lastCandidateEdge.start,this.lastCandidateEdge.end],strokeColor:"blue"}),this.lastOverlappingEdges)for(const e of this.lastOverlappingEdges)t.lines.push({points:St([e.start,e.end],{dir:e.facingDirection,amt:.05}),strokeColor:"red",strokeDash:"2 2"});if(this.lastUncoveredSegments)for(const e of this.lastUncoveredSegments)t.lines.push({points:St([e.start,e.end],{dir:e.facingDirection,amt:-.05}),strokeColor:"green",strokeDash:"2 2"});return t}},_t=t=>({minX:Math.min(...t.map(t=>t.x)),minY:Math.min(...t.map(t=>t.y)),maxX:Math.max(...t.map(t=>t.x)),maxY:Math.max(...t.map(t=>t.y))}),Nt=1e-4,Ct=class extends M{constructor(t){super(),this.input=t,this.unprocessedSegments=[...this.input.segmentsWithAdjacentEmptySpace],this.rectSpatialIndex=new ot,this.rectSpatialIndex.load(this.input.boardVoid?.boardVoidRects.map((t,e)=>({capacityMeshNodeId:`void-rect-${e}`,center:{x:t.x+t.width/2,y:t.y+t.height/2},width:t.width,height:t.height,availableZ:Array.from({length:this.input.boardVoid?.layerCount||0},(t,e)=>e),layer:"void",minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height}))||[]),this.rectSpatialIndex.load(this.input.inputMeshNodes.map(t=>({...t,minX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxX:t.center.x+t.width/2,maxY:t.center.y+t.height/2})))}unprocessedSegments=[];expandedSegments=[];lastSegment=null;lastSearchBounds=null;lastCollidingNodes=null;lastSearchCorner1=null;lastSearchCorner2=null;lastExpandedSegment=null;rectSpatialIndex;_step(){if(0===this.unprocessedSegments.length)return void(this.solved=!0);const t=this.unprocessedSegments.shift();this.lastSegment=t;const{dx:e,dy:n}=bt[t.facingDirection],o=t.end.x-t.start.x,i=t.end.y-t.start.y,s=Math.sqrt(o**2+i**2),r=o/s,a=i/s;let c=null,h=1;const l={x:t.start.x+e*Nt+r*Nt*10,y:t.start.y+n*Nt+a*Nt*10},d={x:t.end.x+e*Nt-r*Nt*10,y:t.end.y+n*Nt-a*Nt*10};for(this.lastSearchCorner1=l,this.lastSearchCorner2=d;(!c||0===c.length)&&h<1e3;){const o=_t([l,d,{x:l.x+e*h,y:l.y+n*h},{x:d.x+e*h,y:d.y+n*h}]);this.lastSearchBounds=o,c=this.rectSpatialIndex.search(o).filter(e=>e.availableZ.includes(t.z)).filter(e=>e.capacityMeshNodeId!==t.parent.capacityMeshNodeId),h*=4}if(!c||0===c.length)return;this.lastCollidingNodes=c;let u=1/0;for(const e of c){const n=K(t.start,t.end,e);n<u&&(u=n)}const p=u,f=_t([t.start,t.end,{x:t.start.x+e*p,y:t.start.y+n*p},{x:t.end.x+e*p,y:t.end.y+n*p}]),g={x:(f.minX+f.maxX)/2,y:(f.minY+f.maxY)/2},m=f.maxX-f.minX,y=f.maxY-f.minY,x={segment:t,newNode:{capacityMeshNodeId:`new-${t.parent.capacityMeshNodeId}-${this.expandedSegments.length}`,center:g,width:m,height:y,availableZ:[t.z],layer:t.parent.layer}};this.lastExpandedSegment=x,m<Nt||y<Nt||(this.expandedSegments.push(x),this.rectSpatialIndex.insert({...x.newNode,...f}))}getOutput(){return{expandedSegments:this.expandedSegments}}visualize(){const t={title:"ExpandEdgesToEmptySpace",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.input.inputMeshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.1)",layer:`z${e.availableZ.join(",")}`,label:[`node ${e.capacityMeshNodeId}`,`z:${e.availableZ.join(",")}`].join("\n")});for(const{newNode:e}of this.expandedSegments)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"green",label:`expandedSegment (z=${e.availableZ.join(",")})`,layer:`z${e.availableZ.join(",")}`});if(this.lastSegment&&t.lines.push({points:[this.lastSegment.start,this.lastSegment.end],strokeColor:"rgba(0, 0, 255, 0.5)"}),this.lastSearchBounds&&t.rects.push({center:{x:(this.lastSearchBounds.minX+this.lastSearchBounds.maxX)/2,y:(this.lastSearchBounds.minY+this.lastSearchBounds.maxY)/2},width:this.lastSearchBounds.maxX-this.lastSearchBounds.minX,height:this.lastSearchBounds.maxY-this.lastSearchBounds.minY,fill:"rgba(0, 0, 255, 0.25)"}),this.lastSearchCorner1&&this.lastSearchCorner2&&(t.points.push({x:this.lastSearchCorner1.x,y:this.lastSearchCorner1.y,color:"rgba(0, 0, 255, 0.5)",label:["searchCorner1",`z=${this.lastSegment?.z}`].join("\n")}),t.points.push({x:this.lastSearchCorner2.x,y:this.lastSearchCorner2.y,color:"rgba(0, 0, 255, 0.5)",label:["searchCorner2",`z=${this.lastSegment?.z}`].join("\n")})),this.lastExpandedSegment&&t.rects.push({center:this.lastExpandedSegment.newNode.center,width:this.lastExpandedSegment.newNode.width,height:this.lastExpandedSegment.newNode.height,fill:"purple",label:`expandedSegment (z=${this.lastExpandedSegment.segment.z})`}),this.lastCollidingNodes)for(const e of this.lastCollidingNodes)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(255, 0, 0, 0.5)"});return t}},Tt=class extends N{findSegmentsWithAdjacentEmptySpaceSolver;expandEdgesToEmptySpaceSolver;pipelineDef=[_("findSegmentsWithAdjacentEmptySpaceSolver",Mt,t=>[{meshNodes:t.inputProblem.meshNodes}],{onSolved:()=>{}}),_("expandEdgesToEmptySpaceSolver",Ct,t=>[{inputMeshNodes:t.inputProblem.meshNodes,segmentsWithAdjacentEmptySpace:t.findSegmentsWithAdjacentEmptySpaceSolver.getOutput().segmentsWithAdjacentEmptySpace,boardVoid:t.inputProblem.boardVoid}],{onSolved:()=>{}})];getOutput(){const t=(this.expandEdgesToEmptySpaceSolver?.getOutput().expandedSegments??[]).map(t=>t.newNode);return{outputNodes:[...this.inputProblem.meshNodes,...t]}}initialVisualize(){const t={title:"GapFillSolverPipeline - Initial",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]};for(const e of this.inputProblem.meshNodes)t.rects.push({center:e.center,width:e.width,height:e.height,stroke:"rgba(0, 0, 0, 0.3)",fill:"rgba(100, 100, 100, 0.1)",layer:`z${e.availableZ.join(",")}`,label:[`node ${e.capacityMeshNodeId}`,`z:${e.availableZ.join(",")}`].join("\n")});return t}finalVisualize(){const t={title:"GapFillSolverPipeline - Final",coordinateSystem:"cartesian",rects:[],points:[],lines:[],circles:[],arrows:[],texts:[]},{outputNodes:e}=this.getOutput(),n=this.expandEdgesToEmptySpaceSolver?.getOutput().expandedSegments??[],o=new Set(n.map(t=>t.newNode.capacityMeshNodeId));for(const n of e){const e=o.has(n.capacityMeshNodeId);t.rects.push({center:n.center,width:n.width,height:n.height,stroke:e?"rgba(0, 128, 0, 0.8)":"rgba(0, 0, 0, 0.3)",fill:e?"rgba(0, 200, 0, 0.3)":"rgba(100, 100, 100, 0.1)",layer:`z${n.availableZ.join(",")}`,label:[`${e?"[expanded] ":""}node ${n.capacityMeshNodeId}`,`z:${n.availableZ.join(",")}`].join("\n")})}return t}},Et=1e-9,wt=(t,e,n)=>Math.max(e,Math.min(n,t)),Rt=(t,e)=>t>e+Et,Ot=(t,e)=>t>e-Et,At=(t,e)=>t<e-Et,zt=(t,e)=>t<e+Et;function Dt(t,e){return!(t.x+t.width<=e.x+Et||e.x+e.width<=t.x+Et||t.y+t.height<=e.y+Et||e.y+e.height<=t.y+Et)}function Lt(t,e){const n=[[e.x,e.y,e.x+e.width,e.y],[e.x+e.width,e.y,e.x+e.width,e.y+e.height],[e.x+e.width,e.y+e.height,e.x,e.y+e.height],[e.x,e.y+e.height,e.x,e.y]];let o=1/0;for(const[e,i,s,r]of n){const n=t.x-e,a=t.y-i,c=s-e,h=r-i,l=c*c+h*h;let d=0!==l?(n*c+a*h)/l:0;d=wt(d,0,1);const u=e+d*c,p=i+d*h;o=Math.min(o,Math.hypot(t.x-u,t.y-p))}return o}function Yt(t,e){const n=Math.max(t[0],e[0]),o=Math.min(t[1],e[1]);return o>n+Et?[n,o]:null}function Xt(t,e){if(!Dt(t,e))return[t];const n=Yt([t.x,t.x+t.width],[e.x,e.x+e.width]),o=Yt([t.y,t.y+t.height],[e.y,e.y+e.height]);if(!n||!o)return[t];const[i,s]=n,[r,a]=o,c=[];i>t.x+Et&&c.push({x:t.x,y:t.y,width:i-t.x,height:t.height}),t.x+t.width>s+Et&&c.push({x:s,y:t.y,width:t.x+t.width-s,height:t.height});const h=Math.max(0,s-i);return h>Et&&r>t.y+Et&&c.push({x:i,y:t.y,width:h,height:r-t.y}),h>Et&&t.y+t.height>a+Et&&c.push({x:i,y:a,width:h,height:t.y+t.height-a}),c.filter(t=>t.width>Et&&t.height>Et)}function Ft(t,e){let n=!1;for(let o=0,i=e.length-1;o<e.length;i=o++){const s=e[o].x,r=e[o].y,a=e[i].x,c=e[i].y;r>t.y!=c>t.y&&t.x<(a-s)*(t.y-r)/(c-r)+s&&(n=!n)}return n}function kt(t,e){if(!e||e.length<3)return[];const n=e.length>100?function(t,e){const n=t=>Math.round(t/e)*e,o=new Set,i=[];for(const e of t){const t=n(e.x),s=n(e.y),r=`${t},${s}`;o.has(r)||(o.add(r),i.push({x:t,y:s}))}return i}(e,Math.max(t.width,t.height)/100):e,o=new Set([t.x,t.x+t.width]),i=new Set([t.y,t.y+t.height]);for(const t of n)o.add(t.x),i.add(t.y);const s=Array.from(o).sort((t,e)=>t-e),r=Array.from(i).sort((t,e)=>t-e),a=[];for(let n=0;n<s.length-1;n++)for(let o=0;o<r.length-1;o++){const i=s[n],c=s[n+1],h=r[o],l=r[o+1],d=(i+c)/2,u=(h+l)/2;d>=t.x&&d<=t.x+t.width&&u>=t.y&&u<=t.y+t.height&&(Ft({x:d,y:u},e)||a.push({x:i,y:h,width:c-i,height:l-h}))}const c=[];a.sort((t,e)=>Math.abs(t.y-e.y)>Et?t.y-e.y:t.x-e.x);let h=null;for(const t of a){if(!h){h=t;continue}const e=Math.abs(h.y-t.y)<Et,n=Math.abs(h.height-t.height)<Et,o=Math.abs(h.x+h.width-t.x)<Et;e&&n&&o?h.width+=t.width:(c.push(h),h=t)}h&&c.push(h),c.sort((t,e)=>Math.abs(t.x-e.x)>Et?t.x-e.x:t.y-e.y);const l=[];h=null;for(const t of c){if(!h){h=t;continue}const e=Math.abs(h.x-t.x)<Et,n=Math.abs(h.width-t.width)<Et,o=Math.abs(h.y+h.height-t.y)<Et;e&&n&&o?h.height+=t.height:(l.push(h),h=t)}return h&&l.push(h),l}function $t(t){const e=t.toLowerCase();if("top"===e)return-1e6;if("bottom"===e)return 1e6;const n=/^inner(\d+)$/i.exec(e);return n?parseInt(n[1],10)||0:100+e.charCodeAt(0)}function Bt(t){const e=function(t){return Array.from(new Set(t)).sort((t,e)=>{const n=$t(t),o=$t(e);return n!==o?n-o:t.localeCompare(e)})}((t.obstacles??[]).flatMap(t=>t.layers??[])),n=Math.max(1,t.layerCount||e.length||1),o=Array.from({length:n},(t,e)=>0===e?"top":e===n-1?"bottom":`inner${e}`),i=[],s=new Set,r=t=>{const e=t.toLowerCase();s.has(e)||(s.add(e),i.push(t))};o.forEach(r),e.forEach(r);const a=i.slice(0,n),c=new Map;return a.forEach((t,e)=>c.set(t.toLowerCase(),e)),i.slice(a.length).forEach(t=>{const e=t.toLowerCase();c.set(e,(t=>{if(a.length<=1)return 0;if("top"===t)return 0;if("bottom"===t)return a.length-1;const e=/^inner(\d+)$/i.exec(t);if(e){if(a.length<=2)return a.length-1;const t=parseInt(e[1],10),n=a.length-2;return Math.min(n,Math.max(1,Number.isFinite(t)?t:1))}return 0})(e))}),{layerNames:a,zIndexByName:c}}function jt(t,e){if(t.zLayers?.length)return Array.from(new Set(t.zLayers)).sort((t,e)=>t-e);const n=(t.layers??[]).map(t=>e.get(t.toLowerCase())).filter(t=>"number"==typeof t);return Array.from(new Set(n)).sort((t,e)=>t-e)}function Wt(t){const e=t.width,n=t.height;return"number"!=typeof e||"number"!=typeof n?null:{x:t.center.x-e/2,y:t.center.y-n/2,width:e,height:n}}var Vt=1e-9,Ht=t=>Math.abs(t.rect.x+t.rect.width/2-t.startX)<Vt&&Math.abs(t.rect.y+t.rect.height/2-t.startY)<Vt&&Math.abs(t.rect.width-t.initialW)<Vt&&Math.abs(t.rect.height-t.initialH)<Vt,Ut=({rect:t,bounds:e})=>({x:t.x,y:t.y,width:e.x+e.width-t.x,height:t.height}),Gt=({rect:t,bounds:e})=>({x:t.x,y:t.y,width:t.width,height:e.y+e.height-t.y}),Zt=({rect:t,bounds:e})=>({x:e.x,y:t.y,width:t.x-e.x,height:t.height}),qt=({rect:t,bounds:e})=>({x:t.x,y:e.y,width:t.width,height:t.y-e.y});function Jt(t){const{r:e,bounds:n,blockers:o,maxAspect:i}=t;let s=n.x+n.width-e.x;for(const t of o){if(e.y+e.height>t.y+Et&&t.y+t.height>e.y+Et)if(Ot(t.x,e.x+e.width))s=Math.min(s,t.x-e.x);else if(t.x+t.width>e.x+e.width-Et&&t.x<e.x+e.width+Et)return 0}let r=Math.max(0,s-e.width);if(r<=0)return 0;if(null!=i){const t=e.width,n=e.height;t>=n&&(r=Math.min(r,i*n-t))}return Math.max(0,r)}function Kt(t){const{r:e,bounds:n,blockers:o,maxAspect:i}=t;let s=n.y+n.height-e.y;for(const t of o){if(e.x+e.width>t.x+Et&&t.x+t.width>e.x+Et)if(Ot(t.y,e.y+e.height))s=Math.min(s,t.y-e.y);else if(t.y+t.height>e.y+e.height-Et&&t.y<e.y+e.height+Et)return 0}let r=Math.max(0,s-e.height);if(r<=0)return 0;if(null!=i){const t=e.width,n=e.height;n>=t&&(r=Math.min(r,i*t-n))}return Math.max(0,r)}function Qt(t){const{r:e,bounds:n,blockers:o,maxAspect:i}=t;let s=n.x;for(const t of o){if(e.y+e.height>t.y+Et&&t.y+t.height>e.y+Et)if(zt(t.x+t.width,e.x))s=Math.max(s,t.x+t.width);else if(t.x<e.x+Et&&t.x+t.width>e.x-Et)return 0}let r=Math.max(0,e.x-s);if(r<=0)return 0;if(null!=i){const t=e.width,n=e.height;t>=n&&(r=Math.min(r,i*n-t))}return Math.max(0,r)}function te(t){const{r:e,bounds:n,blockers:o,maxAspect:i}=t;let s=n.y;for(const t of o){if(e.x+e.width>t.x+Et&&t.x+t.width>e.x+Et)if(zt(t.y+t.height,e.y))s=Math.max(s,t.y+t.height);else if(t.y<e.y+Et&&t.y+t.height>e.y-Et)return 0}let r=Math.max(0,e.y-s);if(r<=0)return 0;if(null!=i){const t=e.width,n=e.height;n>=t&&(r=Math.min(r,i*t-n))}return Math.max(0,r)}var ee=t=>({x:t.minX,y:t.minY,width:t.maxX-t.minX,height:t.maxY-t.minY}),ne=t=>{const{rect:e,seen:n,blockers:o}=t,i=`${e.x}|${e.y}|${e.width}|${e.height}`;n.has(i)||(n.add(i),o.push(e))};function oe(t){const{startX:e,startY:n,gridSize:o,bounds:i,obsticalIndexByLayer:s,placedIndexByLayer:r,initialCellRatio:a,maxAspectRatio:c,minReq:h}=t,l=Math.max(1e-9,o*a),d=Math.max(l,h.width),u=Math.max(l,h.height),p=[],f=new Set,g=r.length,m=o=>{const a=(t=>{const{bounds:e,rect:n}=t,o=Math.max(e.x,n.x),i=Math.max(e.y,n.y),s=Math.min(e.x+e.width,n.x+n.width),r=Math.min(e.y+e.height,n.y+n.height);return s<=o+Et||r<=i+Et?null:{minX:o,minY:i,maxX:s,maxY:r}})({bounds:i,rect:o});if(a)for(const o of t.zLayers){const t=s[o];if(t)for(const e of t.search(a))ne({rect:ee(e),seen:f,blockers:p});const i=r[o];if(i)for(const t of i.search(a)){if(!(t.zLayers.length>=g))continue;const o=ee(t);Ht({rect:o,startX:e,startY:n,initialW:d,initialH:u})||ne({rect:o,seen:f,blockers:p})}}},y=[{ox:0,oy:0},{ox:-d,oy:0},{ox:0,oy:-u},{ox:-d,oy:-u},{ox:-d/2,oy:-u/2}];let x=null,v=0;t:for(const t of y){let o={x:e+t.ox,y:n+t.oy,width:d,height:u};if(m(o),At(o.x,i.x)||At(o.y,i.y)||Rt(o.x+o.width,i.x+i.width)||Rt(o.y+o.height,i.y+i.height))continue;for(const t of p)if(Dt(o,t))continue t;const s=1e-6,r=1e3;let a=!0,l=0;for(;a&&l<r;){l++,a=!1;const t={bounds:i,blockers:p,maxAspect:c};m(Ut({rect:o,bounds:i}));const e=Jt({...t,r:o});e>s&&(o={...o,width:o.width+e},m(o),a=!0),m(Gt({rect:o,bounds:i}));const n=Kt({...t,r:o});n>s&&(o={...o,height:o.height+n},m(o),a=!0),m(Zt({rect:o,bounds:i}));const r=Qt({...t,r:o});r>s&&(o={x:o.x-r,y:o.y,width:o.width+r,height:o.height},m(o),a=!0),m(qt({rect:o,bounds:i}));const h=te({...t,r:o});h>s&&(o={x:o.x,y:o.y-h,width:o.width,height:o.height+h},m(o),a=!0)}if(o.width+Et>=h.width&&o.height+Et>=h.height){const t=o.width*o.height;t>v&&(x=o,v=t)}}return x}function ie(t){const e=Math.max(t.width,t.height);return[e/8,e/16,e/32]}function se(t){const e={minX:t.point.x,minY:t.point.y,maxX:t.point.x,maxY:t.point.y};for(let n=0;n<t.layerCount;n++){const o=t.obstacleIndexByLayer[n],i=!!o&&o.search(e).length>0,s=t.placedIndexByLayer[n],r=!!s&&s.search(e).length>0;if(!i&&!r)return!1}return!0}function re(t){const{x:e,y:n,z:o,layerCount:i,minSpan:s,maxSpan:r,obstacleIndexByLayer:a,additionalBlockersByLayer:c}=t,h=t=>{const o={minX:e,minY:n,maxX:e,maxY:n},i=a[t];if(i&&i.search(o).length>0)return!1;return!(c?.[t]??[]).some(t=>{return(i={x:e,y:n}).x>=(o=t).x-Et&&i.x<=o.x+o.width+Et&&i.y>=o.y-Et&&i.y<=o.y+o.height+Et;var o,i})};let l=o,d=o;for(;l-1>=0&&h(l-1);)l--;for(;d+1<i&&h(d+1);)d++;if("number"==typeof r){const t=wt(r,1,i);for(;d-l+1>t;)o-l>d-o?l++:d--}const u=[];for(let t=l;t<=d;t++)u.push(t);return u.length>=s?u:[]}function ae(t){const{lineStart:e,lineEnd:n,coveringIntervals:o,minSegmentLength:i}=t;if(0===o.length){return[{start:e,end:n,center:(e+n)/2}]}const s=[...o].sort((t,e)=>t.start-e.start),r=[];let a={...s[0]};for(let t=1;t<s.length;t++){const e=s[t];e.start<=a.end+Et?a.end=Math.max(a.end,e.end):(r.push(a),a={...e})}r.push(a);const c=[];if(r[0].start>e+Et){const t=e,n=r[0].start;n-t>=i&&c.push({start:t,end:n,center:(t+n)/2})}for(let t=0;t<r.length-1;t++){const e=r[t].end,n=r[t+1].start;n-e>=i&&c.push({start:e,end:n,center:(e+n)/2})}if(r[r.length-1].end<n-Et){const t=r[r.length-1].end,e=n;e-t>=i&&c.push({start:t,end:e,center:(t+e)/2})}return c}function ce(t){const{bounds:e,minSize:n,layerCount:o,obstacleIndexByLayer:i,placedIndexByLayer:s,hardPlacedByLayer:r}=t,a=[],c=Math.max(.15*n,3*Et),h=new Set;function l(t){const{x:n,y:c,z:l}=t;if(n<e.x+Et||c<e.y+Et||n>e.x+e.width-Et||c>e.y+e.height-Et)return;if(function(t){return se({layerCount:o,obstacleIndexByLayer:i,placedIndexByLayer:s,point:t})}({x:n,y:c}))return;const d=[...i[l]?.all()??[],...r[l]??[]],u=Math.min(Lt({x:n,y:c},e),...d.length?d.map(t=>Lt({x:n,y:c},t)):[1/0]),p=(t=>`${t.z}|${t.x.toFixed(6)}|${t.y.toFixed(6)}`)({x:n,y:c,z:l});if(h.has(p))return;h.add(p);const f=re({x:n,y:c,z:l,layerCount:o,minSpan:1,maxSpan:void 0,obstacleIndexByLayer:i,additionalBlockersByLayer:r});a.push({x:n,y:c,z:l,distance:u,zSpanLen:f.length,isEdgeSeed:!0})}for(let t=0;t<o;t++){const o=[...i[t]?.all()??[],...r[t]??[]],s=[{x:e.x+c,y:e.y+c},{x:e.x+e.width-c,y:e.y+c},{x:e.x+c,y:e.y+e.height-c},{x:e.x+e.width-c,y:e.y+e.height-c}];for(const e of s)l({x:e.x,y:e.y,z:t});const a=e.y+c,h=o.filter(t=>t.y<=a&&t.y+t.height>=a).map(t=>({start:Math.max(e.x,t.x),end:Math.min(e.x+e.width,t.x+t.width)})),d=ae({lineStart:e.x+c,lineEnd:e.x+e.width-c,coveringIntervals:h,minSegmentLength:.5*n});for(const e of d){const o=e.end-e.start;o>=n&&(l({x:e.center,y:a,z:t}),o>1.5*n&&(l({x:e.start+.4*n,y:a,z:t}),l({x:e.end-.4*n,y:a,z:t})))}const u=e.y+e.height-c,p=o.filter(t=>t.y<=u&&t.y+t.height>=u).map(t=>({start:Math.max(e.x,t.x),end:Math.min(e.x+e.width,t.x+t.width)})),f=ae({lineStart:e.x+c,lineEnd:e.x+e.width-c,coveringIntervals:p,minSegmentLength:.5*n});for(const e of f){const o=e.end-e.start;o>=n&&(l({x:e.center,y:u,z:t}),o>1.5*n&&(l({x:e.start+.4*n,y:u,z:t}),l({x:e.end-.4*n,y:u,z:t})))}const g=e.x+c,m=o.filter(t=>t.x<=g&&t.x+t.width>=g).map(t=>({start:Math.max(e.y,t.y),end:Math.min(e.y+e.height,t.y+t.height)})),y=ae({lineStart:e.y+c,lineEnd:e.y+e.height-c,coveringIntervals:m,minSegmentLength:.5*n});for(const e of y){const o=e.end-e.start;o>=n&&(l({x:g,y:e.center,z:t}),o>1.5*n&&(l({x:g,y:e.start+.4*n,z:t}),l({x:g,y:e.end-.4*n,z:t})))}const x=e.x+e.width-c,v=o.filter(t=>t.x<=x&&t.x+t.width>=x).map(t=>({start:Math.max(e.y,t.y),end:Math.min(e.y+e.height,t.y+t.height)})),b=ae({lineStart:e.y+c,lineEnd:e.y+e.height-c,coveringIntervals:v,minSegmentLength:.5*n});for(const e of b){const o=e.end-e.start;o>=n&&(l({x:x,y:e.center,z:t}),o>1.5*n&&(l({x:x,y:e.start+.4*n,z:t}),l({x:x,y:e.end-.4*n,z:t})))}for(const i of o){const s=i.x-c;if(s>e.x+Et&&s<e.x+e.width-Et){const e=o.filter(t=>t!==i&&t.x<=s&&t.x+t.width>=s).map(t=>({start:Math.max(i.y,t.y),end:Math.min(i.y+i.height,t.y+t.height)})),r=ae({lineStart:i.y,lineEnd:i.y+i.height,coveringIntervals:e,minSegmentLength:.5*n});for(const e of r)l({x:s,y:e.center,z:t})}const r=i.x+i.width+c;if(r>e.x+Et&&r<e.x+e.width-Et){const e=o.filter(t=>t!==i&&t.x<=r&&t.x+t.width>=r).map(t=>({start:Math.max(i.y,t.y),end:Math.min(i.y+i.height,t.y+t.height)})),s=ae({lineStart:i.y,lineEnd:i.y+i.height,coveringIntervals:e,minSegmentLength:.5*n});for(const e of s)l({x:r,y:e.center,z:t})}const a=i.y-c;if(a>e.y+Et&&a<e.y+e.height-Et){const e=o.filter(t=>t!==i&&t.y<=a&&t.y+t.height>=a).map(t=>({start:Math.max(i.x,t.x),end:Math.min(i.x+i.width,t.x+t.width)})),s=ae({lineStart:i.x,lineEnd:i.x+i.width,coveringIntervals:e,minSegmentLength:.5*n});for(const e of s)l({x:e.center,y:a,z:t})}const h=i.y+i.height+c;if(h>e.y+Et&&h<e.y+e.height-Et){const e=o.filter(t=>t!==i&&t.y<=h&&t.y+t.height>=h).map(t=>({start:Math.max(i.x,t.x),end:Math.min(i.x+i.width,t.x+t.width)})),s=ae({lineStart:i.x,lineEnd:i.x+i.width,coveringIntervals:e,minSegmentLength:.5*n});for(const e of s)l({x:e.center,y:h,z:t})}}}return a.sort((t,e)=>e.zSpanLen-t.zSpanLen||e.distance-t.distance),a}var he=(t,e)=>({...t,minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:e.zLayers});function le(t,e){const n=t.placed[e],{rect:o,zLayers:i}=n,s=t.layerCount,r=[],a=[];for(let n=0;n<t.placed.length;n++){if(n===e)continue;const c=t.placed[n];if(c.zLayers.length>=s)continue;const h=c.zLayers.filter(t=>i.includes(t));if(0===h.length)continue;if(!Dt(c.rect,o))continue;const l=Xt(c.rect,o);r.push(n);const d=c.zLayers.filter(t=>!i.includes(t));d.length>0&&a.push({rect:c.rect,zLayers:d});const u=Math.min(t.options.minSingle.width,t.options.minMulti.width),p=Math.min(t.options.minSingle.height,t.options.minMulti.height);for(const t of l)t.width+Et>=u&&t.height+Et>=p&&a.push({rect:t,zLayers:h.slice()})}const c=(t,e)=>t.minX===e.minX&&t.minY===e.minY&&t.maxX===e.maxX&&t.maxY===e.maxY;r.sort((t,e)=>e-t).forEach(e=>{const n=t.placed.splice(e,1)[0];if(t.placedIndexByLayer)for(const e of n.zLayers){const o=t.placedIndexByLayer[e];o&&o.remove(he(n.rect,{zLayers:n.zLayers}),c)}});for(const e of a){t.placed.push(e);for(const n of e.zLayers)if(t.placedIndexByLayer){const o=t.placedIndexByLayer[n];o&&o.insert(he(e.rect,{zLayers:e.zLayers.slice()}))}}}var de=t=>{const e=[{fill:"#dbeafe",stroke:"#3b82f6"},{fill:"#fef3c7",stroke:"#f59e0b"},{fill:"#d1fae5",stroke:"#10b981"},{fill:"#e9d5ff",stroke:"#a855f7"},{fill:"#fed7aa",stroke:"#f97316"},{fill:"#fecaca",stroke:"#ef4444"}];return e[Math.min(...t)%e.length]},ue=class extends M{constructor(t){super(),this.input=t}srj;layerNames;layerCount;bounds;options;boardVoidRects;gridIndex;candidates;placed;placedIndexByLayer;expansionIndex;edgeAnalysisDone;totalSeedsThisGrid;consumedSeedsThisGrid;_setup(){const t=this.input.simpleRouteJson,e=this.input.gridOptions??{},{layerNames:n,zIndexByName:o}=Bt(t),i=Math.max(1,n.length,t.layerCount||1),s={x:t.bounds.minX,y:t.bounds.minY,width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY},r=Math.max(.01,t.minTraceWidth||.15),a={...{gridSizes:[],initialCellRatio:.2,maxAspectRatio:3,minSingle:{width:2*r,height:2*r},minMulti:{width:4*r,height:4*r,minLayers:Math.min(2,Math.max(1,t.layerCount||1))},preferMultiLayer:!0,maxMultiLayerSpan:void 0},...e,gridSizes:e.gridSizes??ie(s)};this.srj=t,this.layerNames=n,this.layerCount=i,this.bounds=s,this.options=a,this.boardVoidRects=this.input.boardVoidRects,this.gridIndex=0,this.candidates=[],this.placed=[],this.placedIndexByLayer=Array.from({length:i},()=>new ot),this.expansionIndex=0,this.edgeAnalysisDone=!1,this.totalSeedsThisGrid=0,this.consumedSeedsThisGrid=0,this.stats={gridIndex:this.gridIndex}}_step(){this._stepGrid(),this.stats.gridIndex=this.gridIndex,this.stats.placed=this.placed.length}_stepGrid(){const{gridSizes:t,initialCellRatio:e,maxAspectRatio:n,minSingle:o,minMulti:i,preferMultiLayer:s,maxMultiLayerSpan:r}=this.options,a=t[this.gridIndex],c=function(t){const e=Array.from({length:t.layerCount},()=>[]);for(const n of t.placed)if(n.zLayers.length>=t.layerCount)for(const t of n.zLayers)e[t].push(n.rect);return e}({layerCount:this.layerCount,placed:this.placed});if(0===this.candidates.length&&0===this.consumedSeedsThisGrid&&(this.candidates=function(t){const{bounds:e,gridSize:n,layerCount:o,obstacleIndexByLayer:i,placedIndexByLayer:s,hardPlacedByLayer:r}=t,a=new Map;for(let t=e.x;t<e.x+e.width;t+=n)for(let c=e.y;c<e.y+e.height;c+=n){if(Math.abs(t-e.x)<Et||Math.abs(c-e.y)<Et||t>e.x+e.width-n-Et||c>e.y+e.height-n-Et)continue;if(se({layerCount:o,obstacleIndexByLayer:i,placedIndexByLayer:s,point:{x:t,y:c}}))continue;let h=[],l=0;for(let e=0;e<o;e++){const n=re({x:t,y:c,z:e,layerCount:o,minSpan:1,maxSpan:void 0,obstacleIndexByLayer:i,additionalBlockersByLayer:r});n.length>h.length&&(h=n,l=e)}const d=h.length?h[Math.floor(h.length/2)]:l,u=[...i[d]?.all()??[],...r[d]??[]],p=Math.min(Lt({x:t,y:c},e),...u.length?u.map(e=>Lt({x:t,y:c},e)):[1/0]),f=`${t.toFixed(6)}|${c.toFixed(6)}`,g={x:t,y:c,z:d,distance:p,zSpanLen:h.length},m=a.get(f);(!m||g.zSpanLen>(m.zSpanLen??0)||g.zSpanLen===m.zSpanLen&&g.distance>m.distance)&&a.set(f,g)}const c=Array.from(a.values());return c.sort((t,e)=>e.zSpanLen-t.zSpanLen||e.distance-t.distance),c}({bounds:this.bounds,gridSize:a,layerCount:this.layerCount,hardPlacedByLayer:c,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer}),this.totalSeedsThisGrid=this.candidates.length,this.consumedSeedsThisGrid=0),0===this.candidates.length){if(this.gridIndex+1<t.length)return this.gridIndex+=1,this.totalSeedsThisGrid=0,void(this.consumedSeedsThisGrid=0);if(!this.edgeAnalysisDone){const t=Math.min(o.width,o.height);return this.candidates=ce({bounds:this.bounds,minSize:t,layerCount:this.layerCount,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,hardPlacedByLayer:c}),this.edgeAnalysisDone=!0,this.totalSeedsThisGrid=this.candidates.length,void(this.consumedSeedsThisGrid=0)}return this.solved=!0,void(this.expansionIndex=0)}const h=this.candidates.shift();this.consumedSeedsThisGrid+=1;const l=re({x:h.x,y:h.y,z:h.z,layerCount:this.layerCount,minSpan:i.minLayers,maxSpan:r,obstacleIndexByLayer:this.input.obstacleIndexByLayer,additionalBlockersByLayer:c}),d=[];l.length>=i.minLayers&&d.push({kind:"multi",layers:l,minReq:{width:i.width,height:i.height}}),d.push({kind:"single",layers:[h.z],minReq:{width:o.width,height:o.height}});const u=s?d:d.reverse();for(const t of u){const o=oe({startX:h.x,startY:h.y,gridSize:a,bounds:this.bounds,obsticalIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,initialCellRatio:e,maxAspectRatio:n,minReq:t.minReq,zLayers:t.layers});if(!o)continue;const i={rect:o,zLayers:[...t.layers]},s=this.placed.push(i)-1;for(const e of t.layers){const t=this.placedIndexByLayer[e];t&&t.insert(he(o,{zLayers:i.zLayers}))}return le({layerCount:this.layerCount,placed:this.placed,options:this.options,placedIndexByLayer:this.placedIndexByLayer},s),void(this.candidates=this.candidates.filter(t=>!se({layerCount:this.layerCount,obstacleIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,point:{x:t.x,y:t.y}})))}}computeProgress(){if(this.solved)return 1;const t=this.options.gridSizes.length,e=this.gridIndex/(t+1),n=Math.max(1,this.totalSeedsThisGrid),o=n?this.consumedSeedsThisGrid/n:1;return Math.min(.999,e+o*(1/(t+1)))}getOutput(){return{srj:this.srj,layerNames:this.layerNames,layerCount:this.layerCount,bounds:this.bounds,options:this.options,boardVoidRects:this.boardVoidRects,gridIndex:this.gridIndex,candidates:this.candidates,placed:this.placed,expansionIndex:this.expansionIndex,edgeAnalysisDone:this.edgeAnalysisDone,totalSeedsThisGrid:this.totalSeedsThisGrid,consumedSeedsThisGrid:this.consumedSeedsThisGrid}}visualize(){const t=[],e=[],n=[],o=this.srj??this.input.simpleRouteJson,i=o.bounds.minX,s=o.bounds.maxX,r=o.bounds.minY,a=o.bounds.maxY;o.outline&&o.outline.length>1?n.push({points:[...o.outline,o.outline[0]],strokeColor:"#111827",strokeWidth:.01,label:"outline"}):t.push({center:{x:(i+s)/2,y:(r+a)/2},width:s-i,height:a-r,fill:"none",stroke:"#111827",label:"board"});for(const e of o.obstacles??[])"rect"!==e.type&&"oval"!==e.type||t.push({center:{x:e.center.x,y:e.center.y},width:e.width,height:e.height,fill:"#fee2e2",stroke:"#ef4444",layer:"obstacle",label:"obstacle"});if(this.boardVoidRects){let e=null;if(o.outline&&o.outline.length>0){const t=o.outline.map(t=>t.x),n=o.outline.map(t=>t.y),i=Math.min(...t),s=Math.min(...n);e={x:i,y:s,width:Math.max(...t)-i,height:Math.max(...n)-s}}for(const n of this.boardVoidRects)e&&!Dt(n,e)||t.push({center:{x:n.x+n.width/2,y:n.y+n.height/2},width:n.width,height:n.height,fill:"rgba(0, 0, 0, 0.5)",stroke:"none",label:"void"})}if(this.candidates?.length)for(const t of this.candidates)e.push({x:t.x,y:t.y,fill:"#9333ea",stroke:"#6b21a8",label:`z:${t.z}`});if(this.placed?.length)for(const e of this.placed){const n=de(e.zLayers);t.push({center:{x:e.rect.x+e.rect.width/2,y:e.rect.y+e.rect.height/2},width:e.rect.width,height:e.rect.height,fill:n.fill,stroke:n.stroke,layer:`z${e.zLayers.join(",")}`,label:`free\nz:${e.zLayers.join(",")}`})}return{title:"RectDiff Grid",coordinateSystem:"cartesian",rects:t,points:e,lines:n}}};var pe=(t,e)=>t.minX===e.minX&&t.minY===e.minY&&t.maxX===e.maxX&&t.maxY===e.maxY,fe=class extends M{constructor(t){super(),this.input=t}placedIndexByLayer=[];_meshNodes=[];_setup(){this.stats={gridIndex:this.input.gridIndex},this.placedIndexByLayer=Array.from({length:this.input.layerCount},()=>new ot);for(const t of this.input.placed)for(const e of t.zLayers){const n=this.placedIndexByLayer[e];n&&n.insert(he(t.rect,{zLayers:t.zLayers}))}}_step(){this.solved||(this._stepExpansion(),this.stats.gridIndex=this.input.gridIndex,this.stats.placed=this.input.placed.length,this.input.expansionIndex>=this.input.placed.length&&this.finalizeIfNeeded())}_stepExpansion(){if(this.input.expansionIndex>=this.input.placed.length)return;const t=this.input.expansionIndex,e=this.input.placed[t],n=this.input.options.gridSizes[this.input.options.gridSizes.length-1],o=e.rect,i=oe({startX:e.rect.x+e.rect.width/2,startY:e.rect.y+e.rect.height/2,gridSize:n,bounds:this.input.bounds,obsticalIndexByLayer:this.input.obstacleIndexByLayer,placedIndexByLayer:this.placedIndexByLayer,initialCellRatio:0,maxAspectRatio:null,minReq:{width:e.rect.width,height:e.rect.height},zLayers:e.zLayers});if(i){this.input.placed[t]={rect:i,zLayers:e.zLayers};for(const t of e.zLayers){const n=this.placedIndexByLayer[t];n&&(n.remove(he(o,{zLayers:e.zLayers}),pe),n.insert(he(i,{zLayers:e.zLayers})))}le({layerCount:this.input.layerCount,placed:this.input.placed,options:this.input.options,placedIndexByLayer:this.placedIndexByLayer},t)}this.input.expansionIndex+=1}finalizeIfNeeded(){if(this.solved)return;const t=function(t){const e=t.placed.map(t=>({minX:t.rect.x,minY:t.rect.y,maxX:t.rect.x+t.rect.width,maxY:t.rect.y+t.rect.height,zLayers:[...t.zLayers].sort((t,e)=>t-e)})),{zIndexByName:n}=Bt(t.srj),o=new Map;for(const e of t.srj.obstacles??[]){const t=Wt(e);if(!t)continue;const i=e.zLayers?.length&&e.zLayers.length>0?e.zLayers:jt(e,n),s=`${t.x}:${t.y}:${t.width}:${t.height}`;let r=o.get(s);r||(r={rect:t,layers:new Set},o.set(s,r)),i.forEach(t=>r.layers.add(t))}for(const{rect:t,layers:n}of o.values())e.push({minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:Array.from(n).sort((t,e)=>t-e),isObstacle:!0});return e}({placed:this.input.placed,srj:this.input.srj,boardVoidRects:this.input.boardVoidRects});this._meshNodes=function(t){let e=0;const n=[];for(const o of t){const t=Math.max(0,o.maxX-o.minX),i=Math.max(0,o.maxY-o.minY);t<=0||i<=0||0===o.zLayers.length||n.push({capacityMeshNodeId:"cmn_"+e++,center:{x:(o.minX+o.maxX)/2,y:(o.minY+o.maxY)/2},width:t,height:i,layer:"top",availableZ:o.zLayers.slice(),_containsObstacle:o.isObstacle,_containsTarget:o.isObstacle})}return n}(t),this.solved=!0}computeProgress(){if(this.solved)return 1;const t=this.input.options.gridSizes.length,e=t/(t+1),n=Math.max(1,this.input.placed.length),o=n?this.input.expansionIndex/n:1;return Math.min(.999,e+o*(1/(t+1)))}getOutput(){if(this.solved)return{meshNodes:this._meshNodes};return{meshNodes:this.input.placed.map((t,e)=>({capacityMeshNodeId:`expand-preview-${e}`,center:{x:t.rect.x+t.rect.width/2,y:t.rect.y+t.rect.height/2},width:t.rect.width,height:t.rect.height,availableZ:t.zLayers.slice(),layer:`z${t.zLayers.join(",")}`}))}}visualize(){const t=[];for(const e of this.input.placed??[])t.push({center:{x:e.rect.x+e.rect.width/2,y:e.rect.y+e.rect.height/2},width:e.rect.width,height:e.rect.height,stroke:"rgba(37, 99, 235, 0.9)",fill:"rgba(191, 219, 254, 0.5)",layer:`z${e.zLayers.join(",")}`,label:`expanded\nz:${e.zLayers.join(",")}`});return{title:"RectDiff Expansion",coordinateSystem:"cartesian",rects:t,points:[],lines:[]}}},ge=class extends N{rectDiffSeedingSolver;rectDiffExpansionSolver;obstacleIndexByLayer;constructor(t){super(t);const{obstacleIndexByLayer:e}=(t=>{const{srj:e,boardVoidRects:n}=t,{layerNames:o,zIndexByName:i}=Bt(e),s=Math.max(1,o.length,e.layerCount||1),r=(e.bounds.minX,e.bounds.minY,e.bounds.maxX,e.bounds.minX,e.bounds.maxY,e.bounds.minY,Array.from({length:s},()=>new ot)),a=(t,e)=>{const n={...t,minX:t.x,minY:t.y,maxX:t.x+t.width,maxY:t.y+t.height,zLayers:[e]};r[e]?.insert(n)};if(e.outline&&e.outline.length>2)for(const t of n??[])for(let e=0;e<s;e++)a(t,e);for(const t of e.obstacles??[]){const e=Wt(t);if(!e)continue;const n=jt(t,i),o=n.filter(t=>t<0||t>=s);if(o.length)throw new Error(`RectDiff: obstacle uses z-layer indices ${o.join(",")} outside 0-${s-1}`);t.zLayers&&0!==t.zLayers.length||!n.length||(t.zLayers=n);for(const t of n)a(e,t)}return{obstacleIndexByLayer:r}})({srj:t.simpleRouteJson,boardVoidRects:t.boardVoidRects});this.obstacleIndexByLayer=e}pipelineDef=[_("rectDiffSeedingSolver",ue,t=>[{simpleRouteJson:t.inputProblem.simpleRouteJson,gridOptions:t.inputProblem.gridOptions,obstacleIndexByLayer:t.obstacleIndexByLayer,boardVoidRects:t.inputProblem.boardVoidRects}]),_("rectDiffExpansionSolver",fe,t=>{const e=t.rectDiffSeedingSolver?.getOutput();if(!e)throw new Error("RectDiffSeedingSolver did not produce output");return[{srj:t.inputProblem.simpleRouteJson,layerNames:e.layerNames??[],boardVoidRects:t.inputProblem.boardVoidRects??[],layerCount:t.inputProblem.simpleRouteJson.layerCount,bounds:e.bounds,candidates:e.candidates,consumedSeedsThisGrid:e.placed.length,totalSeedsThisGrid:e.candidates.length,placed:e.placed,edgeAnalysisDone:e.edgeAnalysisDone,gridIndex:e.gridIndex,expansionIndex:e.expansionIndex,obstacleIndexByLayer:t.obstacleIndexByLayer,options:e.options}]})];getConstructorParams(){return[this.inputProblem]}getOutput(){if(this.rectDiffExpansionSolver)return this.rectDiffExpansionSolver.getOutput();if(this.rectDiffSeedingSolver){return{meshNodes:this.rectDiffSeedingSolver.getOutput().placed.map((t,e)=>({capacityMeshNodeId:`grid-${e}`,center:{x:t.rect.x+t.rect.width/2,y:t.rect.y+t.rect.height/2},width:t.rect.width,height:t.rect.height,availableZ:t.zLayers,layer:`z${t.zLayers.join(",")}`}))}}return{meshNodes:[]}}visualize(){return this.rectDiffExpansionSolver?this.rectDiffExpansionSolver.visualize():this.rectDiffSeedingSolver?this.rectDiffSeedingSolver.visualize():{title:"RectDiff Grid Pipeline",coordinateSystem:"cartesian",rects:[],points:[],lines:[]}}};function me(t,e="RectDiff"){const n=[],o=[],i=t.bounds.minX,s=t.bounds.maxX,r=t.bounds.minY,a=t.bounds.maxY;t.outline&&t.outline.length>1?o.push({points:[...t.outline,t.outline[0]],strokeColor:"#111827",strokeWidth:.01,label:"outline"}):n.push({center:{x:(i+s)/2,y:(r+a)/2},width:s-i,height:a-r,fill:"none",stroke:"#111827",label:"board"});for(const e of t.obstacles??[])"rect"!==e.type&&"oval"!==e.type||n.push({center:{x:e.center.x,y:e.center.y},width:e.width,height:e.height,fill:"#fee2e2",stroke:"#ef4444",layer:"obstacle",label:"obstacle"});return{title:e,coordinateSystem:"cartesian",rects:n,points:[],lines:o}}var ye=class extends N{rectDiffGridSolverPipeline;gapFillSolver;boardVoidRects;pipelineDef=[_("rectDiffGridSolverPipeline",ge,t=>[{simpleRouteJson:t.inputProblem.simpleRouteJson,gridOptions:t.inputProblem.gridOptions,boardVoidRects:t.boardVoidRects}]),_("gapFillSolver",Tt,t=>[{meshNodes:t.rectDiffGridSolverPipeline?.getOutput().meshNodes??[],boardVoid:{boardVoidRects:t.boardVoidRects||[],layerCount:t.inputProblem.simpleRouteJson.layerCount||0}}])];_setup(){this.inputProblem.simpleRouteJson.outline&&(this.boardVoidRects=kt({x:this.inputProblem.simpleRouteJson.bounds.minX,y:this.inputProblem.simpleRouteJson.bounds.minY,width:this.inputProblem.simpleRouteJson.bounds.maxX-this.inputProblem.simpleRouteJson.bounds.minX,height:this.inputProblem.simpleRouteJson.bounds.maxY-this.inputProblem.simpleRouteJson.bounds.minY},this.inputProblem.simpleRouteJson.outline??[]))}getConstructorParams(){return[this.inputProblem]}getOutput(){const t=this.gapFillSolver?.getOutput();return t?{meshNodes:t.outputNodes}:this.rectDiffGridSolverPipeline?this.rectDiffGridSolverPipeline.getOutput():{meshNodes:[]}}initialVisualize(){const t=me(this.inputProblem.simpleRouteJson,"RectDiffPipeline - Initial"),e=this.rectDiffGridSolverPipeline?.getOutput().meshNodes??[];for(const n of e)t.rects.push({center:n.center,width:n.width,height:n.height,stroke:"rgba(0, 0, 0, 0.3)",fill:"rgba(100, 100, 100, 0.1)",layer:`z${n.availableZ.join(",")}`,label:[`node ${n.capacityMeshNodeId}`,`z:${n.availableZ.join(",")}`].join("\n")});return t}finalVisualize(){const t=me(this.inputProblem.simpleRouteJson,"RectDiffPipeline - Final"),{meshNodes:e}=this.getOutput(),n=new Set((this.rectDiffGridSolverPipeline?.getOutput().meshNodes??[]).map(t=>t.capacityMeshNodeId));for(const o of e){const e=!n.has(o.capacityMeshNodeId);t.rects.push({center:o.center,width:o.width,height:o.height,stroke:e?"rgba(0, 128, 0, 0.8)":"rgba(0, 0, 0, 0.3)",fill:e?"rgba(0, 200, 0, 0.3)":"rgba(100, 100, 100, 0.1)",layer:`z${o.availableZ.join(",")}`,label:[`${e?"[expanded] ":""}node ${o.capacityMeshNodeId}`,`z:${o.availableZ.join(",")}`].join("\n")})}return t}},xe=class{cacheHitsByPrefix={};cacheMissesByPrefix={};isSyncCache=!0;cacheHits=0;cacheMisses=0;cache=new Map;getCachedSolutionSync(t){const e=this.cache.get(t);if(void 0!==e){this.cacheHits++;const n=t.split(":")[0];return this.cacheHitsByPrefix[n]=(this.cacheHitsByPrefix[n]||0)+1,structuredClone(e)}{this.cacheMisses++;const e=t.split(":")[0];return void(this.cacheMissesByPrefix[e]=(this.cacheMissesByPrefix[e]||0)+1)}}async getCachedSolution(t){return this.getCachedSolutionSync(t)}setCachedSolutionSync(t,e){this.cache.set(t,structuredClone(e))}async setCachedSolution(t,e){this.setCachedSolutionSync(t,e)}clearCache(){this.cache.clear(),this.cacheHits=0,this.cacheMisses=0,this.cacheHitsByPrefix={},this.cacheMissesByPrefix={}}getAllCacheKeys(){return Array.from(this.cache.keys())}},ve="tscircuit_autorouter_cache_",be=class{isSyncCache=!0;cacheHits=0;cacheMisses=0;cacheHitsByPrefix={};cacheMissesByPrefix={};constructor(){}getKey(t){return`${ve}${t}`}getCachedSolutionSync(t){if("undefined"==typeof localStorage)return;const e=this.getKey(t);try{const n=localStorage.getItem(e);if(null!==n){const e=JSON.parse(n);this.cacheHits++;const o=t.split(":")[0];return this.cacheHitsByPrefix[o]=(this.cacheHitsByPrefix[o]||0)+1,e}{this.cacheMisses++;const e=t.split(":")[0];return void(this.cacheMissesByPrefix[e]=(this.cacheMissesByPrefix[e]||0)+1)}}catch(n){console.error(`Error getting cached solution sync for ${e}:`,n),this.cacheMisses++;const o=t.split(":")[0];return void(this.cacheMissesByPrefix[o]=(this.cacheMissesByPrefix[o]||0)+1)}}async getCachedSolution(t){return this.getCachedSolutionSync(t)}setCachedSolutionSync(t,e){if("undefined"==typeof localStorage)return;const n=this.getKey(t);try{const t=JSON.stringify(e);localStorage.setItem(n,t)}catch(t){console.error(`Error setting cached solution sync for ${n}:`,t),t instanceof DOMException&&("QuotaExceededError"===t.name||"NS_ERROR_DOM_QUOTA_REACHED"===t.name)&&console.warn(`LocalStorage quota exceeded. Failed to cache solution for ${n}. Consider clearing the cache.`)}}async setCachedSolution(t,e){this.setCachedSolutionSync(t,e)}clearCache(){if("undefined"!=typeof localStorage)try{const t=[];for(let e=0;e<localStorage.length;e++){const n=localStorage.key(e);n?.startsWith(ve)&&t.push(n)}t.forEach(t=>localStorage.removeItem(t)),console.log(`Cleared ${t.length} items from LocalStorage cache.`)}catch(t){console.error("Error clearing LocalStorage cache:",t)}finally{this.cacheHits=0,this.cacheMisses=0,this.cacheHitsByPrefix={},this.cacheMissesByPrefix={}}}getAllCacheKeys(){const t=[];for(let e=0;e<1e4;e++){const n=localStorage.key(e);if(!n)break;n.includes(ve)&&t.push(n)}return t}};function Pe(){return globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE||Ie(),globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE}function Se(){return globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE||Ie(),globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE}function Ie(){globalThis.TSCIRCUIT_AUTOROUTER_LOCAL_STORAGE_CACHE??=new be,globalThis.TSCIRCUIT_AUTOROUTER_IN_MEMORY_CACHE??=new xe}function Me(t){const e={minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2};for(const n of t.portPoints)n.x<e.minX&&(e.minX=n.x),n.x>e.maxX&&(e.maxX=n.x),n.y<e.minY&&(e.minY=n.y),n.y>e.maxY&&(e.maxY=n.y);return e}var _e=(t,e)=>t<=e?[t,e]:[e,t],Ne=t=>`${t[0]}|${t[1]}`,Ce=({portPointId:t,currentNodeId:e,inputNodes:n})=>{let o;if(t)for(const e of n){const n=e.portPoints.find(e=>e.portPointId===t);if(n?.connectionNodeIds){o=n.connectionNodeIds;break}}if(!o||2!==o.length)return[e,e];const[i,s]=o;return i&&s?_e(i,s):[e,e]},Te=1e-6,Ee=(t,e)=>Math.abs(t-e)<=Te,we=({nodeAId:t,nodeBId:e,nodeBounds:n})=>{if(t===e)return null;const o=n.get(t),i=n.get(e);if(!o||!i)return null;const s=_e(t,e),r=Ne(s);if(Ee(o.maxX,i.minX)||Ee(i.maxX,o.minX)){const n=Math.max(o.minY,i.minY),a=Math.min(o.maxY,i.maxY),c=a-n;if(c>Te){const h=Ee(o.maxX,i.minX)?o.maxX:o.minX;return{ownerNodeIds:s,ownerPairKey:r,orientation:"vertical",x1:h,y1:n,x2:h,y2:a,center:{x:h,y:(n+a)/2},length:c,nodeSideByOwnerId:Ee(o.maxX,i.minX)?{[t]:"right",[e]:"left"}:{[t]:"left",[e]:"right"}}}}if(Ee(o.maxY,i.minY)||Ee(i.maxY,o.minY)){const n=Math.max(o.minX,i.minX),a=Math.min(o.maxX,i.maxX),c=a-n;if(c>Te){const h=Ee(o.maxY,i.minY)?o.maxY:o.minY;return{ownerNodeIds:s,ownerPairKey:r,orientation:"horizontal",x1:n,y1:h,x2:a,y2:h,center:{x:(n+a)/2,y:h},length:c,nodeSideByOwnerId:Ee(o.maxY,i.minY)?{[t]:"top",[e]:"bottom"}:{[t]:"bottom",[e]:"top"}}}}return null},Re=({portPoint:t,ownerNodeIds:e,inputNodes:n})=>{for(const o of e){const e=n.find(t=>t.capacityMeshNodeId===o);if(e?._containsTarget)return!0;const i=e?.portPoints.find(e=>e.portPointId===t.portPointId);if(i?.connectionNodeIds?.some(t=>n.find(e=>e.capacityMeshNodeId===t)?._containsTarget))return!0}return!1},Oe=1e-6,Ae=class extends M{constructor(t){super(),this.input=t;for(const e of t.nodeWithPortPoints)this.mapOfNodeIdToBounds.set(e.capacityMeshNodeId,Me(e));const e=new Map;for(const n of t.nodeWithPortPoints)for(const o of n.portPoints){if(!o.portPointId)continue;const i=Ce({portPointId:o.portPointId,currentNodeId:n.capacityMeshNodeId,inputNodes:t.inputNodesWithPortPoints}),s=Ne(i),r=this.mapOfOwnerPairToPortPoints.get(s)??[];r.some(t=>t.portPointId&&t.portPointId===o.portPointId)||r.push({...o,ownerNodeIds:i,ownerPairKey:s}),this.mapOfOwnerPairToPortPoints.set(s,r),e.set(s,i)}this.mapOfOwnerPairToSharedEdge=(({ownerPairs:t,nodeBounds:e})=>{const n=new Map;for(const o of t){const[t,i]=o;if(t===i)continue;const s=we({nodeAId:t,nodeBId:i,nodeBounds:e});s&&n.set(Ne(o),s)}return n})({ownerPairs:Array.from(e.values()),nodeBounds:this.mapOfNodeIdToBounds}),this.ownerPairsToProcess=Array.from(this.mapOfOwnerPairToSharedEdge.keys()),this.ownerPairsToProcess.sort((t,e)=>{const n=this.mapOfOwnerPairToSharedEdge.get(t),o=this.mapOfOwnerPairToSharedEdge.get(e);return n.center.x-o.center.x||n.center.y-o.center.y})}getSolverName(){return"UniformPortDistributionSolver"}mapOfNodeIdToBounds=new Map;mapOfOwnerPairToPortPoints=new Map;mapOfOwnerPairToSharedEdge=new Map;ownerPairsToProcess=[];currentOwnerPairBeingProcessed=null;redistributedNodes=[];step(){if(0===this.ownerPairsToProcess.length)return this.rebuildNodes(),void(this.solved=!0);this.currentOwnerPairBeingProcessed=this.ownerPairsToProcess.shift();const t=this.currentOwnerPairBeingProcessed,e=this.mapOfOwnerPairToSharedEdge.get(t);if(!e)return;if((({sharedEdge:t,obstacles:e})=>{for(const n of e){const e=n.center.x-n.width/2,o=n.center.x+n.width/2,i=n.center.y-n.height/2,s=n.center.y+n.height/2;if("vertical"!==t.orientation){if(Math.abs(t.y1-i)<Oe||Math.abs(t.y1-s)<Oe){const n=Math.max(t.x1,e);if(Math.min(t.x2,o)-n>Oe)return!0}}else if(Math.abs(t.x1-e)<Oe||Math.abs(t.x1-o)<Oe){const e=Math.max(t.y1,i);if(Math.min(t.y2,s)-e>Oe)return!0}}return!1})({sharedEdge:e,obstacles:this.input.obstacles}))return;const n=this.mapOfOwnerPairToPortPoints.get(t)??[],o=[];for(const t of n)Re({portPoint:t,ownerNodeIds:t.ownerNodeIds,inputNodes:this.input.inputNodesWithPortPoints})||o.push(t);const i=(({sharedEdge:t,portPoints:e})=>{if(0===e.length)return[];const n=new Map;for(const t of e){const e=t.z??0,o=n.get(e)??[];o.push(t),n.set(e,o)}const o=[],i=Array.from(n.keys()).sort((t,e)=>t-e);for(const e of i){const i=n.get(e),s=i.length;i.sort((e,n)=>"horizontal"===t.orientation?e.x-n.x:e.y-n.y);for(let e=0;e<s;e++){const n=(2*e+1)/(2*s),r="horizontal"===t.orientation?t.x1+t.length*n:t.x1,a="horizontal"===t.orientation?t.y1:t.y1+t.length*n;o.push({...i[e],x:r,y:a})}}return o})({sharedEdge:e,portPoints:o});this.mapOfOwnerPairToPortPoints.set(t,i)}rebuildNodes(){const t=new Map;for(const e of this.mapOfOwnerPairToPortPoints.values())for(const n of e)n.portPointId&&t.set(n.portPointId,{x:n.x,y:n.y});this.redistributedNodes=this.input.nodeWithPortPoints.map(e=>({...e,portPoints:e.portPoints.map(e=>{if(e.portPointId&&t.has(e.portPointId)){const n=t.get(e.portPointId);return{...e,x:n.x,y:n.y}}return e})}))}getOutput=()=>this.redistributedNodes;visualize(){return(({obstacles:t,nodeWithPortPoints:e,mapOfOwnerPairToPortPoints:n,mapOfOwnerPairToSharedEdge:o,ownerPairsToProcess:i,currentOwnerPairBeingProcessed:s,mapOfNodeIdToBounds:r})=>{const a=t.map(t=>({...t,fill:"#ec000070"})),c=[],h=[],l=new Map,d=new Map,u=new Map;for(const t of e)for(const e of t.portPoints)e.portPointId&&(l.set(e.portPointId,{x:e.x,y:e.y}),d.set(e.portPointId,e.z??0));for(const t of n.values())for(const e of t)e.portPointId&&(l.set(e.portPointId,{x:e.x,y:e.y}),d.set(e.portPointId,e.z??0),u.set(e.portPointId,`${e.ownerNodeIds[0]}&${e.ownerNodeIds[1]}`));e.forEach(t=>{const e=r.get(t.capacityMeshNodeId);if(e){const n=(e.minX+e.maxX)/2,o=(e.minY+e.maxY)/2,i=e.maxX-e.minX,s=e.maxY-e.minY;a.push({center:{x:n,y:o},width:i,height:s,fill:"#00000030",label:`${t.capacityMeshNodeId}`})}t.portPoints.forEach(e=>{if(!e.portPointId)return;const n=l.get(e.portPointId),o=d.get(e.portPointId)??0,i=u.get(e.portPointId)??`${t.capacityMeshNodeId}&${t.capacityMeshNodeId}`;c.push({x:n.x,y:n.y,label:`z:${o}\no:${i}`}),t.portPoints.forEach(t=>{if(t.portPointId&&e!==t&&e.connectionName===t.connectionName){const e=l.get(t.portPointId);h.push({points:[n,e],strokeColor:"#fff822c9"})}})})});for(const t of i){const e=o.get(t);e&&h.push({points:[{x:e.x1,y:e.y1},{x:e.x2,y:e.y2}],strokeColor:"orange",strokeWidth:.01})}if(s){const t=o.get(s);t&&(h.push({points:[{x:t.x1,y:t.y1},{x:t.x2,y:t.y2}],strokeColor:"red",strokeWidth:.03}),c.push({x:t.center.x,y:t.center.y,label:t.ownerPairKey}))}for(const t of o.values())h.push({points:[{x:t.x1,y:t.y1},{x:t.x2,y:t.y2}],strokeColor:"#33b5ff80",strokeWidth:.006});return{rects:a,lines:h,points:c}})({obstacles:this.input.obstacles,nodeWithPortPoints:this.input.nodeWithPortPoints,mapOfOwnerPairToPortPoints:this.mapOfOwnerPairToPortPoints,mapOfOwnerPairToSharedEdge:this.mapOfOwnerPairToSharedEdge,ownerPairsToProcess:this.ownerPairsToProcess,currentOwnerPairBeingProcessed:this.currentOwnerPairBeingProcessed,mapOfNodeIdToBounds:this.mapOfNodeIdToBounds})}},ze=(t,e)=>{if(1===t&&1===e)return"inner1";if(t<0||t>=e)throw new Error(`Invalid z "${t}" for layer count: ${e}`);return 0===t?"top":t===e-1?"bottom":`inner${t}`},De=(t,e)=>{const n=[];if(0===t.route.length)return n;let o=[],i=t.route[0].z;for(let s=0;s<t.route.length;s++){const r=t.route[s];if(r.z!==i){const s=ze(i,e);for(const e of o)n.push({route_type:"wire",x:e.x,y:e.y,width:t.traceThickness,layer:s});if(t.vias.some(t=>Math.abs(t.x-r.x)<.001&&Math.abs(t.y-r.y)<.001)){const t=ze(i,e),o=ze(r.z,e);n.push({route_type:"via",x:r.x,y:r.y,from_layer:t,to_layer:o})}o=[r],i=r.z}else o.push(r)}const s=ze(i,e);for(const e of o)n.push({route_type:"wire",x:e.x,y:e.y,width:t.traceThickness,layer:s});if(t.jumpers&&t.jumpers.length>0){const o=ze(t.route[0]?.z??0,e);for(const e of t.jumpers)n.push({route_type:"jumper",start:e.start,end:e.end,footprint:e.footprint,layer:o})}return n};function Le(){return Le=Object.assign?Object.assign.bind():function(t){for(var e=1;e<arguments.length;e++){var n=arguments[e];for(var o in n)({}).hasOwnProperty.call(n,o)&&(t[o]=n[o])}return t},Le.apply(null,arguments)}function Ye(t,e){return(Ye=Object.setPrototypeOf?Object.setPrototypeOf.bind():function(t,e){return t.__proto__=e,t})(t,e)}function Xe(t){return(Xe=Object.setPrototypeOf?Object.getPrototypeOf.bind():function(t){return t.__proto__||Object.getPrototypeOf(t)})(t)}function Fe(){try{var t=!Boolean.prototype.valueOf.call(Reflect.construct(Boolean,[],function(){}))}catch(t){}return(Fe=function(){return!!t})()}function ke(t){var e="function"==typeof Map?new Map:void 0;return ke=function(t){if(null===t||!function(t){try{return-1!==Function.toString.call(t).indexOf("[native code]")}catch(e){return"function"==typeof t}}(t))return t;if("function"!=typeof t)throw new TypeError("Super expression must either be null or a function");if(void 0!==e){if(e.has(t))return e.get(t);e.set(t,n)}function n(){return function(t,e,n){if(Fe())return Reflect.construct.apply(null,arguments);var o=[null];o.push.apply(o,e);var i=new(t.bind.apply(t,o));return n&&Ye(i,n.prototype),i}(t,arguments,Xe(this).constructor)}return n.prototype=Object.create(t.prototype,{constructor:{value:n,enumerable:!1,writable:!0,configurable:!0}}),Ye(n,t)},ke(t)}var $e={1:"Passed invalid arguments to hsl, please pass multiple numbers e.g. hsl(360, 0.75, 0.4) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75 }).\n\n",2:"Passed invalid arguments to hsla, please pass multiple numbers e.g. hsla(360, 0.75, 0.4, 0.7) or an object e.g. rgb({ hue: 255, saturation: 0.4, lightness: 0.75, alpha: 0.7 }).\n\n",3:"Passed an incorrect argument to a color function, please pass a string representation of a color.\n\n",4:"Couldn't generate valid rgb string from %s, it returned %s.\n\n",5:"Couldn't parse the color string. Please provide the color as a string in hex, rgb, rgba, hsl or hsla notation.\n\n",6:"Passed invalid arguments to rgb, please pass multiple numbers e.g. rgb(255, 205, 100) or an object e.g. rgb({ red: 255, green: 205, blue: 100 }).\n\n",7:"Passed invalid arguments to rgba, please pass multiple numbers e.g. rgb(255, 205, 100, 0.75) or an object e.g. rgb({ red: 255, green: 205, blue: 100, alpha: 0.75 }).\n\n",8:"Passed invalid argument to toColorString, please pass a RgbColor, RgbaColor, HslColor or HslaColor object.\n\n",9:"Please provide a number of steps to the modularScale helper.\n\n",10:"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\n\n",11:'Invalid value passed as base to modularScale, expected number or em string but got "%s"\n\n',12:'Expected a string ending in "px" or a number passed as the first argument to %s(), got "%s" instead.\n\n',13:'Expected a string ending in "px" or a number passed as the second argument to %s(), got "%s" instead.\n\n',14:'Passed invalid pixel value ("%s") to %s(), please pass a value like "12px" or 12.\n\n',15:'Passed invalid base value ("%s") to %s(), please pass a value like "12px" or 12.\n\n',16:"You must provide a template to this method.\n\n",17:"You passed an unsupported selector state to this method.\n\n",18:"minScreen and maxScreen must be provided as stringified numbers with the same units.\n\n",19:"fromSize and toSize must be provided as stringified numbers with the same units.\n\n",20:"expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\n\n",21:"expects the objects in the first argument array to have the properties `prop`, `fromSize`, and `toSize`.\n\n",22:"expects the first argument object to have the properties `prop`, `fromSize`, and `toSize`.\n\n",23:"fontFace expects a name of a font-family.\n\n",24:"fontFace expects either the path to the font file(s) or a name of a local copy.\n\n",25:"fontFace expects localFonts to be an array.\n\n",26:"fontFace expects fileFormats to be an array.\n\n",27:"radialGradient requries at least 2 color-stops to properly render.\n\n",28:"Please supply a filename to retinaImage() as the first argument.\n\n",29:"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\n\n",30:"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n",31:"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation\n\n",32:"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s')\n\n",33:"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation\n\n",34:"borderRadius expects a radius value as a string or number as the second argument.\n\n",35:'borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.\n\n',36:"Property must be a string value.\n\n",37:"Syntax Error at %s.\n\n",38:"Formula contains a function that needs parentheses at %s.\n\n",39:"Formula is missing closing parenthesis at %s.\n\n",40:"Formula has too many closing parentheses at %s.\n\n",41:"All values in a formula must have the same unit or be unitless.\n\n",42:"Please provide a number of steps to the modularScale helper.\n\n",43:"Please pass a number or one of the predefined scales to the modularScale helper as the ratio.\n\n",44:"Invalid value passed as base to modularScale, expected number or em/rem string but got %s.\n\n",45:"Passed invalid argument to hslToColorString, please pass a HslColor or HslaColor object.\n\n",46:"Passed invalid argument to rgbToColorString, please pass a RgbColor or RgbaColor object.\n\n",47:"minScreen and maxScreen must be provided as stringified numbers with the same units.\n\n",48:"fromSize and toSize must be provided as stringified numbers with the same units.\n\n",49:"Expects either an array of objects or a single object with the properties prop, fromSize, and toSize.\n\n",50:"Expects the objects in the first argument array to have the properties prop, fromSize, and toSize.\n\n",51:"Expects the first argument object to have the properties prop, fromSize, and toSize.\n\n",52:"fontFace expects either the path to the font file(s) or a name of a local copy.\n\n",53:"fontFace expects localFonts to be an array.\n\n",54:"fontFace expects fileFormats to be an array.\n\n",55:"fontFace expects a name of a font-family.\n\n",56:"linearGradient requries at least 2 color-stops to properly render.\n\n",57:"radialGradient requries at least 2 color-stops to properly render.\n\n",58:"Please supply a filename to retinaImage() as the first argument.\n\n",59:"Passed invalid argument to triangle, please pass correct pointingDirection e.g. 'right'.\n\n",60:"Passed an invalid value to `height` or `width`. Please provide a pixel based unit.\n\n",61:"Property must be a string value.\n\n",62:"borderRadius expects a radius value as a string or number as the second argument.\n\n",63:'borderRadius expects one of "top", "bottom", "left" or "right" as the first argument.\n\n',64:"The animation shorthand only takes 8 arguments. See the specification for more information: http://mdn.io/animation.\n\n",65:"To pass multiple animations please supply them in arrays, e.g. animation(['rotate', '2s'], ['move', '1s'])\\nTo pass a single animation please supply them in simple values, e.g. animation('rotate', '2s').\n\n",66:"The animation shorthand arrays can only have 8 elements. See the specification for more information: http://mdn.io/animation.\n\n",67:"You must provide a template to this method.\n\n",68:"You passed an unsupported selector state to this method.\n\n",69:'Expected a string ending in "px" or a number passed as the first argument to %s(), got %s instead.\n\n',70:'Expected a string ending in "px" or a number passed as the second argument to %s(), got %s instead.\n\n',71:'Passed invalid pixel value %s to %s(), please pass a value like "12px" or 12.\n\n',72:'Passed invalid base value %s to %s(), please pass a value like "12px" or 12.\n\n',73:"Please provide a valid CSS variable.\n\n",74:"CSS variable not found and no default was provided.\n\n",75:"important requires a valid style object, got a %s instead.\n\n",76:"fromSize and toSize must be provided as stringified numbers with the same units as minScreen and maxScreen.\n\n",77:'remToPx expects a value in "rem" but you provided it in "%s".\n\n',78:'base must be set in "px" or "%" but you set it in "%s".\n'};function Be(){for(var t=arguments.length,e=new Array(t),n=0;n<t;n++)e[n]=arguments[n];var o,i=e[0],s=[];for(o=1;o<e.length;o+=1)s.push(e[o]);return s.forEach(function(t){i=i.replace(/%[a-z]/,t)}),i}var je=function(t){var e,n;function o(e){var n;if("production"===process.env.NODE_ENV)n=t.call(this,"An error occurred. See https://github.com/styled-components/polished/blob/main/src/internalHelpers/errors.md#"+e+" for more information.")||this;else{for(var o=arguments.length,i=new Array(o>1?o-1:0),s=1;s<o;s++)i[s-1]=arguments[s];n=t.call(this,Be.apply(void 0,[$e[e]].concat(i)))||this}return function(t){if(void 0===t)throw new ReferenceError("this hasn't been initialised - super() hasn't been called");return t}(n)}return n=t,(e=o).prototype=Object.create(n.prototype),e.prototype.constructor=e,Ye(e,n),o}(ke(Error));function We(t,e){return t.substr(-e.length)===e}var Ve=/^([+-]?(?:\d+|\d*\.\d+))([a-z]*|%)$/;function He(t){return"string"!=typeof t?t:t.match(Ve)?parseFloat(t):t}var Ue=function(t){return function(e,n){void 0===n&&(n="16px");var o=e,i=n;if("string"==typeof e){if(!We(e,"px"))throw new je(69,t,e);o=He(e)}if("string"==typeof n){if(!We(n,"px"))throw new je(70,t,n);i=He(n)}if("string"==typeof o)throw new je(71,e,t);if("string"==typeof i)throw new je(72,n,t);return""+o/i+t}};Ue("em"),Ue("rem");function Ge(t){return Math.round(255*t)}function Ze(t,e,n){return Ge(t)+","+Ge(e)+","+Ge(n)}function qe(t,e,n,o){if(void 0===o&&(o=Ze),0===e)return o(n,n,n);var i=(t%360+360)%360/60,s=(1-Math.abs(2*n-1))*e,r=s*(1-Math.abs(i%2-1)),a=0,c=0,h=0;i>=0&&i<1?(a=s,c=r):i>=1&&i<2?(a=r,c=s):i>=2&&i<3?(c=s,h=r):i>=3&&i<4?(c=r,h=s):i>=4&&i<5?(a=r,h=s):i>=5&&i<6&&(a=s,h=r);var l=n-s/2;return o(a+l,c+l,h+l)}var Je={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"00ffff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"0000ff",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"00ffff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"ff00ff",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"639",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"};var Ke=/^#[a-fA-F0-9]{6}$/,Qe=/^#[a-fA-F0-9]{8}$/,tn=/^#[a-fA-F0-9]{3}$/,en=/^#[a-fA-F0-9]{4}$/,nn=/^rgb\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*\)$/i,on=/^rgb(?:a)?\(\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,)?\s*(\d{1,3})\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i,sn=/^hsl\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*\)$/i,rn=/^hsl(?:a)?\(\s*(\d{0,3}[.]?[0-9]+(?:deg)?)\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,)?\s*(\d{1,3}[.]?[0-9]?)%\s*(?:,|\/)\s*([-+]?\d*[.]?\d+[%]?)\s*\)$/i;function an(t){if("string"!=typeof t)throw new je(3);var e=function(t){if("string"!=typeof t)return t;var e=t.toLowerCase();return Je[e]?"#"+Je[e]:t}(t);if(e.match(Ke))return{red:parseInt(""+e[1]+e[2],16),green:parseInt(""+e[3]+e[4],16),blue:parseInt(""+e[5]+e[6],16)};if(e.match(Qe)){var n=parseFloat((parseInt(""+e[7]+e[8],16)/255).toFixed(2));return{red:parseInt(""+e[1]+e[2],16),green:parseInt(""+e[3]+e[4],16),blue:parseInt(""+e[5]+e[6],16),alpha:n}}if(e.match(tn))return{red:parseInt(""+e[1]+e[1],16),green:parseInt(""+e[2]+e[2],16),blue:parseInt(""+e[3]+e[3],16)};if(e.match(en)){var o=parseFloat((parseInt(""+e[4]+e[4],16)/255).toFixed(2));return{red:parseInt(""+e[1]+e[1],16),green:parseInt(""+e[2]+e[2],16),blue:parseInt(""+e[3]+e[3],16),alpha:o}}var i=nn.exec(e);if(i)return{red:parseInt(""+i[1],10),green:parseInt(""+i[2],10),blue:parseInt(""+i[3],10)};var s=on.exec(e.substring(0,50));if(s)return{red:parseInt(""+s[1],10),green:parseInt(""+s[2],10),blue:parseInt(""+s[3],10),alpha:parseFloat(""+s[4])>1?parseFloat(""+s[4])/100:parseFloat(""+s[4])};var r=sn.exec(e);if(r){var a="rgb("+qe(parseInt(""+r[1],10),parseInt(""+r[2],10)/100,parseInt(""+r[3],10)/100)+")",c=nn.exec(a);if(!c)throw new je(4,e,a);return{red:parseInt(""+c[1],10),green:parseInt(""+c[2],10),blue:parseInt(""+c[3],10)}}var h=rn.exec(e.substring(0,50));if(h){var l="rgb("+qe(parseInt(""+h[1],10),parseInt(""+h[2],10)/100,parseInt(""+h[3],10)/100)+")",d=nn.exec(l);if(!d)throw new je(4,e,l);return{red:parseInt(""+d[1],10),green:parseInt(""+d[2],10),blue:parseInt(""+d[3],10),alpha:parseFloat(""+h[4])>1?parseFloat(""+h[4])/100:parseFloat(""+h[4])}}throw new je(5)}function cn(t){return function(t){var e,n=t.red/255,o=t.green/255,i=t.blue/255,s=Math.max(n,o,i),r=Math.min(n,o,i),a=(s+r)/2;if(s===r)return void 0!==t.alpha?{hue:0,saturation:0,lightness:a,alpha:t.alpha}:{hue:0,saturation:0,lightness:a};var c=s-r,h=a>.5?c/(2-s-r):c/(s+r);switch(s){case n:e=(o-i)/c+(o<i?6:0);break;case o:e=(i-n)/c+2;break;default:e=(n-o)/c+4}return e*=60,void 0!==t.alpha?{hue:e,saturation:h,lightness:a,alpha:t.alpha}:{hue:e,saturation:h,lightness:a}}(an(t))}var hn=function(t){return 7===t.length&&t[1]===t[2]&&t[3]===t[4]&&t[5]===t[6]?"#"+t[1]+t[3]+t[5]:t};function ln(t){var e=t.toString(16);return 1===e.length?"0"+e:e}function dn(t){return ln(Math.round(255*t))}function un(t,e,n){return hn("#"+dn(t)+dn(e)+dn(n))}function pn(t,e,n){return qe(t,e,n,un)}function fn(t,e,n){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n)return hn("#"+ln(t)+ln(e)+ln(n));if("object"==typeof t&&void 0===e&&void 0===n)return hn("#"+ln(t.red)+ln(t.green)+ln(t.blue));throw new je(6)}function gn(t,e,n,o){if("string"==typeof t&&"number"==typeof e){var i=an(t);return"rgba("+i.red+","+i.green+","+i.blue+","+e+")"}if("number"==typeof t&&"number"==typeof e&&"number"==typeof n&&"number"==typeof o)return o>=1?fn(t,e,n):"rgba("+t+","+e+","+n+","+o+")";if("object"==typeof t&&void 0===e&&void 0===n&&void 0===o)return t.alpha>=1?fn(t.red,t.green,t.blue):"rgba("+t.red+","+t.green+","+t.blue+","+t.alpha+")";throw new je(7)}function mn(t){if("object"!=typeof t)throw new je(8);if(function(t){return"number"==typeof t.red&&"number"==typeof t.green&&"number"==typeof t.blue&&"number"==typeof t.alpha}(t))return gn(t);if(function(t){return"number"==typeof t.red&&"number"==typeof t.green&&"number"==typeof t.blue&&("number"!=typeof t.alpha||void 0===t.alpha)}(t))return fn(t);if(function(t){return"number"==typeof t.hue&&"number"==typeof t.saturation&&"number"==typeof t.lightness&&"number"==typeof t.alpha}(t))return function(t,e,n,o){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n&&"number"==typeof o)return o>=1?pn(t,e,n):"rgba("+qe(t,e,n)+","+o+")";if("object"==typeof t&&void 0===e&&void 0===n&&void 0===o)return t.alpha>=1?pn(t.hue,t.saturation,t.lightness):"rgba("+qe(t.hue,t.saturation,t.lightness)+","+t.alpha+")";throw new je(2)}(t);if(function(t){return"number"==typeof t.hue&&"number"==typeof t.saturation&&"number"==typeof t.lightness&&("number"!=typeof t.alpha||void 0===t.alpha)}(t))return function(t,e,n){if("number"==typeof t&&"number"==typeof e&&"number"==typeof n)return pn(t,e,n);if("object"==typeof t&&void 0===e&&void 0===n)return pn(t.hue,t.saturation,t.lightness);throw new je(1)}(t);throw new je(8)}function yn(t,e,n){return function(){var o=n.concat(Array.prototype.slice.call(arguments));return o.length>=e?t.apply(this,o):yn(t,e,o)}}function xn(t){return yn(t,t.length,[])}xn(function(t,e){if("transparent"===e)return e;var n=cn(e);return mn(Le({},n,{hue:n.hue+parseFloat(t)}))});function vn(t,e,n){return Math.max(t,Math.min(e,n))}xn(function(t,e){if("transparent"===e)return e;var n=cn(e);return mn(Le({},n,{lightness:vn(0,1,n.lightness-parseFloat(t))}))});xn(function(t,e){if("transparent"===e)return e;var n=cn(e);return mn(Le({},n,{saturation:vn(0,1,n.saturation-parseFloat(t))}))});xn(function(t,e){if("transparent"===e)return e;var n=cn(e);return mn(Le({},n,{lightness:vn(0,1,n.lightness+parseFloat(t))}))});var bn=xn(function(t,e,n){if("transparent"===e)return n;if("transparent"===n)return e;if(0===t)return n;var o=an(e),i=Le({},o,{alpha:"number"==typeof o.alpha?o.alpha:1}),s=an(n),r=Le({},s,{alpha:"number"==typeof s.alpha?s.alpha:1}),a=i.alpha-r.alpha,c=2*parseFloat(t)-1,h=((c*a===-1?c:c+a)/(1+c*a)+1)/2,l=1-h;return gn({red:Math.floor(i.red*h+r.red*l),green:Math.floor(i.green*h+r.green*l),blue:Math.floor(i.blue*h+r.blue*l),alpha:i.alpha*parseFloat(t)+r.alpha*(1-parseFloat(t))})});xn(function(t,e){if("transparent"===e)return e;var n=an(e);return gn(Le({},n,{alpha:vn(0,1,(100*("number"==typeof n.alpha?n.alpha:1)+100*parseFloat(t))/100)}))});xn(function(t,e){if("transparent"===e)return e;var n=cn(e);return mn(Le({},n,{saturation:vn(0,1,n.saturation+parseFloat(t))}))});xn(function(t,e){return"transparent"===e?e:mn(Le({},cn(e),{hue:parseFloat(t)}))});xn(function(t,e){return"transparent"===e?e:mn(Le({},cn(e),{lightness:parseFloat(t)}))});xn(function(t,e){return"transparent"===e?e:mn(Le({},cn(e),{saturation:parseFloat(t)}))});xn(function(t,e){return"transparent"===e?e:bn(parseFloat(t),"rgb(0, 0, 0)",e)});xn(function(t,e){return"transparent"===e?e:bn(parseFloat(t),"rgb(255, 255, 255)",e)});var Pn=xn(function(t,e){if("transparent"===e)return e;var n=an(e);return gn(Le({},n,{alpha:vn(0,1,+(100*("number"==typeof n.alpha?n.alpha:1)-100*parseFloat(t)).toFixed(2)/100)}))}),Sn=["blue","orange","purple","cyan","magenta","yellowgreen","darkgoldenrod","deeppink"],In=(t,e)=>{const n={};for(let o=0;o<t.connections.length;o++){const i=t.connections[o],s=e?.getNetConnectedToId(i.name);s&&!n[s]&&(n[s]=`hsl(${300*o/t.connections.length}, 100%, 50%)`),n[i.name]=(s?n[s]:null)??`hsl(${340*o/t.connections.length}, 100%, 50%)`}return n},Mn=(t,e)=>{try{return Pn(e,t)}catch(e){return console.error(e),t}},_n=(t,e=1)=>{if(!t)return"rgba(0, 0, 0, 0.5)";const n=300*t.split("").reduce((t,e)=>t+e.charCodeAt(0),0)/t.length;return e<1?`hsla(${n}, 100%, 50%, ${e})`:`hsl(${n}, 100%, 50%)`};function Nn(t){return"layers"in t&&Array.isArray(t.layers)}function Cn(t){return Nn(t)?t.layers[0]:t.layer}function Tn(t){return Nn(t)?t.layers:[t.layer]}var En={"0603":{length:1.65,width:.95,padLength:.8,padWidth:.95},1206:{length:3.2,width:1.6,padLength:.6,padWidth:1.6},"1206x4_pair":{length:2.7,width:.5,padLength:.8,padWidth:.5}},wn=(t,e)=>"top"===t?0:"bottom"===t?e-1:parseInt(t.slice(5)),Rn=t=>{const e=[],n=[],o=[],i=[],s=In(t),r=(t.minViaDiameter??.3)/2;if(t.connections)for(const e of t.connections)for(const t of e.pointsToConnect){const n=Tn(t);o.push({x:t.x,y:t.y,color:s[e.name],layer:n[0]??("z"in t?ze(t.z,2):"top"),label:`${e.name} (${n.join(",")})`})}if(t.traces)for(const o of t.traces){let a=t.minTraceWidth;const c=o.route.filter(t=>"jumper"===t.route_type),h=(t,e)=>{const n=.01;for(const o of c){const i=Math.abs(t.x-o.start.x)<n&&Math.abs(t.y-o.start.y)<n&&Math.abs(e.x-o.end.x)<n&&Math.abs(e.y-o.end.y)<n,s=Math.abs(t.x-o.end.x)<n&&Math.abs(t.y-o.end.y)<n&&Math.abs(e.x-o.start.x)<n&&Math.abs(e.y-o.start.y)<n;if(i||s)return!0}return!1};for(let t=0;t<o.route.length-1;t++){const c=o.route[t],l=o.route[t+1];if("via"===c.route_type)n.push({center:{x:c.x,y:c.y},radius:r,fill:"blue",stroke:"none",layer:"z0,1"});else if("jumper"===c.route_type){const t=s[o.connection_name]??"rgba(255, 165, 0, 0.8)",n=c.footprint,r=En["1206x4_pair"===n?"1206x4_pair":"0603"]??En["0603"],a=c.end.x-c.start.x,h=c.end.y-c.start.y,l=Math.abs(a)>Math.abs(h),d=l?r.padLength:r.padWidth,u=l?r.padWidth:r.padLength;i.push({center:c.start,width:d,height:u,fill:Mn(t,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),i.push({center:c.end,width:d,height:u,fill:Mn(t,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),e.push({points:[c.start,c.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*r.padWidth,layer:"jumper-body"})}else if("wire"===c.route_type&&"wire"===l.route_type&&l.layer===c.layer){if(h({x:c.x,y:c.y},{x:l.x,y:l.y}))continue;a=c.width;const t=s[o.connection_name],n="top"===c.layer,i=t??{top:"red",bottom:"blue",inner1:"green",inner2:"yellow"}[c.layer];e.push({points:[{x:c.x,y:c.y},{x:l.x,y:l.y}],layer:`z${wn(c.layer,2)}`,strokeWidth:a,strokeColor:n?i:Mn(i,.5),...n?{}:{strokeDash:"3 2"}})}}}for(const e of t.obstacles)i.push({center:e.center,width:e.width,height:e.height,fill:"rgba(255,0,0,0.5)",layer:`z${e.layers.map(t=>wn(t,2)).join(",")}`});if(t.jumpers)for(const e of t.jumpers)for(const t of e.pads)i.push({center:t.center,width:t.width,height:t.height,fill:"rgba(255, 165, 0, 0.3)",stroke:"rgba(255, 165, 0, 0.8)",layer:"jumper"});return{rects:i,circles:n,lines:e,points:o}},On=class{netMap;idToNetMap;constructor(t){this.netMap=t,this.idToNetMap={};for(const[e,n]of Object.entries(t))for(const t of n)this.idToNetMap[t]=e}addConnections(t){for(const e of t){const t=new Set;for(const n of e){const e=this.idToNetMap[n];e&&t.add(e)}let n;if(0===t.size)n=`connectivity_net${Object.keys(this.netMap).length}`,this.netMap[n]=[];else if(1===t.size)n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;else{n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;for(const e of t)if(e!==n){this.netMap[n].push(...this.netMap[e]),this.netMap[e]=this.netMap[n];for(const t of this.netMap[n])this.idToNetMap[t]=n}}for(const t of e)this.netMap[n].includes(t)||this.netMap[n].push(t),this.idToNetMap[t]=n}}getIdsConnectedToNet(t){return this.netMap[t]||[]}getNetConnectedToId(t){return this.idToNetMap[t]}areIdsConnected(t,e){if(t===e)return!0;const n=this.getNetConnectedToId(t);if(!n)return!1;const o=this.getNetConnectedToId(e);return!!o&&(n===o||o===t||o===t)}areAllIdsConnected(t){const e=this.getNetConnectedToId(t[0]);for(const n of t){const t=this.getNetConnectedToId(n);if(void 0===t)return!1;if(t!==e)return!1}return!0}},An=t=>`${Math.round(100*t.x)},${Math.round(100*t.y)}`,zn=t=>{const e=new On({});for(const n of t.connections){if(n.rootConnectionName&&e.addConnections([[n.name,n.rootConnectionName]]),n.netConnectionName&&e.addConnections([[n.name,n.netConnectionName]]),n.mergedConnectionNames)for(const t of n.mergedConnectionNames)e.addConnections([[n.name,t]]);for(const o of n.pointsToConnect)e.addConnections([[n.name,`${An(o)}:${"layers"in o?o.layers.map(e=>wn(e,t.layerCount)).sort().join("-"):wn(o.layer,t.layerCount)}`]]),"pcb_port_id"in o&&o.pcb_port_id&&e.addConnections([[n.name,o.pcb_port_id]])}for(const n of t.obstacles){const o=n.offBoardConnectsTo??[],i=Array.from(new Set([n.obstacleId,...n.connectedTo,...o,`${An(n.center)}:${n.layers.map(e=>wn(e,t.layerCount)).sort().join("-")}`].filter(Boolean)));i.length>0&&e.addConnections([i])}return e},Dn=class{MAX_ITERATIONS=1e3;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};cacheHit;cacheKey;cacheToSolveSpaceTransform;getSolverName(){return this.constructor.name}step(){if(!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,console.error(this.error),this.failed=!0,t}!this.solved&&this.iterations>this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations (MAX_ITERATIONS=${this.MAX_ITERATIONS})`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function Ln(t){const e=new Map;for(const n of t)for(const t of n.nodeIds)e.set(t,[...e.get(t)??[],n]);return e}var Yn=class extends Dn{getSolverName(){return"AvailableSegmentPointSolver"}nodes;edges;traceWidth;obstacleMargin;minPortSpacing;nodeMap;nodeEdgeMap;sharedEdgeSegments=[];edgeSegmentMap=new Map;portPointMap=new Map;colorMap;shouldReturnCrampedPortPoints;constructor({nodes:t,edges:e,traceWidth:n,obstacleMargin:o,colorMap:i,shouldReturnCrampedPortPoints:s}){super(),this.nodes=t,this.edges=e,this.traceWidth=n,this.obstacleMargin=o??.15,this.shouldReturnCrampedPortPoints=s,this.minPortSpacing=this.traceWidth+this.obstacleMargin,this.colorMap=i??{},this.nodeMap=new Map(t.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Ln(e),this.MAX_ITERATIONS=1}_step(){this.computeAllSharedEdgeSegments(),this.solved=!0}computeAllSharedEdgeSegments(){for(const t of this.edges){const[e,n]=t.nodeIds,o=this.nodeMap.get(e),i=this.nodeMap.get(n);if(!o||!i)continue;const s=this.computeSharedEdgeSegment(t,o,i);if(s){this.sharedEdgeSegments.push(s),this.edgeSegmentMap.set(t.capacityMeshEdgeId,s);for(const t of s.portPoints)this.portPointMap.set(t.segmentPortPointId,t)}}}computeSharedEdgeSegment(t,e,n){const o=this.findOverlappingSegment(e,n);if(!o)return null;const i=e.availableZ.filter(t=>n.availableZ.includes(t));if(0===i.length)return null;const s=Math.sqrt((o.end.x-o.start.x)**2+(o.end.y-o.start.y)**2),r=3*this.minPortSpacing/4,a=Math.max(0,s-2*r);if(a<=0&&!e._containsTarget&&!n._containsTarget){if(!this.shouldReturnCrampedPortPoints)return null;const s=[];for(const r of i)s.push({segmentPortPointId:`${t.capacityMeshEdgeId}_pp0_z${r}_cramped`,x:(o.start.x+o.end.x)/2,y:(o.start.y+o.end.y)/2,availableZ:[r],nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],edgeId:t.capacityMeshEdgeId,connectionName:null,distToCentermostPortOnZ:0,cramped:!0});return{edgeId:t.capacityMeshEdgeId,nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],start:o.start,end:o.end,availableZ:i,portPoints:s}}let c=Math.max(1,Math.floor(a/this.minPortSpacing)+1);if(e._offBoardConnectionId||n._offBoardConnectionId){if(e._offBoardConnectionId&&!n._offBoardConnectionId){if(this.shouldSkipOffBoardPortPoint(e,n))return null}else if(n._offBoardConnectionId&&!e._offBoardConnectionId&&this.shouldSkipOffBoardPortPoint(n,e))return null;c=1}const h=[],l=o.end.x-o.start.x,d=o.end.y-o.start.y,u=(o.start.x+o.end.x)/2,p=(o.start.y+o.end.y)/2;c>5&&(c=5+Math.floor(c/4));const f=[];for(let t=0;t<c;t++){let e;e=0===s||1===c?.5:(r+a*t/(c-1))/s;const n=o.start.x+l*e,i=o.start.y+d*e,h=Math.sqrt((n-u)**2+(i-p)**2);f.push({x:n,y:i,distToCenter:h})}const g=f.reduce((t,e)=>e.distToCenter<t.distToCenter?e:t);for(let o=0;o<c;o++){const{x:s,y:r}=f[o],a=Math.sqrt((s-g.x)**2+(r-g.y)**2);for(const c of i){const i={segmentPortPointId:`${t.capacityMeshEdgeId}_pp${o}_z${c}`,x:s,y:r,availableZ:[c],nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],edgeId:t.capacityMeshEdgeId,connectionName:null,distToCentermostPortOnZ:a,cramped:!1};h.push(i)}}return{edgeId:t.capacityMeshEdgeId,nodeIds:[e.capacityMeshNodeId,n.capacityMeshNodeId],start:o.start,end:o.end,availableZ:i,portPoints:h}}shouldSkipOffBoardPortPoint(t,e){const n=this.nodeEdgeMap.get(e.capacityMeshNodeId)??[];for(const o of n){const n=o.nodeIds[0]===e.capacityMeshNodeId?o.nodeIds[1]:o.nodeIds[0];if(n===t.capacityMeshNodeId)continue;const i=this.nodeMap.get(n);if(i?._offBoardConnectionId!==t._offBoardConnectionId)continue;if(2!==this.nodes.filter(e=>e._offBoardConnectionId===t._offBoardConnectionId).length)continue;const s={x:(t.center.x+i.center.x)/2,y:(t.center.y+i.center.y)/2};if(s.x>=e.center.x-e.width/2&&s.x<=e.center.x+e.width/2&&s.y>=e.center.y-e.height/2&&s.y<=e.center.y+e.height/2)return!0}return!1}findOverlappingSegment(t,e){const n={start:Math.max(t.center.x-t.width/2,e.center.x-e.width/2),end:Math.min(t.center.x+t.width/2,e.center.x+e.width/2)},o={start:Math.max(t.center.y-t.height/2,e.center.y-e.height/2),end:Math.min(t.center.y+t.height/2,e.center.y+e.height/2)},i=n.end-n.start,s=o.end-o.start;if(i<-1e-4||s<-1e-4)return null;if(i<s){const t=(n.start+n.end)/2;return{start:{x:t,y:o.start},end:{x:t,y:o.end}}}{const t=(o.start+o.end)/2;return{start:{x:n.start,y:t},end:{x:n.end,y:t}}}}getAvailablePortPointsBetweenNodes(t,e){const n=this.edges.find(n=>n.nodeIds[0]===t&&n.nodeIds[1]===e||n.nodeIds[0]===e&&n.nodeIds[1]===t);if(!n)return[];const o=this.edgeSegmentMap.get(n.capacityMeshEdgeId);return o?o.portPoints.filter(t=>null===t.connectionName):[]}getPortPointsForEdge(t,e){const n=this.edges.find(n=>n.nodeIds[0]===t&&n.nodeIds[1]===e||n.nodeIds[0]===e&&n.nodeIds[1]===t);if(!n)return[];const o=this.edgeSegmentMap.get(n.capacityMeshEdgeId);return o?.portPoints??[]}assignPortPoint(t,e,n){const o=this.portPointMap.get(t);return!!o&&(null===o.connectionName&&(o.connectionName=e,o.rootConnectionName=n,!0))}releasePortPoint(t){const e=this.portPointMap.get(t);return!!e&&(e.connectionName=null,e.rootConnectionName=void 0,!0)}getAvailablePortCountForEdge(t,e){return this.getAvailablePortPointsBetweenNodes(t,e).length}getOutput(){return this.sharedEdgeSegments}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.sharedEdgeSegments){t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.5)"});for(const n of e.portPoints){const e=n.connectionName?this.colorMap[n.connectionName]??"blue":"rgba(0, 200, 0, 0.7)";n.cramped?t.rects.push({center:{x:n.x,y:n.y},width:.1,height:.1,fill:e,layer:`z${n.availableZ.join(",")}`,label:`cramped ${n.segmentPortPointId}`}):t.circles.push({center:{x:n.x,y:n.y},radius:this.traceWidth/2,fill:e,layer:`z${n.availableZ.join(",")}`,label:[n.segmentPortPointId,n.connectionName,n.availableZ.join(","),`cd: ${n.distToCentermostPortOnZ}`,`connects: ${n.nodeIds.join(",")}`].filter(Boolean).join("\n")})}}return t}};function Xn(t,e){const n=t.center.x-t.width/2,o=t.center.x+t.width/2,i=t.center.y-t.height/2,s=t.center.y+t.height/2,r=e.center.x-e.width/2,a=e.center.x+e.width/2,c=e.center.y-e.height/2,h=e.center.y+e.height/2,l=.001,d=(Math.abs(o-r)<l||Math.abs(n-a)<l)&&Math.min(s,h)-Math.max(i,c)>=l,u=(Math.abs(s-c)<l||Math.abs(i-h)<l)&&Math.min(o,a)-Math.max(n,r)>=l;return d||u}var Fn=class extends Dn{constructor(t){super(),this.nodes=t,this.edges=[]}getSolverName(){return"CapacityMeshEdgeSolver"}edges;nodeMap;getNextCapacityMeshEdgeId(){return`ce${this.edges.length}`}_step(){this.edges=[];for(let t=0;t<this.nodes.length;t++)for(let e=t+1;e<this.nodes.length;e++){!(this.nodes[t]._strawNode&&this.nodes[e]._strawNode&&this.nodes[t]._strawParentCapacityMeshNodeId===this.nodes[e]._strawParentCapacityMeshNodeId)&&Xn(this.nodes[t],this.nodes[e])&&this.doNodesHaveSharedLayer(this.nodes[t],this.nodes[e])&&this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[this.nodes[t].capacityMeshNodeId,this.nodes[e].capacityMeshNodeId]})}this.handleTargetNodes(),this.solved=!0}handleTargetNodes(){const t=this.nodes.filter(t=>t._containsTarget);for(const e of t){if(this.edges.some(t=>t.nodeIds.includes(e.capacityMeshNodeId)))continue;let t=null,n=1/0;for(const o of this.nodes){if(o._containsObstacle)continue;if(o._containsTarget)continue;const i=F(e.center,o.center);i<n&&(n=i,t=o)}t&&this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[e.capacityMeshNodeId,t.capacityMeshNodeId]})}}doNodesHaveSharedLayer(t,e){return t.availableZ.some(t=>e.availableZ.includes(t))}visualize(){const t=new Map;for(const e of this.edges)for(const n of e.nodeIds)t.set(n,1+(t.get(n)??0));const e={lines:[],points:[],rects:this.nodes.map(e=>{const n=Math.min(...e.availableZ);return{width:Math.max(e.width-2,.8*e.width),height:Math.max(e.height-2,.8*e.height),center:{x:e.center.x+n*e.width*.05,y:e.center.y-n*e.width*.05},fill:e._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[e.availableZ.join(",")]??"rgba(0,200,200,0.1)",label:[e.capacityMeshNodeId,`availableZ: ${e.availableZ.join(",")}`,`target? ${e._containsTarget??!1}`,`obs? ${e._containsObstacle??!1}`,`conn: ${t.get(e.capacityMeshNodeId)??0}`].join("\n"),layer:`z${e.availableZ.join(",")}`}}),circles:[]};if(!this.nodeMap){this.nodeMap=new Map;for(const t of this.nodes)this.nodeMap.set(t.capacityMeshNodeId,t)}for(const t of this.edges){const n=this.nodeMap.get(t.nodeIds[0]),o=this.nodeMap.get(t.nodeIds[1]);if(n?.center&&o?.center){const t=Math.min(...n.availableZ),i=Math.min(...o.availableZ),s={x:n.center.x+t*n.width*.05,y:n.center.y-t*n.width*.05},r={x:o.center.x+i*o.width*.05,y:o.center.y-i*o.width*.05},a=Array.from(new Set([...n.availableZ,...o.availableZ])).sort();e.lines.push({layer:`z${a.join(",")}`,points:[s,r],strokeDash:n.availableZ.join(",")===o.availableZ.join(",")?void 0:"10 5"})}}return e}},kn=class{constructor(t){this.nodes=t,this.buckets=new Map;for(const e of t){const t=e.center.x-e.width/2,n=e.center.y-e.height/2,o=e.center.x+e.width/2,i=e.center.y+e.height/2;for(let s=t;s<=o;s+=this.CELL_SIZE)for(let t=n;t<=i;t+=this.CELL_SIZE){const n=this.getBucketKey(s,t),o=this.buckets.get(n);o?o.push(e):this.buckets.set(n,[e])}}}buckets;CELL_SIZE=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getNodesInArea(t,e,n,o){const i=[],s=new Set,r=e-o/2,a=t+n/2,c=e+o/2;for(let e=t-n/2;e<=a;e+=this.CELL_SIZE)for(let t=r;t<=c;t+=this.CELL_SIZE){const n=this.getBucketKey(e,t),o=this.buckets.get(n)||[];for(const t of o)s.has(t.capacityMeshNodeId)||(s.add(t.capacityMeshNodeId),i.push(t))}return i}},$n=class extends Fn{constructor(t){super(t),this.nodes=t,this.MAX_ITERATIONS=1e7,this.nodeTree=new kn(this.nodes),this.currentNodeIndex=0,this.edgeSet=new Set}getSolverName(){return"CapacityMeshEdgeSolver2_NodeTreeOptimization"}nodeTree;currentNodeIndex;edgeSet;_step(){if(this.currentNodeIndex>=this.nodes.length)return this.handleTargetNodes(),void(this.solved=!0);const t=this.nodes[this.currentNodeIndex],e=this.nodeTree.getNodesInArea(t.center.x,t.center.y,2*t.width,2*t.height);for(const n of e){if(!Xn(t,n))continue;const e=t._strawNode&&n._strawNode&&t._strawParentCapacityMeshNodeId===n._strawParentCapacityMeshNodeId;t.capacityMeshNodeId===n.capacityMeshNodeId||e||!this.doNodesHaveSharedLayer(t,n)||this.edgeSet.has(`${t.capacityMeshNodeId}-${n.capacityMeshNodeId}`)||(this.edgeSet.add(`${t.capacityMeshNodeId}-${n.capacityMeshNodeId}`),this.edgeSet.add(`${n.capacityMeshNodeId}-${t.capacityMeshNodeId}`),this.edges.push({capacityMeshEdgeId:this.getNextCapacityMeshEdgeId(),nodeIds:[t.capacityMeshNodeId,n.capacityMeshNodeId]}))}this.currentNodeIndex++}},Bn=(...t)=>{const e={points:[],lines:[],circles:[],rects:[]};return t.forEach((t,n)=>{t&&(t.lines&&(e.lines=[...e.lines||[],...t.lines.map(t=>({...t,step:n}))]),t.points&&(e.points=[...e.points||[],...t.points.map(t=>({...t,step:n}))]),t.circles&&(e.circles=[...e.circles||[],...t.circles.map(t=>({...t,step:n}))]),t.rects&&(e.rects=[...e.rects||[],...t.rects.map(t=>({...t,step:n}))]))}),e};function jn(t,e,n){const o=[];let i=null;for(let s=0;s<t.length;s++){const r=t[s];i?i.z===r.z?i.points.push({x:r.x,y:r.y}):(o.push(i),i={points:[{x:r.x,y:r.y}],z:r.z,connectionName:e,color:n}):i={points:[{x:r.x,y:r.y}],z:r.z,connectionName:e,color:n},s===t.length-1&&i&&o.push(i)}return o}import Wn from"object-hash";function Vn(t){let e=t;for(let t=0;t<10;t++)e=16807*e%2147483647;let n=e;e=(69069*t+1)%2147483647;for(let t=0;t<10;t++)e=48271*e%2147483647;let o=e;return()=>{let t=n;n=o,t^=t<<23,t^=t>>>17,t^=o,t^=o>>>26,o=t;const e=(n+o)/4294967296;return e-Math.floor(e)}}var Hn={1:[[0]],2:[[0,1],[1,0]],3:[[0,1,2],[2,0,1],[1,0,2],[0,2,1],[1,2,0],[2,1,0]],4:[[0,1,2,3],[2,0,1,3],[1,3,2,0],[3,0,1,2],[0,2,1,3],[2,1,3,0],[3,0,2,1],[1,2,0,3],[3,1,0,2],[0,3,2,1],[2,3,0,1],[2,3,1,0],[1,2,3,0],[3,1,2,0],[0,1,3,2],[0,2,3,1],[0,3,1,2],[1,0,2,3],[1,0,3,2],[1,3,0,2],[2,0,3,1],[2,1,0,3],[3,2,0,1],[3,2,1,0]]};function Un(t,e){if(0===e)return t;if(0===t.length)return t;if(t.length<=4){const n=Hn[t.length];return n[e%n.length].map(e=>t[e])}const n=Vn(e),o=t.slice();for(let t=0;t<o.length;t++){const e=Math.floor(n()*o.length),i=Math.floor(n()*(t+1));[o[e],o[i]]=[o[i],o[e]]}return o}var Gn=t=>{let e=1/0;const n=t.portPoints;for(let t=0;t<n.length;t++)for(let o=t+1;o<n.length;o++){const i=n[t],s=n[o];if(i.z!==s.z)continue;if(i.rootConnectionName&&i.rootConnectionName===s.rootConnectionName)continue;const r=Math.sqrt((i.x-s.x)**2+(i.y-s.y)**2);e=Math.min(e,r)}return e===1/0?0:e},Zn=class{heap=[];constructor(t){this.heap=[];for(const e of t)this.enqueue(e)}getLeftChildIndex(t){return 2*t+1}getRightChildIndex(t){return 2*t+2}getParentIndex(t){return Math.floor((t-1)/2)}hasLeftChild(t){return this.getLeftChildIndex(t)<this.heap.length}hasRightChild(t){return this.getRightChildIndex(t)<this.heap.length}hasParent(t){return this.getParentIndex(t)>=0}leftChild(t){return this.heap[this.getLeftChildIndex(t)]}rightChild(t){return this.heap[this.getRightChildIndex(t)]}parent(t){return this.heap[this.getParentIndex(t)]}swap(t,e){const n=this.heap[t];this.heap[t]=this.heap[e],this.heap[e]=n}dequeue(){if(0===this.heap.length)return null;const t=this.heap[0];return this.heap[0]=this.heap[this.heap.length-1],this.heap.pop(),this.heapifyDown(),t}peek(){return 0===this.heap.length?null:this.heap[0]}enqueue(t){this.heap.push(t),this.heapifyUp()}heapifyUp(){let t=this.heap.length-1;for(;this.hasParent(t)&&this.parent(t).f>this.heap[t].f;)this.swap(this.getParentIndex(t),t),t=this.getParentIndex(t)}heapifyDown(){let t=0;for(;this.hasLeftChild(t);){let e=this.getLeftChildIndex(t);if(this.hasRightChild(t)&&this.rightChild(t).f<this.leftChild(t).f&&(e=this.getRightChildIndex(t)),this.heap[t].f<this.heap[e].f)break;this.swap(t,e),t=e}}getTopN(t){return[...this.heap].sort((t,e)=>t.f-e.f).slice(0,t)}},qn=class extends Dn{getSolverName(){return"SingleHighDensityRouteSolver"}obstacleRoutes;bounds;boundsSize;boundsCenter;A;B;straightLineDistance;viaDiameter;traceThickness;obstacleMargin;layerCount;minCellSize=.05;cellStep=.05;GREEDY_MULTIPLER=1.1;numRoutes;VIA_PENALTY_FACTOR=.3;CELL_SIZE_FACTOR;exploredNodes;candidates;connectionName;solvedPath=null;futureConnections;hyperParameters;connMap;obstacleSegments=[];obstacleSegmentIndex=null;obstacleVias=[];obstacleViaIndex=null;debug_exploredNodesOrdered;debug_nodesTooCloseToObstacle;debug_nodePathToParentIntersectsObstacle;debugEnabled=!0;initialNodeGridOffset;constructor(t){super(),this.bounds=t.bounds,this.connMap=t.connMap,this.hyperParameters=t.hyperParameters??{},this.CELL_SIZE_FACTOR=this.hyperParameters.CELL_SIZE_FACTOR??1,this.boundsSize={width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY},this.boundsCenter={x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},this.connectionName=t.connectionName,this.obstacleRoutes=t.obstacleRoutes,this.A=t.A,this.B=t.B,this.viaDiameter=t.viaDiameter??.3,this.traceThickness=t.traceThickness??.15,this.obstacleMargin=t.obstacleMargin??.2,this.layerCount=t.layerCount??2,this.exploredNodes=new Set,this.straightLineDistance=F(this.A,this.B),this.futureConnections=t.futureConnections??[],this.MAX_ITERATIONS=1e4,this.debug_exploredNodesOrdered=[],this.debug_nodesTooCloseToObstacle=new Set,this.debug_nodePathToParentIntersectsObstacle=new Set,this.numRoutes=this.obstacleRoutes.length+this.futureConnections.length,this.buildObstacleIndexes();const e=Math.ceil(5*(this.numRoutes+1));let n=this.boundsSize.width/this.cellStep,o=this.boundsSize.height/this.cellStep;for(;n*o>e**2&&!(2*this.cellStep>t.minDistBetweenEnteringPoints);)this.cellStep*=2,n=this.boundsSize.width/this.cellStep,o=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const i=Math.abs(this.A.x-this.bounds.minX)<.001&&Math.abs(this.B.x-this.bounds.minX)<.001||Math.abs(this.A.x-this.bounds.maxX)<.001&&Math.abs(this.B.x-this.bounds.maxX)<.001||Math.abs(this.A.y-this.bounds.minY)<.001&&Math.abs(this.B.y-this.bounds.minY)<.001||Math.abs(this.A.y-this.bounds.maxY)<.001&&Math.abs(this.B.y-this.bounds.maxY)<.001;this.futureConnections&&0===this.futureConnections.length&&0===this.obstacleRoutes.length&&!i&&this.handleSimpleCases();const s={x:Math.round(t.A.x/(this.cellStep/2))*(this.cellStep/2),y:Math.round(t.A.y/(this.cellStep/2))*(this.cellStep/2)};this.initialNodeGridOffset={x:s.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:s.y-Math.round(t.A.y/this.cellStep)*this.cellStep},this.candidates=new Zn([{...t.A,...s,z:t.A.z??0,g:0,h:0,f:0,parent:{...t.A,z:t.A.z??0,g:0,h:0,f:0,parent:null}}])}handleSimpleCases(){this.solved=!0;const{A:t,B:e}=this,n=t.z===e.z?[t,e]:[t,{...this.boundsCenter,z:this.A.z},{...this.boundsCenter,z:e.z},e];this.solvedPath={connectionName:this.connectionName,route:n,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:this.A.z===this.B.z?[]:[this.boundsCenter]}}get viaPenaltyDistance(){return this.cellStep+this.straightLineDistance*this.VIA_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e,n){if(e??=this.obstacleMargin,n&&t.parent){const n=this.getViasInNodePath(t.parent);for(const o of n)if(F(t,o)<this.viaDiameter/2+e)return!0}const o=this.traceThickness+e;if(this.obstacleSegmentIndex){const e=this.obstacleSegmentIndex.search(t.x-o,t.y-o,t.x+o,t.y+o);for(const i of e){const e=this.obstacleSegments[i];if(e&&!e.connectedToCurrentConnection&&((n||e.z===t.z)&&X(t,e.A,e.B)<o))return!0}}const i=this.viaDiameter/2+this.traceThickness/2+e;if(this.obstacleViaIndex){const e=this.obstacleViaIndex.search(t.x-i,t.y-i,t.x+i,t.y+i);for(const n of e){const e=this.obstacleVias[n];if(e&&F(t,e)<i)return!0}}return!1}isNodeTooCloseToEdge(t,e){const n=e?this.viaDiameter/2+this.obstacleMargin/2:this.obstacleMargin/2,o=t.x<this.bounds.minX+n||t.x>this.bounds.maxX-n||t.y<this.bounds.minY+n||t.y>this.bounds.maxY-n;return!(o&&!e&&(F(t,this.B)<2*n||F(t,this.A)<2*n))&&o}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;if(!this.obstacleSegmentIndex)return!1;const n=Math.min(t.x,e.x),o=Math.max(t.x,e.x),i=Math.min(t.y,e.y),s=Math.max(t.y,e.y),r=this.obstacleSegmentIndex.search(n,i,o,s);for(const n of r){const o=this.obstacleSegments[n];if(o&&!o.connectedToCurrentConnection&&(o.z===t.z&&D(t,e,o.A,o.B)))return!0}return!1}buildObstacleIndexes(){if(0===this.obstacleRoutes.length)return this.obstacleSegmentIndex=null,void(this.obstacleViaIndex=null);const t=[],e=[];for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName)??!1;for(const e of Jn(n))t.push({...e,connectedToCurrentConnection:o});for(const t of n.vias)e.push(t)}if(this.obstacleSegments=t,this.obstacleVias=e,t.length>0){const e=new E(t.length);for(const n of t)e.add(Math.min(n.A.x,n.B.x),Math.min(n.A.y,n.B.y),Math.max(n.A.x,n.B.x),Math.max(n.A.y,n.B.y));e.finish(),this.obstacleSegmentIndex=e}else this.obstacleSegmentIndex=null;if(e.length>0){const t=new E(e.length);for(const n of e)t.add(n.x,n.y,n.x,n.y);t.finish(),this.obstacleViaIndex=t}else this.obstacleViaIndex=null}computeH(t){return F(t,this.B)+(t.z!==this.B.z?this.viaPenaltyDistance:0)}computeG(t){return(t.parent?.g??0)+(t.z===t.parent?.z?0:this.viaPenaltyDistance)+F(t,t.parent)}computeF(t,e){return t+e*this.GREEDY_MULTIPLER}getNodeKey(t){return`${Math.round(t.x/this.cellStep)*this.cellStep},${Math.round(t.y/this.cellStep)*this.cellStep},${t.z}`}getNeighbors(t){const e=[],{maxX:n,minX:o,maxY:i,minY:s}=this.bounds;for(let r=-1;r<=1;r++)for(let a=-1;a<=1;a++){if(0===r&&0===a)continue;const c={...t,parent:t,x:Kn(t.x+r*this.cellStep,o,n),y:Kn(t.y+a*this.cellStep,s,i)},h=this.getNodeKey(c);this.exploredNodes.has(h)||(this.isNodeTooCloseToObstacle(c)?(this.debug_nodesTooCloseToObstacle.add(h),this.exploredNodes.add(h)):this.isNodeTooCloseToEdge(c,!1)?this.exploredNodes.add(h):this.doesPathToParentIntersectObstacle(c)?(this.debug_nodePathToParentIntersectsObstacle.add(h),this.exploredNodes.add(h)):(c.g=this.computeG(c),c.h=this.computeH(c),c.f=this.computeF(c.g,c.h),e.push(c)))}for(let n=0;n<this.layerCount;n++){if(n===t.z)continue;const o={...t,parent:t,z:n};this.exploredNodes.has(this.getNodeKey(o))||this.isNodeTooCloseToObstacle(o,this.viaDiameter/2+this.obstacleMargin/2,!0)||this.isNodeTooCloseToEdge(o,!0)||(o.g=this.computeG(o),o.h=this.computeH(o),o.f=this.computeF(o.g,o.h),e.push(o))}return e}getNodePath(t){const e=[];for(;t;)e.push(t),t=t.parent;return e}getViasInNodePath(t){const e=this.getNodePath(t),n=[];for(let t=0;t<e.length-1;t++)e[t].z!==e[t+1].z&&n.push({x:e[t].x,y:e[t].y});return n}setSolvedPath(t){const e=this.getNodePath(t);e.reverse();const n=[];for(let t=0;t<e.length-1;t++)e[t].z!==e[t+1].z&&n.push({x:e[t].x,y:e[t].y});this.solvedPath={connectionName:this.connectionName,traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,route:e.map(t=>({x:t.x,y:t.y,z:t.z})).concat([this.B]),vias:n}}computeProgress(t,e,n){n||(e+=this.viaPenaltyDistance);const o=1-e/this.straightLineDistance;return Math.max(this.progress||0,2/Math.PI*Math.atan(.112*o/(1-o)))}_step(){let t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;for(;t&&e&&this.exploredNodes.has(e);)t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;if(!t||!e)return this.failed=!0,void(this.error="Ran out of candidate nodes to explore");this.exploredNodes.add(e),this.debug_exploredNodesOrdered.push(e);const n=F(t,this.B);this.progress=this.computeProgress(t,n,t.z===this.B.z),n<=this.cellStep*Math.SQRT2&&t.z===this.B.z&&!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})&&(this.solved=!0,this.setSolvedPath(t));const o=this.getNeighbors(t);for(const t of o)this.candidates.enqueue(t)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:`Input A\nz: ${this.A.z}`,color:"orange"}),t.points.push({x:this.B.x,y:this.B.y,label:`Input B\nz: ${this.B.z}`,color:"orange"}),t.lines.push({points:[this.A,this.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:"Direct Input Connection"});for(let e=0;e<this.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let o=0;o<n.route.length-1;o++){const i=n.route[o].z;t.lines.push({points:[n.route[o],n.route[o+1]],strokeColor:0===i?"rgba(255, 0, 0, 0.75)":"rgba(255, 128, 0, 0.25)",strokeWidth:n.traceThickness,label:"Obstacle Route",layer:`obstacle${e.toString()}`})}}for(let e=0;e<this.debug_exploredNodesOrdered.length;e++){const n=this.debug_exploredNodesOrdered[e],[o,i,s]=n.split(",").map(Number);this.debug_nodesTooCloseToObstacle.has(n)||(this.debug_nodePathToParentIntersectsObstacle.has(n)||t.rects.push({center:{x:o+this.initialNodeGridOffset.x+s*this.cellStep/20,y:i+this.initialNodeGridOffset.y+s*this.cellStep/20},fill:0===s?`rgba(255,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`:`rgba(0,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`,width:.9*this.cellStep,height:.9*this.cellStep,label:`Explored (z=${s})`}))}if(this.candidates.peek()){const e=this.candidates.peek();t.rects.push({center:{x:e.x+e.z*this.cellStep/20,y:e.y+e.z*this.cellStep/20},fill:"rgba(0, 255, 0, 0.8)",width:.9*this.cellStep,height:.9*this.cellStep,label:`Next (z=${e.z})`})}for(const e of this.obstacleRoutes)for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:this.viaDiameter/2,fill:"rgba(255, 0, 0, 0.5)",label:"Via"});if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:"green",label:"Solved Route"});for(const e of this.solvedPath.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"green",label:"Via"})}return t}};function Jn(t){const e=[];for(let n=0;n<t.route.length-1;n++)t.route[n].z===t.route[n+1].z&&e.push({z:t.route[n].z,A:t.route[n],B:t.route[n+1]});return e}function Kn(t,e,n){return Math.max(e,Math.min(t,n))}var Qn=class extends qn{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR=2;FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR=1;FUTURE_CONNECTION_PROXIMITY_VD=10;MISALIGNED_DIST_PENALTY_FACTOR=5;VIA_PENALTY_FACTOR_2=1;FLIP_TRACE_ALIGNMENT_DIRECTION=!1;constructor(t){super(t);for(const e in t.hyperParameters)this[e]=t.hyperParameters[e];const e=this.boundsSize.width/this.viaDiameter,n=Math.max(1,this.numRoutes);this.VIA_PENALTY_FACTOR=e/n*.3*this.VIA_PENALTY_FACTOR_2}getClosestFutureConnectionPoint(t){let e=1/0,n=null;for(const o of this.futureConnections)for(const i of o.points){const o=F(t,i)+(t.z!==i.z?this.viaPenaltyDistance:0);o<e&&(e=o,n=i)}return n}diminishCloseToGoal(t){const e=F(t,this.B);return 1-Math.exp(-e/this.straightLineDistance*5)}getFutureConnectionPenalty(t,e){let n=0;const o=this.getClosestFutureConnectionPoint(t),i=F(t,this.B);if(o){const s=F(t,o);if(i<=s)return 0;const r=s/(this.viaDiameter*this.FUTURE_CONNECTION_PROXIMITY_VD);n=(e?this.straightLineDistance*this.FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:this.straightLineDistance*this.FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR)*Math.exp(5*-r)}return n}computeH(t){const e=F(t,this.B)**1.6;this.straightLineDistance;return e+(t.z!==this.B.z?this.viaPenaltyDistance:0)+this.getFutureConnectionPenalty(t,t.z!==t.parent?.z)}computeG(t){const e=Math.abs(t.x-t.parent.x),n=Math.abs(t.y-t.parent.y),o=Math.sqrt(e**2+n**2),i=t.z%2==0,s=this.FLIP_TRACE_ALIGNMENT_DIRECTION?i?e:n:i?n:e;return(t.parent?.g??0)+(t.z===t.parent?.z?0:this.viaPenaltyDistance)+o+s*this.MISALIGNED_DIST_PENALTY_FACTOR+this.getFutureConnectionPenalty(t,t.z!==t.parent?.z)}},to=class extends Dn{getSolverName(){return"IntraNodeRouteSolver"}nodeWithPortPoints;colorMap;unsolvedConnections;totalConnections;solvedRoutes;failedSubSolvers;hyperParameters;minDistBetweenEnteringPoints;viaDiameter;traceWidth;activeSubSolver=null;connMap;get failedSolvers(){return this.failedSubSolvers}get activeSolver(){return this.activeSubSolver}constructor(t){const{nodeWithPortPoints:e,colorMap:n}=t;super(),this.nodeWithPortPoints=e,this.colorMap=n??{},this.solvedRoutes=[],this.hyperParameters=t.hyperParameters??{},this.failedSubSolvers=[],this.connMap=t.connMap,this.viaDiameter=t.viaDiameter??.3,this.traceWidth=t.traceWidth??.15;const o=new Map;for(const{connectionName:t,x:n,y:i,z:s}of e.portPoints)o.set(t,[...o.get(t)??[],{x:n,y:i,z:s??0}]);this.unsolvedConnections=Array.from(o.entries().map(([t,e])=>({connectionName:t,points:e}))),this.hyperParameters.SHUFFLE_SEED&&(this.unsolvedConnections=Un(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=>({...e,points:Un(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Gn(this.nodeWithPortPoints)}computeProgress(){return(this.solvedRoutes.length+(this.activeSubSolver?.progress||0))/this.totalConnections}_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),this.progress=this.computeProgress(),void(this.activeSubSolver.solved?(this.solvedRoutes.push(this.activeSubSolver.solvedPath),this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSubSolvers.push(this.activeSubSolver),this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=>t.error).join("\n"),this.failed=!0));const t=this.unsolvedConnections.pop();if(this.progress=this.computeProgress(),!t)return void(this.solved=0===this.failedSubSolvers.length);if(1===t.points.length)return;if(2===t.points.length){const[e,n]=t.points,o=Math.abs(e.x-n.x)<1e-6,i=Math.abs(e.y-n.y)<1e-6;if(o&&i&&e.z===n.z)return;if(o&&i&&e.z!==n.z){const o={x:this.nodeWithPortPoints.center.x,y:this.nodeWithPortPoints.center.y},i=[{x:e.x,y:e.y,z:e.z},{...o,z:e.z},{...o,z:n.z},{x:n.x,y:n.y,z:n.z}].filter((t,e,n)=>0===e||Math.abs(t.x-n[e-1].x)>1e-6||Math.abs(t.y-n[e-1].y)>1e-6||t.z!==n[e-1].z);return void this.solvedRoutes.push({connectionName:t.connectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:i,vias:[o]})}}const{connectionName:e,points:n}=t;this.activeSubSolver=new Qn({connectionName:e,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:Me(this.nodeWithPortPoints),A:{x:n[0].x,y:n[0].y,z:n[0].z},B:{x:n[n.length-1].x,y:n[n.length-1].y,z:n[n.length-1].z},obstacleRoutes:this.connMap?this.solvedRoutes.filter(t=>!this.connMap.areIdsConnected(t.connectionName,e)):this.solvedRoutes,futureConnections:this.unsolvedConnections,layerCount:this.nodeWithPortPoints.portPoints.reduce((t,e)=>Math.max(t,(e.z??0)+1),2),hyperParameters:this.hyperParameters,connMap:this.connMap,viaDiameter:this.viaDiameter,traceThickness:this.traceWidth})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:[e.connectionName,`layer: ${e.z}`].join("\n"),color:this.colorMap[e.connectionName]??"blue"});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length>0){const o=this.colorMap[n.connectionName]??"blue";for(let i=0;i<n.route.length-1;i++){const s=n.route[i],r=n.route[i+1];t.lines.push({points:[s,r],strokeColor:0===s.z?Mn(o,.2):Mn(o,.8),layer:`route-layer-${s.z}`,step:e,strokeWidth:n.traceThickness})}for(const i of n.vias)t.circles.push({center:{x:i.x,y:i.y},radius:n.viaDiameter/2,fill:Mn(o,.5),layer:"via",step:e})}}const e=Me(this.nodeWithPortPoints),{minX:n,minY:o,maxX:i,maxY:s}=e;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:s},{x:n,y:s},{x:n,y:o}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}},eo=t=>Math.round(200*t)/200,no=t=>"function"==typeof structuredClone?structuredClone(t):JSON.parse(JSON.stringify(t));Ie();var oo=class extends to{getSolverName(){return"CachedIntraNodeRouteSolver"}cacheProvider;cacheHit=!1;hasAttemptedToUseCache=!1;initialUnsolvedConnections;constructor(t){super(t),this.cacheProvider=void 0===t.cacheProvider?Se():t.cacheProvider,this.initialUnsolvedConnections=no(this.unsolvedConnections),(this.solved||this.failed)&&this.cacheProvider&&!this.cacheHit&&this.saveToCacheSync()}_step(){if(!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync())return;const t=this.solved,e=this.failed;super._step(),!this.cacheProvider||this.cacheHit||!this.solved&&!this.failed||t||e||this.saveToCacheSync()}computeCacheKeyAndTransform(){const t=this.nodeWithPortPoints.center,e=this.initialUnsolvedConnections.map(({connectionName:e,points:n})=>({connectionName:e,points:n.map(n=>({connectionName:e,x:eo(n.x-t.x),y:eo(n.y-t.y),z:n.z??0}))})),n=Object.fromEntries(Object.entries(this.hyperParameters??{}).filter(([,t])=>void 0!==t).sort(([t],[e])=>t.localeCompare(e))),o=this.connMap?this.initialUnsolvedConnections.map(({connectionName:t})=>({connectionName:t,connectedIds:[...new Set(this.connMap.getIdsConnectedToNet(t)??[])].sort()})):void 0,i={node:{width:eo(this.nodeWithPortPoints.width),height:eo(this.nodeWithPortPoints.height),center:{x:eo(this.nodeWithPortPoints.center.x),y:eo(this.nodeWithPortPoints.center.y)},availableZ:this.nodeWithPortPoints.availableZ?[...this.nodeWithPortPoints.availableZ].sort():void 0},normalizedConnections:e,normalizedHyperParameters:n,minDistBetweenEnteringPoints:eo(this.minDistBetweenEnteringPoints),normalizedConnMap:o},s=`intranode-solver:${Wn(i)}`,r={};return this.cacheKey=s,this.cacheToSolveSpaceTransform=r,{cacheKey:s,cacheToSolveSpaceTransform:r}}applyCachedSolution(t){t.success?(this.solvedRoutes=no(t.solvedRoutes),this.solved=!0,this.failed=!1):(this.solvedRoutes=[],this.failedSubSolvers=[],this.solved=!1,this.failed=!0,this.error=t.error??this.error),this.unsolvedConnections=[],this.activeSubSolver=null,this.cacheHit=!0,this.progress=1}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return!1;if(!this.cacheKey)try{this.computeCacheKeyAndTransform()}catch(t){return console.error("Error computing cache key:",t),!1}if(!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(null!=t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(!this.cacheProvider?.isSyncCache)return;if(!this.cacheKey)try{this.computeCacheKeyAndTransform()}catch(t){return void console.error("Error computing cache key during save:",t)}if(!this.cacheKey)return void console.error("Failed to compute cache key before saving.");const t=this.failed?{success:!1,error:this.error??void 0}:{success:!0,solvedRoutes:no(this.solvedRoutes)};try{this.cacheProvider.setCachedSolutionSync(this.cacheKey,t)}catch(t){console.error("Error saving solution to cache:",t)}}},io=class extends Dn{getSolverName(){return"HyperParameterSupervisorSolver"}GREEDY_MULTIPLIER=1.2;MIN_SUBSTEPS=1;supervisedSolvers;winningSolver;getHyperParameterDefs(){throw new Error("Not implemented")}getCombinationDefs(){return null}getHyperParameterCombinations(t){t||(t=this.getHyperParameterDefs());const e=[];if(0===t.length)return[{}];const[n,...o]=t,i=this.getHyperParameterCombinations(o);return n.possibleValues.forEach(t=>{i.forEach(n=>{e.push({...n,...t})})}),e}initializeSolvers(){const t=this.getHyperParameterDefs(),e=this.getCombinationDefs()??[t.map(t=>t.name)];this.supervisedSolvers=[];for(const n of e){const e=this.getHyperParameterCombinations(t.filter(t=>n.includes(t.name)));for(const t of e){const e=this.generateSolver(t),n=this.computeG(e);this.supervisedSolvers.push({hyperParameters:t,solver:e,h:0,g:n,f:n})}}}generateSolver(t){throw new Error("Not implemented")}computeG(t){return t.iterations/t.MAX_ITERATIONS}computeH(t){return 1-(t.progress||0)}computeF(t,e){return t+e*this.GREEDY_MULTIPLIER}getSupervisedSolverWithBestFitness(){let t=1/0,e=null;for(const n of this.supervisedSolvers??[]){if(n.solver.solved)return n;if(n.solver.failed)continue;const o=n.f;o<t&&(t=o,e=n)}return e}getFailureMessage(){return`All solvers failed in hyper solver. Example failures: ${this.supervisedSolvers?.sort((t,e)=>e.f-t.f)?.slice(0,5).map(t=>t.solver.error).join(", ")}`}_step(){this.supervisedSolvers||this.initializeSolvers();const t=this.getSupervisedSolverWithBestFitness();if(!t)return this.failed=!0,void(this.error=this.getFailureMessage());for(let e=0;e<this.MIN_SUBSTEPS;e++)t.solver.step();this.activeSubSolver=t.solver,t.g=this.computeG(t.solver),t.h=this.computeH(t.solver),t.f=this.computeF(t.g,t.h),t.solver.solved&&(this.solved=!0,this.winningSolver=t.solver,this.onSolve?.(t))}onSolve(t){}visualize(){const t=this.getSupervisedSolverWithBestFitness();let e={lines:[],circles:[],points:[],rects:[]};return t&&(e=t.solver.visualize()),e}};function so({A:t,B:e,C:n,D:o,E:i,F:s,radius:r,margin:a,subdivisions:c=0}){const h=(t,e)=>({x:(t.x+e.x)/2,y:(t.y+e.y)/2}),l=(t,e,n)=>{const o=e.x-t.x,i=e.y-t.y,s=Math.sqrt(o*o+i*i),r=o/s,a=i/s,c=-a,h=r;return{midpoint:{x:(t.x+e.x)/2,y:(t.y+e.y)/2},A_Opp:{x:t.x-r*n,y:t.y-a*n},A_Right:{x:t.x+c*n,y:t.y+h*n},A_Left:{x:t.x-c*n,y:t.y-h*n},B_Opp:{x:e.x+r*n,y:e.y+a*n},B_Right:{x:e.x+c*n,y:e.y+h*n},B_Left:{x:e.x-c*n,y:e.y-h*n}}},d=(t,e)=>{const n=F(t,e.start),o=F(t,e.end),i=F(e.start,e.end);return Math.abs(n+o-i)<1e-4},u=(t,e)=>{const{start:n,end:o}=t,{start:i,end:s}=e;if(d(n,e)||d(o,e)||d(i,t)||d(s,t))return!0;const r=o.x-n.x,a=o.y-n.y,c=s.x-i.x,h=s.y-i.y,l=r*h-a*c;if(Math.abs(l)<1e-4)return!1;const u=i.x-n.x,p=i.y-n.y,f=(u*h-p*c)/l,g=(u*a-p*r)/l;return f>0&&f<1&&g>0&&g<1},p=(t,e)=>{const n=[];for(let e=0;e<t.length-1;e++)n.push({start:t[e],end:t[e+1]});const o=[];for(let t=0;t<e.length-1;t++)o.push({start:e[t],end:e[t+1]});for(const t of n)for(const e of o)if(u(t,e))return!0;return!1},f=t=>{let e=0;for(let n=1;n<t.length;n++){const o=t[n].x-t[n-1].x,i=t[n].y-t[n-1].y;e+=Math.sqrt(o*o+i*i)}return e},g=(t,e)=>{const{start:n,end:o}=t,i=o.x-n.x,s=o.y-n.y,r=i*i+s*s;if(0===r)return{...n,t:0};const a=Math.max(0,Math.min(1,((e.x-n.x)*i+(e.y-n.y)*s)/r));return{x:n.x+a*i,y:n.y+a*s,t:a}},m=(e,n,o)=>{const i=g(e,n);if(F(i,n)>=o)return i;const s=i.x-n.x,r=i.y-n.y,a=Math.sqrt(s*s+r*r);if(0===a){const s=e.end.x-e.start.x,r=e.end.y-e.start.y,a=Math.sqrt(s*s+r*r);return{x:n.x+o*s/a,y:n.y+o*r/a,t:i.t,isSpecial:!0,specialType:n===t?"A":"B"}}return{x:n.x+o*s/a,y:n.y+o*r/a,t:i.t,isSpecial:!0,specialType:n===t?"A":"B"}},y=l(t,e,r),x=l(t,e,r+a),v=(t,e,n,o,i)=>{const s=t.points;if(s.length<2)return s;const a=n+o,c=[s[0]];for(let t=0;t<s.length-1;t++){const n={start:s[t],end:s[t+1]};if(X(e,n.start,n.end)<a){const t=g(n,e),o=t.x-e.x,i=t.y-e.y,s=Math.sqrt(o*o+i*i);let h=null;if(s>1e-6)h={x:e.x+a*o/s,y:e.y+a*i/s};else{const t=n.end.x-n.start.x,o=n.end.y-n.start.y,i=Math.sqrt(t*t+o*o);i>1e-6&&(h={x:e.x+a*t/i,y:e.y+a*o/i})}h&&F(n.start,h)>r/10&&c.push(h)}F(c[c.length-1],n.end)>r/10&&c.push(n.end)}if(c.length>1){const t=[c[0]];for(let e=1;e<c.length;e++)F(t[t.length-1],c[e])>r/10&&t.push(c[e]);return t}return c},b=(()=>{const t=[[n,y.B_Left,y.B_Opp,y.B_Right,h(y.midpoint,h(y.B_Right,y.A_Right)),h(y.midpoint,h(y.A_Left,y.B_Left)),y.A_Left,y.A_Opp,y.A_Right,o],[n,y.B_Right,y.B_Opp,y.B_Left,h(y.midpoint,h(y.A_Left,y.B_Left)),h(y.midpoint,h(y.A_Right,y.B_Right)),y.A_Right,y.A_Opp,y.A_Left,o],[o,y.B_Left,y.B_Opp,y.B_Right,h(y.midpoint,h(y.A_Right,y.B_Right)),h(y.midpoint,h(y.A_Left,y.B_Left)),y.A_Left,y.A_Opp,y.A_Right,n],[o,y.B_Right,y.B_Opp,y.B_Left,h(y.midpoint,h(y.A_Left,y.B_Left)),h(y.midpoint,h(y.A_Right,y.B_Right)),y.A_Right,y.A_Opp,y.A_Left,n]],e=[];for(let n=0;n<t.length;n++){const o=t[n],i={start:o[0],end:o[1]},s={start:o[o.length-2],end:o[o.length-1]},r={start:o[3],end:o[4]};u(i,s)||u(i,r)||u(s,r)||e.push({index:n+1,path:o,length:f(o)})}if(0===e.length)return{index:0,path:[]};const i=e.sort((t,e)=>t.length-e.length)[0],s=[...i.path],r=s[0],a=F(r,s[2]),c=F(r,s[3]),l=a<c?2:3;(a<F(r,s[1])||c<F(r,s[1]))&&s.splice(1,l-1);const d=s[s.length-1],p=F(d,s[s.length-3]),g=F(d,s[s.length-4]),m=p<g?s.length-3:s.length-4;return(p<F(d,s[s.length-2])||g<F(d,s[s.length-2]))&&s.splice(m+1,s.length-m-2),{index:i.index,path:s,startsAt:s[0]===n?"C":"D",goesTo:s[s.length-1]===n?"C":"D"}})(),P=c>0?((n,o)=>{if(n.length<2)return n;const i=[n[0]];for(let s=0;s<n.length-1;s++){const a={start:n[s],end:n[s+1]},c={x:(a.start.x+a.end.x)/2,y:(a.start.y+a.end.y)/2},h=F(c,t),l=F(c,e);if((h<=r||l<=r)&&Math.abs(h-l)>1e-4){const n=g(a,t),s=g(a,e),c=F(n,t),h=F(s,e)<r,l=c<r?m(a,t,r):null,d=h?m(a,e,r):null;let u=[];if(F(a.start,a.end)>r/2&&o>0)for(let n=1;n<=o;n++){const i=n/(o+1),s={x:a.start.x+i*(a.end.x-a.start.x),y:a.start.y+i*(a.end.y-a.start.y),t:i,isSpecial:!1},c=F(s,t),h=F(s,e);c<r||h<r||(l&&Math.abs(s.t-l.t)<.1||d&&Math.abs(s.t-d.t)<.1||u.push(s))}if(l&&u.push(l),d&&u.push(d),u.sort((t,e)=>t.t-e.t),u.length>1){const t=[u[0]];for(let e=1;e<u.length;e++){const n=t[t.length-1],o=u[e];F(n,o)>r/10&&t.push(o)}u=t}u.forEach(t=>i.push(t))}i.push(n[s+1])}if(i.length>1){const t=[i[0]];for(let e=1;e<i.length;e++){const n=t[t.length-1],o=i[e];F(n,o)>r/10&&t.push(o)}return t}return i})(b.path,c):b.path;let S=(()=>{if(0===b.path.length)return null;const n=(()=>{const n=h(y.A_Right,y.B_Right),o=h(y.B_Left,y.A_Left);return[{startsAt:"E",goesTo:"B",points:[i,e]},{startsAt:"E",goesTo:"A",points:[i,t]},{startsAt:"F",goesTo:"B",points:[s,e]},{startsAt:"F",goesTo:"A",points:[s,t]},{startsAt:"E",goesTo:"B",points:[i,n,e]},{startsAt:"E",goesTo:"A",points:[i,n,t]},{startsAt:"F",goesTo:"B",points:[s,n,e]},{startsAt:"F",goesTo:"A",points:[s,n,t]},{startsAt:"E",goesTo:"B",points:[i,o,e]},{startsAt:"E",goesTo:"A",points:[i,o,t]},{startsAt:"F",goesTo:"B",points:[s,o,e]},{startsAt:"F",goesTo:"A",points:[s,o,t]},{startsAt:"E",goesTo:"B",points:[i,x.A_Right,n,e]},{startsAt:"F",goesTo:"B",points:[s,x.B_Right,n,e]},{startsAt:"E",goesTo:"A",points:[i,x.B_Left,o,t]},{startsAt:"F",goesTo:"A",points:[s,x.A_Left,o,t]},{startsAt:"E",goesTo:"B",points:[i,x.A_Left,o,e]},{startsAt:"E",goesTo:"A",points:[i,x.B_Right,n,t]},{startsAt:"E",goesTo:"B",points:[i,x.A_Opp,x.A_Right,n,e]},{startsAt:"E",goesTo:"A",points:[i,x.B_Opp,x.B_Left,o,t]},{startsAt:"F",goesTo:"B",points:[s,x.A_Opp,x.A_Left,o,e]},{startsAt:"F",goesTo:"A",points:[s,x.B_Opp,x.B_Right,n,t]},{startsAt:"F",goesTo:"A",points:[s,x.B_Opp,x.B_Left,o,t]},{startsAt:"E",goesTo:"B",points:[i,x.A_Opp,x.A_Left,o,e]},{startsAt:"E",goesTo:"A",points:[i,x.B_Opp,x.B_Right,n,t]},{startsAt:"E",goesTo:"B",points:[i,x.A_Left,x.A_Opp,x.A_Right,n,e]},{startsAt:"E",goesTo:"A",points:[i,x.B_Right,x.B_Opp,x.B_Left,o,t]},{startsAt:"F",goesTo:"B",points:[s,x.A_Right,x.A_Opp,x.A_Left,o,e]},{startsAt:"F",goesTo:"A",points:[s,x.B_Left,x.B_Opp,x.B_Right,n,t]},{startsAt:"F",goesTo:"A",points:[s,x.B_Right,x.B_Opp,x.B_Left,o,t]},{startsAt:"E",goesTo:"B",points:[i,x.A_Right,x.A_Opp,x.A_Left,o,e]},{startsAt:"E",goesTo:"A",points:[i,x.B_Left,x.B_Opp,x.B_Right,n,t]}].map((t,e)=>({...t,index:e}))})(),o=n.filter(t=>"E"===t.startsAt),r=n.filter(t=>"F"===t.startsAt),a=[],c=[];for(const t of o)if(!p(t.points,b.path)){a.push(t);break}for(const t of r)if(!p(t.points,b.path)){c.push(t);break}return 0===a.length||0===c.length?null:{line1:a[0],line2:c[0]}})();if(S){const n="A"===S.line1.goesTo?e:t,o="A"===S.line2.goesTo?e:t,i=v(S.line1,n,r,a),s=v(S.line2,o,r,a);S={line1:{...S.line1,points:i},line2:{...S.line2,points:s}}}return{jPair:S,optimalPath:{startsAt:b.startsAt,goesTo:b.goesTo,points:P}}}var ro=class extends Dn{getSolverName(){return"TwoCrossingRoutesHighDensitySolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;layerCount=2;debugViaPositions;escapeLayer=1;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.layerCount=t?.layerCount??2,this.debugViaPositions=[],this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),2!==this.routes.length)return this.failed=!0,void(this.error=`Expected 2 routes, but got ${this.routes.length}`);const[e,n]=this.routes;if(!(e.startPort.z===e.endPort.z))return this.failed=!0,void(this.error="Route A must start and end on the same layer");if(!(n.startPort.z===n.endPort.z))return this.failed=!0,void(this.error="Route B must start and end on the same layer");if(!(e.startPort.z===n.startPort.z))return this.failed=!0,void(this.error="Both routes must be on the same layer");0===e.startPort.z?this.escapeLayer=1:this.escapeLayer=0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e)?.push(t)}for(const[e,o]of n.entries())2===o.length&&t.push({startPort:{...o[0],z:o[0].z??0},endPort:{...o[1],z:o[1].z??0},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}doRoutesCross(t,e){return D(t.startPort,t.endPort,e.startPort,e.endPort)}calculateViaPositions(t,e){const n=this.bounds.maxX-this.bounds.minX,o=this.bounds.maxY-this.bounds.minY,i=this.bounds.minX,s=this.bounds.minY,r={width:n-2*this.obstacleMargin-this.viaDiameter,height:o-2*this.obstacleMargin-this.viaDiameter,x:i+this.obstacleMargin+this.viaDiameter/2,y:s+this.obstacleMargin+this.viaDiameter/2},a=this.viaDiameter+this.obstacleMargin,c=e.startPort,h=e.endPort,l=[{x:r.x,y:r.y},{x:r.x+r.width,y:r.y},{x:r.x+r.width,y:r.y+r.height},{x:r.x,y:r.y+r.height}],d=(t,e)=>F(t,e),u=[];l.forEach((t,e)=>{d(t,c)>=a&&d(t,h)>=a&&u.push({...t,type:"corner",index:e})});const p=[{p1:l[0],p2:l[1]},{p1:l[1],p2:l[2]},{p1:l[2],p2:l[3]},{p1:l[3],p2:l[0]}];if([c,h].forEach((t,e)=>{p.forEach((n,o)=>{((t,e)=>{const n=t.x,o=t.y,i=t.r,s=e.p1.x,r=e.p1.y,a=e.p2.x,c=e.p2.y;if(Math.abs(a-s)<.001){const t=s,e=i*i-(t-n)**2;if(e<0)return[];if(Math.abs(e)<.001){const e=o;return e>=Math.min(r,c)&&e<=Math.max(r,c)?[{x:t,y:e}]:[]}const a=o+Math.sqrt(e),h=o-Math.sqrt(e),l=[];return a>=Math.min(r,c)&&a<=Math.max(r,c)&&l.push({x:t,y:a}),h>=Math.min(r,c)&&h<=Math.max(r,c)&&l.push({x:t,y:h}),l}const h=(c-r)/(a-s),l=r-h*s,d=1+h*h,u=2*(h*l-h*o-n),p=u*u-4*d*(n*n+(l-o)*(l-o)-i*i);if(p<0)return[];if(Math.abs(p)<.001){const t=-u/(2*d),e=h*t+l;return t>=Math.min(s,a)&&t<=Math.max(s,a)&&e>=Math.min(r,c)&&e<=Math.max(r,c)?[{x:t,y:e}]:[]}const f=(-u+Math.sqrt(p))/(2*d),g=(-u-Math.sqrt(p))/(2*d),m=h*f+l,y=h*g+l,x=[];return f>=Math.min(s,a)&&f<=Math.max(s,a)&&m>=Math.min(r,c)&&m<=Math.max(r,c)&&x.push({x:f,y:m}),g>=Math.min(s,a)&&g<=Math.max(s,a)&&y>=Math.min(r,c)&&y<=Math.max(r,c)&&x.push({x:g,y:y}),x})({...t,r:a},n).forEach(t=>{d(t,0===e?h:c)>=a&&u.push({...t,type:"intersection",circle:e,edge:o})})})}),u.length<2){const t=.8*a;if(l.forEach((e,n)=>{d(e,c)>=t&&d(e,h)>=t&&!u.some(t=>t.x===e.x&&t.y===e.y)&&u.push({...e,type:"relaxed_corner",index:n})}),u.length<2){const t=[...l].sort((t,e)=>{const n=Math.min(d(t,c),d(t,h));return Math.min(d(e,c),d(e,h))-n});for(const e of t)if(!u.some(t=>t.x===e.x&&t.y===e.y)&&(u.push({...e,type:"forced_corner"}),u.length>=2))break}}if(u.length<2)return null;let f=0,g=[u[0],u[u.length>1?1:0]];for(let t=0;t<u.length;t++)for(let e=t+1;e<u.length;e++){const n=d(u[t],u[e]);n>f&&(f=n,g=[u[t],u[e]])}let m={x:g[0].x,y:g[0].y},y={x:g[1].x,y:g[1].y};const x=F(m,t.startPort);return F(y,t.startPort)<x&&([m,y]=[y,m]),{via1:m,via2:y}}trySolveAOverB(t,e,n=!1){const o=n?this.calculateViaPositions(t,e):this.calculateViaPositions(e,t);if(!o)return!1;this.debugViaPositions.push(o);const{via1:i,via2:s}=this.pushViasFromEndpoints(this.moveViasAsCloseAsPossible(o));this.debugViaPositions.push({via1:i,via2:s});const{jPair:r,optimalPath:a}=so({A:i,B:s,C:t.startPort,D:t.endPort,E:e.startPort,F:e.endPort,radius:this.viaDiameter/2+this.obstacleMargin+this.traceThickness/2*1.5,margin:2*this.obstacleMargin+this.traceThickness/2*1.5,subdivisions:1});if(!r)return!1;const c={connectionName:t.connectionName,route:a.points.map(e=>({x:e.x,y:e.y,z:t.startPort.z??0})),traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]};r.line2.points.reverse();const h={connectionName:e.connectionName,route:[...r.line1.points.map(t=>({x:t.x,y:t.y,z:e.startPort.z??0})),{...r.line1.points[r.line1.points.length-1],z:this.escapeLayer},{...r.line2.points[0],z:this.escapeLayer},...r.line2.points.map(t=>({x:t.x,y:t.y,z:e.startPort.z??0}))],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[i,s]};return this.solvedRoutes.push(c,h),!0}pushViasFromEndpoints(t){const e={...t.via1},n={...t.via2},o=[this.routes[0].startPort,this.routes[0].endPort,this.routes[1].startPort,this.routes[1].endPort],i=this.getMinDistanceBetweenViaCenters(),s=this.viaDiameter/2+2*this.traceThickness+2*this.obstacleMargin;for(let t=0;t<10;t++){let r=!1,a=!1;const c=.9**t;for(const t of o){const o=F(e,t);if(o<s){const n=(s-o)*c,i=e.x-t.x,a=e.y-t.y,h=Math.sqrt(i*i+a*a);h>1e-6&&(e.x+=i/h*n,e.y+=a/h*n,r=!0)}const i=F(n,t);if(i<s){const e=(s-i)*c,o=n.x-t.x,r=n.y-t.y,h=Math.sqrt(o*o+r*r);h>1e-6&&(n.x+=o/h*e,n.y+=r/h*e,a=!0)}}const h=F(e,n);if(h<i){const t=(i-h)/2,o=n.x-e.x,s=n.y-e.y,c=Math.sqrt(o*o+s*s);c>1e-6?(e.x-=o/c*t,e.y-=s/c*t,n.x+=o/c*t,n.y+=s/c*t,r=!0,a=!0):(e.x-=t,n.x+=t,r=!0,a=!0)}if(!r&&!a)break}const r=F(e,n);if(r<i){const t=(i-r)/2,o=n.x-e.x,s=n.y-e.y,a=Math.sqrt(o*o+s*s);a>1e-6?(e.x-=o/a*t,e.y-=s/a*t,n.x+=o/a*t,n.y+=s/a*t):(e.x-=t,n.x+=t)}return{via1:e,via2:n}}getMinDistanceBetweenViaCenters(){return this.viaDiameter+this.traceThickness+2*this.obstacleMargin}moveViasAsCloseAsPossible(t){const{via1:e,via2:n}=t,o=this.getMinDistanceBetweenViaCenters(),i=F(e,n);if(i<=o)return t;const s=n.x-e.x,r=n.y-e.y,a=Math.sqrt(s*s+r*r),c=s/a,h=r/a,l=(e.x,n.x,e.y,n.y,(i-o)/2);return{via1:{x:e.x+c*l,y:e.y+h*l},via2:{x:n.x-c*l,y:n.y-h*l}}}handleRoutesDontCross(){const[t,e]=this.routes,n={connectionName:t.connectionName,route:[{x:t.startPort.x,y:t.startPort.y,z:t.startPort.z??0},{x:t.endPort.x,y:t.endPort.y,z:t.endPort.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]},o={connectionName:e.connectionName,route:[{x:e.startPort.x,y:e.startPort.y,z:e.startPort.z??0},{x:e.endPort.x,y:e.endPort.y,z:e.endPort.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]};this.solvedRoutes.push(n,o),this.solved=!0}_step(){if(2!==this.routes.length)return void(this.failed=!0);const[t,e]=this.routes;this.doRoutesCross(t,e)?this.trySolveAOverB(t,e)||this.trySolveAOverB(e,t)||this.trySolveAOverB(t,e,!0)||this.trySolveAOverB(e,t,!0)?this.solved=!0:(this.failed=!0,this.error="All crossover strategies failed"):this.handleRoutesDontCross()}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)"});for(const[e,n]of[["Route A",this.routes[0]],["Route B",this.routes[1]]])t.points.push({x:n.startPort.x,y:n.startPort.y,label:`${e}\n${n.connectionName} start`,color:"orange"}),t.points.push({x:n.endPort.x,y:n.endPort.y,label:`${e}\n${n.connectionName} end`,color:"orange"}),t.lines.push({points:[n.startPort,n.endPort],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e}\n${n.connectionName} direct`});for(let e=0;e<this.debugViaPositions.length;e++){const{via1:n,via2:o}=this.debugViaPositions[e],i=["rgba(255, 165, 0, 0.3)","rgba(128, 0, 128, 0.3)"],s=i[e%i.length];t.circles.push({center:n,radius:this.viaDiameter/2,fill:s,stroke:"rgba(0, 0, 0, 0.3)",label:`Computed Via A (attempt ${e+1})`}),t.circles.push({center:o,radius:this.viaDiameter/2,fill:s,stroke:"rgba(0, 0, 0, 0.3)",label:`Computed Via B (attempt ${e+1})`});const r=this.viaDiameter/2+this.obstacleMargin;t.circles.push({center:n,radius:r,stroke:s,fill:"rgba(0, 0, 0, 0)",label:`Debug Via 1 Safety Margin (attempt ${e+1})`}),t.circles.push({center:o,radius:r,stroke:s,fill:"rgba(0, 0, 0, 0)",label:`Debug Via 2 Safety Margin (attempt ${e+1})`}),t.lines.push({points:[this.routes[e%2].startPort,n,o,this.routes[e%2].endPort],strokeColor:`${s.substring(0,s.lastIndexOf(","))}, 0.3)`,strokeDash:[5,5],label:`Potential Route (attempt ${e+1})`})}for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],o=e%2==0?"rgba(0, 255, 0, 0.75)":"rgba(255, 0, 255, 0.75)";for(let e=0;e<n.route.length-1;e++){const i=n.route[e],s=n.route[e+1];t.lines.push({points:[i,s],strokeColor:o,strokeDash:1===i.z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${i.z}`}),i._label&&t.points.push({x:i.x,y:i.y,label:i._label})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Solved Via Margin"})}return t}getSolvedRoutes(){return this.solvedRoutes}},ao=({value:t,min:e,max:n})=>t>=e&&t<=n,co=({value:t,target:e,epsilon:n})=>Math.abs(t-e)<=n,ho=({point:t,bounds:e,epsilon:n=1e-6})=>{if(![t.x,t.y,e.minX,e.maxX,e.minY,e.maxY].every(t=>(({value:t})=>Number.isFinite(t))({value:t})))return"outside";const o=function(t,e){return t.x>=e.minX&&t.x<=e.maxX&&t.y>=e.minY&&t.y<=e.maxY?0:F(t,{x:z(t.x,e.minX,e.maxX),y:z(t.y,e.minY,e.maxY)})}(t,e);if(o>n)return"outside";const i=co({value:t.x,target:e.minX,epsilon:n}),s=co({value:t.x,target:e.maxX,epsilon:n}),r=co({value:t.y,target:e.minY,epsilon:n}),a=co({value:t.y,target:e.maxY,epsilon:n}),c=i||s,h=r||a;if(c&&h)return"on-boundary";const l=ao({value:t.y,min:e.minY,max:e.maxY}),d=ao({value:t.x,min:e.minX,max:e.maxX});return c&&l||h&&d?"on-boundary":"inside"};function lo(t,e,n,o,i){const s={x:(t.x+e.x+n.x)/3,y:(t.y+e.y+n.y)/3},r=(t,e)=>Math.sqrt((e.x-t.x)**2+(e.y-t.y)**2),a=s=>{const a=r(s,t),c=r(s,e),h=r(s,n),l=s.x>=i.minX&&s.x<=i.maxX&&s.y>=i.minY&&s.y<=i.maxY;return a>=o&&c>=o&&h>=o&&l};if(a(s))return s;const c=(t,e,n)=>{const o=t.x-e.x,i=t.y-e.y,s=Math.sqrt(o*o+i*i);return s<1e-10?{x:e.x+n,y:e.y}:{x:e.x+o/s*n,y:e.y+i/s*n}},h=(t,e,n)=>{const o=e.x-t.x,i=e.y-t.y,s=Math.sqrt(o*o+i*i);if(s>2*n-1e-10||s<1e-10)return[];const a=s*s/(2*s),c=Math.sqrt(Math.max(0,n*n-a*a)),h=t.x+o*a/s,l=t.y+i*a/s,d={x:h+c*i/s,y:l-c*o/s},u={x:h-c*i/s,y:l+c*o/s},p=[],f=1e-6;return Math.abs(r(d,t)-n)<f&&Math.abs(r(d,e)-n)<f&&p.push(d),Math.abs(r(u,t)-n)<f&&Math.abs(r(u,e)-n)<f&&p.push(u),p},l=[c(s,t,o),c(s,e,o),c(s,n,o),...h(t,e,o),...h(e,n,o),...h(n,t,o)],d=l.filter(a);if(d.length>0){const t=d.filter(t=>!(t=>{const e=1e-6;return Math.abs(t.x-i.minX)<e||Math.abs(t.x-i.maxX)<e||Math.abs(t.y-i.minY)<e||Math.abs(t.y-i.maxY)<e})(t));if(t.length>0)return t.sort((t,e)=>r(t,s)-r(e,s)),t[0]}let u=null,p=1/0;for(let t=i.minX+1;t<i.maxX;t+=5)for(let e=i.minY+1;e<i.maxY;e+=5){const n={x:t,y:e};if(a(n)){const t=r(n,s);t<p&&(p=t,u=n)}}if(null!==u)return u;const f=[];for(let t=0;t<=100;t++){const e=t/100;f.push({x:i.minX+e*(i.maxX-i.minX),y:i.minY}),f.push({x:i.maxX,y:i.minY+e*(i.maxY-i.minY)}),f.push({x:i.maxX-e*(i.maxX-i.minX),y:i.maxY}),f.push({x:i.minX,y:i.maxY-e*(i.maxY-i.minY)})}const g=f.filter(a);if(g.length>0)return g.sort((t,e)=>r(t,s)-r(e,s)),g[0];let m=1/0,y={x:i.minX,y:i.minY};for(const s of[...l,...f])if(s.x>=i.minX&&s.x<=i.maxX&&s.y>=i.minY&&s.y<=i.maxY){const i=Math.max(0,o-r(s,t))+Math.max(0,o-r(s,e))+Math.max(0,o-r(s,n));i<m&&(m=i,y=s)}return y}function uo(t,e,n){const o=po(e,t,n.center,n.radius),i=po(t,e,n.center,n.radius),s=fo(o,e),r=fo(t,i),a=1e-6;let c;if(s>a&&r>a){c={x:(o.x+i.x)/2,y:(o.y+i.y)/2};const s=fo(o,c),r=fo(i,c);if(Math.abs(s-r)>.5*Math.min(s,r)){const n=fo(t,o),s=fo(e,i),r=n+s;if(r>a){const t=s/r,e=n/r;c={x:o.x*t+i.x*e,y:o.y*t+i.y*e}}}const h=fo(c,n.center);if(h<1.05*n.radius){const t={x:(c.x-n.center.x)/h,y:(c.y-n.center.y)/h};c={x:n.center.x+t.x*n.radius*1.2,y:n.center.y+t.y*n.radius*1.2}}}else{const o={x:(t.x+e.x)/2,y:(t.y+e.y)/2},i=fo(o,n.center);if(i<1.1*n.radius){const t={x:(o.x-n.center.x)/i,y:(o.y-n.center.y)/i};c={x:n.center.x+t.x*n.radius*1.2,y:n.center.y+t.y*n.radius*1.2}}else c=o}return{B:o,D:i,E:c}}function po(t,e,n,o){const i=[n.x-t.x,n.y-t.y],s=Math.sqrt(i[0]*i[0]+i[1]*i[1]);if(s<=o){if(s<1e-8){const i=[e.x-t.x,e.y-t.y],s=Math.sqrt(i[0]*i[0]+i[1]*i[1]);return s<1e-8?{x:n.x+o,y:n.y}:{x:n.x+i[0]/s*o,y:n.y+i[1]/s*o}}const r=[i[0]/s,i[1]/s];return{x:n.x-r[0]*o,y:n.y-r[1]*o}}const r=[e.x-t.x,e.y-t.y],a=Math.sqrt(s*s-o*o),c=[i[0]/s,i[1]/s],h=[-c[1],c[0]],l=[c[1],-c[0]],d=r[0]*h[0]+r[1]*h[1]>r[0]*l[0]+r[1]*l[1]?h:l,u=o/s,p=a/s,f=[c[0]*p+d[0]*u,c[1]*p+d[1]*u];return{x:t.x+a*f[0],y:t.y+a*f[1]}}function fo(t,e){const n=e.x-t.x,o=e.y-t.y;return Math.sqrt(n*n+o*o)}var go=1e-9;function mo(t,e,n,o="cw"){const i=yo(t,n),s=yo(e,n);return Math.abs(s-i)<go?{left:0,top:0,right:0,bottom:0}:function(t,e,n,o){const i=n.maxX-n.minX,s=n.maxY-n.minY;if(i<go&&s<go)return{left:0,top:0,right:0,bottom:0};const r=2*(i+s);if(r<go)return{left:0,top:0,right:0,bottom:0};const a=i/r*(2*Math.PI),c=(i+s)/r*(2*Math.PI),h=(i+i+s)/r*(2*Math.PI),l=2*Math.PI,d=[{name:"top",start:0,end:a,length:i},{name:"right",start:a,end:c,length:s},{name:"bottom",start:c,end:h,length:i},{name:"left",start:h,end:l,length:s}],u={left:0,top:0,right:0,bottom:0},p=(t,e,n,o,i)=>{const s=e>2*Math.PI-go?2*Math.PI:e;if(s<=t+go)return 0;if(i){const e=Math.max(t,n),i=Math.min(s,2*Math.PI),r=Math.max(0,i-e),a=Math.max(t,0),c=Math.min(s,o);return r+Math.max(0,c-a)}{const e=Math.max(t,n),i=Math.min(s,o);return Math.max(0,i-e)}};for(const n of d){const i=n.end-n.start;if(i<go||n.length<go)continue;let s=0;if("cw"===o){const o=t>e+go;s=p(n.start,n.end,t,e,o)}else{const o=e>t+go;s=p(n.start,n.end,e,t,o)}if(s>go){const t=s/i;u[n.name]+=Math.max(0,Number.isFinite(t)?t:0)}}for(const t in u)u[t]=Math.max(0,Math.min(1,u[t]));return u}(i,s,n,o)}function yo(t,e){const n=e.maxX-e.minX,o=e.maxY-e.minY;if(n<go&&o<go)return 0;const i=2*(n+o);if(i<go)return 0;let s=0;if(Math.abs(t.y-e.maxY)<go&&t.x>=e.minX-go&&t.x<=e.maxX+go)s=Math.max(0,Math.min(n,t.x-e.minX));else if(Math.abs(t.x-e.maxX)<go&&t.y>=e.minY-go&&t.y<=e.maxY+go)s=n+Math.max(0,Math.min(o,e.maxY-t.y));else if(Math.abs(t.y-e.minY)<go&&t.x>=e.minX-go&&t.x<=e.maxX+go)s=n+o+Math.max(0,Math.min(n,e.maxX-t.x));else{if(!(Math.abs(t.x-e.minX)<go&&t.y>=e.minY-go&&t.y<=e.maxY+go))throw new Error(`Point (${t.x}, ${t.y}) does not lie on the boundary defined by ${JSON.stringify(e)}`);s=n+o+n+Math.max(0,Math.min(o,t.y-e.minY))}return s=Math.max(0,Math.min(i,s)),i>go?s/i*(2*Math.PI):0}function xo(t,e,n,o){return function({angleA:t,angleB:e,angleC:n}){const o=Math.cos(t),i=Math.sin(t),s=Math.cos(e),r=Math.sin(e),a=Math.cos(n);return(s-o)*(Math.sin(n)-i)-(r-i)*(a-o)<0?"ccw":"cw"}({angleA:yo(t,o),angleB:yo(e,o),angleC:yo(n,o)})}var vo=class extends Dn{getSolverName(){return"SingleTransitionCrossingRouteSolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;layerCount=2;debugViaPositions;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.layerCount=t?.layerCount??2,this.debugViaPositions=[],this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),2!==this.routes.length)return this.failed=!0,void(this.error=`Expected 2 routes, but got ${this.routes.length}`);const e=this.routes.flatMap(t=>[t.A,t.B]).map(t=>this.getPortPointBoundsPosition(t));if(e.includes("outside"))return this.failed=!0,void(this.error="Invalid route input: SingleTransitionCrossingRouteSolver received port point(s) outside node bounds");if(e.includes("inside"))return void(this.failed=!0);const[n,o]=this.routes,i=n.A.z!==n.B.z,s=o.A.z!==o.B.z;return i&&s||!i&&!s?(this.failed=!0,void(this.error="Exactly one route must have a layer transition")):void 0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e)?.push(t)}for(const[e,o]of n.entries())2===o.length&&t.push({A:{...o[0],z:o[0].z??0},B:{...o[1],z:o[1].z??0},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}getPortPointBoundsPosition(t,e=1e-6){return ho({point:t,bounds:this.bounds,epsilon:e})}doRoutesCross(t,e){return D(t.A,t.B,e.A,e.B)}calculateViaPosition(t,e){const n=e.A.z,o=t.A.z!==n?t.A:t.B,i=2*this.obstacleMargin+this.viaDiameter/2+this.traceThickness,s=this.obstacleMargin+this.viaDiameter/2,r=e.A,a=o,c=e.B,h=xo(r,a,c,this.bounds),l=function(t,e,n,o,i){const s=mo(t,e,o,i),r=mo(e,n,o,i),a={left:Math.min(1,s.left+r.left),top:Math.min(1,s.top+r.top),right:Math.min(1,s.right+r.right),bottom:Math.min(1,s.bottom+r.bottom)};for(const t in a)Math.abs(a[t])<go&&(a[t]=0);return a}(r,a,c,this.bounds,h),d={minX:this.bounds.minX+(l.left>.5?i:s),minY:this.bounds.minY+(l.bottom>.5?i:s),maxX:this.bounds.maxX-(l.right>.5?i:s),maxY:this.bounds.maxY-(l.top>.5?i:s)};return d.maxY<d.minY&&(d.minY=(d.minY+d.maxY)/2,d.maxY=d.minY),d.maxX<d.minX&&(d.minX=(d.minX+d.maxX)/2,d.maxX=d.minX),lo(r,a,c,i,d)}createTransitionRoute(t,e,n,o){return{connectionName:o,route:[{x:t.x,y:t.y,z:t.z??0},{x:n.x,y:n.y,z:t.z??0},{x:n.x,y:n.y,z:e.z??0},{x:e.x,y:e.y,z:e.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[n]}}createFlatRoute(t,e,n,o,i,s){o.z,t.z;const r=this.viaDiameter/2+this.traceThickness/2+this.obstacleMargin,a=((t,e,n,o)=>{const i=n.x-t.x,s=n.y-t.y;return((t,e)=>({x:(t.x+e.x)/2,y:(t.y+e.y)/2}))({x:t.x+i*e,y:t.y+s*e},{x:n.x-i*o,y:n.y-s*o})})(n,this.viaDiameter,o.z!==t.z?o:i,this.traceThickness),c={center:{x:n.x,y:n.y},radius:r},h=uo(t,a,c).E,l=uo(a,e,c).E,d=uo(t,h,c).E,u=uo(h,a,c).E,p=uo(a,l,c).E,f=uo(l,e,c).E,g=uo(u,p,c).E;return{connectionName:s,route:[{x:t.x,y:t.y,z:t.z??0},{x:d.x,y:d.y,z:t.z??0},{x:h.x,y:h.y,z:t.z??0},{x:u.x,y:u.y,z:t.z??0},{x:g.x,y:g.y,z:t.z??0},{x:p.x,y:p.y,z:t.z??0},{x:l.x,y:l.y,z:t.z??0},{x:f.x,y:f.y,z:t.z??0},{x:e.x,y:e.y,z:e.z??0}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[]}}trySolve(){const[t,e]=this.routes,n=t.A.z!==t.B.z,o=n?t:e,i=n?e:t,s=this.calculateViaPosition(o,i);if(!s)return!1;this.debugViaPositions.push({via:s});const r=this.createTransitionRoute(o.A,o.B,s,o.connectionName),a=this.createFlatRoute(i.A,i.B,s,o.A,o.B,i.connectionName);return this.solvedRoutes.push(r,a),!0}_step(){if(!this.doRoutesCross(this.routes[0],this.routes[1]))return this.failed=!0,void(this.error="Can only solve routes that have a single transition crossing");this.trySolve()?this.solved=!0:(this.failed=!0,this.error="Failed to find a valid via position and route path")}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)",label:"PCB Bounds"});for(const e of this.routes)t.points.push({x:e.A.x,y:e.A.y,label:`${e.connectionName} start (z=${e.A.z})`,color:"orange"}),t.points.push({x:e.B.x,y:e.B.y,label:`${e.connectionName} end (z=${e.B.z})`,color:"orange"}),t.lines.push({points:[e.A,e.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e.connectionName} direct`});for(let e=0;e<this.debugViaPositions.length;e++){const{via:n}=this.debugViaPositions[e];t.circles.push({center:n,radius:this.viaDiameter/2,fill:"rgba(255, 165, 0, 0.7)",stroke:"rgba(0, 0, 0, 0.5)",label:`Computed Via (attempt ${e+1})`});const o=this.viaDiameter/2+this.obstacleMargin;t.circles.push({center:n,radius:o,stroke:"rgba(255, 165, 0, 0.7)",fill:"rgba(0, 0, 0, 0)",label:"Safety Margin"})}for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],o=e%2==0?"rgba(0, 255, 0, 0.75)":"rgba(255, 0, 255, 0.75)";for(let e=0;e<n.route.length-1;e++){const i=n.route[e],s=n.route[e+1];t.lines.push({points:[i,s],strokeColor:o,strokeDash:i.z!==n.route[0].z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${i.z}`})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Via Margin"})}return t}getSolvedRoutes(){return this.solvedRoutes}},bo=class extends Dn{getSolverName(){return"SingleTransitionIntraNodeSolver"}nodeWithPortPoints;routes;viaDiameter;traceThickness;obstacleMargin;solvedRoutes=[];bounds;constructor(t){if(super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.viaDiameter=t?.viaDiameter??.3,this.traceThickness=t?.traceThickness??.15,this.obstacleMargin=t?.obstacleMargin??.1,this.routes=this.extractRoutesFromNode(),this.bounds=this.calculateBounds(),1!==this.routes.length)return this.failed=!0,void(this.error=`Expected 1 route, but got ${this.routes.length}`);const e=this.routes[0];if(void 0===e.A.z||void 0===e.B.z)return this.failed=!0,void(this.error="Route points should have predefined z values");if(e.A.z===e.B.z)return this.failed=!0,void(this.error="Only one route provided, but it has no transition");const n=this.viaDiameter/2+this.obstacleMargin,o={x:z((e.A.x+e.B.x)/2,this.bounds.minX+n,this.bounds.maxX-n),y:z((e.A.y+e.B.y)/2,this.bounds.minY+n,this.bounds.maxY-n)};this.solvedRoutes.push(this.createTransitionRoute(e.A,e.B,o,e.connectionName)),this.solved=!0}extractRoutesFromNode(){const t=[],e=this.nodeWithPortPoints.portPoints,n=new Map;for(const t of e){const{connectionName:e}=t;n.has(e)||n.set(e,[]),n.get(e).push(t)}for(const[e,o]of n.entries())2===o.length&&t.push({A:{...o[0]},B:{...o[1]},connectionName:e});return t}calculateBounds(){return{minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2}}createTransitionRoute(t,e,n,o){return{connectionName:o,route:[{x:t.x,y:t.y,z:t.z},{x:n.x,y:n.y,z:t.z},{x:n.x,y:n.y,z:e.z},{x:e.x,y:e.y,z:e.z}],traceThickness:this.traceThickness,viaDiameter:this.viaDiameter,vias:[n]}}_step(){this.solved=!0}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(t.rects.push({center:{x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY,stroke:"rgba(0, 0, 0, 0.5)",fill:"rgba(240, 240, 240, 0.1)",label:"PCB Bounds"}),this.routes.length>0)for(const e of this.routes)t.points.push({x:e.A.x,y:e.A.y,label:`${e.connectionName} start (z=${e.A.z})`,color:"orange"}),t.points.push({x:e.B.x,y:e.B.y,label:`${e.connectionName} end (z=${e.B.z})`,color:"orange"}),t.lines.push({points:[e.A,e.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:`${e.connectionName} direct`});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e],o="rgba(0, 255, 0, 0.75)";for(let e=0;e<n.route.length-1;e++){const i=n.route[e],s=n.route[e+1];t.lines.push({points:[i,s],strokeColor:o,strokeDash:i.z!==n.route[0].z?[.2,.2]:void 0,strokeWidth:n.traceThickness,label:`${n.connectionName} z=${i.z}`})}for(const e of n.vias)t.circles.push({center:e,radius:this.viaDiameter/2,fill:"rgba(0, 0, 255, 0.8)",stroke:"black",label:"Solved Via"}),t.circles.push({center:e,radius:this.viaDiameter/2+this.obstacleMargin,fill:"rgba(0, 0, 255, 0.3)",stroke:"black",label:"Via Margin"})}return t}},Po=(t,e)=>{const n={};return t.portPoints.forEach((e,o)=>{n[e.connectionName]=`hsl(${360*o/t.portPoints.length}, 100%, 50%)`}),n},So=class extends Dn{getSolverName(){return"ViaPossibilitiesSolver2"}bounds;maxViaCount;portPairMap;colorMap;nodeWidth;availableZ;hyperParameters;VIA_INTERSECTION_BUFFER_DISTANCE=.05;PLACEHOLDER_WALL_BUFFER_DISTANCE=.1;NEW_HEAD_WALL_BUFFER_DISTANCE=.05;viaDiameter;unprocessedConnections;completedPaths=new Map;placeholderPaths=new Map;currentHead;currentConnectionName;currentPath;currentViaCount;constructor({nodeWithPortPoints:t,colorMap:e,hyperParameters:n,viaDiameter:o}){super(),this.MAX_ITERATIONS=1e5,this.colorMap=e??Po(t),this.maxViaCount=5,this.bounds=Me(t),this.nodeWidth=this.bounds.maxX-this.bounds.minX,this.portPairMap=(t=>{const e=new Map;return t.portPoints.forEach(t=>{e.has(t.connectionName)?e.get(t.connectionName).end=t:e.set(t.connectionName,{start:t,end:null,connectionName:t.connectionName})}),e})(t),this.stats.solutionsFound=0,this.availableZ=t.availableZ??[0,1],this.hyperParameters=n??{SHUFFLE_SEED:0},this.viaDiameter=o??.3,this.unprocessedConnections=Array.from(this.portPairMap.keys()).sort(),n?.SHUFFLE_SEED&&(this.unprocessedConnections=Un(this.unprocessedConnections,n.SHUFFLE_SEED));for(const[t,{start:e,end:n}]of this.portPairMap.entries())if(e.z===n.z){const o=Math.abs(e.x-n.x)<1e-9,i=Math.abs(e.y-n.y)<1e-9;o||i?this.placeholderPaths.set(t,[e,this._padByPlaceholderWallBuffer(e),this._padByPlaceholderWallBuffer(n),n]):this.placeholderPaths.set(t,[e,n])}else{const o=(e.x+n.x)/2,i=(e.y+n.y)/2,s=this._padByPlaceholderWallBuffer({x:o,y:i,z:e.z}),r=this._padByPlaceholderWallBuffer({x:o,y:i,z:n.z});this.placeholderPaths.set(t,[e,this._padByPlaceholderWallBuffer(e),s,r,this._padByPlaceholderWallBuffer(n),n])}this.currentConnectionName=this.unprocessedConnections.pop();const i=this.portPairMap.get(this.currentConnectionName).start;this.currentHead=this._padByNewHeadWallBuffer(i),this.currentPath=[i,this.currentHead],this.currentViaCount=0,this.placeholderPaths.delete(this.currentConnectionName)}_padByNewHeadWallBuffer(t){return{x:z(t.x,this.bounds.minX+this.NEW_HEAD_WALL_BUFFER_DISTANCE,this.bounds.maxX-this.NEW_HEAD_WALL_BUFFER_DISTANCE),y:z(t.y,this.bounds.minY+this.NEW_HEAD_WALL_BUFFER_DISTANCE,this.bounds.maxY-this.NEW_HEAD_WALL_BUFFER_DISTANCE),z:t.z}}_padByPlaceholderWallBuffer(t){return{x:z(t.x,this.bounds.minX+this.PLACEHOLDER_WALL_BUFFER_DISTANCE,this.bounds.maxX-this.PLACEHOLDER_WALL_BUFFER_DISTANCE),y:z(t.y,this.bounds.minY+this.PLACEHOLDER_WALL_BUFFER_DISTANCE,this.bounds.maxY-this.PLACEHOLDER_WALL_BUFFER_DISTANCE),z:t.z}}_step(){if(this.solved)return;const t=this.portPairMap.get(this.currentConnectionName).end,e=[this.currentHead,t];let n=null,o=null;const i=t=>{for(const i of t.values())for(let t=0;t<i.length-1;t++){const s=[i[t],i[t+1]];if(s[0].x===s[1].x&&s[0].y===s[1].y)continue;if(s[0].z!==this.currentHead.z)continue;const r=k(e[0],e[1],s[0],s[1]);if(r){const t=F(this.currentHead,r);if(t<1e-6)continue;(!n||t<n.dist)&&(n={point:r,dist:t},o=s[0].z)}}};i(this.completedPaths),i(this.placeholderPaths);const s=this.currentHead.z!==t.z;if((n||s)&&(this.currentViaCount++,this.currentViaCount>=this.maxViaCount))return this.failed=!0,void(this.error=`Exceeded max via count of ${this.maxViaCount}`);if(n){let t;const e=n.dist;if(e<=this.VIA_INTERSECTION_BUFFER_DISTANCE+1e-6)t=B(this.currentHead,n.point);else{const o=n.point,i=o.x-this.currentHead.x,s=o.y-this.currentHead.y,r=(e-this.VIA_INTERSECTION_BUFFER_DISTANCE)/e;t={x:this.currentHead.x+i*r,y:this.currentHead.y+s*r}}const i=this.availableZ.find(t=>t!==o);if(void 0===i)return this.error="Could not determine next Z level for via placement!",void(this.failed=!0);const s={...t,z:this.currentHead.z},r={...t,z:i};this.currentPath.push(s,r),this.currentHead=r}else if(s){let e;const n=F(this.currentHead,t);if(n<this.VIA_INTERSECTION_BUFFER_DISTANCE)e=B(this.currentHead,t);else{const o=t.x-this.currentHead.x,i=t.y-this.currentHead.y,s=(n-this.VIA_INTERSECTION_BUFFER_DISTANCE)/n;e={x:this.currentHead.x+o*s,y:this.currentHead.y+i*s}}const o=t.z,i={...e,z:this.currentHead.z},s={...e,z:o};this.currentPath.push(i,s),this.currentHead=s}else if(this.currentPath.push(t),this.completedPaths.set(this.currentConnectionName,this.currentPath),0===this.unprocessedConnections.length)this.solved=!0,this.stats.solutionsFound=1;else{this.currentConnectionName=this.unprocessedConnections.pop();const{start:t}=this.portPairMap.get(this.currentConnectionName);this.currentHead=this._padByNewHeadWallBuffer(t),this.currentPath=[t,this.currentHead],this.currentViaCount=0,this.placeholderPaths.delete(this.currentConnectionName)}}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Via Possibilities Solver State",coordinateSystem:"cartesian"},e=this.colorMap;t.lines.push({points:[{x:this.bounds.minX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.minY}],strokeColor:"gray",strokeWidth:.01});for(const[e,{start:n,end:o}]of this.portPairMap.entries()){const i=this.colorMap[e]??"black";t.points.push({x:n.x,y:n.y,color:i,label:`Port: ${e} Start (z${n.z})`}),t.points.push({x:o.x,y:o.y,color:i,label:`Port: ${e} End (z${o.z})`})}const n=(n,o)=>{for(const[i,s]of n.entries()){const n=e[i]??"black";for(let e=0;e<s.length-1;e++){const r=s[e],a=s[e+1];r.x===a.x&&r.y===a.y&&r.z!==a.z?t.circles.push({center:{x:r.x,y:r.y},radius:this.viaDiameter/2,fill:Mn(n,.5),label:`${o}: ${i} Via (z${r.z}->z${a.z})`}):t.lines.push({points:[r,a],strokeColor:Mn(n,.5),strokeDash:0===r.z?void 0:[.1,.1],strokeWidth:.1,label:`${o}: ${i} (z${r.z})`})}}};if(n(this.placeholderPaths,"Placeholder"),n(this.completedPaths,"Completed"),this.currentPath&&this.currentPath.length>0){const n=e[this.currentConnectionName]??"orange";for(let e=0;e<this.currentPath.length-1;e++){const o=this.currentPath[e],i=this.currentPath[e+1];o.x===i.x&&o.y===i.y&&o.z!==i.z?t.circles.push({center:{x:o.x,y:o.y},radius:this.viaDiameter/2,fill:Mn(n,.5),label:`Current: ${this.currentConnectionName} Via (z${o.z}->z${i.z})`}):t.lines.push({points:[o,i],strokeColor:Mn(n,.5),strokeWidth:.15,strokeDash:"2,2",label:`Current: ${this.currentConnectionName} (z${o.z})`})}t.points.push({x:this.currentHead.x,y:this.currentHead.y,color:"green",label:`Current Head: ${this.currentConnectionName} (z${this.currentHead.z})`})}return t}},Io=t=>Math.round(1e4*t),Mo=t=>{let e=0,n=[];const o=[];for(const e of t.portPoints){if(n.some(t=>t.connectionName===e.connectionName))continue;if(o.some(t=>t.connectionName===e.connectionName))continue;const i={connectionName:e.connectionName,z:e.z,points:[{x:Io(e.x),y:Io(e.y),z:e.z}]};for(const n of t.portPoints)e.connectionName===n.connectionName&&(e.x===n.x&&e.y===n.y||i.points.push({x:Io(n.x),y:Io(n.y),z:n.z}));i.points.some(t=>t.z!==i.z)?o.push(i):n.push(i)}n=n.filter(t=>t.points.length>1);for(let t=0;t<n.length;t++)for(let o=t+1;o<n.length;o++){const i=n[t],s=n[o];i.z===s.z&&D(i.points[0],i.points[1],s.points[0],s.points[1])&&e++}let i=0;for(let t=0;t<o.length;t++)for(let e=t+1;e<o.length;e++){const n=o[t],s=o[e];D(n.points[0],n.points[1],s.points[0],s.points[1])&&i++}return{numSameLayerCrossings:e,numEntryExitLayerChanges:o.length,numTransitionPairCrossings:i}};var _o=t=>{const{start:e,end:n,segmentsPerPolyline:o,viaPositions:i,viaCount:s,availableZ:r}=t,a=function(t,e){const n=new Array(t).fill(0);if(0===e)return n;if(e===t)return n.fill(1);if(e<=t/2){const o=Math.floor(t/e),i=Math.floor((t-(o*(e-1)+1))/2);for(let t=0;t<e;t++)n[i+t*o]=1}else{const o=t-e,i=Math.floor(t/o),s=Math.floor((t-(i*(o-1)+1))/2);n.fill(1);for(let t=0;t<o;t++)n[s+t*i]=0}return n}(o,s),c=a.map(()=>null);let h=0,l=e.z1;const d=r.indexOf(e.z1);for(let t=0;t<a.length;t++)if(1===a[t]){const e=r[(d+h+1)%r.length];c[t]={...i[h],z1:l,z2:e},l=e,h++}let u=e;for(let t=0;t<c.length;t++){if(c[t]){u=c[t];continue}let e=n,o=c.length;for(let n=t+1;n<c.length;n++)if(c[n]){e=c[n],o=n;break}const i=o-t,s=e.x-u.x,r=e.y-u.y;for(let e=1/(i+1),n=0;t+n!==o;e+=1/(i+1),n++)c[t+n]={x:u.x+s*e,y:u.y+r*e,z1:u.z2,z2:u.z2}}return c},No=1e-9;function Co(t,e){return Math.abs(t-e)<No}function To(t){return`${Math.round(t.x/No)}:${Math.round(t.y/No)}`}function Eo(t,e,n,o){return t*o-e*n}function wo(t,e,n,o){const i={x:e.x-t.x,y:e.y-t.y},s={x:o.x-n.x,y:o.y-n.y},r=Eo(i.x,i.y,s.x,s.y),a={x:n.x-t.x,y:n.y-t.y};if(Co(r,0))return null;const c=Eo(a.x,a.y,s.x,s.y)/r,h=Eo(a.x,a.y,i.x,i.y)/r;return c>=-1e-9&&c<=1+No&&h>=-1e-9&&h<=1+No?{x:t.x+c*i.x,y:t.y+c*i.y}:null}function Ro(t,e,n){return Co(Math.hypot(t.x-e.x,t.y-e.y)+Math.hypot(t.x-n.x,t.y-n.y),Math.hypot(e.x-n.x,e.y-n.y))}function Oo(t,e){const n=[],o=new Map;for(const e of t){const t=[e.start,...e.mPoints,e.end];for(let i=0;i<t.length-1;i++){const s=t[i],r=t[i+1],a=s.z2;if(n.push({start:{x:s.x,y:s.y},end:{x:r.x,y:r.y},connectionName:e.connectionName,layer:a}),s.z1!==s.z2){const t=To(s);o.has(t)||o.set(t,{point:s,connectionName:e.connectionName})}}const i=t[t.length-1];if(i.z1!==i.z2){const t=To(i);o.has(t)||o.set(t,{point:i,connectionName:e.connectionName})}}const i=[{start:{x:e.minX,y:e.minY},end:{x:e.maxX,y:e.minY},connectionName:null,layer:0},{start:{x:e.maxX,y:e.minY},end:{x:e.maxX,y:e.maxY},connectionName:null,layer:0},{start:{x:e.maxX,y:e.maxY},end:{x:e.minX,y:e.maxY},connectionName:null,layer:0},{start:{x:e.minX,y:e.maxY},end:{x:e.minX,y:e.minY},connectionName:null,layer:0}];n.push(...i);const s=new Map;let r=0;function a(t,e){const n=To(t);let i=s.get(n);if(!i){const e=o.has(n);i={id:r++,x:t.x,y:t.y,isVia:e,connectionNames:new Set,outgoingEdges:[]},s.set(n,i),e&&o.get(n)&&i.connectionNames.add(o.get(n).connectionName)}return e&&i.connectionNames.add(e),i}for(const t of n)a(t.start,t.connectionName),a(t.end,t.connectionName);const c=new Map;for(const t of n)c.set(t,[]);for(let t=0;t<n.length;t++)for(let e=t+1;e<n.length;e++){if(n[t].layer!==n[e].layer)continue;const o=wo(n[t].start,n[t].end,n[e].start,n[e].end);o&&(a(o),Ro(o,n[t].start,n[t].end)&&c.get(n[t]).push(o),Ro(o,n[e].start,n[e].end)&&c.get(n[e]).push(o))}const h=[];let l=0;for(const t of n){const e=[t.start,...c.get(t),t.end];e.sort((e,n)=>{const o=t.end.x-t.start.x,i=t.end.y-t.start.y;return Math.abs(o)>Math.abs(i)?(e.x-t.start.x)/o-(n.x-t.start.x)/o:Math.abs(i)<No?0:(e.y-t.start.y)/i-(n.y-t.start.y)/i});const n=[];if(e.length>0){n.push(e[0]);for(let t=1;t<e.length;t++)Co(e[t].x,e[t-1].x)&&Co(e[t].y,e[t-1].y)||n.push(e[t])}for(let e=0;e<n.length-1;e++){const o=n[e],i=n[e+1],s=a(o,t.connectionName),r=a(i,t.connectionName);if(s===r)continue;const c={id:l++,origin:s,twin:null,next:null,face:null,connectionName:t.connectionName,layer:t.layer,visited:!1},d={id:l++,origin:r,twin:c,next:null,face:null,connectionName:t.connectionName,layer:t.layer,visited:!1};c.twin=d,h.push(c,d),s.outgoingEdges.push(c),r.outgoingEdges.push(d)}}for(const t of s.values()){t.outgoingEdges.sort((e,n)=>{const o=e.twin.origin,i=n.twin.origin;return Math.atan2(o.y-t.y,o.x-t.x)-Math.atan2(i.y-t.y,i.x-t.x)});const e=t.outgoingEdges.length;for(let n=0;n<e;n++){const o=t.outgoingEdges[n],i=t.outgoingEdges[(n-1+e)%e];o.twin&&(o.twin.next=i)}}const d=[];let u=0,p=null,f=-1/0;for(const t of h){if(t.visited)continue;const e={id:u++,outerComponent:t,innerComponents:[],isOuterFace:!1};d.push(e);let n=t;const o=[],i=[],s=new Set;let r=0;do{if(!n||n.visited){console.warn("Face traversal encountered visited edge or null, breaking loop.",e.id),o.length=0;break}n.visited=!0,n.face=e,o.push(n),i.push(n.origin),null!==n.connectionName&&s.add(n.connectionName);const t=n.origin,a=n.twin.origin;r+=t.x*a.y-a.x*t.y,n=n.next}while(n!==t&&null!==n);if(n===t){if(r=.5*Math.abs(r),r>f&&(f=r,p&&(p.isOuterFace=!1),p=e,e.isOuterFace=!0),!e.isOuterFace&&o.length>0){if([...s].filter(t=>null!==t).length>1){let t=!1;for(const e of i)if(e.isVia){t=!0;break}if(!t)return!0}}}else console.warn(`Face ${e.id} did not close properly.`),d.pop(),u--}return!1}var Ao=t=>{if(0===t.length)return[[]];const e=[];for(let n=0;n<t.length;n++){const o=t[n],i=[...t.slice(0,n),...t.slice(n+1)],s=Ao(i);for(const t of s)e.push([o,...t])}return e},zo=1e-9;function Do(t,e,n=1e-9){return Math.abs(t-e)<n}function Lo(t,e,n,o){return t*o-e*n}function Yo(t,e,n,o){const i={x:e.x-t.x,y:e.y-t.y},s={x:o.x-n.x,y:o.y-n.y},r=Lo(i.x,i.y,s.x,s.y);if(Do(r,0))return null;const a={x:n.x-t.x,y:n.y-t.y},c=Lo(a.x,a.y,s.x,s.y)/r,h=Lo(a.x,a.y,i.x,i.y)/r;return c<-1e-9||c>1+zo||h<-1e-9||h>1+zo?null:{x:t.x+c*i.x,y:t.y+c*i.y}}function Xo(t){let e=0;for(let n=0,o=t.length;n<o;++n){const i=(n+1)%o;e+=t[n].x*t[i].y-t[i].x*t[n].y}return.5*e}function Fo(t){let e=0,n=0,o=0;for(let i=0,s=t.length;i<s;++i){const r=(i+1)%s,a=t[i].x*t[r].y-t[r].x*t[i].y;e+=a,n+=(t[i].x+t[r].x)*a,o+=(t[i].y+t[r].y)*a}return e*=.5,Do(e,0)?null:(n/=6*e,o/=6*e,{x:n,y:o})}var ko=class{x;y;out;connectionNames;constructor(t,e){this.x=t,this.y=e,this.out=[],this.connectionNames=new Set}},$o=class{orig;dest;twin;next;visited;constructor(t,e){this.orig=t,this.dest=e,this.twin=null,this.next=null,this.visited=!1}};function Bo(t,e){const n=[...e,...[{start:{x:t.minX,y:t.minY},end:{x:t.maxX,y:t.minY}},{start:{x:t.maxX,y:t.minY},end:{x:t.maxX,y:t.maxY}},{start:{x:t.maxX,y:t.maxY},end:{x:t.minX,y:t.maxY}},{start:{x:t.minX,y:t.maxY},end:{x:t.minX,y:t.minY}}]],o=n.map(()=>[]);for(let t=0;t<n.length;++t){const e=n[t];o[t].push(e.start,e.end)}for(let t=0;t<n.length;++t)for(let e=t+1;e<n.length;++e){const i=Yo(n[t].start,n[t].end,n[e].start,n[e].end);i&&(o[t].push(i),o[e].push(i))}const i=new Map,s=[];function r(t){const e=function(t,e=1e-9){return`${Math.round(t.x/e)}:${Math.round(t.y/e)}`}(t);if(!i.has(e)){const n=s.length;return i.set(e,n),s.push(new ko(t.x,t.y)),n}return i.get(e)}const a=[];for(let t=0;t<n.length;++t){const e=n[t],i=o[t].slice();i.sort((t,n)=>{const o=e.end.x-e.start.x,i=e.end.y-e.start.y;return(Do(Math.abs(o),0)?(t.y-e.start.y)/i:(t.x-e.start.x)/o)-(Do(Math.abs(o),0)?(n.y-e.start.y)/i:(n.x-e.start.x)/o)});for(let t=0;t<i.length-1;++t){const n=i[t],o=i[t+1],c=r(n),h=r(o);c!==h&&(a.push([c,h]),e.connectionName&&(s[c].connectionNames.add(e.connectionName),s[h].connectionNames.add(e.connectionName)))}}const c=[];for(const[t,e]of a){const n=new $o(t,e),o=new $o(e,t);n.twin=c.length+1,o.twin=c.length;const i=c.length;c.push(n,o),s[t].out.push(i),s[e].out.push(i+1)}for(let t=0;t<s.length;++t){const e=s[t];e.out.sort((t,n)=>{const o=c[t],i=c[n],r=s[o.dest],a=s[i.dest];return Math.atan2(r.y-e.y,r.x-e.x)-Math.atan2(a.y-e.y,a.x-e.x)});const n=e.out.length;for(let t=0;t<n;++t){const o=e.out[t],i=e.out[(t-1+n)%n],s=c[o];null!==s.twin&&(c[s.twin].next=i)}}const h=[],l=[];for(let t=0;t<c.length;++t){if(c[t].visited)continue;let e=t;const n=[],o=[];do{if(null===e)break;const t=c[e];t.visited=!0,n.push(s[t.orig]),o.push(e),e=t.next}while(null!==e&&e!==t&&!c[e].visited);if(n.length<3)continue;if(Xo(n)>zo){const t=Fo(n);t&&(h.push(t),l.push({vertices:n.map(t=>({x:t.x,y:t.y,connectionNames:t.connectionNames.size>0?t.connectionNames:void 0})),centroid:t}))}}return{centroids:h,faces:l,allVertices:s}}function jo(t,e){if(t>e)throw new Error("oneCount cannot be greater than length");if(t<0||e<0)throw new Error("oneCount and length must be non-negative");const n=[];return function t(o,i,s){s!==e?(o[s]=0,t(o,i,s+1),i>0&&(o[s]=1,t(o,i-1,s+1))):0===i&&n.push([...o])}(Array(e).fill(0),t,0),n}var Wo=class extends Dn{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver"}nodeWithPortPoints;colorMap;hyperParameters;connMap;candidates;bounds;solvedRoutes=[];unsolvedConnections=[];SEGMENTS_PER_POLYLINE;cellSize;MAX_CANDIDATES=5e4;viaDiameter=.3;obstacleMargin=.1;traceWidth=.15;availableZ=[];uniqueConnections=0;BOUNDARY_PADDING;lastCandidate=null;maxViaCount;minViaCount;phase="setup";progress=0;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??Po(t.nodeWithPortPoints),this.hyperParameters=t.hyperParameters??{},this.SEGMENTS_PER_POLYLINE=t.hyperParameters?.SEGMENTS_PER_POLYLINE??3,this.BOUNDARY_PADDING=t.hyperParameters?.BOUNDARY_PADDING??.05,this.connMap=t.connMap,this.viaDiameter=t.viaDiameter??this.viaDiameter,this.cellSize=this.nodeWithPortPoints.width/1024,this.candidates=[],this.availableZ=this.nodeWithPortPoints.availableZ??[0,1],this.bounds={minX:this.nodeWithPortPoints.center.x-this.nodeWithPortPoints.width/2,maxX:this.nodeWithPortPoints.center.x+this.nodeWithPortPoints.width/2,minY:this.nodeWithPortPoints.center.y-this.nodeWithPortPoints.height/2,maxY:this.nodeWithPortPoints.center.y+this.nodeWithPortPoints.height/2};const e=this.nodeWithPortPoints.width*this.nodeWithPortPoints.height,n=(this.viaDiameter+2*this.obstacleMargin+this.traceWidth/2)**2,o=new Set(this.nodeWithPortPoints.portPoints.map(t=>t.connectionName)).size;this.uniqueConnections=o;const{numSameLayerCrossings:i,numEntryExitLayerChanges:s}=Mo(this.nodeWithPortPoints);if(this.minViaCount=2*i+s,this.maxViaCount=Math.min(Math.floor(e/n),Math.ceil(1.5*o)),this.minViaCount>this.SEGMENTS_PER_POLYLINE*(o/2))return this.failed=!0,void(this.error=`Not possible to solve problem with given SEGMENTS_PER_POLYLINE (${this.SEGMENTS_PER_POLYLINE}), atleast ${this.minViaCount} vias are required`);this.maxViaCount>this.SEGMENTS_PER_POLYLINE&&(this.maxViaCount=this.SEGMENTS_PER_POLYLINE),this.maxViaCount<this.minViaCount&&(this.maxViaCount=this.minViaCount)}computeMinGapBtwPolyLines(t){const e=[],n=[],o=[];for(let e=0;e<t.length;e++){const i=t[e],s=[i.start,...i.mPoints,i.end],r=new Map(this.availableZ.map(t=>[t,[]]));for(let t=0;t<s.length-1;t++){const e=[s[t],s[t+1]],n=e[0].z2;r.has(n)||r.set(n,[]),r.get(n).push(e)}n.push(r),o.push(s.filter(t=>t.z1!==t.z2))}for(let i=0;i<t.length;i++){const s=n[i],r=o[i];for(let a=i+1;a<t.length;a++){if(this.connMap?.areIdsConnected(t[i].connectionName,t[a].connectionName))continue;const c=n[a],h=o[a];let l=1;for(const t of this.availableZ){const e=s.get(t)??[],n=c.get(t)??[];for(const t of e)for(const e of n)l=Math.min(l,J(t[0],t[1],e[0],e[1])-this.traceWidth);for(const t of r)for(const e of n)l=Math.min(l,X(t,e[0],e[1])-this.traceWidth/2-this.viaDiameter/2);for(const t of h)for(const n of e)l=Math.min(l,X(t,n[0],n[1])-this.traceWidth/2-this.viaDiameter/2);for(const t of r)for(const e of h)l=Math.min(l,F(t,e)-this.viaDiameter)}e.push(l)}}return e}insertCandidate(t){let e=0,n=this.candidates.length-1;for(;e<=n;){const o=Math.floor((e+n)/2);this.candidates[o].f<t.f?e=o+1:n=o-1}this.candidates.splice(e,0,t)}setupInitialPolyLines(){const t=new Map;this.nodeWithPortPoints.portPoints.forEach(e=>{t.has(e.connectionName)?t.get(e.connectionName).end={...e,z1:e.z??0,z2:e.z??0}:t.set(e.connectionName,{start:{...e,z1:e.z??0,z2:e.z??0},end:null})});for(const[e,n]of t.entries())null===n.end&&t.delete(e);if(0===t.size)return this.failed=!0,void(this.error="No port pairs found, can't solve");const e=Array.from(t.entries()),n=((t,e,n,o)=>{const i=[];for(const[,n]of t){const t=n.start.z1!==n.end.z1,o=[];for(let n=0;n<=e;n++){const e=n%2!=0;t&&e?o.push(n):t||e||o.push(n)}i.push(o)}if(0===i.length)return[[]];let s=(t=>{if(!t||0===t.length)return[[]];let e=[[]];for(const n of t){const t=[];for(const o of e)for(const e of n)t.push([...o,e]);e=t}return e})(i).filter(t=>{for(let e=0;e<t.length;e++)if(t.reduce((t,e)=>t+e,0)<o)return!1;return!0});return s=s.filter(e=>{for(let n=0;n<t.length;n++){const[,o]=t[n];if(o.start.z1!==o.start.z2&&0===e[n])return!1}return!0}),s=s.filter(e=>{for(let n=0;n<t.length;n++){const[,o]=t[n];if(t[n][1].start.z1===t[n][1].start.z2)for(let i=n+1;i<t.length;i++){if(t[i][1].start.z1!==t[i][1].start.z2)continue;const[,s]=t[i];if(o.start.z1===o.end.z1&&s.start.z1===s.end.z1&&o.start.z1===s.start.z1&&D(o.start,o.end,s.start,s.end)&&e[n]+e[i]<2)return!1}}return!0}),s=s.filter(t=>!(t.reduce((t,e)=>t+e,0)>n)),s})(e,this.SEGMENTS_PER_POLYLINE,this.maxViaCount,this.minViaCount),o=(t=>{const{bounds:e,portPairsEntries:n,viaCountVariants:o}=t,{centroids:i}=Bo(e,n.map(([t,e])=>e)),s=[];for(const t of o){const n=t.reduce((t,e)=>t+e,0);let o=i;if(i.length<n){o=[];const t=Math.ceil(Math.sqrt(n)),i=t;for(let n=0;n<t;n++)for(let s=0;s<i;s++)o.push({x:e.minX+(s+1)/(i+1)*(e.maxX-e.minX),y:e.minY+(n+1)/(t+1)*(e.maxY-e.minY)})}const r=jo(n,o.length);for(const e of r){const n=[];for(let t=0;t<e.length;t++)1===e[t]&&n.push(o[t]);s.push({viaPositions:n,viaCountVariant:t})}}return s})({portPairsEntries:e,viaCountVariants:n,bounds:this.bounds}),i=[];for(const{viaCountVariant:t,viaPositions:e}of o){const n=Ao(e);for(const e of n)i.push({viaCountVariant:t,viaPositions:e})}for(const{viaPositions:t,viaCountVariant:n}of i){const o=[];let i=0;for(let s=0;s<e.length;s++){const[r,a]=e[s],c=n[s],h=t.slice(i,i+c),l=_o({start:a.start,end:a.end,segmentsPerPolyline:this.SEGMENTS_PER_POLYLINE,viaPositions:h,viaCount:c,availableZ:this.availableZ});i+=c,o.push({connectionName:r,start:a.start,end:a.end,mPoints:l})}if(Oo(o,this.bounds))continue;const s=this.computeMinGapBtwPolyLines(o),r=this.computeH({minGaps:s,forces:[]}),a={polyLines:o,g:0,h:r,f:r,viaCount:n.reduce((t,e)=>t+e,0),minGaps:s};if(this.checkIfSolved(a))return void(this.candidates=[a]);if(this.candidates.push(a),this.candidates.length>this.MAX_CANDIDATES)return}this.candidates.sort((t,e)=>t.f-e.f)}computeG(t,e){return e.g+5e-6+5e-6*e.viaCount*100}computeH(t){let e=0;for(const n of t.forces??[])for(const t of n)for(const n of t.values())e+=n.fx*n.fx+n.fy*n.fy;return e}getNeighbors(t){const{polyLines:e}=t,n=e.length,o=.02,i=.008,s=1e-6,r=Array.from({length:n},(t,n)=>Array.from({length:e[n].mPoints.length},()=>new Map)),a=(t,n,o,i,s)=>{if(n>0&&n<e[t].mPoints.length+1){const e=n-1,a=r[t][e],c=a.get(o)||{fx:0,fy:0};a.set(o,{fx:c.fx+i,fy:c.fy+s})}};for(let t=0;t<n;t++)for(let i=t+1;i<n;i++){const n=e[t],r=e[i],c=[n.start,...n.mPoints,n.end],h=[r.start,...r.mPoints,r.end],l=[],d=[];for(let t=0;t<c.length-1;t++)l.push({p1:c[t],p2:c[t+1],layer:c[t].z2,p1Idx:t,p2Idx:t+1});c.forEach((t,e)=>{t.z1!==t.z2&&d.push({point:t,layers:[t.z1,t.z2],index:e})});const u=[],p=[];for(let t=0;t<h.length-1;t++)u.push({p1:h[t],p2:h[t+1],layer:h[t].z2,p1Idx:t,p2Idx:t+1});h.forEach((t,e)=>{t.z1!==t.z2&&p.push({point:t,layers:[t.z1,t.z2],index:e})});for(const e of l)for(const n of u)if(e.layer===n.layer){if(J(e.p1,e.p2,n.p1,n.p2)<s)continue;const o={x:(e.p1.x+e.p2.x)/2,y:(e.p1.y+e.p2.y)/2},r={x:(n.p1.x+n.p2.x)/2,y:(n.p1.y+n.p2.y)/2},c=o.x-r.x,h=o.y-r.y,l=c*c+h*h;if(l>s){const o=Math.sqrt(l),r=(Math.exp(-6*o),`seg:${i}:${n.p1Idx}:${n.p2Idx}`),c=`seg:${t}:${e.p1Idx}:${e.p2Idx}`,h=(t,e,n,o,i,r,c)=>{const h=Q(t,n.p1,n.p2),l=t.x-h.x,d=t.y-h.y,u=l*l+d*d;if(u<=s)return;const p=Math.sqrt(u),f=.02*Math.exp(-6*p),g=l/p*f,m=d/p*f;a(o,e,r,g,m),a(i,n.p1Idx,c,-g/2,-m/2),a(i,n.p2Idx,c,-g/2,-m/2)};h(e.p1,e.p1Idx,n,t,i,r,c),h(e.p2,e.p2Idx,n,t,i,r,c),h(n.p1,n.p1Idx,e,i,t,c,r),h(n.p2,n.p2Idx,e,i,t,c,r)}}for(const e of d)for(const n of u)if(e.layers.includes(n.layer)){const r=Q(e.point,n.p1,n.p2),c=e.point.x-r.x,h=e.point.y-r.y,l=c*c+h*h;if(l>s){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(s,r)):u=Math.max(s,r-this.viaDiameter/2);const p=d*o*Math.exp(-6*u),f=c/r*p,g=h/r*p,m=`seg:${i}:${n.p1Idx}:${n.p2Idx}`;a(t,e.index,m,f,g);const y=`via:${t}:${e.index}`;a(i,n.p1Idx,y,-f/2,-g/2),a(i,n.p2Idx,y,-f/2,-g/2)}}for(const e of p)for(const n of l)if(e.layers.includes(n.layer)){const r=Q(e.point,n.p1,n.p2),c=e.point.x-r.x,h=e.point.y-r.y,l=c*c+h*h;if(l>s){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(s,r)):u=Math.max(s,r-this.viaDiameter/2);const p=d*o*Math.exp(-6*u),f=c/r*p,g=h/r*p,m=`seg:${t}:${n.p1Idx}:${n.p2Idx}`;a(i,e.index,m,f,g);const y=`via:${i}:${e.index}`;a(t,n.p1Idx,y,-f/2,-g/2),a(t,n.p2Idx,y,-f/2,-g/2)}}for(const e of d)for(const n of p){if(e.layers.filter(t=>n.layers.includes(t)).length>0){const r=e.point.x-n.point.x,c=e.point.y-n.point.y,h=r*r+c*c;if(h>s){const l=Math.sqrt(h);let d=2,u=l;l<this.viaDiameter?(d*=4,u=Math.max(s,l)):u=Math.max(s,l-this.viaDiameter);const p=d*o*Math.exp(-6*u),f=r/l*p,g=c/l*p,m=`via:${i}:${n.index}`,y=`via:${t}:${e.index}`;a(t,e.index,m,f,g),a(i,n.index,y,-f,-g)}}}}for(let t=0;t<n;t++){const n=e[t],i=[n.start,...n.mPoints,n.end],r=[];if(i.forEach((t,e)=>{t.z1!==t.z2&&r.push({point:t,layers:[t.z1,t.z2],index:e})}),!(r.length<2))for(let e=0;e<r.length;e++)for(let n=e+1;n<r.length;n++){const i=r[e],c=r[n],h=i.point.x-c.point.x,l=i.point.y-c.point.y,d=h*h+l*l;if(d>s){const e=Math.sqrt(d);let n=2,r=e;e<this.viaDiameter?(n*=4,r=Math.max(s,e)):r=Math.max(s,e-this.viaDiameter);const u=n*o*Math.exp(-6*r),p=h/e*u,f=l/e*u,g=`via:${t}:${c.index}`,m=`via:${t}:${i.index}`;a(t,i.index,g,p,f),a(t,c.index,m,-p,-f)}}}const c=e.map(t=>({...t,mPoints:t.mPoints.map(t=>({...t}))}));let h=!1;for(let t=0;t<n;t++)for(let e=0;e<c[t].mPoints.length;e++){const n=c[t].mPoints[e],o=r[t][e],a={fx:0,fy:0};for(const t of o.values())a.fx+=t.fx,a.fy+=t.fy;const l=n.z1!==n.z2;let d=n.x+a.fx,u=n.y+a.fy;if(l){const t=this.viaDiameter/2;let e=0,o=0;const s=this.viaDiameter/2+this.BOUNDARY_PADDING,r=this.bounds.minX+s,c=this.bounds.maxX-s,h=this.bounds.minY+s,l=this.bounds.maxY-s,p=r+t-n.x,f=n.x-(c-t),g=h+t-n.y,m=n.y-(l-t);p>0?e=i*(Math.exp(p/(2*this.obstacleMargin))-1):f>0&&(e=-.008*(Math.exp(f/(2*this.obstacleMargin))-1)),g>0?o=i*(Math.exp(g/(2*this.obstacleMargin))-1):m>0&&(o=-.008*(Math.exp(m/(2*this.obstacleMargin))-1)),a.fx+=e,a.fy+=o,d=n.x+a.fx,u=n.y+a.fy}else{const t=this.traceWidth/2+this.BOUNDARY_PADDING;d=Math.max(this.bounds.minX+t,Math.min(this.bounds.maxX-t,d)),u=Math.max(this.bounds.minY+t,Math.min(this.bounds.maxY-t,u))}Math.abs(a.fx)<s&&Math.abs(a.fy)<s||(Math.abs(n.x-d)>s||Math.abs(n.y-u)>s)&&(n.x=d,n.y=u,h=!0)}if(!h)return[];const l=this.computeMinGapBtwPolyLines(c),d=this.computeG(c,t),u=this.computeH({minGaps:l,forces:r});return[{polyLines:c,g:d,h:u,f:Math.round(5*d)/5+u,minGaps:l,forces:r,viaCount:t.viaCount}]}checkIfSolved(t){const e=t.minGaps.every(t=>t>=this.obstacleMargin),n=t.polyLines.every(t=>t.mPoints.every(t=>{const e=(t.z1!==t.z2?this.viaDiameter/2:this.traceWidth/2)+this.BOUNDARY_PADDING;return((t,e,n=0)=>t.x>=e.minX+n&&t.x<=e.maxX-n&&t.y>=e.minY+n&&t.y<=e.maxY-n)(t,this.bounds,e)}));return e&&n}tryFinalAcceptance(){const t=this.hyperParameters?.MINIMUM_FINAL_ACCEPTANCE_GAP??void 0;if(void 0===t||null===this.lastCandidate||0===this.lastCandidate.minGaps.length)return;return Math.min(...this.lastCandidate.minGaps)>=t?(this.solved=!0,void this._setSolvedRoutes()):void 0}_step(){if("setup"===this.phase)return this.setupInitialPolyLines(),void(this.phase="solving");const t=this.candidates.shift();if(!t){if(this.tryFinalAcceptance(),this.solved)return;return this.failed=!0,void(this.error="No candidates left")}if(this.lastCandidate=t,this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();if(!t)return void(this.failed=!0);const e=this.getNeighbors(t);for(const t of e)this.insertCandidate(t)}visualize(){const t={points:[],lines:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"MultiHeadPolyLineIntraNodeSolver Visualization"};t.lines.push({points:[{x:this.bounds.minX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.minY},{x:this.bounds.maxX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.maxY},{x:this.bounds.minX,y:this.bounds.minY}],strokeColor:"gray"});const e=this.lastCandidate??this.candidates[0];if(e?.hasClosedSameLayerFace){const e=.1*(this.bounds.maxX-this.bounds.minX),n=.1*(this.bounds.maxY-this.bounds.minY);t.rects.push({center:{x:this.bounds.maxX+.6*e,y:this.bounds.maxY+.6*n},width:e,height:n,fill:"red",label:"HAS CLOSED FACE"})}for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:`${e.connectionName} (Port z=${e.z??0})`,color:this.colorMap[e.connectionName]??"blue"});return e&&e.polyLines.forEach((n,o)=>{const i=this.colorMap[n.connectionName]??"purple",s=[n.start,...n.mPoints,n.end];for(let e=0;e<s.length-1;e++){const o=s[e],r=s[e+1],a=o.z2,c=0===a,h=c?i:Mn(i,.5);t.lines.push({points:[o,r],strokeColor:h,strokeWidth:this.traceWidth,strokeDash:c?void 0:[.15,.15],label:`${n.connectionName} segment (z=${a})`})}s.forEach((r,a)=>{const c=r.z1!==r.z2,h=r.z1,l=a>0&&a<s.length-1;let d="",u="";if(l){const i=a-1,s=e.forces?.[o]?.[i];if(s&&s.size>0){const o={fx:0,fy:0};s.forEach((s,a)=>{if(o.fx+=s.fx,o.fy+=s.fy,Math.abs(s.fx)>1e-6||Math.abs(s.fy)>1e-6){const o=a.split(":"),c=o[0],h=parseInt(o[1],10),l=e.polyLines[h],d=this.colorMap[l.connectionName]??"gray",u=20,p={x:r.x+s.fx*u,y:r.y+s.fy*u};let f=l.connectionName;if("via"===c){f+=` Via ${parseInt(o[2],10)}`}else if("seg"===c){f+=` Seg ${parseInt(o[2],10)}-${parseInt(o[3],10)}`}t.lines.push({points:[r,p],strokeColor:d,strokeWidth:.02,strokeDash:"2,2",label:`Force by ${f} on ${n.connectionName} mPoint ${i}`})}}),(Math.abs(o.fx)>1e-6||Math.abs(o.fy)>1e-6)&&(u=`\nNet Force: (${o.fx.toFixed(3)}, ${o.fy.toFixed(3)})`)}}if(c)d=`Via (${n.connectionName} z=${r.z1} -> z=${r.z2})${u}`,t.circles.push({center:r,radius:this.viaDiameter/2,fill:Mn(i,.5),label:d});else if(l){const e=0===h?i:Mn(i,.5);d=`mPoint (${n.connectionName} z=${h})${u}`,t.circles.push({center:r,radius:this.cellSize/8,fill:e,label:d})}})}),t}_setSolvedRoutes(){if(!this.solved||!this.lastCandidate)return[];const t=[];for(const e of this.lastCandidate.polyLines){const n=[],o=[],i=[e.start,...e.mPoints,e.end];for(let t=0;t<i.length;t++){const e=i[t];n.push({x:e.x,y:e.y,z:e.z1}),e.z1!==e.z2&&(o.push({x:e.x,y:e.y}),n.push({x:e.x,y:e.y,z:e.z2}))}t.push({connectionName:e.connectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:n,vias:o})}this.solvedRoutes=t}},Vo=class extends Wo{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver2"}computeG(t,e){return e.g+5e-6+5e-6*e.viaCount*100}computeH(t){const{minGaps:e}=t;let n=0;for(const t of e)t<0&&(n+=this.obstacleMargin),t<this.obstacleMargin&&(n+=this.obstacleMargin-t);return.011*n}_step(){if("setup"===this.phase)return this.setupInitialPolyLines(),void(this.phase="solving");const t=this.candidates.shift();if(!t){if(this.tryFinalAcceptance(),this.solved)return;return void(this.failed=!0)}if(this.lastCandidate=t,this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();let e=!1,n=0;const o=void 0===t.magForceApplied?1:10;for(let i=0;i<o;i++){const o=this.applyForcesToPolyLines(t.polyLines);if(n+=o.magForceApplied,e=o.lastStepMoved,!o.lastStepMoved)break}if(t.magForceApplied=n,t.minGaps=this.computeMinGapBtwPolyLines(t.polyLines),this.checkIfSolved(t))return this.solved=!0,void this._setSolvedRoutes();t.g=this.computeG(t.polyLines,t),t.h=this.computeH(t),t.f=t.g+t.h,e&&this.insertCandidate(t)}applyForcesToPolyLines(t){let e=0;const n=t.length,o=.02,i=.008,s=1e-6,r=Array.from({length:n},(e,n)=>Array.from({length:t[n].mPoints.length},()=>({fx:0,fy:0}))),a=(e,n,o,i)=>{if(n>0&&n<t[e].mPoints.length+1){const t=n-1;r[e][t].fx+=o,r[e][t].fy+=i}},c=(t,e,n,o,i)=>{const r=Q(t,n.p1,n.p2),c=t.x-r.x,h=t.y-r.y,l=c*c+h*h;if(l<=s)return;const d=Math.sqrt(l),u=.02*Math.exp(-6*d),p=c/d*u,f=h/d*u;a(o,e,p,f),a(i,n.p1Idx,-p/2,-f/2),a(i,n.p2Idx,-p/2,-f/2)};for(let e=0;e<n;e++)for(let i=e+1;i<n;i++){const n=t[e],r=t[i],h=[n.start,...n.mPoints,n.end],l=[r.start,...r.mPoints,r.end],d=[],u=[];for(let t=0;t<h.length-1;t++)d.push({p1:h[t],p2:h[t+1],layer:h[t].z2,p1Idx:t,p2Idx:t+1});h.forEach((t,e)=>{t.z1!==t.z2&&u.push({point:t,layers:[t.z1,t.z2],index:e})});const p=[],f=[];for(let t=0;t<l.length-1;t++)p.push({p1:l[t],p2:l[t+1],layer:l[t].z2,p1Idx:t,p2Idx:t+1});l.forEach((t,e)=>{t.z1!==t.z2&&f.push({point:t,layers:[t.z1,t.z2],index:e})});for(const t of d)for(const n of p)if(t.layer===n.layer){J(t.p1,t.p2,n.p1,n.p2);c(t.p1,t.p1Idx,n,e,i),c(t.p2,t.p2Idx,n,e,i),c(n.p1,n.p1Idx,t,i,e),c(n.p2,n.p2Idx,t,i,e)}for(const t of u)for(const n of p)if(t.layers.includes(n.layer)){const r=Q(t.point,n.p1,n.p2),c=t.point.x-r.x,h=t.point.y-r.y,l=c*c+h*h;if(l>s){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(s,r)):u=Math.max(s,r-this.viaDiameter/2);const p=d*o*Math.exp(-6*u),f=c/r*p,g=h/r*p;a(e,t.index,f,g),a(i,n.p1Idx,-f/2,-g/2),a(i,n.p2Idx,-f/2,-g/2)}}for(const t of f)for(const n of d)if(t.layers.includes(n.layer)){const r=Q(t.point,n.p1,n.p2),c=t.point.x-r.x,h=t.point.y-r.y,l=c*c+h*h;if(l>s){const r=Math.sqrt(l);let d=2,u=r;r<this.viaDiameter/2?(d*=4,u=Math.max(s,r)):u=Math.max(s,r-this.viaDiameter/2);const p=d*o*Math.exp(-6*u),f=c/r*p,g=h/r*p;a(i,t.index,f,g),a(e,n.p1Idx,-f/2,-g/2),a(e,n.p2Idx,-f/2,-g/2)}}for(const t of u)for(const n of f){if(t.layers.filter(t=>n.layers.includes(t)).length>0){const r=t.point.x-n.point.x,c=t.point.y-n.point.y,h=r*r+c*c;if(h>s){const l=Math.sqrt(h);let d=2,u=l;l<this.viaDiameter?(d*=4,u=Math.max(s,l)):u=Math.max(s,l-this.viaDiameter);const p=d*o*Math.exp(-6*u),f=r/l*p,g=c/l*p;a(e,t.index,f,g),a(i,n.index,-f,-g)}}}}for(let e=0;e<n;e++){const n=t[e],i=[n.start,...n.mPoints,n.end],r=[];if(i.forEach((t,e)=>{t.z1!==t.z2&&r.push({point:t,layers:[t.z1,t.z2],index:e})}),!(r.length<2))for(let t=0;t<r.length;t++)for(let n=t+1;n<r.length;n++){const i=r[t],c=r[n],h=i.point.x-c.point.x,l=i.point.y-c.point.y,d=h*h+l*l;if(d>s){const t=Math.sqrt(d);let n=2,r=t;t<this.viaDiameter?(n*=4,r=Math.max(s,t)):r=Math.max(s,t-this.viaDiameter);const u=n*o*Math.exp(-6*r),p=h/t*u,f=l/t*u;a(e,i.index,p,f),a(e,c.index,-p,-f)}}}let h=!1;for(let o=0;o<n;o++)for(let n=0;n<t[o].mPoints.length;n++){const a=t[o].mPoints[n],c=r[o][n],l=a.z1!==a.z2;let d=c.fx,u=c.fy,p=a.x+d,f=a.y+u;if(l){const t=this.viaDiameter/2;let e=0,n=0;const o=this.viaDiameter/2+this.BOUNDARY_PADDING,s=this.bounds.minX+o,r=this.bounds.maxX-o,c=this.bounds.minY+o,h=this.bounds.maxY-o,l=s+t-a.x,g=a.x-(r-t),m=c+t-a.y,y=a.y-(h-t);l>0?e=i*(Math.exp(l/(2*this.obstacleMargin))-1):g>0&&(e=-.008*(Math.exp(g/(2*this.obstacleMargin))-1)),m>0?n=i*(Math.exp(m/(2*this.obstacleMargin))-1):y>0&&(n=-.008*(Math.exp(y/(2*this.obstacleMargin))-1)),d+=e,u+=n,p=a.x+d,f=a.y+u}else{const t=this.traceWidth/2+this.BOUNDARY_PADDING;p=Math.max(this.bounds.minX+t,Math.min(this.bounds.maxX-t,p)),f=Math.max(this.bounds.minY+t,Math.min(this.bounds.maxY-t,f))}if(Math.abs(d)<s&&Math.abs(u)<s)continue;e+=Math.sqrt(d*d+u*u),(Math.abs(a.x-p)>s||Math.abs(a.y-f)>s)&&(a.x=p,a.y=f,h=!0)}return{lastStepMoved:h,magForceApplied:e}}},Ho=t=>t.flatMap(t=>`${t.connectionName}-${t.mPoints.map(t=>`${t.x.toFixed(2)},${t.y.toFixed(2)},${t.z1},${t.z2}`)}`).sort().join("|");var Uo=class extends Vo{getSolverName(){return"MultiHeadPolyLineIntraNodeSolver3"}constructor(t){super(t),this.MAX_ITERATIONS=1e3}createInitialCandidateFromSeed(t){const e=new So({nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,hyperParameters:{SHUFFLE_SEED:t},viaDiameter:this.viaDiameter});if(e.solve(),e.failed||!e.solved)return this.failed=!0,this.error=`ViaPossibilitiesSolver2 failed with: ${e.error}`,null;const n=[];let o=0;for(const[t,i]of e.completedPaths.entries()){if(i.length<2){console.warn(`Skipping connection "${t}" due to insufficient points (${i.length}) in ViaPossibilitiesSolver2 path.`);continue}const e=i[0],s=i[i.length-1],r=i.slice(1,-1),a=[];let c=0,h=e.z;for(let t=0;t<r.length;t++){const e=r[t],n=t+1<r.length?r[t+1]:s,o=h,i=t+1<r.length&&e.x===n.x&&e.y===n.y&&e.z!==n.z?n.z:e.z;a.push({x:e.x,y:e.y,z1:o,z2:i}),o!==i?(c++,t++,h=i):h=e.z}o+=c;const l=this.SEGMENTS_PER_POLYLINE;let d=a.length+1;for(;d<l;){let n=-1,o=-1,i=null,r=null;const c=[{...e,z1:e.z,z2:e.z,connectionName:t},...a,{...s,z1:s.z,z2:s.z,connectionName:t}];for(let t=0;t<c.length-1;t++){const e=c[t],s=c[t+1];if(e.x===s.x&&e.y===s.y)continue;const a=F(e,s);a>n&&(n=a,o=t,i=e,r=s)}if(-1===o||!i||!r){console.warn(`Could not find longest segment for ${t} while trying to reach ${l} segments.`);break}const h=(i.x+r.x)/2,u=(i.y+r.y)/2,p=i.z2,f={x:h,y:u,z1:p,z2:p};a.splice(o,0,f),d++}n.push({connectionName:t,start:{...e,z1:e.z,z2:e.z},end:{...s,z1:s.z,z2:s.z},mPoints:a})}if(0===n.length)return this.failed=!0,this.error="No valid polylines generated from ViaPossibilitiesSolver2.",console.error(this.error),null;const i=this.computeMinGapBtwPolyLines(n),s=this.computeH({minGaps:i,forces:[]}),r={polyLines:n,g:0,h:s,f:0+s,viaCount:o,minGaps:i};return r.g=this.computeG(n,r),r.f=r.g+r.h,r}setupInitialPolyLines(){this.candidates=[];const t=Math.min(2e3,function(t){if(!Number.isInteger(t)||t<0)throw new RangeError("n must be a non-negative integer");let e=1;for(let n=2;n<=t;n++)e*=n;return e}(this.uniqueConnections)),e=new Set;for(let n=0;n<t;n++){const t=this.createInitialCandidateFromSeed(n);if(!t)continue;const o=Ho(t.polyLines);e.has(o)||(e.add(o),this.candidates.push(t))}this.candidates.sort((t,e)=>t.f-e.f)}};import{HighDensitySolverA01 as Go,HighDensitySolverA02 as Zo}from"@tscircuit/high-density-a01";var qo=Object.create,Jo=Object.defineProperty,Ko=Object.getOwnPropertyDescriptor,Qo=Object.getOwnPropertyNames,ti=Object.getPrototypeOf,ei=Object.prototype.hasOwnProperty,ni=(t,e)=>function(){return e||(0,t[Qo(t)[0]])((e={exports:{}}).exports,e),e.exports},oi=ni({"node_modules/binary-search-bounds/search-bounds.js"(t,e){function n(t,e,n,o,i){for(var s=i+1;o<=i;){var r=o+i>>>1,a=t[r];(void 0!==n?n(a,e):a-e)>=0?(s=r,i=r-1):o=r+1}return s}function o(t,e,n,o,i){for(var s=i+1;o<=i;){var r=o+i>>>1,a=t[r];(void 0!==n?n(a,e):a-e)>0?(s=r,i=r-1):o=r+1}return s}function i(t,e,n,o,i){for(var s=o-1;o<=i;){var r=o+i>>>1,a=t[r];(void 0!==n?n(a,e):a-e)<0?(s=r,o=r+1):i=r-1}return s}function s(t,e,n,o,i){for(var s=o-1;o<=i;){var r=o+i>>>1,a=t[r];(void 0!==n?n(a,e):a-e)<=0?(s=r,o=r+1):i=r-1}return s}function r(t,e,n,o,i){for(;o<=i;){var s=o+i>>>1,r=t[s],a=void 0!==n?n(r,e):r-e;if(0===a)return s;a<=0?o=s+1:i=s-1}return-1}function a(t,e,n,o,i,s){return"function"==typeof n?s(t,e,n,void 0===o?0:0|o,void 0===i?t.length-1:0|i):s(t,e,void 0,void 0===n?0:0|n,void 0===o?t.length-1:0|o)}e.exports={ge:function(t,e,o,i,s){return a(t,e,o,i,s,n)},gt:function(t,e,n,i,s){return a(t,e,n,i,s,o)},lt:function(t,e,n,o,s){return a(t,e,n,o,s,i)},le:function(t,e,n,o,i){return a(t,e,n,o,i,s)},eq:function(t,e,n,o,i){return a(t,e,n,o,i,r)}}}}),ii=ni({"node_modules/two-product/two-product.js"(t,e){e.exports=function(t,e,o){var i=t*e,s=n*t,r=s-(s-t),a=t-r,c=n*e,h=c-(c-e),l=e-h,d=a*l-(i-r*h-a*h-r*l);if(o)return o[0]=d,o[1]=i,o;return[d,i]};var n=+(Math.pow(2,27)+1)}}),si=ni({"node_modules/robust-sum/robust-sum.js"(t,e){e.exports=function(t,e){var n=0|t.length,o=0|e.length;if(1===n&&1===o)return function(t,e){var n=t+e,o=n-t,i=n-o,s=e-o,r=t-i,a=r+s;if(a)return[a,n];return[n]}(t[0],e[0]);var i,s,r=new Array(n+o),a=0,c=0,h=0,l=Math.abs,d=t[c],u=l(d),p=e[h],f=l(p);u<f?(s=d,(c+=1)<n&&(u=l(d=t[c]))):(s=p,(h+=1)<o&&(f=l(p=e[h])));c<n&&u<f||h>=o?(i=d,(c+=1)<n&&(u=l(d=t[c]))):(i=p,(h+=1)<o&&(f=l(p=e[h])));var g,m,y=i+s,x=y-i,v=s-x,b=v,P=y;for(;c<n&&h<o;)u<f?(i=d,(c+=1)<n&&(u=l(d=t[c]))):(i=p,(h+=1)<o&&(f=l(p=e[h]))),(v=(s=b)-(x=(y=i+s)-i))&&(r[a++]=v),b=P-((g=P+y)-(m=g-P))+(y-m),P=g;for(;c<n;)(v=(s=b)-(x=(y=(i=d)+s)-i))&&(r[a++]=v),b=P-((g=P+y)-(m=g-P))+(y-m),P=g,(c+=1)<n&&(d=t[c]);for(;h<o;)(v=(s=b)-(x=(y=(i=p)+s)-i))&&(r[a++]=v),b=P-((g=P+y)-(m=g-P))+(y-m),P=g,(h+=1)<o&&(p=e[h]);b&&(r[a++]=b);P&&(r[a++]=P);a||(r[a++]=0);return r.length=a,r}}}),ri=ni({"node_modules/two-sum/two-sum.js"(t,e){e.exports=function(t,e,n){var o=t+e,i=o-t,s=e-i,r=t-(o-i);if(n)return n[0]=r+s,n[1]=o,n;return[r+s,o]}}}),ai=ni({"node_modules/robust-scale/robust-scale.js"(t,e){var n=ii(),o=ri();e.exports=function(t,e){var i=t.length;if(1===i){var s=n(t[0],e);return s[0]?s:[s[1]]}var r=new Array(2*i),a=[.1,.1],c=[.1,.1],h=0;n(t[0],e,a),a[0]&&(r[h++]=a[0]);for(var l=1;l<i;++l){n(t[l],e,c);var d=a[1];o(d,c[0],a),a[0]&&(r[h++]=a[0]);var u=c[1],p=a[1],f=u+p,g=p-(f-u);a[1]=f,g&&(r[h++]=g)}a[1]&&(r[h++]=a[1]);0===h&&(r[h++]=0);return r.length=h,r}}}),ci=ni({"node_modules/robust-subtract/robust-diff.js"(t,e){e.exports=function(t,e){var n=0|t.length,o=0|e.length;if(1===n&&1===o)return function(t,e){var n=t+e,o=n-t,i=n-o,s=e-o,r=t-i,a=r+s;if(a)return[a,n];return[n]}(t[0],-e[0]);var i,s,r=new Array(n+o),a=0,c=0,h=0,l=Math.abs,d=t[c],u=l(d),p=-e[h],f=l(p);u<f?(s=d,(c+=1)<n&&(u=l(d=t[c]))):(s=p,(h+=1)<o&&(f=l(p=-e[h])));c<n&&u<f||h>=o?(i=d,(c+=1)<n&&(u=l(d=t[c]))):(i=p,(h+=1)<o&&(f=l(p=-e[h])));var g,m,y=i+s,x=y-i,v=s-x,b=v,P=y;for(;c<n&&h<o;)u<f?(i=d,(c+=1)<n&&(u=l(d=t[c]))):(i=p,(h+=1)<o&&(f=l(p=-e[h]))),(v=(s=b)-(x=(y=i+s)-i))&&(r[a++]=v),b=P-((g=P+y)-(m=g-P))+(y-m),P=g;for(;c<n;)(v=(s=b)-(x=(y=(i=d)+s)-i))&&(r[a++]=v),b=P-((g=P+y)-(m=g-P))+(y-m),P=g,(c+=1)<n&&(d=t[c]);for(;h<o;)(v=(s=b)-(x=(y=(i=p)+s)-i))&&(r[a++]=v),b=P-((g=P+y)-(m=g-P))+(y-m),P=g,(h+=1)<o&&(p=-e[h]);b&&(r[a++]=b);P&&(r[a++]=P);a||(r[a++]=0);return r.length=a,r}}}),hi=ni({"node_modules/robust-orientation/orientation.js"(t,e){var n=ii(),o=si(),i=ai(),s=ci();function r(t,e,n,o){return function(n,i,s){var r=t(t(e(i[1],s[0]),e(-s[1],i[0])),t(e(n[1],i[0]),e(-i[1],n[0]))),a=t(e(n[1],s[0]),e(-s[1],n[0])),c=o(r,a);return c[c.length-1]}}function a(t,e,n,o){return function(i,s,r,a){var c=t(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),s[2]),t(n(t(e(s[1],a[0]),e(-a[1],s[0])),-r[2]),n(t(e(s[1],r[0]),e(-r[1],s[0])),a[2]))),t(n(t(e(s[1],a[0]),e(-a[1],s[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),a[2])))),h=t(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),t(n(t(e(s[1],r[0]),e(-r[1],s[0])),i[2]),t(n(t(e(i[1],r[0]),e(-r[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),r[2])))),l=o(c,h);return l[l.length-1]}}function c(t,e,n,o){return function(i,s,r,a,c){var h=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-a[2]),n(t(e(r[1],a[0]),e(-a[1],r[0])),c[2]))),s[3]),t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),s[2]),t(n(t(e(s[1],c[0]),e(-c[1],s[0])),-a[2]),n(t(e(s[1],a[0]),e(-a[1],s[0])),c[2]))),-r[3]),n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),s[2]),t(n(t(e(s[1],c[0]),e(-c[1],s[0])),-r[2]),n(t(e(s[1],r[0]),e(-r[1],s[0])),c[2]))),a[3]))),t(n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),s[2]),t(n(t(e(s[1],a[0]),e(-a[1],s[0])),-r[2]),n(t(e(s[1],r[0]),e(-r[1],s[0])),a[2]))),-c[3]),t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),s[2]),t(n(t(e(s[1],c[0]),e(-c[1],s[0])),-a[2]),n(t(e(s[1],a[0]),e(-a[1],s[0])),c[2]))),i[3]),n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-a[2]),n(t(e(i[1],a[0]),e(-a[1],i[0])),c[2]))),-s[3])))),t(t(n(t(n(t(e(s[1],c[0]),e(-c[1],s[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),c[2]))),a[3]),t(n(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),a[2]))),-c[3]),n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),s[2]),t(n(t(e(s[1],a[0]),e(-a[1],s[0])),-r[2]),n(t(e(s[1],r[0]),e(-r[1],s[0])),a[2]))),i[3]))),t(n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),-s[3]),t(n(t(n(t(e(s[1],a[0]),e(-a[1],s[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),a[2]))),r[3]),n(t(n(t(e(s[1],r[0]),e(-r[1],s[0])),i[2]),t(n(t(e(i[1],r[0]),e(-r[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),r[2]))),-a[3]))))),l=t(t(t(n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),r[2]),t(n(t(e(r[1],c[0]),e(-c[1],r[0])),-a[2]),n(t(e(r[1],a[0]),e(-a[1],r[0])),c[2]))),i[3]),n(t(n(t(e(a[1],c[0]),e(-c[1],a[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-a[2]),n(t(e(i[1],a[0]),e(-a[1],i[0])),c[2]))),-r[3])),t(n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),c[2]))),a[3]),n(t(n(t(e(r[1],a[0]),e(-a[1],r[0])),i[2]),t(n(t(e(i[1],a[0]),e(-a[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),a[2]))),-c[3]))),t(t(n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),s[2]),t(n(t(e(s[1],c[0]),e(-c[1],s[0])),-r[2]),n(t(e(s[1],r[0]),e(-r[1],s[0])),c[2]))),i[3]),n(t(n(t(e(r[1],c[0]),e(-c[1],r[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-r[2]),n(t(e(i[1],r[0]),e(-r[1],i[0])),c[2]))),-s[3])),t(n(t(n(t(e(s[1],c[0]),e(-c[1],s[0])),i[2]),t(n(t(e(i[1],c[0]),e(-c[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),c[2]))),r[3]),n(t(n(t(e(s[1],r[0]),e(-r[1],s[0])),i[2]),t(n(t(e(i[1],r[0]),e(-r[1],i[0])),-s[2]),n(t(e(i[1],s[0]),e(-s[1],i[0])),r[2]))),-c[3])))),d=o(h,l);return d[d.length-1]}}function h(t){return(3===t?r:4===t?a:c)(o,n,i,s)}var l=h(3),d=h(4),u=[function(){return 0},function(){return 0},function(t,e){return e[0]-t[0]},function(t,e,n){var o,i=(t[1]-n[1])*(e[0]-n[0]),s=(t[0]-n[0])*(e[1]-n[1]),r=i-s;if(i>0){if(s<=0)return r;o=i+s}else{if(!(i<0))return r;if(s>=0)return r;o=-(i+s)}var a=33306690738754716e-32*o;return r>=a||r<=-a?r:l(t,e,n)},function(t,e,n,o){var i=t[0]-o[0],s=e[0]-o[0],r=n[0]-o[0],a=t[1]-o[1],c=e[1]-o[1],h=n[1]-o[1],l=t[2]-o[2],u=e[2]-o[2],p=n[2]-o[2],f=s*h,g=r*c,m=r*a,y=i*h,x=i*c,v=s*a,b=l*(f-g)+u*(m-y)+p*(x-v),P=7771561172376103e-31*((Math.abs(f)+Math.abs(g))*Math.abs(l)+(Math.abs(m)+Math.abs(y))*Math.abs(u)+(Math.abs(x)+Math.abs(v))*Math.abs(p));return b>P||-b>P?b:d(t,e,n,o)}];function p(t){var e=u[t.length];return e||(e=u[t.length]=h(t.length)),e.apply(void 0,t)}function f(t,e,n,o,i,s,r){return function(e,n,a,c,h){switch(arguments.length){case 0:case 1:return 0;case 2:return o(e,n);case 3:return i(e,n,a);case 4:return s(e,n,a,c);case 5:return r(e,n,a,c,h)}for(var l=new Array(arguments.length),d=0;d<arguments.length;++d)l[d]=arguments[d];return t(l)}}!function(){for(;u.length<=5;)u.push(h(u.length));e.exports=f.apply(void 0,[p].concat(u));for(var t=0;t<=5;++t)e.exports[t]=u[t]}()}}),li=ni({"node_modules/cdt2d/lib/monotone.js"(t,e){var n=oi(),o=hi()[3];function i(t,e,n,o,i){this.a=t,this.b=e,this.idx=n,this.lowerIds=o,this.upperIds=i}function s(t,e,n,o){this.a=t,this.b=e,this.type=n,this.idx=o}function r(t,e){var n=t.a[0]-e.a[0]||t.a[1]-e.a[1]||t.type-e.type;return n||(0!==t.type&&(n=o(t.a,t.b,e.b))?n:t.idx-e.idx)}function a(t,e){return o(t.a,t.b,e)}function c(t,e,i,s,r){for(var c=n.lt(e,s,a),h=n.gt(e,s,a),l=c;l<h;++l){for(var d=e[l],u=d.lowerIds,p=u.length;p>1&&o(i[u[p-2]],i[u[p-1]],s)>0;)t.push([u[p-1],u[p-2],r]),p-=1;u.length=p,u.push(r);var f=d.upperIds;for(p=f.length;p>1&&o(i[f[p-2]],i[f[p-1]],s)<0;)t.push([f[p-2],f[p-1],r]),p-=1;f.length=p,f.push(r)}}function h(t,e){var n;return(n=t.a[0]<e.a[0]?o(t.a,t.b,e.a):o(e.b,e.a,t.a))?n:(n=e.b[0]<t.b[0]?o(t.a,t.b,e.b):o(e.b,e.a,t.b))||t.idx-e.idx}function l(t,e,o){var s=n.le(t,o,h),r=t[s],a=r.upperIds,c=a[a.length-1];r.upperIds=[c],t.splice(s+1,0,new i(o.a,o.b,o.idx,[c],a))}function d(t,e,o){var i=o.a;o.a=o.b,o.b=i;var s=n.eq(t,o,h),r=t[s];t[s-1].upperIds=r.upperIds,t.splice(s,1)}e.exports=function(t,e){for(var n=t.length,o=e.length,a=[],h=0;h<n;++h)a.push(new s(t[h],null,0,h));for(h=0;h<o;++h){var u=e[h],p=t[u[0]],f=t[u[1]];p[0]<f[0]?a.push(new s(p,f,2,h),new s(f,p,1,h)):p[0]>f[0]&&a.push(new s(f,p,2,h),new s(p,f,1,h))}a.sort(r);for(var g=a[0].a[0]-(1+Math.abs(a[0].a[0]))*Math.pow(2,-52),m=[new i([g,1],[g,0],-1,[],[],[],[])],y=[],x=(h=0,a.length);h<x;++h){var v=a[h],b=v.type;0===b?c(y,m,t,v.a,v.idx):2===b?l(m,t,v):d(m,t,v)}return y}}}),di=ni({"node_modules/cdt2d/lib/triangulation.js"(t,e){var n=oi();function o(t,e){this.stars=t,this.edges=e}e.exports=function(t,e){for(var n=new Array(t),i=0;i<t;++i)n[i]=[];return new o(n,e)};var i=o.prototype;function s(t,e,n){for(var o=1,i=t.length;o<i;o+=2)if(t[o-1]===e&&t[o]===n)return t[o-1]=t[i-2],t[o]=t[i-1],void(t.length=i-2)}i.isConstraint=function(){var t=[0,0];function e(t,e){return t[0]-e[0]||t[1]-e[1]}return function(o,i){return t[0]=Math.min(o,i),t[1]=Math.max(o,i),n.eq(this.edges,t,e)>=0}}(),i.removeTriangle=function(t,e,n){var o=this.stars;s(o[t],e,n),s(o[e],n,t),s(o[n],t,e)},i.addTriangle=function(t,e,n){var o=this.stars;o[t].push(e,n),o[e].push(n,t),o[n].push(t,e)},i.opposite=function(t,e){for(var n=this.stars[e],o=1,i=n.length;o<i;o+=2)if(n[o]===t)return n[o-1];return-1},i.flip=function(t,e){var n=this.opposite(t,e),o=this.opposite(e,t);this.removeTriangle(t,e,n),this.removeTriangle(e,t,o),this.addTriangle(t,o,n),this.addTriangle(e,n,o)},i.edges=function(){for(var t=this.stars,e=[],n=0,o=t.length;n<o;++n)for(var i=t[n],s=0,r=i.length;s<r;s+=2)e.push([i[s],i[s+1]]);return e},i.cells=function(){for(var t=this.stars,e=[],n=0,o=t.length;n<o;++n)for(var i=t[n],s=0,r=i.length;s<r;s+=2){var a=i[s],c=i[s+1];n<Math.min(a,c)&&e.push([n,a,c])}return e}}}),ui=ni({"node_modules/robust-in-sphere/in-sphere.js"(t,e){var n=ii(),o=si(),i=ci(),s=ai();function r(t){return(3===t?a:4===t?c:5===t?h:l)(o,i,n,s)}function a(t,e,n,o){return function(i,s,r){var a=n(i[0],i[0]),c=o(a,s[0]),h=o(a,r[0]),l=n(s[0],s[0]),d=o(l,i[0]),u=o(l,r[0]),p=n(r[0],r[0]),f=o(p,i[0]),g=o(p,s[0]),m=t(e(g,u),e(d,c)),y=e(f,h),x=e(m,y);return x[x.length-1]}}function c(t,e,n,o){return function(i,s,r,a){var c=t(n(i[0],i[0]),n(i[1],i[1])),h=o(c,s[0]),l=o(c,r[0]),d=o(c,a[0]),u=t(n(s[0],s[0]),n(s[1],s[1])),p=o(u,i[0]),f=o(u,r[0]),g=o(u,a[0]),m=t(n(r[0],r[0]),n(r[1],r[1])),y=o(m,i[0]),x=o(m,s[0]),v=o(m,a[0]),b=t(n(a[0],a[0]),n(a[1],a[1])),P=o(b,i[0]),S=o(b,s[0]),I=o(b,r[0]),M=t(t(o(e(I,v),s[1]),t(o(e(S,g),-r[1]),o(e(x,f),a[1]))),t(o(e(S,g),i[1]),t(o(e(P,d),-s[1]),o(e(p,h),a[1])))),_=t(t(o(e(I,v),i[1]),t(o(e(P,d),-r[1]),o(e(y,l),a[1]))),t(o(e(x,f),i[1]),t(o(e(y,l),-s[1]),o(e(p,h),r[1])))),N=e(M,_);return N[N.length-1]}}function h(t,e,n,o){return function(i,s,r,a,c){var h=t(n(i[0],i[0]),t(n(i[1],i[1]),n(i[2],i[2]))),l=o(h,s[0]),d=o(h,r[0]),u=o(h,a[0]),p=o(h,c[0]),f=t(n(s[0],s[0]),t(n(s[1],s[1]),n(s[2],s[2]))),g=o(f,i[0]),m=o(f,r[0]),y=o(f,a[0]),x=o(f,c[0]),v=t(n(r[0],r[0]),t(n(r[1],r[1]),n(r[2],r[2]))),b=o(v,i[0]),P=o(v,s[0]),S=o(v,a[0]),I=o(v,c[0]),M=t(n(a[0],a[0]),t(n(a[1],a[1]),n(a[2],a[2]))),_=o(M,i[0]),N=o(M,s[0]),C=o(M,r[0]),T=o(M,c[0]),E=t(n(c[0],c[0]),t(n(c[1],c[1]),n(c[2],c[2]))),w=o(E,i[0]),R=o(E,s[0]),O=o(E,r[0]),A=o(E,a[0]),z=t(t(t(o(t(o(e(A,T),r[1]),t(o(e(O,I),-a[1]),o(e(C,S),c[1]))),s[2]),t(o(t(o(e(A,T),s[1]),t(o(e(R,x),-a[1]),o(e(N,y),c[1]))),-r[2]),o(t(o(e(O,I),s[1]),t(o(e(R,x),-r[1]),o(e(P,m),c[1]))),a[2]))),t(o(t(o(e(C,S),s[1]),t(o(e(N,y),-r[1]),o(e(P,m),a[1]))),-c[2]),t(o(t(o(e(A,T),s[1]),t(o(e(R,x),-a[1]),o(e(N,y),c[1]))),i[2]),o(t(o(e(A,T),i[1]),t(o(e(w,p),-a[1]),o(e(_,u),c[1]))),-s[2])))),t(t(o(t(o(e(R,x),i[1]),t(o(e(w,p),-s[1]),o(e(g,l),c[1]))),a[2]),t(o(t(o(e(N,y),i[1]),t(o(e(_,u),-s[1]),o(e(g,l),a[1]))),-c[2]),o(t(o(e(C,S),s[1]),t(o(e(N,y),-r[1]),o(e(P,m),a[1]))),i[2]))),t(o(t(o(e(C,S),i[1]),t(o(e(_,u),-r[1]),o(e(b,d),a[1]))),-s[2]),t(o(t(o(e(N,y),i[1]),t(o(e(_,u),-s[1]),o(e(g,l),a[1]))),r[2]),o(t(o(e(P,m),i[1]),t(o(e(b,d),-s[1]),o(e(g,l),r[1]))),-a[2]))))),D=t(t(t(o(t(o(e(A,T),r[1]),t(o(e(O,I),-a[1]),o(e(C,S),c[1]))),i[2]),o(t(o(e(A,T),i[1]),t(o(e(w,p),-a[1]),o(e(_,u),c[1]))),-r[2])),t(o(t(o(e(O,I),i[1]),t(o(e(w,p),-r[1]),o(e(b,d),c[1]))),a[2]),o(t(o(e(C,S),i[1]),t(o(e(_,u),-r[1]),o(e(b,d),a[1]))),-c[2]))),t(t(o(t(o(e(O,I),s[1]),t(o(e(R,x),-r[1]),o(e(P,m),c[1]))),i[2]),o(t(o(e(O,I),i[1]),t(o(e(w,p),-r[1]),o(e(b,d),c[1]))),-s[2])),t(o(t(o(e(R,x),i[1]),t(o(e(w,p),-s[1]),o(e(g,l),c[1]))),r[2]),o(t(o(e(P,m),i[1]),t(o(e(b,d),-s[1]),o(e(g,l),r[1]))),-c[2])))),L=e(z,D);return L[L.length-1]}}function l(t,e,n,o){return function(i,s,r,a,c,h){var l=t(t(n(i[0],i[0]),n(i[1],i[1])),t(n(i[2],i[2]),n(i[3],i[3]))),d=o(l,s[0]),u=o(l,r[0]),p=o(l,a[0]),f=o(l,c[0]),g=o(l,h[0]),m=t(t(n(s[0],s[0]),n(s[1],s[1])),t(n(s[2],s[2]),n(s[3],s[3]))),y=o(m,i[0]),x=o(m,r[0]),v=o(m,a[0]),b=o(m,c[0]),P=o(m,h[0]),S=t(t(n(r[0],r[0]),n(r[1],r[1])),t(n(r[2],r[2]),n(r[3],r[3]))),I=o(S,i[0]),M=o(S,s[0]),_=o(S,a[0]),N=o(S,c[0]),C=o(S,h[0]),T=t(t(n(a[0],a[0]),n(a[1],a[1])),t(n(a[2],a[2]),n(a[3],a[3]))),E=o(T,i[0]),w=o(T,s[0]),R=o(T,r[0]),O=o(T,c[0]),A=o(T,h[0]),z=t(t(n(c[0],c[0]),n(c[1],c[1])),t(n(c[2],c[2]),n(c[3],c[3]))),D=o(z,i[0]),L=o(z,s[0]),Y=o(z,r[0]),X=o(z,a[0]),F=o(z,h[0]),k=t(t(n(h[0],h[0]),n(h[1],h[1])),t(n(h[2],h[2]),n(h[3],h[3]))),$=o(k,i[0]),B=o(k,s[0]),j=o(k,r[0]),W=o(k,a[0]),V=o(k,c[0]),H=t(t(t(o(t(t(o(t(o(e(V,F),a[1]),t(o(e(W,A),-c[1]),o(e(X,O),h[1]))),r[2]),o(t(o(e(V,F),r[1]),t(o(e(j,C),-c[1]),o(e(Y,N),h[1]))),-a[2])),t(o(t(o(e(W,A),r[1]),t(o(e(j,C),-a[1]),o(e(R,_),h[1]))),c[2]),o(t(o(e(X,O),r[1]),t(o(e(Y,N),-a[1]),o(e(R,_),c[1]))),-h[2]))),s[3]),t(o(t(t(o(t(o(e(V,F),a[1]),t(o(e(W,A),-c[1]),o(e(X,O),h[1]))),s[2]),o(t(o(e(V,F),s[1]),t(o(e(B,P),-c[1]),o(e(L,b),h[1]))),-a[2])),t(o(t(o(e(W,A),s[1]),t(o(e(B,P),-a[1]),o(e(w,v),h[1]))),c[2]),o(t(o(e(X,O),s[1]),t(o(e(L,b),-a[1]),o(e(w,v),c[1]))),-h[2]))),-r[3]),o(t(t(o(t(o(e(V,F),r[1]),t(o(e(j,C),-c[1]),o(e(Y,N),h[1]))),s[2]),o(t(o(e(V,F),s[1]),t(o(e(B,P),-c[1]),o(e(L,b),h[1]))),-r[2])),t(o(t(o(e(j,C),s[1]),t(o(e(B,P),-r[1]),o(e(M,x),h[1]))),c[2]),o(t(o(e(Y,N),s[1]),t(o(e(L,b),-r[1]),o(e(M,x),c[1]))),-h[2]))),a[3]))),t(t(o(t(t(o(t(o(e(W,A),r[1]),t(o(e(j,C),-a[1]),o(e(R,_),h[1]))),s[2]),o(t(o(e(W,A),s[1]),t(o(e(B,P),-a[1]),o(e(w,v),h[1]))),-r[2])),t(o(t(o(e(j,C),s[1]),t(o(e(B,P),-r[1]),o(e(M,x),h[1]))),a[2]),o(t(o(e(R,_),s[1]),t(o(e(w,v),-r[1]),o(e(M,x),a[1]))),-h[2]))),-c[3]),o(t(t(o(t(o(e(X,O),r[1]),t(o(e(Y,N),-a[1]),o(e(R,_),c[1]))),s[2]),o(t(o(e(X,O),s[1]),t(o(e(L,b),-a[1]),o(e(w,v),c[1]))),-r[2])),t(o(t(o(e(Y,N),s[1]),t(o(e(L,b),-r[1]),o(e(M,x),c[1]))),a[2]),o(t(o(e(R,_),s[1]),t(o(e(w,v),-r[1]),o(e(M,x),a[1]))),-c[2]))),h[3])),t(o(t(t(o(t(o(e(V,F),a[1]),t(o(e(W,A),-c[1]),o(e(X,O),h[1]))),s[2]),o(t(o(e(V,F),s[1]),t(o(e(B,P),-c[1]),o(e(L,b),h[1]))),-a[2])),t(o(t(o(e(W,A),s[1]),t(o(e(B,P),-a[1]),o(e(w,v),h[1]))),c[2]),o(t(o(e(X,O),s[1]),t(o(e(L,b),-a[1]),o(e(w,v),c[1]))),-h[2]))),i[3]),o(t(t(o(t(o(e(V,F),a[1]),t(o(e(W,A),-c[1]),o(e(X,O),h[1]))),i[2]),o(t(o(e(V,F),i[1]),t(o(e($,g),-c[1]),o(e(D,f),h[1]))),-a[2])),t(o(t(o(e(W,A),i[1]),t(o(e($,g),-a[1]),o(e(E,p),h[1]))),c[2]),o(t(o(e(X,O),i[1]),t(o(e(D,f),-a[1]),o(e(E,p),c[1]))),-h[2]))),-s[3])))),t(t(t(o(t(t(o(t(o(e(V,F),s[1]),t(o(e(B,P),-c[1]),o(e(L,b),h[1]))),i[2]),o(t(o(e(V,F),i[1]),t(o(e($,g),-c[1]),o(e(D,f),h[1]))),-s[2])),t(o(t(o(e(B,P),i[1]),t(o(e($,g),-s[1]),o(e(y,d),h[1]))),c[2]),o(t(o(e(L,b),i[1]),t(o(e(D,f),-s[1]),o(e(y,d),c[1]))),-h[2]))),a[3]),o(t(t(o(t(o(e(W,A),s[1]),t(o(e(B,P),-a[1]),o(e(w,v),h[1]))),i[2]),o(t(o(e(W,A),i[1]),t(o(e($,g),-a[1]),o(e(E,p),h[1]))),-s[2])),t(o(t(o(e(B,P),i[1]),t(o(e($,g),-s[1]),o(e(y,d),h[1]))),a[2]),o(t(o(e(w,v),i[1]),t(o(e(E,p),-s[1]),o(e(y,d),a[1]))),-h[2]))),-c[3])),t(o(t(t(o(t(o(e(X,O),s[1]),t(o(e(L,b),-a[1]),o(e(w,v),c[1]))),i[2]),o(t(o(e(X,O),i[1]),t(o(e(D,f),-a[1]),o(e(E,p),c[1]))),-s[2])),t(o(t(o(e(L,b),i[1]),t(o(e(D,f),-s[1]),o(e(y,d),c[1]))),a[2]),o(t(o(e(w,v),i[1]),t(o(e(E,p),-s[1]),o(e(y,d),a[1]))),-c[2]))),h[3]),o(t(t(o(t(o(e(W,A),r[1]),t(o(e(j,C),-a[1]),o(e(R,_),h[1]))),s[2]),o(t(o(e(W,A),s[1]),t(o(e(B,P),-a[1]),o(e(w,v),h[1]))),-r[2])),t(o(t(o(e(j,C),s[1]),t(o(e(B,P),-r[1]),o(e(M,x),h[1]))),a[2]),o(t(o(e(R,_),s[1]),t(o(e(w,v),-r[1]),o(e(M,x),a[1]))),-h[2]))),i[3]))),t(t(o(t(t(o(t(o(e(W,A),r[1]),t(o(e(j,C),-a[1]),o(e(R,_),h[1]))),i[2]),o(t(o(e(W,A),i[1]),t(o(e($,g),-a[1]),o(e(E,p),h[1]))),-r[2])),t(o(t(o(e(j,C),i[1]),t(o(e($,g),-r[1]),o(e(I,u),h[1]))),a[2]),o(t(o(e(R,_),i[1]),t(o(e(E,p),-r[1]),o(e(I,u),a[1]))),-h[2]))),-s[3]),o(t(t(o(t(o(e(W,A),s[1]),t(o(e(B,P),-a[1]),o(e(w,v),h[1]))),i[2]),o(t(o(e(W,A),i[1]),t(o(e($,g),-a[1]),o(e(E,p),h[1]))),-s[2])),t(o(t(o(e(B,P),i[1]),t(o(e($,g),-s[1]),o(e(y,d),h[1]))),a[2]),o(t(o(e(w,v),i[1]),t(o(e(E,p),-s[1]),o(e(y,d),a[1]))),-h[2]))),r[3])),t(o(t(t(o(t(o(e(j,C),s[1]),t(o(e(B,P),-r[1]),o(e(M,x),h[1]))),i[2]),o(t(o(e(j,C),i[1]),t(o(e($,g),-r[1]),o(e(I,u),h[1]))),-s[2])),t(o(t(o(e(B,P),i[1]),t(o(e($,g),-s[1]),o(e(y,d),h[1]))),r[2]),o(t(o(e(M,x),i[1]),t(o(e(I,u),-s[1]),o(e(y,d),r[1]))),-h[2]))),-a[3]),o(t(t(o(t(o(e(R,_),s[1]),t(o(e(w,v),-r[1]),o(e(M,x),a[1]))),i[2]),o(t(o(e(R,_),i[1]),t(o(e(E,p),-r[1]),o(e(I,u),a[1]))),-s[2])),t(o(t(o(e(w,v),i[1]),t(o(e(E,p),-s[1]),o(e(y,d),a[1]))),r[2]),o(t(o(e(M,x),i[1]),t(o(e(I,u),-s[1]),o(e(y,d),r[1]))),-a[2]))),h[3]))))),U=t(t(t(o(t(t(o(t(o(e(V,F),a[1]),t(o(e(W,A),-c[1]),o(e(X,O),h[1]))),r[2]),o(t(o(e(V,F),r[1]),t(o(e(j,C),-c[1]),o(e(Y,N),h[1]))),-a[2])),t(o(t(o(e(W,A),r[1]),t(o(e(j,C),-a[1]),o(e(R,_),h[1]))),c[2]),o(t(o(e(X,O),r[1]),t(o(e(Y,N),-a[1]),o(e(R,_),c[1]))),-h[2]))),i[3]),t(o(t(t(o(t(o(e(V,F),a[1]),t(o(e(W,A),-c[1]),o(e(X,O),h[1]))),i[2]),o(t(o(e(V,F),i[1]),t(o(e($,g),-c[1]),o(e(D,f),h[1]))),-a[2])),t(o(t(o(e(W,A),i[1]),t(o(e($,g),-a[1]),o(e(E,p),h[1]))),c[2]),o(t(o(e(X,O),i[1]),t(o(e(D,f),-a[1]),o(e(E,p),c[1]))),-h[2]))),-r[3]),o(t(t(o(t(o(e(V,F),r[1]),t(o(e(j,C),-c[1]),o(e(Y,N),h[1]))),i[2]),o(t(o(e(V,F),i[1]),t(o(e($,g),-c[1]),o(e(D,f),h[1]))),-r[2])),t(o(t(o(e(j,C),i[1]),t(o(e($,g),-r[1]),o(e(I,u),h[1]))),c[2]),o(t(o(e(Y,N),i[1]),t(o(e(D,f),-r[1]),o(e(I,u),c[1]))),-h[2]))),a[3]))),t(t(o(t(t(o(t(o(e(W,A),r[1]),t(o(e(j,C),-a[1]),o(e(R,_),h[1]))),i[2]),o(t(o(e(W,A),i[1]),t(o(e($,g),-a[1]),o(e(E,p),h[1]))),-r[2])),t(o(t(o(e(j,C),i[1]),t(o(e($,g),-r[1]),o(e(I,u),h[1]))),a[2]),o(t(o(e(R,_),i[1]),t(o(e(E,p),-r[1]),o(e(I,u),a[1]))),-h[2]))),-c[3]),o(t(t(o(t(o(e(X,O),r[1]),t(o(e(Y,N),-a[1]),o(e(R,_),c[1]))),i[2]),o(t(o(e(X,O),i[1]),t(o(e(D,f),-a[1]),o(e(E,p),c[1]))),-r[2])),t(o(t(o(e(Y,N),i[1]),t(o(e(D,f),-r[1]),o(e(I,u),c[1]))),a[2]),o(t(o(e(R,_),i[1]),t(o(e(E,p),-r[1]),o(e(I,u),a[1]))),-c[2]))),h[3])),t(o(t(t(o(t(o(e(V,F),r[1]),t(o(e(j,C),-c[1]),o(e(Y,N),h[1]))),s[2]),o(t(o(e(V,F),s[1]),t(o(e(B,P),-c[1]),o(e(L,b),h[1]))),-r[2])),t(o(t(o(e(j,C),s[1]),t(o(e(B,P),-r[1]),o(e(M,x),h[1]))),c[2]),o(t(o(e(Y,N),s[1]),t(o(e(L,b),-r[1]),o(e(M,x),c[1]))),-h[2]))),i[3]),o(t(t(o(t(o(e(V,F),r[1]),t(o(e(j,C),-c[1]),o(e(Y,N),h[1]))),i[2]),o(t(o(e(V,F),i[1]),t(o(e($,g),-c[1]),o(e(D,f),h[1]))),-r[2])),t(o(t(o(e(j,C),i[1]),t(o(e($,g),-r[1]),o(e(I,u),h[1]))),c[2]),o(t(o(e(Y,N),i[1]),t(o(e(D,f),-r[1]),o(e(I,u),c[1]))),-h[2]))),-s[3])))),t(t(t(o(t(t(o(t(o(e(V,F),s[1]),t(o(e(B,P),-c[1]),o(e(L,b),h[1]))),i[2]),o(t(o(e(V,F),i[1]),t(o(e($,g),-c[1]),o(e(D,f),h[1]))),-s[2])),t(o(t(o(e(B,P),i[1]),t(o(e($,g),-s[1]),o(e(y,d),h[1]))),c[2]),o(t(o(e(L,b),i[1]),t(o(e(D,f),-s[1]),o(e(y,d),c[1]))),-h[2]))),r[3]),o(t(t(o(t(o(e(j,C),s[1]),t(o(e(B,P),-r[1]),o(e(M,x),h[1]))),i[2]),o(t(o(e(j,C),i[1]),t(o(e($,g),-r[1]),o(e(I,u),h[1]))),-s[2])),t(o(t(o(e(B,P),i[1]),t(o(e($,g),-s[1]),o(e(y,d),h[1]))),r[2]),o(t(o(e(M,x),i[1]),t(o(e(I,u),-s[1]),o(e(y,d),r[1]))),-h[2]))),-c[3])),t(o(t(t(o(t(o(e(Y,N),s[1]),t(o(e(L,b),-r[1]),o(e(M,x),c[1]))),i[2]),o(t(o(e(Y,N),i[1]),t(o(e(D,f),-r[1]),o(e(I,u),c[1]))),-s[2])),t(o(t(o(e(L,b),i[1]),t(o(e(D,f),-s[1]),o(e(y,d),c[1]))),r[2]),o(t(o(e(M,x),i[1]),t(o(e(I,u),-s[1]),o(e(y,d),r[1]))),-c[2]))),h[3]),o(t(t(o(t(o(e(X,O),r[1]),t(o(e(Y,N),-a[1]),o(e(R,_),c[1]))),s[2]),o(t(o(e(X,O),s[1]),t(o(e(L,b),-a[1]),o(e(w,v),c[1]))),-r[2])),t(o(t(o(e(Y,N),s[1]),t(o(e(L,b),-r[1]),o(e(M,x),c[1]))),a[2]),o(t(o(e(R,_),s[1]),t(o(e(w,v),-r[1]),o(e(M,x),a[1]))),-c[2]))),i[3]))),t(t(o(t(t(o(t(o(e(X,O),r[1]),t(o(e(Y,N),-a[1]),o(e(R,_),c[1]))),i[2]),o(t(o(e(X,O),i[1]),t(o(e(D,f),-a[1]),o(e(E,p),c[1]))),-r[2])),t(o(t(o(e(Y,N),i[1]),t(o(e(D,f),-r[1]),o(e(I,u),c[1]))),a[2]),o(t(o(e(R,_),i[1]),t(o(e(E,p),-r[1]),o(e(I,u),a[1]))),-c[2]))),-s[3]),o(t(t(o(t(o(e(X,O),s[1]),t(o(e(L,b),-a[1]),o(e(w,v),c[1]))),i[2]),o(t(o(e(X,O),i[1]),t(o(e(D,f),-a[1]),o(e(E,p),c[1]))),-s[2])),t(o(t(o(e(L,b),i[1]),t(o(e(D,f),-s[1]),o(e(y,d),c[1]))),a[2]),o(t(o(e(w,v),i[1]),t(o(e(E,p),-s[1]),o(e(y,d),a[1]))),-c[2]))),r[3])),t(o(t(t(o(t(o(e(Y,N),s[1]),t(o(e(L,b),-r[1]),o(e(M,x),c[1]))),i[2]),o(t(o(e(Y,N),i[1]),t(o(e(D,f),-r[1]),o(e(I,u),c[1]))),-s[2])),t(o(t(o(e(L,b),i[1]),t(o(e(D,f),-s[1]),o(e(y,d),c[1]))),r[2]),o(t(o(e(M,x),i[1]),t(o(e(I,u),-s[1]),o(e(y,d),r[1]))),-c[2]))),-a[3]),o(t(t(o(t(o(e(R,_),s[1]),t(o(e(w,v),-r[1]),o(e(M,x),a[1]))),i[2]),o(t(o(e(R,_),i[1]),t(o(e(E,p),-r[1]),o(e(I,u),a[1]))),-s[2])),t(o(t(o(e(w,v),i[1]),t(o(e(E,p),-s[1]),o(e(y,d),a[1]))),r[2]),o(t(o(e(M,x),i[1]),t(o(e(I,u),-s[1]),o(e(y,d),r[1]))),-a[2]))),c[3]))))),G=e(H,U);return G[G.length-1]}}var d=[function(){return 0},function(){return 0},function(){return 0}];function u(t){var e=d[t.length];return e||(e=d[t.length]=r(t.length)),e.apply(void 0,t)}function p(t,e,n,o,i,s,r,a){return function(e,n,c,h,l,d){switch(arguments.length){case 0:case 1:return 0;case 2:return o(e,n);case 3:return i(e,n,c);case 4:return s(e,n,c,h);case 5:return r(e,n,c,h,l);case 6:return a(e,n,c,h,l,d)}for(var u=new Array(arguments.length),p=0;p<arguments.length;++p)u[p]=arguments[p];return t(u)}}!function(){for(;d.length<=6;)d.push(r(d.length));e.exports=p.apply(void 0,[u].concat(d));for(var t=0;t<=6;++t)e.exports[t]=d[t]}()}}),pi=ni({"node_modules/cdt2d/lib/delaunay.js"(t,e){var n=ui()[4];oi();function o(t,e,o,i,s,r){var a=e.opposite(i,s);if(!(a<0)){if(s<i){var c=i;i=s,s=c,c=r,r=a,a=c}e.isConstraint(i,s)||n(t[i],t[s],t[r],t[a])<0&&o.push(i,s)}}e.exports=function(t,e){for(var i=[],s=t.length,r=e.stars,a=0;a<s;++a)for(var c=r[a],h=1;h<c.length;h+=2){if(!((p=c[h])<a)&&!e.isConstraint(a,p)){for(var l=c[h-1],d=-1,u=1;u<c.length;u+=2)if(c[u-1]===p){d=c[u];break}d<0||n(t[a],t[p],t[l],t[d])<0&&i.push(a,p)}}for(;i.length>0;){for(var p=i.pop(),f=(l=-1,d=-1,c=r[a=i.pop()],1);f<c.length;f+=2){var g=c[f-1],m=c[f];g===p?d=m:m===p&&(l=g)}l<0||d<0||(n(t[a],t[p],t[l],t[d])>=0||(e.flip(a,p),o(t,e,i,l,a,d),o(t,e,i,a,d,l),o(t,e,i,d,p,l),o(t,e,i,p,l,d)))}}}}),fi=ni({"node_modules/cdt2d/lib/filter.js"(t,e){var n=oi();function o(t,e,n,o,i,s,r){this.cells=t,this.neighbor=e,this.flags=o,this.constraint=n,this.active=i,this.next=s,this.boundary=r}function i(t,e){return t[0]-e[0]||t[1]-e[1]||t[2]-e[2]}e.exports=function(t,e,n){var s=function(t,e){for(var n=t.cells(),s=n.length,r=0;r<s;++r){var a=(y=n[r])[0],c=y[1],h=y[2];c<h?c<a&&(y[0]=c,y[1]=h,y[2]=a):h<a&&(y[0]=h,y[1]=a,y[2]=c)}n.sort(i);var l=new Array(s);for(r=0;r<l.length;++r)l[r]=0;var d=[],u=[],p=new Array(3*s),f=new Array(3*s),g=null;e&&(g=[]);var m=new o(n,p,f,l,d,u,g);for(r=0;r<s;++r)for(var y=n[r],x=0;x<3;++x){a=y[x],c=y[(x+1)%3];var v=p[3*r+x]=m.locate(c,a,t.opposite(c,a)),b=f[3*r+x]=t.isConstraint(a,c);v<0&&(b?u.push(r):(d.push(r),l[r]=1),e&&g.push([c,a,-1]))}return m}(t,n);if(0===e)return n?s.cells.concat(s.boundary):s.cells;var r=1,a=s.active,c=s.next,h=s.flags,l=s.cells,d=s.constraint,u=s.neighbor;for(;a.length>0||c.length>0;){for(;a.length>0;){var p=a.pop();if(h[p]!==-r){h[p]=r;l[p];for(var f=0;f<3;++f){var g=u[3*p+f];g>=0&&0===h[g]&&(d[3*p+f]?c.push(g):(a.push(g),h[g]=r))}}}var m=c;c=a,a=m,c.length=0,r=-r}var y=function(t,e,n){for(var o=0,i=0;i<t.length;++i)e[i]===n&&(t[o++]=t[i]);return t.length=o,t}(l,h,e);if(n)return y.concat(s.boundary);return y},o.prototype.locate=function(){var t=[0,0,0];return function(e,o,s){var r=e,a=o,c=s;return o<s?o<e&&(r=o,a=s,c=e):s<e&&(r=s,a=e,c=o),r<0?-1:(t[0]=r,t[1]=a,t[2]=c,n.eq(this.cells,t,i))}}()}}),gi=ni({"node_modules/cdt2d/cdt2d.js"(t,e){var n=li(),o=di(),i=pi(),s=fi();function r(t){return[Math.min(t[0],t[1]),Math.max(t[0],t[1])]}function a(t,e){return t[0]-e[0]||t[1]-e[1]}function c(t,e,n){return e in t?t[e]:n}e.exports=function(t,e,h){Array.isArray(e)?(h=h||{},e=e||[]):(h=e||{},e=[]);var l=!!c(h,"delaunay",!0),d=!!c(h,"interior",!0),u=!!c(h,"exterior",!0),p=!!c(h,"infinity",!1);if(!d&&!u||0===t.length)return[];var f=n(t,e);if(l||d!==u||p){for(var g=o(t.length,function(t){return t.map(r).sort(a)}(e)),m=0;m<f.length;++m){var y=f[m];g.addTriangle(y[0],y[1],y[2])}return l&&i(t,g),u?d?p?s(g,0,p):g.cells():s(g,1,p):s(g,-1)}return f}}}),mi=class{heap=[];maxSize;constructor(t=[],e=1e4){if(this.maxSize=e,t.length>0){this.heap=[...t].sort((t,e)=>t.f-e.f).slice(0,this.maxSize);for(let t=Math.floor(this.heap.length/2)-1;t>=0;t--)this._siftDown(t)}}get size(){return this.heap.length}isEmpty(){return 0===this.heap.length}peek(){return this.isEmpty()?null:this.heap[0]??null}peekMany(t){return[...this.heap].sort((t,e)=>t.f-e.f).slice(0,t)}dequeue(){if(this.isEmpty())return null;const t=this.heap[0],e=this.heap.pop();return 0===this.heap.length&&void 0!==e||void 0!==e&&(this.heap[0]=e,this._siftDown(0)),t}enqueue(t){this.heap.length>=this.maxSize||(this.heap.push(t),this._siftUp(this.heap.length-1))}_siftUp(t){let e=t;for(;e>0;){const t=this._parentIndex(e);if(this.heap[t].f<=this.heap[e].f)break;this._swap(e,t),e=t}}_siftDown(t){let e=t;const n=this.heap.length;for(;;){const t=this._leftChildIndex(e),o=this._rightChildIndex(e);let i=e;if(t<n&&this.heap[t].f<this.heap[i].f&&(i=t),o<n&&this.heap[o].f<this.heap[i].f&&(i=o),i===e)break;this._swap(e,i),e=i}}_swap(t,e){[this.heap[t],this.heap[e]]=[this.heap[e],this.heap[t]]}_parentIndex(t){return Math.floor((t-1)/2)}_leftChildIndex(t){return 2*t+1}_rightChildIndex(t){return 2*t+2}},yi=class extends M{constructor(t){super(),this.input=t,this.graph=(t=>{if(t.ports.length>0&&"region1"in t.ports[0]&&"object"==typeof t.ports[0].region1)return t;const e=new Map,n=new Map;for(const e of t.regions){const{assignments:t,...o}=e;n.set(e.regionId,{...o,ports:[],assignments:void 0})}for(const o of t.ports){const t=n.get(o.region1Id??o.region1?.regionId),i=n.get(o.region2Id??o.region2?.regionId),s={portId:o.portId,region1:t,region2:i,d:o.d};e.set(o.portId,s),t.ports.push(s),i.ports.push(s)}return{ports:Array.from(e.values()),regions:Array.from(n.values())}})(t.inputGraph),this.graph.solvedRoutes=this.solvedRoutes;for(const t of this.graph.regions)t.assignments=[];this.connections=((t,e)=>{const n=[];for(const o of t)"startRegionId"in o?n.push({connectionId:o.connectionId,mutuallyConnectedNetworkId:o.connectionId,startRegion:e.regions.find(t=>t.regionId===o.startRegionId),endRegion:e.regions.find(t=>t.regionId===o.endRegionId)}):n.push(o);return n})(t.inputConnections,this.graph),void 0!==t.greedyMultiplier&&(this.greedyMultiplier=t.greedyMultiplier),void 0!==t.rippingEnabled&&(this.rippingEnabled=t.rippingEnabled),void 0!==t.ripCost&&(this.ripCost=t.ripCost),this.unprocessedConnections=[...this.connections],this.candidateQueue=new mi,this.beginNewConnection()}getSolverName(){return"HyperGraphSolver"}graph;connections;candidateQueue;unprocessedConnections;solvedRoutes=[];currentConnection=null;currentEndRegion=null;greedyMultiplier=1;rippingEnabled=!1;ripCost=0;lastCandidate=null;visitedPointsForCurrentConnection=new Map;getConstructorParams(){return{inputGraph:(e=this.graph,{ports:e.ports.map(t=>({portId:t.portId,region1Id:t.region1.regionId,region2Id:t.region2.regionId,d:t.d})),regions:e.regions.map(t=>({regionId:t.regionId,pointIds:t.ports.map(t=>t.portId),d:t.d}))}),inputConnections:(t=this.connections,t.map(t=>({connectionId:t.connectionId,startRegionId:t.startRegion.regionId,endRegionId:t.endRegion.regionId}))),greedyMultiplier:this.greedyMultiplier,rippingEnabled:this.rippingEnabled,ripCost:this.ripCost};var t,e}computeH(t){return this.estimateCostToEnd(t.port)}estimateCostToEnd(t){return 0}getPortUsagePenalty(t){return 0}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){return 0}getRipsRequiredForPortUsage(t,e,n){return[]}isRipRequiredForPortUsage(t,e,n){return!1}isTransitionAllowed(t,e,n){return!0}computeG(t){return t.parent.g+this.computeIncreasedRegionCostIfPortsAreUsed(t.lastRegion,t.lastPort,t.port)+(t.ripRequired?this.ripCost:0)+this.getPortUsagePenalty(t.port)}selectCandidatesForEnteringRegion(t){return t}computeRoutesToRip(t){const e=this.computeCrossingRoutes(t),n=this.computePortOverlapRoutes(t);return new Set([...e,...n])}computePortOverlapRoutes(t){const e=new Set;for(const n of t.path)n.port.assignment&&n.port.assignment.connection.mutuallyConnectedNetworkId!==t.connection.mutuallyConnectedNetworkId&&e.add(n.port.assignment.solvedRoute);return e}computeCrossingRoutes(t){const e=new Set;for(const n of t.path){if(!n.lastPort||!n.lastRegion)continue;const t=this.getRipsRequiredForPortUsage(n.lastRegion,n.lastPort,n.port);for(const n of t)e.add(n.solvedRoute)}return e}getNextCandidates(t){const e=t.nextRegion,n=t.port,o={};for(const i of e.ports){if(i===t.port)continue;if(!this.isTransitionAllowed(e,n,i))continue;const s=i.assignment&&i.assignment.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId||this.isRipRequiredForPortUsage(e,n,i),r={port:i,hops:t.hops+1,parent:t,lastRegion:e,nextRegion:i.region1===e?i.region2:i.region1,lastPort:n,ripRequired:s};!this.rippingEnabled&&r.ripRequired||(o[r.nextRegion.regionId]??=[],o[r.nextRegion.regionId].push(r))}const i=[];for(const t in o){const e=o[t];i.push(...this.selectCandidatesForEnteringRegion(e))}for(const t of i)t.g=this.computeG(t),t.h=this.computeH(t),t.f=t.g+t.h*this.greedyMultiplier;return i}processSolvedRoute(t){const e={path:[],connection:this.currentConnection,requiredRip:!1};let n=t,o=!1;for(;n;)o||=!!n.ripRequired,e.path.unshift(n),n=n.parent;o&&(e.requiredRip=!0);const i=this.computeRoutesToRip(e);if(i.size>0){e.requiredRip=!0;for(const t of i)this.ripSolvedRoute(t)}for(const t of e.path){if(t.port.assignment={solvedRoute:e,connection:this.currentConnection},!t.lastPort)continue;const n={regionPort1:t.lastPort,regionPort2:t.port,region:t.lastRegion,connection:this.currentConnection,solvedRoute:e};t.lastRegion.assignments?.push(n)}this.solvedRoutes.push(e),this.routeSolvedHook(e)}routeSolvedHook(t){}routeStartedHook(t){}ripSolvedRoute(t){for(const e of t.path.map(t=>t.port))e.ripCount=(e.ripCount??0)+1,e.region1.assignments=e.region1.assignments?.filter(t=>t.regionPort1!==e&&t.regionPort2!==e),e.region2.assignments=e.region2.assignments?.filter(t=>t.regionPort1!==e&&t.regionPort2!==e),e.assignment=void 0;this.solvedRoutes=this.solvedRoutes.filter(e=>e!==t),this.unprocessedConnections.push(t.connection)}beginNewConnection(){this.currentConnection=this.unprocessedConnections.shift(),this.currentEndRegion=this.currentConnection.endRegion,this.candidateQueue=new mi,this.visitedPointsForCurrentConnection.clear(),this.routeStartedHook(this.currentConnection);for(const t of this.currentConnection.startRegion.ports)this.candidateQueue.enqueue({port:t,g:0,h:0,f:0,hops:0,ripRequired:!1,nextRegion:t.region1===this.currentConnection.startRegion?t.region2:t.region1})}_step(){let t=this.candidateQueue.dequeue();if(!t)return this.failed=!0,void(this.error="Ran out of candidates");let e=this.visitedPointsForCurrentConnection.get(t.port.portId);for(;t&&void 0!==e&&!(t.g<e)&&(t=this.candidateQueue.dequeue(),t);)e=this.visitedPointsForCurrentConnection.get(t.port.portId);if(!t)return this.failed=!0,void(this.error="Ran out of candidates");if(this.lastCandidate=t,this.visitedPointsForCurrentConnection.set(t.port.portId,t.g),t.nextRegion===this.currentEndRegion)return this.processSolvedRoute(t),0===this.unprocessedConnections.length?void(this.solved=!0):void this.beginNewConnection();const n=this.getNextCandidates(t);for(const t of n)this.candidateQueue.enqueue(t)}};function xi(t,e){return Array.isArray(e)?[t.a*e[0]+t.c*e[1]+t.e,t.b*e[0]+t.d*e[1]+t.f]:{x:t.a*e.x+t.c*e.y+t.e,y:t.b*e.x+t.d*e.y+t.f}}function vi(t){return void 0===t}function bi(t,e=0){return{a:1,c:0,e:t,b:0,d:1,f:e}}function Pi(...t){const e=(t,e)=>({a:t.a*e.a+t.c*e.b,c:t.a*e.c+t.c*e.d,e:t.a*e.e+t.c*e.f+t.e,b:t.b*e.a+t.d*e.b,d:t.b*e.c+t.d*e.d,f:t.b*e.e+t.d*e.f+t.f});switch((t=Array.isArray(t[0])?t[0]:t).length){case 0:throw new Error("no matrices provided");case 1:return t[0];case 2:return e(t[0],t[1]);default:{const[n,o,...i]=t;return Pi(e(n,o),...i)}}}var{cos:Si,sin:Ii,PI:Mi}=Math;var{tan:_i}=Math,Ni=t=>{let e=Number.POSITIVE_INFINITY,n=Number.NEGATIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const s of t){const{bounds:t}=s.d;e=Math.min(e,t.minX),n=Math.max(n,t.maxX),o=Math.min(o,t.minY),i=Math.max(i,t.maxY)}return{minX:e,maxX:n,minY:o,maxY:i}},Ci=t=>({x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}),Ti=(t,e)=>{const n=t.regions.map(t=>{const{bounds:n,center:o,...i}=t.d,s=[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.minX,y:n.maxY},{x:n.maxX,y:n.maxY}].map(t=>xi(e,t)),r={minX:Math.min(...s.map(t=>t.x)),maxX:Math.max(...s.map(t=>t.x)),minY:Math.min(...s.map(t=>t.y)),maxY:Math.max(...s.map(t=>t.y))},a=xi(e,o);return{...t,ports:[],d:{...i,bounds:r,center:a}}}),o=new Map;for(let e=0;e<t.regions.length;e++)o.set(t.regions[e],n[e]);const i=t.ports.map(t=>{const n=xi(e,t.d),i=o.get(t.region1),s=o.get(t.region2),r={...t,region1:i,region2:s,d:n};return i.ports.push(r),s.ports.push(r),r}),s=t.jumperLocations?.map(t=>{const n=xi(e,t.center),i=t.padRegions.map(t=>o.get(t)),s=xi(e,{x:1,y:0}),r=xi(e,{x:0,y:0}),a=s.x-r.x,c=s.y-r.y;return{center:n,orientation:Math.abs(c)>Math.abs(a)?"horizontal"===t.orientation?"vertical":"horizontal":t.orientation,padRegions:i}});return{regions:n,ports:i,...s&&{jumperLocations:s}}};function Ei(t,e){const n=t.x-e.x,o=t.y-e.y;return n*n+o*o}function wi(t,e,n,o,i){const s=n-e,r=i-o,a=1e-6;if(Math.abs(t.y-i)<a)return t.x-e;if(Math.abs(t.x-n)<a)return s+(i-t.y);if(Math.abs(t.y-o)<a)return s+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*s+r+(t.y-o);const c=Math.abs(t.y-i),h=Math.abs(t.x-n),l=Math.abs(t.y-o),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(s,t.x-e)):u===h?s+Math.max(0,Math.min(r,i-t.y)):u===l?s+r+Math.max(0,Math.min(s,n-t.x)):2*s+r+Math.max(0,Math.min(r,t.y-o))}function Ri(t,e,n){const o=n.x-e.x,i=n.y-e.y,s=t.x-e.x,r=t.y-e.y,a=o*o+i*i,c=a>0?(h=(s*o+r*i)/a,l=0,d=1,Math.max(l,Math.min(d,h))):0;var h,l,d;return{u:c,d2:Ei(t,{x:e.x+c*o,y:e.y+c*i})}}function Oi(t){const e=t.d.polygon;if(!e||e.length<3)return null;const n=t.d.polygonPerimeterCache;if(n)return n;const o=function(t){const e=t.length,n=new Array(e),o=new Array(e+1);o[0]=0;for(let i=0;i<e;i++){const s=t[i],r=t[(i+1)%e],a=Math.hypot(r.x-s.x,r.y-s.y);n[i]=a,o[i+1]=o[i]+a}return{edgeLengths:n,cumulative:o,perimeter:o[e]}}(e);return t.d.polygonPerimeterCache=o,o}function Ai(t){const e=Oi(t);if(e)return e.perimeter;const{minX:n,maxX:o,minY:i,maxY:s}=t.d.bounds;return 2*(o-n)+2*(s-i)}function zi(t,e){if(t.region1===e){if("number"==typeof t.region1T)return t.region1T;const n=Di(t.d,e);return t.region1T=n,n}if(t.region2===e){if("number"==typeof t.region2T)return t.region2T;const n=Di(t.d,e);return t.region2T=n,n}return Di(t.d,e)}function Di(t,e){const n=e.d.polygon;if(n&&n.length>=3){const o=Oi(e);if(o)return function(t,e,n,o=1e-6){let i=0,s=0,r=Number.POSITIVE_INFINITY;const a=o*o;for(let n=0;n<e.length;n++){const o=Ri(t,e[n],e[(n+1)%e.length]);if(o.d2<=a){i=n,s=o.u,r=o.d2;break}o.d2<r&&(i=n,s=o.u,r=o.d2)}return n.cumulative[i]+s*n.edgeLengths[i]}(t,n,o)}const{minX:o,maxX:i,minY:s,maxY:r}=e.d.bounds;return wi(t,o,i,s,r)}function Li(t,e,n=1e-6){return Math.abs(t-e)<n}function Yi(t,e){return(t%e+e)%e}function Xi(t,e,n,o){const i=Math.abs(Yi(t-e,n));return i<o||n-i<o}function Fi(t,e,n,o,i){const s=Yi(t,o),r=Yi(e,o),a=Yi(n,o);return!(Math.abs(r-a)<i)&&(r<a?r<s&&s<a:s>r||s<a)}function ki(t,e,n){if("number"==typeof n&&n>0){let[o,i]=t,[s,r]=e;if(o=Yi(o,n),i=Yi(i,n),s=Yi(s,n),r=Yi(r,n),Xi(o,s,n,1e-6)||Xi(o,r,n,1e-6)||Xi(i,s,n,1e-6)||Xi(i,r,n,1e-6))return!1;return Fi(s,o,i,n,1e-12)!==Fi(r,o,i,n,1e-12)}const[o,i]=t[0]<t[1]?t:[t[1],t[0]],[s,r]=e[0]<e[1]?e:[e[1],e[0]];return!(Li(o,s)||Li(o,r)||Li(i,s)||Li(i,r))&&(o<s&&s<i&&i<r||s<o&&o<r&&r<i)}function $i(t,e){if(e.length<2)return 0;let n=1/0,o=-1/0,i=1/0,s=-1/0;for(const e of t.regions){const t=e;t.d?.bounds?(n=Math.min(n,t.d.bounds.minX),o=Math.max(o,t.d.bounds.maxX),i=Math.min(i,t.d.bounds.minY),s=Math.max(s,t.d.bounds.maxY)):t.d?.center&&(n=Math.min(n,t.d.center.x),o=Math.max(o,t.d.center.x),i=Math.min(i,t.d.center.y),s=Math.max(s,t.d.center.y))}const r=new Map;for(const e of t.regions){const t=e;t.d?.center&&r.set(e.regionId,t.d.center)}const a=[],c=2*(o-n)+2*(s-i);for(const t of e){let e,c;if("startRegion"in t&&t.startRegion){const n=t.startRegion,o=t.endRegion;e=n.d?.center,c=o.d?.center}else"startRegionId"in t&&(e=r.get(t.startRegionId),c=r.get(t.endRegionId));if(!e||!c)continue;const h=wi(e,n,o,i,s),l=wi(c,n,o,i,s);a.push([h,l])}let h=0;for(let t=0;t<a.length;t++)for(let e=t+1;e<a.length;e++)ki(a[t],a[e],c)&&h++;return h}var Bi=(t,e)=>{const n={arrows:[],circles:[],title:"Jumper Graph",lines:[],points:[],rects:[],texts:[],polygons:[],coordinateSystem:"cartesian"};for(const e of t.regions){const{bounds:t,isPad:o,isThroughJumper:i,isConnectionRegion:s,polygon:r}=e.d,a=(t.minX+t.maxX)/2,c=(t.minY+t.maxY)/2,h=t.maxX-t.minX,l=t.maxY-t.minY;let d;if(d=s?"rgba(255, 100, 255, 0.6)":i?"rgba(100, 200, 100, 0.5)":o?"rgba(255, 200, 100, 0.5)":"rgba(200, 200, 255, 0.1)",r&&r.length>=3){const t=r;n.polygons.push({points:t,fill:d})}else n.rects.push({center:{x:a,y:c},width:h-.1,height:l-.1,fill:d})}if(!e?.hidePortPoints)for(const e of t.ports){const t=e.region1.regionId.split(":").pop()??e.region1.regionId,o=e.region2.regionId.split(":").pop()??e.region2.regionId;n.circles.push({center:{x:e.d.x,y:e.d.y},radius:.05,fill:"rgba(128, 128, 128, 0.5)",label:`${t}-${o}`})}if(!e?.hideRegionPortLines)for(const e of t.ports){const t={x:(e.region1.d.bounds.minX+e.region1.d.bounds.maxX)/2,y:(e.region1.d.bounds.minY+e.region1.d.bounds.maxY)/2},o={x:(e.region2.d.bounds.minX+e.region2.d.bounds.maxX)/2,y:(e.region2.d.bounds.minY+e.region2.d.bounds.maxY)/2};n.lines.push({points:[t,{x:e.d.x,y:e.d.y},o],strokeColor:"rgba(100, 100, 100, 0.3)"})}if(e?.connections&&!e?.hideConnectionLines)for(const t of e.connections){const e=t.startRegion,o=t.endRegion,i={x:(e.d.bounds.minX+e.d.bounds.maxX)/2,y:(e.d.bounds.minY+e.d.bounds.maxY)/2},s={x:(o.d.bounds.minX+o.d.bounds.maxX)/2,y:(o.d.bounds.minY+o.d.bounds.maxY)/2},r=(i.x+s.x)/2,a=(i.y+s.y)/2;n.lines.push({points:[i,s],strokeColor:"rgba(255, 50, 150, 0.8)",strokeDash:"3 3"}),n.points.push({x:r,y:a,color:"rgba(200, 0, 100, 1)",label:t.connectionId})}return n},ji=(t,e=.8)=>{let n=0;for(let e=0;e<t.length;e++)n=17777*t.charCodeAt(e)+((n<<5)-n);return`hsla(${Math.abs(n)%360}, 70%, 50%, ${e})`},Wi=.034685181009478865,Vi=0,Hi=4.072520483177124,Ui=0,Gi=35.38577539020022,Zi=.5518001238069296,qi=class extends yi{getSolverName(){return"JumperGraphSolver"}UNIT_OF_COST="hops";portUsagePenalty=Wi;portUsagePenaltySq=Vi;crossingPenalty=Hi;crossingPenaltySq=Ui;ripCost=Gi;baseMaxIterations=4e3;additionalMaxIterationsPerConnection=2e3;additionalMaxIterationsPerCrossing=2e3;constructor(t){super({greedyMultiplier:Zi,rippingEnabled:!0,...t}),this.ripCost=t.ripCost??this.ripCost,this.portUsagePenalty=t.portUsagePenalty??this.portUsagePenalty,this.crossingPenalty=t.crossingPenalty??this.crossingPenalty,this.baseMaxIterations=t.baseMaxIterations??this.baseMaxIterations,this.additionalMaxIterationsPerConnection=t.additionalMaxIterationsPerConnection??this.additionalMaxIterationsPerConnection;const e=$i(this.graph,t.inputConnections);this.MAX_ITERATIONS=this.baseMaxIterations+t.inputConnections.length*this.additionalMaxIterationsPerConnection+e*this.additionalMaxIterationsPerCrossing,this.populateDistanceToEndMaps()}populateDistanceToEndMaps(){const t=new Set(this.connections.map(t=>t.endRegion));for(const e of t){const t=new Map,n=[];for(t.set(e.regionId,0),n.push({region:e,distance:0});n.length>0;){const{region:e,distance:o}=n.shift();for(const i of e.ports){const s=i.region1===e?i.region2:i.region1;t.has(s.regionId)||(t.set(s.regionId,o+1),n.push({region:s,distance:o+1}))}}for(const n of this.graph.ports){n.distanceToEndMap||(n.distanceToEndMap={});const o=t.get(n.region1.regionId)??1/0,i=t.get(n.region2.regionId)??1/0;n.distanceToEndMap[e.regionId]=Math.min(o,i)}}}estimateCostToEnd(t){const e=this.currentEndRegion.regionId;return t.distanceToEndMap[e]}getPortUsagePenalty(t){const e=t.ripCount??0;return e*this.portUsagePenalty+e*this.portUsagePenaltySq}isTransitionAllowed(t,e,n){if(!t.d.isPad)return!0;const o=e=>{const n=e.region1===t?e.region2:e.region1;return Boolean(n.d.isThroughJumper)};return o(e)||o(n)}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){if(t.d.isPad){const e=(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId).length;return e>0?e*this.crossingPenalty+e*this.crossingPenaltySq:0}const o=function(t,e,n){const o=Ai(t),i=[zi(e,t),zi(n,t)];let s=0;const r=t.assignments??[];for(const e of r)ki(i,[zi(e.regionPort1,t),zi(e.regionPort2,t)],o)&&s++;return s}(t,e,n);return o*this.crossingPenalty+o*this.crossingPenaltySq}getRipsRequiredForPortUsage(t,e,n){if(t.d.isPad){return(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}const o=function(t,e,n){const o=Ai(t),i=[zi(e,t),zi(n,t)],s=[],r=t.assignments??[];for(const e of r)ki(i,[zi(e.regionPort1,t),zi(e.regionPort2,t)],o)&&s.push(e);return s}(t,e,n),i=o.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId);if(!t.d.isThroughJumper)return i;for(const e of t.assignments??[])e.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId&&i.push(e);return i}isRipRequiredForPortUsage(t,e,n){if(!t.d.isThroughJumper&&!t.d.isPad)return!1;for(const e of t.assignments??[])if(e.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)return!0;return!1}routeSolvedHook(t){}routeStartedHook(t){}visualize(){return(t=>{const e={regions:t.graph.regions,ports:t.graph.ports},n=Bi(e,{connections:t.connections,...t.iterations>0?{hideRegionPortLines:!0,hideConnectionLines:!0,hidePortPoints:!0}:{}});if(0===t.iterations)for(const t of n.polygons)t.stroke="rgba(128, 128, 128, 0.5)",t.strokeWidth=.03;if(t.currentConnection&&!t.solved){const e=ji(t.currentConnection.connectionId),o=t.currentConnection.startRegion,i=t.currentConnection.endRegion,s={x:(o.d.bounds.minX+o.d.bounds.maxX)/2,y:(o.d.bounds.minY+o.d.bounds.maxY)/2},r={x:(i.d.bounds.minX+i.d.bounds.maxX)/2,y:(i.d.bounds.minY+i.d.bounds.maxY)/2};n.lines.push({points:[s,r],strokeColor:e,strokeDash:"10 5"}),n.points.push({x:s.x-.1,y:s.y+.1,color:e,label:[t.currentConnection.connectionId,"start"].join("\n")}),n.points.push({x:r.x-.1,y:r.y+.1,color:e,label:[t.currentConnection.connectionId,"end"].join("\n")})}for(const e of t.solvedRoutes){const t=ji(e.connection.connectionId),o=[];for(const t of e.path){const e=t.port;o.push({x:e.d.x,y:e.d.y})}o.length>0&&n.lines.push({points:o,strokeColor:t})}const o=t.candidateQueue.peekMany(10);for(let t=0;t<o.length;t++){const e=o[t],i=e.port,s=0===t;n.points.push({x:i.d.x,y:i.d.y,color:s?"green":"rgba(128, 128, 128, 0.25)",label:[e.port.portId,`g: ${e.g.toFixed(2)}`,`h: ${e.h.toFixed(2)}`,`f: ${e.f.toFixed(2)}`].join("\n")})}const i=o[0];if(!t.solved&&i&&t.currentConnection){const e=ji(t.currentConnection.connectionId),o=[];let s=i;for(;s;){const t=s.port;o.unshift({x:t.d.x,y:t.d.y}),s=s.parent}o.length>1&&n.lines.push({points:o,strokeColor:e})}return n})(this)}},Ji=(t,e,n,o)=>{const i={portId:t,region1:e,region2:n,d:{x:o.x,y:o.y}};return e.ports.push(i),n.ports.push(i),i},Ki=(t,e,n)=>{const o=.2;return{regionId:t,ports:[],d:{bounds:{minX:e-o,maxX:e+o,minY:n-o,maxY:n+o},center:{x:e,y:n},isPad:!1,isConnectionRegion:!0}}},Qi=.01,ts=(t,e,n)=>Math.max(e,Math.min(n,t)),es=(t,e,n)=>"left"===e?Math.abs(t.x-n.minX)<Qi:"right"===e?Math.abs(t.x-n.maxX)<Qi:"top"===e?Math.abs(t.y-n.maxY)<Qi:Math.abs(t.y-n.minY)<Qi,ns=(t,e,n,o)=>{const i=o.x-n.x,s=o.y-n.y,r=t-n.x,a=e-n.y,c=i*i+s*s,h=c>0?ts((r*i+a*s)/c,0,1):0,l=n.x+h*i,d=n.y+h*s,u=t-l,p=e-d;return{x:l,y:d,d2:u*u+p*p}},os=(t,e,n,o,i)=>{const s=n.d.polygon;if(s&&s.length>=3){const n=new Set(i);let r=null;for(let a=0;a<s.length;a++){const c=s[a],h=s[(a+1)%s.length];if(i.length>0){if(!i.some(t=>es(c,t,o)&&es(h,t,o)&&n.has(t)))continue}const l=ns(t,e,c,h);(!r||l.d2<r.d2)&&(r=l)}if(r)return r}const r=n.d.bounds,a=[];if(i.length>0)for(const n of i)"left"===n?a.push({side:n,x:r.minX,y:ts(e,r.minY,r.maxY)}):"right"===n?a.push({side:n,x:r.maxX,y:ts(e,r.minY,r.maxY)}):"top"===n?a.push({side:n,x:ts(t,r.minX,r.maxX),y:r.maxY}):a.push({side:n,x:ts(t,r.minX,r.maxX),y:r.minY});0===a.length&&a.push({side:"left",x:r.minX,y:ts(e,r.minY,r.maxY)},{side:"right",x:r.maxX,y:ts(e,r.minY,r.maxY)},{side:"top",x:ts(t,r.minX,r.maxX),y:r.maxY},{side:"bottom",x:ts(t,r.minX,r.maxX),y:r.minY});let c=null;for(const n of a){if(i.length>0&&!i.includes(n.side))continue;const o=t-n.x,s=e-n.y,r=o*o+s*s;(!c||r<c.d2)&&(c={x:n.x,y:n.y,d2:r})}return c},is=(t,e,n,o)=>{const i=((t,e,n)=>{const o=[];return Math.abs(t-n.minX)<Qi&&o.push("left"),Math.abs(t-n.maxX)<Qi&&o.push("right"),Math.abs(e-n.maxY)<Qi&&o.push("top"),Math.abs(e-n.minY)<Qi&&o.push("bottom"),o})(t,e,o);let s=null,r=Number.POSITIVE_INFINITY,a={x:t,y:e};for(const c of n){if(c.d.isPad||c.d.isThroughJumper)continue;const n=c.d.bounds;if(!(Math.abs(n.minX-o.minX)<.01||Math.abs(n.maxX-o.maxX)<.01||Math.abs(n.minY-o.minY)<.01||Math.abs(n.maxY-o.maxY)<.01))continue;const h=os(t,e,c,o,i);if(!h)continue;const l=Math.sqrt(h.d2);l<r&&(r=l,s=c,a={x:h.x,y:h.y})}return s?{region:s,portPosition:a}:null},ss={padWidth:.8,outerPadHeight:.5,innerPadHeight:.4,leftPadCenterX:-.9,rightPadCenterX:.9,row1CenterY:-1.2,row2CenterY:-.4,row3CenterY:.4,row4CenterY:1.2},rs=({cols:t,rows:e,marginX:n,marginY:o,innerColChannelPointCount:i=1,innerRowChannelPointCount:s=1,regionsBetweenPads:r=!1,outerPaddingX:a=.5,outerPaddingY:c=.5,outerChannelXPointCount:h,outerChannelYPointCount:l,orientation:d="vertical",center:u,bounds:p,parallelTracesUnderJumperCount:f=2})=>{const g=[],m=[],{padWidth:y,outerPadHeight:x,innerPadHeight:v,leftPadCenterX:b,rightPadCenterX:P,row1CenterY:S,row2CenterY:I,row3CenterY:M,row4CenterY:_}=ss,N=y/2,C=x/2,T=v/2,E=P-b+y,w=E+n,R=_-S+x,O=R+o;let A=a,z=c;if(p){const i=t*E+(t-1)*n,s=e*R+(e-1)*o;A=(("horizontal"===d?p.maxY-p.minY:p.maxX-p.minX)-i)/2,z=(("horizontal"===d?p.maxX-p.minX:p.maxY-p.minY)-s)/2}const D=h??Math.max(1,Math.floor(A/.4)),L=l??Math.max(1,Math.floor(z/.4)),Y=[],X=[],F=(t,e,n,o)=>({regionId:t,ports:[],d:{bounds:e,center:Ci(e),isPad:n,isThroughJumper:o}}),k=(t,e,n)=>{const o=e.d.bounds,i=n.d.bounds;let s,r;Math.abs(o.maxX-i.minX)<.001?(s=o.maxX,r=(Math.max(o.minY,i.minY)+Math.min(o.maxY,i.maxY))/2):Math.abs(o.minX-i.maxX)<.001?(s=o.minX,r=(Math.max(o.minY,i.minY)+Math.min(o.maxY,i.maxY))/2):Math.abs(o.maxY-i.minY)<.001?(s=(Math.max(o.minX,i.minX)+Math.min(o.maxX,i.maxX))/2,r=o.maxY):(s=(Math.max(o.minX,i.minX)+Math.min(o.maxX,i.maxX))/2,r=o.minY);const a={portId:t,region1:e,region2:n,d:{x:s,y:r}};return e.ports.push(a),n.ports.push(a),a},$=(t,e,n,o)=>{if(o<=0)return[];if(1===o)return[k(t,e,n)];const i=e.d.bounds,s=n.d.bounds,r=[];let a,c,h,l;Math.abs(i.maxX-s.minX)<.001?(a=!0,c=i.maxX,h=Math.max(i.minY,s.minY),l=Math.min(i.maxY,s.maxY)):Math.abs(i.minX-s.maxX)<.001?(a=!0,c=i.minX,h=Math.max(i.minY,s.minY),l=Math.min(i.maxY,s.maxY)):Math.abs(i.maxY-s.minY)<.001?(a=!1,c=i.maxY,h=Math.max(i.minX,s.minX),l=Math.min(i.maxX,s.maxX)):(a=!1,c=i.minY,h=Math.max(i.minX,s.minX),l=Math.min(i.maxX,s.maxX));for(let i=0;i<o;i++){const s=h+(i+.5)/o*(l-h),d={portId:`${t}:${i}`,region1:e,region2:n,d:{x:a?c:s,y:a?s:c}};e.ports.push(d),n.ports.push(d),r.push(d)}return r};for(let n=0;n<e;n++){Y[n]=[];for(let a=0;a<t;a++){const c=`cell_${n}_${a}`,h=a*w,l=-n*O,d=h+b,u=l+S,p=h+b,y=l+I,x=h+b,v=l+M,E=h+b,R=l+_,B=h+P,j=l+_,W=h+P,V=l+M,H=h+P,U=l+I,G=h+P,Z=l+S,q=(t,e,n)=>({minX:t-N,maxX:t+N,minY:e-n,maxY:e+n}),J=q(d,u,C),K=q(p,y,T),Q=q(x,v,T),tt=q(E,R,C),et=q(B,j,C),nt=q(W,V,T),ot=q(H,U,T),it=q(G,Z,C),st={minX:J.maxX,maxX:it.minX,minY:J.minY,maxY:tt.maxY},rt=.3,at={minX:d,maxX:G,minY:u-rt/2,maxY:u+rt/2},ct={minX:p,maxX:H,minY:y-rt/2,maxY:y+rt/2},ht={minX:x,maxX:W,minY:v-rt/2,maxY:v+rt/2},lt={minX:E,maxX:B,minY:R-rt/2,maxY:R+rt/2},dt=J.minX,ut=it.maxX,pt=J.minY,ft=tt.maxY,gt=F(`${c}:pad1`,J,!0),mt=F(`${c}:pad2`,K,!0),yt=F(`${c}:pad3`,Q,!0),xt=F(`${c}:pad4`,tt,!0),vt=F(`${c}:pad5`,et,!0),bt=F(`${c}:pad6`,nt,!0),Pt=F(`${c}:pad7`,ot,!0),St=F(`${c}:pad8`,it,!0),It=F(`${c}:underjumper`,st,!1),Mt=F(`${c}:throughjumper1`,at,!1,!0),_t=F(`${c}:throughjumper2`,ct,!1,!0),Nt=F(`${c}:throughjumper3`,ht,!1,!0),Ct=F(`${c}:throughjumper4`,lt,!1,!0);g.push(gt,mt,yt,xt,vt,bt,Pt,St,It,Mt,_t,Nt,Ct);const Tt=(d+G)/2,Et=(u+R)/2;X.push({center:{x:Tt,y:Et},orientation:"vertical",padRegions:[gt,mt,yt,xt,vt,bt,Pt,St]});let wt=null,Rt=null,Ot=null,At=null,zt=null,Dt=null;r&&(wt=F(`${c}:L-BP12`,{minX:J.minX,maxX:J.maxX,minY:J.maxY,maxY:K.minY},!1),Rt=F(`${c}:L-BP23`,{minX:K.minX,maxX:K.maxX,minY:K.maxY,maxY:Q.minY},!1),Ot=F(`${c}:L-BP34`,{minX:Q.minX,maxX:Q.maxX,minY:Q.maxY,maxY:tt.minY},!1),At=F(`${c}:R-BP87`,{minX:it.minX,maxX:it.maxX,minY:it.maxY,maxY:ot.minY},!1),zt=F(`${c}:R-BP76`,{minX:ot.minX,maxX:ot.maxX,minY:ot.maxY,maxY:nt.minY},!1),Dt=F(`${c}:R-BP65`,{minX:nt.minX,maxX:nt.maxX,minY:nt.maxY,maxY:et.minY},!1),g.push(wt,Rt,Ot,At,zt,Dt));const Lt=0===a,Yt=n===e-1,Xt=a===t-1;let Ft;if(Xt)Ft=ut+A;else{Ft=(a+1)*w+b-N}let kt=null;0===n&&(kt=F(`${c}:T`,{minX:Lt?dt-A:dt,maxX:Ft,minY:ft,maxY:ft+z},!1),g.push(kt));let $t=null;$t=F(`${c}:B`,{minX:Lt?dt-A:dt,maxX:Ft,minY:pt-(Yt?z:o),maxY:pt},!1),g.push($t);let Bt=null;Lt&&(Bt=F(`${c}:L`,{minX:dt-A,maxX:dt,minY:pt,maxY:ft},!1),g.push(Bt));const jt=F(`${c}:R`,{minX:ut,maxX:Ft,minY:pt,maxY:ft},!1);if(g.push(jt),Y[n][a]={pad1:gt,pad2:mt,pad3:yt,pad4:xt,pad5:vt,pad6:bt,pad7:Pt,pad8:St,underjumper:It,throughjumper1:Mt,throughjumper2:_t,throughjumper3:Nt,throughjumper4:Ct,top:kt,bottom:$t,left:Bt,right:jt,leftBP12:wt,leftBP23:Rt,leftBP34:Ot,rightBP87:At,rightBP76:zt,rightBP65:Dt},kt)if(Bt&&m.push(...$(`${c}:T-L`,kt,Bt,D)),m.push(...$(`${c}:T-R`,kt,jt,Xt?D:i)),m.push(k(`${c}:T-P4`,kt,xt)),m.push(k(`${c}:T-P5`,kt,vt)),r){const t=It.d.bounds,e=(t.maxX-t.minX)/(f+1);for(let n=1;n<=f;n++){const o={portId:`${c}:T-UJ${n}`,region1:kt,region2:It,d:{x:t.minX+e*n,y:t.maxY}};kt.ports.push(o),It.ports.push(o),m.push(o)}}else m.push(k(`${c}:T-UJ`,kt,It));if($t)if(Bt&&m.push(...$(`${c}:B-L`,$t,Bt,D)),m.push(...$(`${c}:B-R`,$t,jt,Xt?D:i)),m.push(k(`${c}:B-P1`,$t,gt)),m.push(k(`${c}:B-P8`,$t,St)),r){const t=It.d.bounds,e=(t.maxX-t.minX)/(f+1);for(let n=1;n<=f;n++){const o={portId:`${c}:B-UJ${n}`,region1:$t,region2:It,d:{x:t.minX+e*n,y:t.minY}};$t.ports.push(o),It.ports.push(o),m.push(o)}}else m.push(k(`${c}:B-UJ`,$t,It));Bt&&(m.push(k(`${c}:L-P1`,Bt,gt)),m.push(k(`${c}:L-P2`,Bt,mt)),m.push(k(`${c}:L-P3`,Bt,yt)),m.push(k(`${c}:L-P4`,Bt,xt))),m.push(k(`${c}:R-P5`,jt,vt)),m.push(k(`${c}:R-P6`,jt,bt)),m.push(k(`${c}:R-P7`,jt,Pt)),m.push(k(`${c}:R-P8`,jt,St)),r&&(Bt&&(m.push(k(`${c}:L-BP12`,Bt,wt)),m.push(k(`${c}:L-BP23`,Bt,Rt)),m.push(k(`${c}:L-BP34`,Bt,Ot))),m.push(k(`${c}:UJ-LBP12`,wt,It)),m.push(k(`${c}:UJ-LBP23`,Rt,It)),m.push(k(`${c}:UJ-LBP34`,Ot,It)),m.push(k(`${c}:R-BP87`,jt,At)),m.push(k(`${c}:R-BP76`,jt,zt)),m.push(k(`${c}:R-BP65`,jt,Dt)),m.push(k(`${c}:UJ-RBP87`,At,It)),m.push(k(`${c}:UJ-RBP76`,zt,It)),m.push(k(`${c}:UJ-RBP65`,Dt,It)));const Wt={portId:`${c}:TJ1-P1`,region1:Mt,region2:gt,d:{x:d,y:u}};Mt.ports.push(Wt),gt.ports.push(Wt),m.push(Wt);const Vt={portId:`${c}:TJ1-P8`,region1:Mt,region2:St,d:{x:G,y:Z}};Mt.ports.push(Vt),St.ports.push(Vt),m.push(Vt);const Ht={portId:`${c}:TJ2-P2`,region1:_t,region2:mt,d:{x:p,y:y}};_t.ports.push(Ht),mt.ports.push(Ht),m.push(Ht);const Ut={portId:`${c}:TJ2-P7`,region1:_t,region2:Pt,d:{x:H,y:U}};_t.ports.push(Ut),Pt.ports.push(Ut),m.push(Ut);const Gt={portId:`${c}:TJ3-P3`,region1:Nt,region2:yt,d:{x:x,y:v}};Nt.ports.push(Gt),yt.ports.push(Gt),m.push(Gt);const Zt={portId:`${c}:TJ3-P6`,region1:Nt,region2:bt,d:{x:W,y:V}};Nt.ports.push(Zt),bt.ports.push(Zt),m.push(Zt);const qt={portId:`${c}:TJ4-P4`,region1:Ct,region2:xt,d:{x:E,y:R}};Ct.ports.push(qt),xt.ports.push(qt),m.push(qt);const Jt={portId:`${c}:TJ4-P5`,region1:Ct,region2:vt,d:{x:B,y:j}};if(Ct.ports.push(Jt),vt.ports.push(Jt),m.push(Jt),a>0){const t=Y[n][a-1];m.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P1`,t.right,gt)),m.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P2`,t.right,mt)),m.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P3`,t.right,yt)),m.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-P4`,t.right,xt)),r&&(m.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP12`,t.right,wt)),m.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP23`,t.right,Rt)),m.push(k(`cell_${n}_${a-1}->cell_${n}_${a}:R-LBP34`,t.right,Ot))),kt&&t.top&&m.push(...$(`cell_${n}_${a-1}->cell_${n}_${a}:T-T`,t.top,kt,L)),$t&&t.bottom&&m.push(...$(`cell_${n}_${a-1}->cell_${n}_${a}:B-B`,t.bottom,$t,Yt?L:s))}if(n>0){const t=Y[n-1][a];if(Bt&&m.push(...$(`cell_${n-1}_${a}->cell_${n}_${a}:B-L`,t.bottom,Bt,D)),m.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-P4`,t.bottom,xt)),r){const e=It.d.bounds,o=(e.maxX-e.minX)/(f+1);for(let i=1;i<=f;i++){const s=e.minX+o*i,r={portId:`cell_${n-1}_${a}->cell_${n}_${a}:B-UJ${i}`,region1:t.bottom,region2:It,d:{x:s,y:e.maxY}};t.bottom.ports.push(r),It.ports.push(r),m.push(r)}}else m.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-UJ`,t.bottom,It));m.push(k(`cell_${n-1}_${a}->cell_${n}_${a}:B-P5`,t.bottom,vt)),m.push(...$(`cell_${n-1}_${a}->cell_${n}_${a}:B-R`,t.bottom,jt,Xt?D:i))}}}let B={regions:g,ports:m,jumperLocations:X};const j="horizontal"===d;if(j||void 0!==u||void 0!==p){const t=Ni(B.regions),e=Ci(t),n=[];let o;o=u||(p?Ci(p):e),n.push(bi(o.x,o.y)),j&&n.push(function(t,e,n){const o=Si(t),i=Ii(t),s={a:o,c:-i,e:0,b:i,d:o,f:0};return vi(e)||vi(n)?s:Pi([bi(e,n),s,bi(-e,-n)])}(-Math.PI/2)),n.push(bi(-e.x,-e.y));const i=function(...t){return Pi(...t)}(...n);B=Ti(B,i)}return B};function as(t,e,n,o,i,s,r){return!!ki(t,e,n)||function(t,e,n,o,i=1e-9){const s=(t,e)=>Math.abs(t.x-e.x)<i&&Math.abs(t.y-e.y)<i;if(s(t,n)||s(t,o)||s(e,n)||s(e,o))return!1;const r=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),a=r(n,o,t),c=r(n,o,e),h=r(t,e,n),l=r(t,e,o);if(a*c<0&&h*l<0)return!0;const d=(t,e,n,o)=>{if(Math.abs(o)>i)return!1;const s=Math.min(e.x,n.x)-i,r=Math.max(e.x,n.x)+i,a=Math.min(e.y,n.y)-i,c=Math.max(e.y,n.y)+i;return t.x>=s&&t.x<=r&&t.y>=a&&t.y<=c};return!((!d(t,n,o,a)||s(t,n)||s(t,o))&&(!d(e,n,o,c)||s(e,n)||s(e,o))&&(!d(n,t,e,h)||s(n,t)||s(n,e))&&(!d(o,t,e,l)||s(o,t)||s(o,e)))}(o.d,i.d,s.d,r.d)}var cs=1e-6;function hs(t,e){return Math.abs(t.x-e.x)<=cs&&Math.abs(t.y-e.y)<=cs}function ls(t,e){const n=t[t.length-1];n&&hs(n,e)||t.push(e)}function ds(t,e){let n=null,o=1/0;for(const i of t){const t=i.position.x-e.x,s=i.position.y-e.y,r=Math.hypot(t,s);r<o&&(o=r,n=i)}return n}function us(t,e){const n=new Set(e.map(t=>t.viaId));return t.routeSegments.filter(t=>"bottom"===t.layer&&n.has(t.fromPort)&&n.has(t.toPort)&&t.segments.length>=2)}function ps(t,e){const n=function(t){const e=t.lastIndexOf(":v:");if(-1!==e)return t.slice(e+3);const n=t.lastIndexOf(":");return-1===n?t:t.slice(n+1)}(e.regionId);if(!n)return[];const o=t.viasByNet[n];if(!o||0===o.length)return[];const i=function(t){const e=t.lastIndexOf(":v:");return e<=0?null:t.slice(0,e)}(e.regionId);if(!i)return o;const s=o.filter(t=>t.viaId.startsWith(`${i}:`));return s.length>0?s:o}function fs(t,e,n){const o=function(t){const e=[];for(const n of t)ls(e,n);return e}(e);if(o.length<2)return;const i=t[t.length-1];if(!i||i.layer!==n)return void t.push({points:o,layer:n});const s=i.points[i.points.length-1],r=o[0];if(!s||!r||!hs(s,r))return void t.push({points:o,layer:n});const a=o.slice(1);for(const t of a)ls(i.points,t)}function gs(t,e){if(0===t.path.length)return[];const n=t.path,o=[],i=new Set;for(let t=1;t<n.length;t++){const s=n[t-1],r=n[t],a={x:s.port.d.x,y:s.port.d.y},c={x:r.port.d.x,y:r.port.d.y},h=r.lastRegion;if(!(!!e&&!!h?.d?.isViaRegion)){fs(o,[a,c],"top");continue}const l=ps(e,h);if(0===l.length)continue;const d=ds(l,a),u=ds(l,c);d&&fs(o,[a,d.position],"top");const p=us(e,l);if(p.length>0&&!i.has(h.regionId)){i.add(h.regionId);for(const t of p)fs(o,t.segments,"bottom")}u&&fs(o,[u.position,c],"top")}return o}function ms(t,e){return function(t){const e=[];for(const n of t)for(const t of n.points)ls(e,t);return e}(gs(t,e))}var ys=(t,e=.8)=>{let n=0;for(let e=0;e<t.length;e++)n=17777*t.charCodeAt(e)+((n<<5)-n);return`hsla(${Math.abs(n)%360}, 70%, 50%, ${e})`},xs=["rgba(231, 76, 60, 0.35)","rgba(46, 204, 113, 0.35)","rgba(52, 152, 219, 0.35)","rgba(243, 156, 18, 0.35)","rgba(155, 89, 182, 0.35)","rgba(26, 188, 156, 0.35)","rgba(241, 196, 15, 0.35)","rgba(230, 126, 34, 0.35)"],vs=.034685181009478865,bs=0,Ps=4.072520483177124,Ss=0,Is=35.38577539020022,Ms=.5518001238069296,_s=class extends yi{getSolverName(){return"ViaGraphSolver"}UNIT_OF_COST="hops";viaTile;portUsagePenalty=vs;portUsagePenaltySq=bs;crossingPenalty=Ps;crossingPenaltySq=Ss;ripCost=Is;baseMaxIterations=9e5;additionalMaxIterationsPerConnection=2e3;additionalMaxIterationsPerCrossing=2e3;constructor(t){super({greedyMultiplier:Ms,rippingEnabled:!0,...t}),this.viaTile=t.viaTile,this.ripCost=t.ripCost??this.ripCost,this.portUsagePenalty=t.portUsagePenalty??this.portUsagePenalty,this.crossingPenalty=t.crossingPenalty??this.crossingPenalty,this.baseMaxIterations=t.baseMaxIterations??this.baseMaxIterations,this.additionalMaxIterationsPerConnection=t.additionalMaxIterationsPerConnection??this.additionalMaxIterationsPerConnection;const e=$i(this.graph,t.inputConnections);this.MAX_ITERATIONS=this.baseMaxIterations+t.inputConnections.length*this.additionalMaxIterationsPerConnection+e*this.additionalMaxIterationsPerCrossing,this.populateDistanceToEndMaps()}populateDistanceToEndMaps(){const t=new Set(this.connections.map(t=>t.endRegion));for(const e of t){const t=new Map,n=[];for(t.set(e.regionId,0),n.push({region:e,distance:0});n.length>0;){const{region:e,distance:o}=n.shift();for(const i of e.ports){const s=i.region1===e?i.region2:i.region1;t.has(s.regionId)||(t.set(s.regionId,o+1),n.push({region:s,distance:o+1}))}}for(const n of this.graph.ports){n.distanceToEndMap||(n.distanceToEndMap={});const o=t.get(n.region1.regionId)??1/0,i=t.get(n.region2.regionId)??1/0;n.distanceToEndMap[e.regionId]=Math.min(o,i)}}}estimateCostToEnd(t){const e=this.currentEndRegion.regionId;return t.distanceToEndMap[e]}getPortUsagePenalty(t){const e=t.ripCount??0;return e*this.portUsagePenalty+e*this.portUsagePenaltySq}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){if(t.d.isViaRegion){const e=(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId).length;return e>0?e*this.crossingPenalty+e*this.crossingPenaltySq:0}const o=function(t,e,n){const o=t.d.polygon;if(!o||o.length<3)return 0;const i=Ai(t),s=[zi(e,t),zi(n,t)];let r=0;const a=t.assignments??[];for(const o of a){const a=o.regionPort1,c=o.regionPort2;as(s,[zi(a,t),zi(c,t)],i,e,n,a,c)&&r++}return r}(t,e,n);return o*this.crossingPenalty+o*this.crossingPenaltySq}isRipRequiredForPortUsage(t,e,n){if(t.d.isViaRegion){return(t.assignments??[]).some(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}return!1}getRipsRequiredForPortUsage(t,e,n){if(t.d.isViaRegion){return(t.assignments??[]).filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}const o=function(t,e,n){const o=t.d.polygon;if(!o||o.length<3)return[];const i=Ai(t),s=[zi(e,t),zi(n,t)],r=[],a=t.assignments??[];for(const o of a){const a=o.regionPort1,c=o.regionPort2;as(s,[zi(a,t),zi(c,t)],i,e,n,a,c)&&r.push(o)}return r}(t,e,n);return o.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection.mutuallyConnectedNetworkId)}routeSolvedHook(t){}getSolvedRoutePoints(t){return ms(t,this.viaTile)}getSolvedRouteLineSegments(t){return gs(t,this.viaTile)}routeStartedHook(t){}visualize(){return(t=>{const e={regions:t.graph.regions,ports:t.graph.ports},n=Bi(e,{connections:t.connections,...t.iterations>0?{hideRegionPortLines:!0,hideConnectionLines:!0,hidePortPoints:!0}:{}});if(0===t.iterations)for(const t of n.polygons)t.stroke="rgba(128, 128, 128, 0.5)",t.strokeWidth=.03;const o=new Set(["T","B","L","R"]);let i=0;const s=new Map;let r=0;for(const t of e.regions){const e=t;if(!(e.d.polygon&&e.d.polygon.length>=3))continue;const a=e.regionId.split(":").pop()??"";o.has(a)||e.d.isConnectionRegion||(s.has(a)||(s.set(a,xs[i%xs.length]),i++),n.polygons[r]&&(n.polygons[r].fill=s.get(a))),r++}if(t.currentConnection&&!t.solved){const e=ys(t.currentConnection.connectionId),o=t.currentConnection.startRegion,i=t.currentConnection.endRegion,s={x:(o.d.bounds.minX+o.d.bounds.maxX)/2,y:(o.d.bounds.minY+o.d.bounds.maxY)/2},r={x:(i.d.bounds.minX+i.d.bounds.maxX)/2,y:(i.d.bounds.minY+i.d.bounds.maxY)/2};n.lines.push({points:[s,r],strokeColor:e,strokeDash:"10 5"}),n.points.push({x:s.x-.1,y:s.y+.1,color:e,label:[t.currentConnection.connectionId,"start"].join("\n")}),n.points.push({x:r.x-.1,y:r.y+.1,color:e,label:[t.currentConnection.connectionId,"end"].join("\n")})}for(const e of t.solvedRoutes){const o=ys(e.connection.connectionId),i=t.getSolvedRouteLineSegments(e);for(const t of i){const e="bottom"===t.layer;n.lines.push({points:t.points,strokeColor:e?"rgba(52, 152, 219, 0.95)":o,...e?{strokeDash:"3 2"}:{}})}}const a=t.candidateQueue.peekMany(10);for(let t=0;t<a.length;t++){const e=a[t],o=e.port,i=0===t;n.points.push({x:o.d.x,y:o.d.y,color:i?"green":"rgba(128, 128, 128, 0.25)",label:[e.port.portId,`g: ${e.g.toFixed(2)}`,`h: ${e.h.toFixed(2)}`,`f: ${e.f.toFixed(2)}`].join("\n")})}const c=a[0];if(!t.solved&&c&&t.currentConnection){const e=ys(t.currentConnection.connectionId),o=[];let i=c;for(;i;){const t=i.port;o.unshift({x:t.d.x,y:t.d.y}),i=i.parent}o.length>1&&n.lines.push({points:o,strokeColor:e})}if(t.viaTile){n.circles||(n.circles=[]);for(const[e,o]of Object.entries(t.viaTile.viasByNet)){const t=s.get(e),i=t?t.replace("0.35","0.5"):"rgba(255, 0, 0, 0.3)";for(const t of o)n.circles.push({center:t.position,radius:t.diameter/2,fill:i,label:e})}}return n})(this)}};function Ns(t,e){let n=1/0,o={x:t.x,y:t.y};for(let i=0;i<e.length;i++){const s=e[i],r=e[(i+1)%e.length],a=r.x-s.x,c=r.y-s.y,h=a*a+c*c;if(h<1e-10)continue;const l=Math.max(0,Math.min(1,((t.x-s.x)*a+(t.y-s.y)*c)/h)),d=s.x+l*a,u=s.y+l*c,p=Math.sqrt((t.x-d)**2+(t.y-u)**2);p<n&&(n=p,o={x:d,y:u})}return{...o,dist:n}}var Cs=t=>{const{x:e,y:n,regions:o}=t,i=o.some(t=>t.regionId.startsWith("filler:"));let s=null,r=1/0,a={x:e,y:n};for(const t of o){if(t.d.isPad||t.d.isThroughJumper||t.d.isConnectionRegion)continue;if(i&&!t.regionId.startsWith("filler:"))continue;const o=t.d.polygon;if(!o||o.length<3)continue;const c=Ns({x:e,y:n},o);c.dist<r&&(r=c.dist,s=t,a={x:c.x,y:c.y})}return s?{region:s,portPosition:a}:null},Ts=!0,Es={CCW:-1,CW:1,NOT_ORIENTABLE:0},ws=2*Math.PI,Rs=Object.freeze({__proto__:null,BOUNDARY:2,CCW:Ts,CONTAINS:3,CW:!1,END_VERTEX:2,INSIDE:1,INTERLACE:4,NOT_VERTEX:0,ORIENTATION:Es,OUTSIDE:0,OVERLAP_OPPOSITE:2,OVERLAP_SAME:1,PIx2:ws,START_VERTEX:1}),Os=1e-6;function As(t){Os=t}function zs(){return Os}function Ds(t){return t<Os&&t>-Os}function Ls(t,e){return t-e<Os&&t-e>-Os}function Ys(t,e){return t-e>Os}function Xs(t,e){return t-e<-Os}var Fs={Utils:Object.freeze({__proto__:null,DECIMALS:3,EQ:Ls,EQ_0:Ds,GE:function(t,e){return t-e>-Os},GT:Ys,LE:function(t,e){return t-e<Os},LT:Xs,getTolerance:zs,setTolerance:As}),Errors:void 0,Matrix:void 0,Planar_set:void 0,Point:void 0,Vector:void 0,Line:void 0,Circle:void 0,Segment:void 0,Arc:void 0,Box:void 0,Edge:void 0,Face:void 0,Ray:void 0,Ray_shooting:void 0,Multiline:void 0,Polygon:void 0,Distance:void 0,Inversion:void 0};for(let t in Rs)Fs[t]=Rs[t];Object.defineProperty(Fs,"DP_TOL",{get:function(){return zs()},set:function(t){As(t)}});var ks=class{static get ILLEGAL_PARAMETERS(){return new ReferenceError("Illegal Parameters")}static get ZERO_DIVISION(){return new Error("Zero division")}static get UNRESOLVED_BOUNDARY_CONFLICT(){return new Error("Unresolved boundary conflict in boolean operation")}static get INFINITE_LOOP(){return new Error("Infinite loop")}static get CANNOT_COMPLETE_BOOLEAN_OPERATION(){return new Error("Cannot complete boolean operation")}static get CANNOT_INVOKE_ABSTRACT_METHOD(){return new Error("Abstract method cannot be invoked")}static get OPERATION_IS_NOT_SUPPORTED(){return new Error("Operation is not supported")}static get UNSUPPORTED_SHAPE_TYPE(){return new Error("Unsupported shape type")}};Fs.Errors=ks;var $s=class{constructor(t,e){this.first=t,this.last=e||this.first}[Symbol.iterator](){let t;return{next:()=>(t=t?t.next:this.first,{value:t,done:void 0===t})}}get size(){let t=0;for(let e of this)t++;return t}toArray(t=void 0,e=void 0){let n=[],o=t||this.first,i=e||this.last,s=o;if(void 0===s)return n;do{n.push(s),s=s.next}while(s!==i.next);return n}append(t){return this.isEmpty()?this.first=t:(t.prev=this.last,this.last.next=t),this.last=t,this.last.next=void 0,this.first.prev=void 0,this}insert(t,e){if(this.isEmpty())this.first=t,this.last=t;else if(null==e)t.next=this.first,this.first.prev=t,this.first=t;else{let n=e.next;e.next=t,n&&(n.prev=t),t.prev=e,t.next=n,this.last===e&&(this.last=t)}return this.last.next=void 0,this.first.prev=void 0,this}remove(t){return t===this.first&&t===this.last?(this.first=void 0,this.last=void 0):(t.prev&&(t.prev.next=t.next),t.next&&(t.next.prev=t.prev),t===this.first&&(this.first=t.next),t===this.last&&(this.last=t.prev)),this}isEmpty(){return void 0===this.first}static testInfiniteLoop(t){let e=t,n=t;do{if(e!=t&&e===n)throw ks.INFINITE_LOOP;e=e.next,n=n.next.next}while(e!=t)}},Bs={stroke:"black"},js=class{constructor(t=Bs){for(const e in t)this[e]=t[e];this.stroke=t.stroke??Bs.stroke}toAttributesString(){return Object.keys(this).reduce((t,e)=>t+(void 0!==this[e]?this.toAttrString(e,this[e]):""),"")}toAttrString(t,e){const n="className"===t?"class":this.convertCamelToKebabCase(t);return null===e?`${n} `:`${n}="${e.toString()}" `}convertCamelToKebabCase(t){return t.match(/[A-Z]{2,}(?=[A-Z][a-z]+[0-9]*|\b)|[A-Z]?[a-z]+[0-9]*|[A-Z]|[0-9]+/g).join("-").toLowerCase()}};function Ws(t){return new js(t).toAttributesString()}function Vs(t,e){let n=[],[o,i,s]=t.standard,[r,a,c]=e.standard,h=o*a-i*r,l=s*a-i*c,d=o*c-s*r;if(!Fs.Utils.EQ_0(h)){let t,e;0===i?(t=s/o,e=d/h):0===a?(t=c/r,e=d/h):0===o?(t=l/h,e=s/i):0===r?(t=l/h,e=c/a):(t=l/h,e=d/h),n.push(new Fs.Point(t,e))}return n}function Hs(t,e){let n=[],o=e.pc.projectionOn(t),i=e.pc.distanceTo(o)[0];if(Fs.Utils.EQ(i,e.r))n.push(o);else if(Fs.Utils.LT(i,e.r)){let s,r,a=Math.sqrt(e.r*e.r-i*i);s=t.norm.rotate90CCW().multiply(a),r=o.translate(s),n.push(r),s=t.norm.rotate90CW().multiply(a),r=o.translate(s),n.push(r)}return n}function Us(t,e){let n=[];for(let o of e.toSegments()){let e=Zs(o,t);for(let t of e)pr(t,n)||n.push(t)}return n}function Gs(t,e){let n=[];if(0===Us(t,e.box).length)return n;let o=Hs(t,new Fs.Circle(e.pc,e.r));for(let t of o)t.on(e)&&n.push(t);return n}function Zs(t,e){let n=[];return t.ps.on(e)&&n.push(t.ps),t.pe.on(e)&&!t.isZeroLength()&&n.push(t.pe),n.length>0||t.isZeroLength()||t.ps.leftTo(e)&&t.pe.leftTo(e)||!t.ps.leftTo(e)&&!t.pe.leftTo(e)?n:Vs(new Fs.Line(t.ps,t.pe),e)}function qs(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)&&n.push(t.ps),n;if(e.isZeroLength())return e.ps.on(t)&&n.push(e.ps),n;let o=new Fs.Line(t.ps,t.pe),i=new Fs.Line(e.ps,e.pe);if(o.incidentTo(i))t.ps.on(e)&&n.push(t.ps),t.pe.on(e)&&n.push(t.pe),!e.ps.on(t)||e.ps.equalTo(t.ps)||e.ps.equalTo(t.pe)||n.push(e.ps),!e.pe.on(t)||e.pe.equalTo(t.ps)||e.pe.equalTo(t.pe)||n.push(e.pe);else{let s=Vs(o,i);s.length>0&&Js(s[0],t)&&Js(s[0],e)&&n.push(s[0])}return n}function Js(t,e){const n=e.box;return Fs.Utils.LE(t.x,n.xmax)&&Fs.Utils.GE(t.x,n.xmin)&&Fs.Utils.LE(t.y,n.ymax)&&Fs.Utils.GE(t.y,n.ymin)}function Ks(t,e){let n=[];if(t.isZeroLength()){let[o,i]=t.ps.distanceTo(e.pc);return Fs.Utils.EQ(o,e.r)&&n.push(t.ps),n}let o=Hs(new Fs.Line(t.ps,t.pe),e);for(let e of o)e.on(t)&&n.push(e);return n}function Qs(t,e){let n=[];if(t.isZeroLength())return t.ps.on(e)&&n.push(t.ps),n;let o=Hs(new Fs.Line(t.ps,t.pe),new Fs.Circle(e.pc,e.r));for(let i of o)i.on(t)&&i.on(e)&&n.push(i);return n}function tr(t,e){let n=[],o=new Fs.Vector(t.pc,e.pc),i=t.r,s=e.r;if(Fs.Utils.EQ_0(i)||Fs.Utils.EQ_0(s))return n;if(Fs.Utils.EQ_0(o.x)&&Fs.Utils.EQ_0(o.y)&&Fs.Utils.EQ(i,s))return n.push(t.pc.translate(-i,0)),n;let r,a=t.pc.distanceTo(e.pc)[0];if(Fs.Utils.GT(a,i+s))return n;if(Fs.Utils.LT(a,Math.abs(i-s)))return n;if(o.x/=a,o.y/=a,Fs.Utils.EQ(a,i+s)||Fs.Utils.EQ(a,Math.abs(i-s)))return r=t.pc.translate(i*o.x,i*o.y),n.push(r),n;let c=i*i/(2*a)-s*s/(2*a)+a/2,h=t.pc.translate(c*o.x,c*o.y),l=Math.sqrt(i*i-c*c);return r=h.translate(o.rotate90CCW().multiply(l)),n.push(r),r=h.translate(o.rotate90CW().multiply(l)),n.push(r),n}function er(t,e){let n=[];if(t.pc.equalTo(e.pc)&&Fs.Utils.EQ(t.r,e.r)){let o;return o=t.start,o.on(e)&&n.push(o),o=t.end,o.on(e)&&n.push(o),o=e.start,o.on(t)&&n.push(o),o=e.end,o.on(t)&&n.push(o),n}let o=new Fs.Circle(t.pc,t.r),i=new Fs.Circle(e.pc,e.r),s=o.intersect(i);for(let o of s)o.on(t)&&o.on(e)&&n.push(o);return n}function nr(t,e){let n=[];if(e.pc.equalTo(t.pc)&&Fs.Utils.EQ(e.r,t.r))return n.push(t.start),n.push(t.end),n;let o=tr(e,new Fs.Circle(t.pc,t.r));for(let e of o)e.on(t)&&n.push(e);return n}function or(t,e){return t.isSegment?qs(t.shape,e):Qs(e,t.shape)}function ir(t,e){return t.isSegment?Qs(t.shape,e):er(t.shape,e)}function sr(t,e){return t.isSegment?Zs(t.shape,e):Gs(e,t.shape)}function rr(t,e){return t.isSegment?Ks(t.shape,e):nr(t.shape,e)}function ar(t,e){let n=[];for(let o of e.edges)for(let e of or(o,t))n.push(e);return n}function cr(t,e){let n=[];for(let o of e.edges)for(let e of ir(o,t))n.push(e);return n}function hr(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of sr(o,t))pr(e,n)||n.push(e);return t.sortPoints(n)}function lr(t,e){let n=[];if(e.isEmpty())return n;for(let o of e.edges)for(let e of rr(o,t))n.push(e);return n}function dr(t,e){return t.isSegment?or(e,t.shape):t.isArc?ir(e,t.shape):t.isLine?sr(e,t.shape):t.isRay?(n=e,o=t.shape,n.isSegment?gr(o,n.shape):mr(o,n.shape)):[];var n,o}function ur(t,e){let n=[];if(e.isEmpty()||t.shape.box.not_intersect(e.box))return n;let o=e.edges.search(t.shape.box);for(let e of o)n=[...n,...dr(t,e)];return n}function pr(t,e){return e.some(e=>e.equalTo(t))}function fr(t){return new Fs.Line(t.start,t.norm)}function gr(t,e){return Zs(e,fr(t)).filter(e=>t.contains(e))}function mr(t,e){return Gs(fr(t),e).filter(e=>t.contains(e))}function yr(t,e){return Hs(fr(t),e).filter(e=>t.contains(e))}function xr(t,e){return Vs(fr(t),e).filter(e=>t.contains(e))}function vr(t,e){return hr(fr(t),e).filter(e=>t.contains(e))}function br(t,e){if(t.intersect&&t.intersect instanceof Function)return t.intersect(e);throw ks.UNSUPPORTED_SHAPE_TYPE}function Pr(t,e){let n=[];for(let o of e)n=[...n,...br(t,o.shape)];return n}var Sr=class t extends $s{constructor(...t){if(super(),this.isInfinite=!1,1===t.length&&t[0]instanceof Array&&t[0].length>0){const e=t[0],n=e.length,o=t=>t instanceof Fs.Segment||t instanceof Fs.Arc||t instanceof Fs.Ray,i=t=>t instanceof Fs.Segment||t instanceof Fs.Arc;if(!(1===n&&(t=>t instanceof Fs.Segment||t instanceof Fs.Arc||t instanceof Fs.Ray||t instanceof Fs.Line)(e[0])||n>1&&o(e[0])&&o(e[n-1])&&e.slice(1,n-1).every(i)))throw Fs.Errors.ILLEGAL_PARAMETERS;this.isInfinite=e.some(t=>t instanceof Fs.Ray||t instanceof Fs.Line);for(let t of e){let e=new Fs.Edge(t);this.append(e)}this.setArcLength()}}get edges(){return[...this]}get box(){return this.edges.reduce((t,e)=>t.merge(e.box),new Fs.Box)}get vertices(){let t=this.edges.map(t=>t.start);return t.push(this.last.end),t}get length(){if(this.isEmpty())return 0;if(this.isInfinite)return Number.POSITIVE_INFINITY;let t=0;for(let e of this)t+=e.length;return t}clone(){return new t(this.toShapes())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t)}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}pointAtLength(t){if(t>this.length||t<0)return null;if(this.isInfinite)return null;let e=null;for(let n of this)if(t>=n.arc_length&&(n===this.last||t<n.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}addVertex(t,e){let n=e.shape.split(t);if(null===n[0])return e.prev;if(null===n[1])return e;let o=new Fs.Edge(n[0]),i=e.prev;return this.insert(o,i),e.shape=n[1],o}getChain(t,e){let n=[];for(let o=t;o!==e.next;o=o.next)n.push(o);return n}split(t){for(let e of t){let t=this.findEdgeByPoint(e);this.addVertex(e,t)}return this}findEdgeByPoint(t){let e;for(let n of this)if(n.shape.contains(t)){e=n;break}return e}distanceTo(t){if(t instanceof Point){const[e,n]=Fs.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof Fs.Line){const[e,n]=Fs.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof Fs.Circle){const[e,n]=Fs.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof Fs.Segment){const[e,n]=Fs.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof Fs.Arc){const[e,n]=Fs.Distance.shape2multiline(t,this);return[e,n.reverse()]}if(t instanceof Fs.Multiline)return Fs.Distance.multiline2multiline(this,t);throw Fs.Errors.UNSUPPORTED_SHAPE_TYPE}intersect(t){return t instanceof Fs.Multiline?function(t,e){let n=[];for(let o of t)for(let t of e)n=[...n,...br(o.shape,t.shape)];return n}(this,t):Pr(t,this)}contains(t){if(t instanceof Fs.Point)return this.edges.some(e=>e.shape.contains(t));throw Fs.Errors.UNSUPPORTED_SHAPE_TYPE}translate(e){return new t(this.edges.map(t=>t.shape.translate(e)))}rotate(e=0,n=new Fs.Point){return new t(this.edges.map(t=>t.shape.rotate(e,n)))}transform(e=new Fs.Matrix){return new t(this.edges.map(t=>t.shape.transform(e)))}toShapes(){return this.edges.map(t=>t.shape.clone())}toJSON(){return this.edges.map(t=>t.toJSON())}svgPoints(){return this.vertices.map(t=>`${t.x},${t.y}`).join(" ")}dpath(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let e of this)t+=e.svg();return t}svg(t={}){let e=`\n<path ${Ws({fill:"none",...t})} d="`;e+=`\nM${this.first.start.x},${this.first.start.y}`;for(let t of this)e+=t.svg();return e+='" >\n</path>',e}};Fs.Multiline=Sr;function Ir(t,e,n){let o=n.length,i=t.shape.split(e);if(0===i.length)return;let s=0;s=null===i[0]?0:null===i[1]?t.shape.length:i[0].length;let r,a=0;Ls(s,0)&&(a|=1),Ls(s,t.shape.length)&&(a|=2),r=s===1/0?i[0].coord(e):2&a&&t.next&&0===t.next.arc_length?0:t.arc_length+s,n.push({id:o,pt:e,arc_length:r,edge_before:t,edge_after:void 0,face:t.face,is_vertex:a})}function Mr(t){t.int_points1_sorted=_r(t.int_points1),t.int_points2_sorted=_r(t.int_points2)}function _r(t){let e=new Map,n=0;for(let o of t)e.has(o.face)||(e.set(o.face,n),n++);for(let n of t)n.faceId=e.get(n.face);return t.slice().sort(Nr)}function Nr(t,e){return t.faceId<e.faceId?-1:t.faceId>e.faceId?1:t.arc_length<e.arc_length?-1:t.arc_length>e.arc_length?1:0}function Cr(t){if(t.int_points1.length<2)return;let e,n,o,i,s=!1;for(let r=0;r<t.int_points1_sorted.length;r++)if(-1!==t.int_points1_sorted[r].id){e=t.int_points1_sorted[r],n=t.int_points2[e.id];for(let a=r+1;a<t.int_points1_sorted.length&&(o=t.int_points1_sorted[a],Ls(o.arc_length,e.arc_length));a++)-1!==o.id&&(i=t.int_points2[o.id],-1!==i.id&&o.edge_before===e.edge_before&&o.edge_after===e.edge_after&&i.edge_before===n.edge_before&&i.edge_after===n.edge_after&&(o.id=-1,i.id=-1,s=!0))}n=t.int_points2_sorted[0],e=t.int_points1[n.id];for(let o=1;o<t.int_points2_sorted.length;o++){let i=t.int_points2_sorted[o];if(-1===i.id)continue;if(-1===n.id||!Ls(i.arc_length,n.arc_length)){n=i,e=t.int_points1[n.id];continue}let r=t.int_points1[i.id];r.edge_before===e.edge_before&&r.edge_after===e.edge_after&&i.edge_before===n.edge_before&&i.edge_after===n.edge_after&&(r.id=-1,i.id=-1,s=!0)}s&&(t.int_points1=t.int_points1.filter(t=>t.id>=0),t.int_points2=t.int_points2.filter(t=>t.id>=0),t.int_points1.forEach((t,e)=>t.id=e),t.int_points2.forEach((t,e)=>t.id=e))}function Tr(t){for(let e of t)e.edge_before&&(e.edge_before.bvStart=void 0,e.edge_before.bvEnd=void 0,e.edge_before.bv=void 0,e.edge_before.overlap=void 0),e.edge_after&&(e.edge_after.bvStart=void 0,e.edge_after.bvEnd=void 0,e.edge_after.bv=void 0,e.edge_after.overlap=void 0);for(let e of t)e.edge_before&&(e.edge_before.bvEnd=2),e.edge_after&&(e.edge_after.bvStart=2)}function Er(t,e){for(let n of t)n.edge_before&&n.edge_before.setInclusion(e),n.edge_after&&n.edge_after.setInclusion(e)}function wr(t,e,n){let o,i,s=1;if(1===t.length)return 1;o=t[e];for(let r=e+1;r<t.length&&o.face===n&&(i=t[r],i.pt.equalTo(o.pt)&&i.edge_before===o.edge_before&&i.edge_after===o.edge_after);r++)s++;return s}function Rr(t,e){if(e){for(let n of e){let e=n.edge_before;if(n.is_vertex=0,e.shape.start&&e.shape.start.equalTo(n.pt)&&(n.is_vertex|=1),e.shape.end&&e.shape.end.equalTo(n.pt)&&(n.is_vertex|=2),1&n.is_vertex){n.edge_before=e.prev,e.prev&&(n.is_vertex=2);continue}if(2&n.is_vertex)continue;let o=t.addVertex(n.pt,e);n.edge_before=o}for(let n of e)n.edge_before?n.edge_after=n.edge_before.next:t instanceof Sr&&1&n.is_vertex&&(n.edge_after=t.first)}}function Or(t,e,n){const o=t.edge_before,i=e.edge_after,s=n.length;o.next=n[0],n[0].prev=o,n[s-1].next=i,i.prev=n[s-1]}Fs.multiline=(...t)=>new Fs.Multiline(...t);var{INSIDE:Ar,OUTSIDE:zr,BOUNDARY:Dr,OVERLAP_SAME:Lr,OVERLAP_OPPOSITE:Yr}=Rs,{NOT_VERTEX:Xr,START_VERTEX:Fr,END_VERTEX:kr}=Rs;function $r(t,e){let n=e.clone().reverse(),[o,i]=Ur(t,n,3,!0);return o}function Br(t,e){let[n,o]=Ur(t,e,2,!0);return n}function jr(t,e){let[n,o]=Ur(t,e,2,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=>t.shape)];let s=[];for(let t of o.faces)s=[...s,...[...t.edges].map(t=>t.shape)];return[i,s]}function Wr(t,e){let[n,o]=Ur(t,e,3,!1),i=[];for(let t of n.faces)i=[...i,...[...t.edges].map(t=>t.shape)];return i}function Vr(t,e){let n=t.clone(),o=e.clone(),i=Gr(n,o);return Mr(i),Rr(n,i.int_points1_sorted),Rr(o,i.int_points2_sorted),Cr(i),Mr(i),[i.int_points1_sorted.map(t=>t.pt),i.int_points2_sorted.map(t=>t.pt)]}function Hr(t,e,n,o){let i=Zr(t,n.int_points1),s=Zr(e,n.int_points2);for(qr(i,e),qr(s,t),Tr(n.int_points1),Tr(n.int_points2),Er(n.int_points1,e),Er(n.int_points2,t);Jr(t,e,n.int_points1,n.int_points1_sorted,n.int_points2,n););!function(t){let e,n,o,i=t.int_points1.length;for(let s=0;s<i;s++){let r=t.int_points1_sorted[s];r.face!==e&&(n=s,e=r.face);let a,c=s,h=wr(t.int_points1_sorted,s,e);a=c+h<i&&t.int_points1_sorted[c+h].face===e?c+h:n;let l=wr(t.int_points1_sorted,a,e);o=null;for(let n=a;n<a+l;n++){let i=t.int_points1_sorted[n];if(i.face===e&&t.int_points2[i.id].face===t.int_points2[r.id].face){o=i;break}}if(null===o)continue;let d=r.edge_after,u=o.edge_before;if(2!==d.bv||2!==u.bv)continue;if(d!==u)continue;let p=t.int_points2[r.id],f=t.int_points2[o.id],g=p.edge_after,m=f.edge_before;2===g.bv&&2===m.bv&&g===m||(p=t.int_points2[o.id],f=t.int_points2[r.id],g=p.edge_after,m=f.edge_before),2===g.bv&&2===m.bv&&g===m&&d.setOverlap(g)}}(n),Kr(t,o,n.int_points1_sorted,!0),Kr(e,o,n.int_points2_sorted,!1),ea(t,i,o,!0),ea(e,s,o,!1)}function Ur(t,e,n,o){let i=t.clone(),s=e.clone(),r=Gr(i,s);return Mr(r),Rr(i,r.int_points1_sorted),Rr(s,r.int_points2_sorted),Cr(r),Mr(r),Hr(i,s,r,n),o&&function(t,e,n){!function(t,e,n,o){for(let n of e.faces){for(let e of n)t.edges.add(e);void 0===o.find(t=>t.face===n)&&t.addFace(n.first,n.last)}}(t,e,0,n.int_points2),function(t,e,n){if(0!==n.int_points1.length)for(let t=0;t<n.int_points1.length;t++){let e=n.int_points1[t],o=n.int_points2[t];if(void 0!==e.edge_before&&void 0===e.edge_after&&void 0===o.edge_before&&void 0!==o.edge_after&&(e.edge_before.next=o.edge_after,o.edge_after.prev=e.edge_before,e.edge_after=o.edge_after,o.edge_before=e.edge_before),void 0!==o.edge_before&&void 0===o.edge_after&&void 0===e.edge_before&&void 0!==e.edge_after&&(o.edge_before.next=e.edge_after,e.edge_after.prev=o.edge_before,o.edge_after=e.edge_after,e.edge_before=o.edge_before),void 0!==e.edge_before&&void 0===e.edge_after)for(let t of n.int_points1_sorted)t!==e&&void 0===t.edge_before&&void 0!==t.edge_after&&t.pt.equalTo(e.pt)&&(e.edge_before.next=t.edge_after,t.edge_after.prev=e.edge_before,e.edge_after=t.edge_after,t.edge_before=e.edge_before);if(void 0!==o.edge_before&&void 0===o.edge_after)for(let t of n.int_points2_sorted)t!==o&&void 0===t.edge_before&&void 0!==t.edge_after&&t.pt.equalTo(o.pt)&&(o.edge_before.next=t.edge_after,t.edge_after.prev=o.edge_before,o.edge_after=t.edge_after,t.edge_before=o.edge_before)}}(0,0,n),Qr(t,n.int_points1),Qr(e,n.int_points2),ta(t,n.int_points1,n.int_points2),ta(t,n.int_points2,n.int_points1)}(i,s,r),[i,s]}function Gr(t,e){let n={int_points1:[],int_points2:[]};for(let o of t.edges){let t=e.edges.search(o.box);for(let e of t){let t=o.shape.intersect(e.shape);for(let i of t)Ir(o,i,n.int_points1),Ir(e,i,n.int_points2)}}return n}function Zr(t,e){let n=[];for(let o of t.faces)e.find(t=>t.face===o)||n.push(o);return n}function qr(t,e){for(let n of t)n.first.bv=n.first.bvStart=n.first.bvEnd=void 0,n.first.setInclusion(e)}function Jr(t,e,n,o,i,s){let r,a,c,h=o.length,l=!1;for(let d=0;d<h;d++){let u=o[d];u.face!==r&&(a=d,r=u.face);let p,f=d,g=wr(o,d,r);p=f+g<h&&o[f+g].face===r?f+g:a;let m=wr(o,p,r);c=null;for(let t=p;t<p+m;t++){let e=o[t];if(e.face===r&&i[e.id].face===i[u.id].face){c=e;break}}if(null===c)continue;let y=u.edge_after,x=c.edge_before;if(y.bv!==Dr||x.bv==Dr)if(y.bv==Dr||x.bv!==Dr){if(y.bv===Dr&&x.bv===Dr&&y!=x||y.bv===Ar&&x.bv===zr||y.bv===zr&&x.bv===Ar){let t=y.next;for(;t!=x;)t.bvStart=void 0,t.bvEnd=void 0,t.bv=void 0,t.setInclusion(e),t=t.next}if(y.bv===Dr&&x.bv===Dr&&y!=x){let t,e=y.next;for(;e!=x;){if(e.bv!=Dr)if(void 0===t)t=e.bv;else if(e.bv!=t)throw ks.UNRESOLVED_BOUNDARY_CONFLICT;e=e.next}null!=t&&(y.bv=t,x.bv=t);continue}if(y.bv===Ar&&x.bv===zr||y.bv===zr&&x.bv===Ar){let o=y;for(;o!=x;){if(o.bvStart===y.bv&&o.bvEnd===x.bv){let[r,a]=o.shape.distanceTo(e);if(r<10*Fs.DP_TOL){Ir(o,a.ps,n);let r=n[n.length-1];if(r.is_vertex&Fr)r.edge_after=o,r.edge_before=o.prev,o.bvStart=Dr,o.bv=void 0,o.setInclusion(e);else if(r.is_vertex&kr)r.edge_after=o.next,o.bvEnd=Dr,o.bv=void 0,o.setInclusion(e);else{let t=e.addVertex(r.pt,o);r.edge_before=t,r.edge_after=t.next,t.setInclusion(e),t.next.bvStart=Dr,t.next.bvEnd=void 0,t.next.bv=void 0,t.next.setInclusion(e)}let c=e.findEdgeByPoint(a.pe);Ir(c,a.pe,i);let h=i[i.length-1];if(h.is_vertex&Fr)h.edge_after=c,h.edge_before=c.prev;else if(h.is_vertex&kr)h.edge_after=c.next;else{let n=i.find(t=>t.edge_after===c),o=e.addVertex(h.pt,c);h.edge_before=o,h.edge_after=o.next,n&&(n.edge_after=o),o.bvStart=void 0,o.bvEnd=Dr,o.bv=void 0,o.setInclusion(t),o.next.bvStart=Dr,o.next.bvEnd=void 0,o.next.bv=void 0,o.next.setInclusion(t)}Mr(s),l=!0;break}}o=o.next}if(l)break;throw ks.UNRESOLVED_BOUNDARY_CONFLICT}}else x.bv=y.bv;else y.bv=x.bv}return l}function Kr(t,e,n,o){if(!n)return;let i,s,r,a;for(let c=0;c<n.length;c++){if(r=n[c],r.face!==i&&(s=c,i=r.face),i.isEmpty())continue;let h,l=c,d=wr(n,c,i);h=l+d<n.length&&n[l+d].face===r.face?l+d:s,a=n[h];let u=h,p=wr(n,u,i),f=r.edge_after,g=a.edge_before;if(f.bv===Ar&&g.bv===Ar&&1===e||f.bv===zr&&g.bv===zr&&2===e||(f.bv===zr||g.bv===zr)&&3===e&&!o||(f.bv===Ar||g.bv===Ar)&&3===e&&o||f.bv===Dr&&g.bv===Dr&&f.overlap&Lr&&o||f.bv===Dr&&g.bv===Dr&&f.overlap&Yr){t.removeChain(i,f,g);for(let t=l;t<l+d;t++)n[t].edge_after=void 0;for(let t=u;t<u+p;t++)n[t].edge_before=void 0}c+=d-1}}function Qr(t,e){for(let n of e)t.faces.delete(n.face),n.face=void 0,n.edge_before&&(n.edge_before.face=void 0),n.edge_after&&(n.edge_after.face=void 0)}function ta(t,e,n){for(let o of e){if(void 0===o.edge_before||void 0===o.edge_after)continue;if(o.face)continue;if(o.edge_after.face||o.edge_before.face)continue;let i=o.edge_after,s=o.edge_before;try{$s.testInfiniteLoop(i)}catch(t){throw ks.CANNOT_COMPLETE_BOOLEAN_OPERATION}let r=t.addFace(i,s);for(let t of e)t.edge_before&&t.edge_after&&t.edge_before.face===r&&t.edge_after.face===r&&(t.face=r);for(let t of n)t.edge_before&&t.edge_after&&t.edge_before.face===r&&t.edge_after.face===r&&(t.face=r)}}function ea(t,e,n,o){for(let i of e){let e=i.first.bv;(1===n&&e===Ar||3===n&&e===Ar&&o||3===n&&e===zr&&!o||2===n&&e===zr)&&t.deleteFace(i)}}var na=Object.freeze({__proto__:null,BOOLEAN_INTERSECT:2,BOOLEAN_SUBTRACT:3,BOOLEAN_UNION:1,calculateIntersections:Vr,innerClip:jr,intersect:Br,outerClip:Wr,removeNotRelevantChains:Kr,removeOldFaces:Qr,restoreFaces:ta,subtract:$r,unify:function(t,e){let[n,o]=Ur(t,e,1,!0);return n}}),oa=RegExp("T.F..FFF.|T.F...F.."),ia=RegExp("T........|.T.......|...T.....|....T...."),sa=RegExp("FT.......|F..T.....|F...T...."),ra=RegExp("T.F..F..."),aa=RegExp("T.F..F...|.TF..F...|..FT.F...|..F.TF..."),ca=class{constructor(){this.m=new Array(9).fill(void 0)}get I2I(){return this.m[0]}set I2I(t){this.m[0]=t}get I2B(){return this.m[1]}set I2B(t){this.m[1]=t}get I2E(){return this.m[2]}set I2E(t){this.m[2]=t}get B2I(){return this.m[3]}set B2I(t){this.m[3]=t}get B2B(){return this.m[4]}set B2B(t){this.m[4]=t}get B2E(){return this.m[5]}set B2E(t){this.m[5]=t}get E2I(){return this.m[6]}set E2I(t){this.m[6]=t}get E2B(){return this.m[7]}set E2B(t){this.m[7]=t}get E2E(){return this.m[8]}set E2E(t){this.m[8]=t}toString(){return this.m.map(t=>t instanceof Array&&t.length>0?"T":t instanceof Array&&0===t.length?"F":"*").join("")}equal(){return oa.test(this.toString())}intersect(){return ia.test(this.toString())}touch(){return sa.test(this.toString())}inside(){return ra.test(this.toString())}covered(){return aa.test(this.toString())}};function ha(t,e){let n,o=new Fs.Ray(e),i=new Fs.Line(o.pt,o.norm);const s=new Fs.Box(o.box.xmin-Fs.DP_TOL,o.box.ymin-Fs.DP_TOL,o.box.xmax+Fs.DP_TOL,o.box.ymax+Fs.DP_TOL);if(t.box.not_intersect(s))return Fs.OUTSIDE;let r=t.edges.search(s);if(0===r.length)return Fs.OUTSIDE;for(let t of r)if(t.shape.contains(e))return Fs.BOUNDARY;let a=[...t.faces],c=[];for(let t of r)for(let n of o.intersect(t.shape)){if(n.equalTo(e))return Fs.BOUNDARY;c.push({pt:n,edge:t,face_index:a.indexOf(t.face)})}c.sort((t,e)=>Xs(t.pt.x,e.pt.x)?-1:Ys(t.pt.x,e.pt.x)?1:t.face_index<e.face_index?-1:t.face_index>e.face_index?1:t.edge.arc_length<e.edge.arc_length?-1:t.edge.arc_length>e.edge.arc_length?1:0);let h=0;for(let t=0;t<c.length;t++){let e=c[t];if(e.pt.equalTo(e.edge.shape.start)){if(t>0&&e.pt.equalTo(c[t-1].pt)&&e.face_index===c[t-1].face_index&&e.edge.prev===c[t-1].edge)continue;let n=e.edge.prev;for(;Ds(n.length);)n=n.prev;let o=n.shape.tangentInEnd(),s=e.pt.translate(o),r=e.edge.shape.tangentInStart(),a=e.pt.translate(r),l=s.leftTo(i),d=a.leftTo(i);(l&&!d||!l&&d)&&h++}else if(e.pt.equalTo(e.edge.shape.end)){if(t>0&&e.pt.equalTo(c[t-1].pt)&&e.face_index===c[t-1].face_index&&e.edge.next===c[t-1].edge)continue;let n=e.edge.next;for(;Ds(n.length);)n=n.next;let o=n.shape.tangentInStart(),s=e.pt.translate(o),r=e.edge.shape.tangentInEnd(),a=e.pt.translate(r),l=s.leftTo(i),d=a.leftTo(i);(l&&!d||!l&&d)&&h++}else if(e.edge.shape instanceof Fs.Segment)h++;else{let t=e.edge.shape.box;Ls(e.pt.y,t.ymin)||Ls(e.pt.y,t.ymax)||h++}}return n=h%2==1?1:0,n}function la(t,e){return fa(t,e).intersect()}function da(t,e){return fa(t,e).inside()}function ua(t,e){return fa(t,e).covered()}function pa(t,e){return ua(e,t)}function fa(t,e){return t instanceof Fs.Line&&e instanceof Fs.Line?function(t,e){let n=new ca,o=Vs(t,e);0===o.length?t.contains(e.pt)&&e.contains(t.pt)?(n.I2I=[t],n.I2E=[],n.E2I=[]):(n.I2I=[],n.I2E=[t],n.E2I=[e]):(n.I2I=o,n.I2E=t.split(o),n.E2I=e.split(o));return n}(t,e):t instanceof Fs.Line&&e instanceof Fs.Circle?function(t,e){let n=new ca,o=Hs(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new Sr([t]),s=t.sortPoints(o);i.split(s);let r=i.toShapes();n.I2I=[r[1]],n.I2B=s,n.I2E=[r[0],r[2]],n.E2I=new Fs.Polygon([e.toArc()]).cutWithLine(t)}return n}(t,e):t instanceof Fs.Line&&e instanceof Fs.Box?function(t,e){let n=new ca,o=Us(t,e);if(0===o.length)n.I2I=[],n.I2B=[],n.I2E=[t],n.E2I=[e];else if(1===o.length)n.I2I=[],n.I2B=o,n.I2E=t.split(o),n.E2I=[e];else{let i=new Sr([t]),s=t.sortPoints(o);i.split(s);let r=i.toShapes();e.toSegments().some(t=>t.contains(o[0])&&t.contains(o[1]))?(n.I2I=[],n.I2B=[r[1]],n.I2E=[r[0],r[2]],n.E2I=[e]):(n.I2I=[r[1]],n.I2B=s,n.I2E=[r[0],r[2]],n.E2I=new Fs.Polygon(e.toSegments()).cutWithLine(t))}return n}(t,e):t instanceof Fs.Line&&e instanceof Fs.Polygon?function(t,e){let n=new ca,o=hr(t,e),i=new Sr([t]),s=o.length>0?o.slice():t.sortPoints(o);return i.split(s),[...i].forEach(t=>t.setInclusion(e)),n.I2I=[...i].filter(t=>t.bv===Fs.INSIDE).map(t=>t.shape),n.I2B=[...i].slice(1).map(t=>t.bv===Fs.BOUNDARY?t.shape:t.shape.start),n.I2E=[...i].filter(t=>t.bv===Fs.OUTSIDE).map(t=>t.shape),n.E2I=e.cutWithLine(t),n}(t,e):(t instanceof Fs.Segment||t instanceof Fs.Arc)&&e instanceof Fs.Polygon?ga(t,e):(t instanceof Fs.Segment||t instanceof Fs.Arc)&&(e instanceof Fs.Circle||e instanceof Fs.Box)?ga(t,new Fs.Polygon(e)):t instanceof Fs.Polygon&&e instanceof Fs.Polygon?ma(t,e):(t instanceof Fs.Circle||t instanceof Fs.Box)&&(e instanceof Fs.Circle||e instanceof Fs.Box)?ma(new Fs.Polygon(t),new Fs.Polygon(e)):(t instanceof Fs.Circle||t instanceof Fs.Box)&&e instanceof Fs.Polygon?ma(new Fs.Polygon(t),e):t instanceof Fs.Polygon&&(e instanceof Fs.Circle||e instanceof Fs.Box)?ma(t,new Fs.Polygon(e)):void 0}function ga(t,e){let n=new ca,o=function(t,e){return t instanceof Fs.Line?hr(t,e):t instanceof Fs.Segment?ar(t,e):t instanceof Fs.Arc?cr(t,e):[]}(t,e),i=o.length>0?o.slice():t.sortPoints(o),s=new Sr([t]);s.split(i),[...s].forEach(t=>t.setInclusion(e)),n.I2I=[...s].filter(t=>t.bv===Fs.INSIDE).map(t=>t.shape),n.I2B=[...s].slice(1).map(t=>t.bv===Fs.BOUNDARY?t.shape:t.shape.start),n.I2E=[...s].filter(t=>t.bv===Fs.OUTSIDE).map(t=>t.shape),n.B2I=[],n.B2B=[],n.B2E=[];for(let o of[t.start,t.end])switch(ha(e,o)){case Fs.INSIDE:n.B2I.push(o);break;case Fs.BOUNDARY:n.B2B.push(o);break;case Fs.OUTSIDE:n.B2E.push(o)}return n}function ma(t,e){let n=new ca,[o,i]=Vr(t,e),s=Br(t,e),r=$r(t,e),a=$r(e,t),[c,h]=jr(t,e),l=Wr(t,e),d=Wr(e,t);return n.I2I=s.isEmpty()?[]:[s],n.I2B=h,n.I2E=r.isEmpty()?[]:[r],n.B2I=c,n.B2B=o,n.B2E=l,n.E2I=a.isEmpty()?[]:[a],n.E2B=d,n}var ya=Object.freeze({__proto__:null,contain:function(t,e){return da(e,t)},cover:pa,covered:ua,disjoint:function(t,e){return!la(t,e)},equal:function(t,e){return fa(t,e).equal()},inside:da,intersect:la,relate:fa,touch:function(t,e){return fa(t,e).touch()}}),xa=class t{constructor(t=1,e=0,n=0,o=1,i=0,s=0){this.a=t,this.b=e,this.c=n,this.d=o,this.tx=i,this.ty=s}fromMatrix3x3(e){const[n,o,i]=e[0],[s,r,a]=e[1];return new t(n,s,o,r,i,a)}toMatrix3x3(){return[[this.a,this.c,this.tx],[this.b,this.d,this.ty],[0,0,1]]}clone(){return new t(this.a,this.b,this.c,this.d,this.tx,this.ty)}transform(t){return[t[0]*this.a+t[1]*this.c+this.tx,t[0]*this.b+t[1]*this.d+this.ty]}multiply(e){return new t(this.a*e.a+this.c*e.b,this.b*e.a+this.d*e.b,this.a*e.c+this.c*e.d,this.b*e.c+this.d*e.d,this.a*e.tx+this.c*e.ty+this.tx,this.b*e.tx+this.d*e.ty+this.ty)}translate(...e){let n,o;if(1!=e.length||isNaN(e[0].x)||isNaN(e[0].y)){if(2!==e.length||"number"!=typeof e[0]||"number"!=typeof e[1])throw ks.ILLEGAL_PARAMETERS;n=e[0],o=e[1]}else n=e[0].x,o=e[0].y;return this.multiply(new t(1,0,0,1,n,o))}rotate(e,n=0,o=0){let i=Math.cos(e),s=Math.sin(e);return this.translate(n,o).multiply(new t(i,s,-s,i,0,0)).translate(-n,-o)}scale(e,n){return this.multiply(new t(e,0,0,n,0,0))}equalTo(t){return!!Fs.Utils.EQ(this.tx,t.tx)&&(!!Fs.Utils.EQ(this.ty,t.ty)&&(!!Fs.Utils.EQ(this.a,t.a)&&(!!Fs.Utils.EQ(this.b,t.b)&&(!!Fs.Utils.EQ(this.c,t.c)&&!!Fs.Utils.EQ(this.d,t.d)))))}};Fs.Matrix=xa;Fs.matrix=(...t)=>new Fs.Matrix(...t);var va=class{constructor(t,e){this.low=t,this.high=e}get max(){return this.clone()}less_than(t){return this.low<t.low||this.low===t.low&&this.high<t.high}equal_to(t){return this.low===t.low&&this.high===t.high}intersect(t){return!this.not_intersect(t)}not_intersect(t){return this.high<t.low||t.high<this.low}merge(t){const e=void 0===this.low?t.low:this.low<t.low?this.low:t.low,n=void 0===this.high?t.high:this.high>t.high?this.high:t.high,o=this.clone();return o.low=e,o.high=n,o}output(){return[this.low,this.high]}comparable_less_than(t,e){return t<e}},ba=class t extends va{clone(){return new t(this.low,this.high)}},Pa=class{constructor(t,e,n=null,o=null,i=null,s=0){if(this.left=n,this.right=o,this.parent=i,this.color=s,this.item={key:void 0,values:[]},void 0!==e&&this.item.values.push(e),void 0!==t)if(Array.isArray(t)){const[e,n]=t;if(!Number.isNaN(e)&&!Number.isNaN(n)){let t=e,o=n;t>o&&([t,o]=[o,t]),this.item.key=new ba(t,o)}}else this.item.key=t;this.max=this.item.key?this.item.key.max:void 0}isNil(){return void 0===this.item.key&&0===this.item.values.length&&null===this.left&&null===this.right&&0===this.color}requireKey(){if(!this.item.key)throw new Error("Node key is undefined (nil/sentinel). Operation is not applicable.");return this.item.key}less_than(t){const e=this.requireKey(),n=t.requireKey();return e.less_than(n)}_value_equal(t){const e=this.item.values[0],n=t.item.values[0];return e&&n&&e.equal_to?e.equal_to(n):e===n}equal_to(t){const e=this.requireKey(),n=t.requireKey();return e.equal_to(n)}intersect(t){const e=this.requireKey(),n=t.requireKey();return e.intersect(n)}copy_data(t){this.item.key=t.item.key,this.item.values=t.item.values.slice()}update_max(){this.max=this.item.key?this.item.key.max:void 0,this.right&&this.right.max&&(this.max=this.max?this.max.merge(this.right.max):this.right.max),this.left&&this.left.max&&(this.max=this.max?this.max.merge(this.left.max):this.left.max)}not_intersect_left_subtree(t){if(!this.left)return!0;const e=this.left.max?this.left.max.high:this.left.item.key.high,n=this.requireKey(),o=t.requireKey();return n.comparable_less_than(e,o.low)}not_intersect_right_subtree(t){if(!this.right)return!0;const e=this.right.max?this.right.max.low:this.right.item.key.low,n=this.requireKey(),o=t.requireKey();return n.comparable_less_than(o.high,e)}},Sa=class t{constructor(){this.root=null,this.nil_node=new Pa}get size(){let t=0;return this.tree_walk(this.root,e=>t+=e.item.values.length),t}get keys(){const t=[];return this.tree_walk(this.root,e=>t.push(e.item.key.output())),t}get values(){const t=[];return this.tree_walk(this.root,e=>{for(const n of e.item.values)t.push(n)}),t}get items(){const t=[];return this.tree_walk(this.root,e=>{const n=e.item.key.output();for(const o of e.item.values)t.push({key:n,value:o})}),t}isEmpty(){return null==this.root||this.root===this.nil_node}clear(){this.root=null}insert(t,e=t){if(void 0===t)return;const n=this.tree_search(this.root,new Pa(t));if(n)return n.item.values.push(e),n;const o=new Pa(t,e,this.nil_node,this.nil_node,null,1);return this.tree_insert(o),this.recalc_max(o),o}exist(t,e=t){const n=this.tree_search(this.root,new Pa(t));return!!n&&(arguments.length<2||e===t||n.item.values.some(t=>t&&t.equal_to?t.equal_to(e):t===e))}remove(t,e=t){const n=this.tree_search(this.root,new Pa(t));if(!n)return;if(arguments.length<2)return this.tree_delete(n),n;const o=n.item.values.findIndex(t=>t&&t.equal_to?t.equal_to(e):t===e);return o>=0?(n.item.values.splice(o,1),0===n.item.values.length&&this.tree_delete(n),n):void 0}search(t,e=(t,e)=>t===e?e.output():t){const n=new Pa(t),o=[];this.tree_search_interval(this.root,n,o);const i=[];for(const t of o)for(const n of t.item.values)i.push(e(n,t.item.key));return i}intersect_any(t){const e=new Pa(t);return this.tree_find_any_interval(this.root,e)}forEach(t){this.tree_walk(this.root,e=>{for(const n of e.item.values)t(e.item.key,n)})}map(e){const n=new t;return this.tree_walk(this.root,t=>{for(const o of t.item.values)n.insert(t.item.key,e(o,t.item.key))}),n}*iterate(t,e=(t,e)=>t===e?e.output():t){let n=null;for(t?n=this.tree_search_nearest_forward(this.root,new Pa(t)):this.root&&(n=this.local_minimum(this.root));n;){for(const t of n.item.values)yield e(t,n.item.key);n=this.tree_successor(n)}}recalc_max(t){let e=t;for(;null!=e.parent;)e.parent.update_max(),e=e.parent}tree_insert(t){let e=this.root,n=null;if(null==this.root||this.root===this.nil_node)this.root=t;else{for(;e!==this.nil_node;)n=e,e=t.less_than(e)?e.left:e.right;t.parent=n,t.less_than(n)?n.left=t:n.right=t}this.insert_fixup(t)}insert_fixup(t){let e,n;for(e=t;e!==this.root&&1===e.parent.color;)e.parent===e.parent.parent.left?(n=e.parent.parent.right,1===n.color?(e.parent.color=0,n.color=0,e.parent.parent.color=1,e=e.parent.parent):(e===e.parent.right&&(e=e.parent,this.rotate_left(e)),e.parent.color=0,e.parent.parent.color=1,this.rotate_right(e.parent.parent))):(n=e.parent.parent.left,1===n.color?(e.parent.color=0,n.color=0,e.parent.parent.color=1,e=e.parent.parent):(e===e.parent.left&&(e=e.parent,this.rotate_right(e)),e.parent.color=0,e.parent.parent.color=1,this.rotate_left(e.parent.parent)));this.root.color=0}tree_delete(t){let e,n;e=t.left===this.nil_node||t.right===this.nil_node?t:this.tree_successor(t),n=e.left!==this.nil_node?e.left:e.right,n.parent=e.parent,e===this.root?this.root=n:(e===e.parent.left?e.parent.left=n:e.parent.right=n,e.parent.update_max()),this.recalc_max(n),e!==t&&(t.copy_data(e),t.update_max(),this.recalc_max(t)),0===e.color&&this.delete_fixup(n)}delete_fixup(t){let e,n=t;for(;n!==this.root&&null!=n.parent&&0===n.color;)n===n.parent.left?(e=n.parent.right,1===e.color&&(e.color=0,n.parent.color=1,this.rotate_left(n.parent),e=n.parent.right),0===e.left.color&&0===e.right.color?(e.color=1,n=n.parent):(0===e.right.color&&(e.color=1,e.left.color=0,this.rotate_right(e),e=n.parent.right),e.color=n.parent.color,n.parent.color=0,e.right.color=0,this.rotate_left(n.parent),n=this.root)):(e=n.parent.left,1===e.color&&(e.color=0,n.parent.color=1,this.rotate_right(n.parent),e=n.parent.left),0===e.left.color&&0===e.right.color?(e.color=1,n=n.parent):(0===e.left.color&&(e.color=1,e.right.color=0,this.rotate_left(e),e=n.parent.left),e.color=n.parent.color,n.parent.color=0,e.left.color=0,this.rotate_right(n.parent),n=this.root));n.color=0}tree_search(t,e){if(null!=t&&t!==this.nil_node)return e.equal_to(t)?t:e.less_than(t)?this.tree_search(t.left,e):this.tree_search(t.right,e)}tree_search_nearest_forward(t,e){let n=null,o=t;for(;o&&o!==this.nil_node;)o.less_than(e)?o.intersect(e)?(n=o,o=o.left):o=o.right:(n&&!o.less_than(n)||(n=o),o=o.left);return n||null}tree_search_interval(t,e,n){null!=t&&t!==this.nil_node&&(t.left===this.nil_node||t.not_intersect_left_subtree(e)||this.tree_search_interval(t.left,e,n),t.intersect(e)&&n.push(t),t.right===this.nil_node||t.not_intersect_right_subtree(e)||this.tree_search_interval(t.right,e,n))}tree_find_any_interval(t,e){let n=!1;return null!=t&&t!==this.nil_node&&(t.left===this.nil_node||t.not_intersect_left_subtree(e)||(n=this.tree_find_any_interval(t.left,e)),n||(n=t.intersect(e)),n||t.right===this.nil_node||t.not_intersect_right_subtree(e)||(n=this.tree_find_any_interval(t.right,e))),n}local_minimum(t){let e=t;for(;null!=e.left&&e.left!==this.nil_node;)e=e.left;return e}local_maximum(t){let e=t;for(;null!=e.right&&e.right!==this.nil_node;)e=e.right;return e}tree_successor(t){let e,n,o;if(t.right!==this.nil_node)e=this.local_minimum(t.right);else{for(n=t,o=t.parent;null!=o&&o.right===n;)n=o,o=o.parent;e=o}return e}rotate_left(t){const e=t.right;t.right=e.left,e.left!==this.nil_node&&(e.left.parent=t),e.parent=t.parent,t===this.root?this.root=e:t===t.parent.left?t.parent.left=e:t.parent.right=e,e.left=t,t.parent=e,null!==t&&t!==this.nil_node&&t.update_max(),null!=e&&e!==this.nil_node&&e.update_max()}rotate_right(t){const e=t.left;t.left=e.right,e.right!==this.nil_node&&(e.right.parent=t),e.parent=t.parent,t===this.root?this.root=e:t===t.parent.left?t.parent.left=e:t.parent.right=e,e.right=t,t.parent=e,null!==t&&t!==this.nil_node&&t.update_max(),null!=e&&e!==this.nil_node&&e.update_max()}tree_walk(t,e){null!=t&&t!==this.nil_node&&(this.tree_walk(t.left,e),e(t),this.tree_walk(t.right,e))}testRedBlackProperty(){let t=!0;return this.tree_walk(this.root,function(e){1===e.color&&(0===e.left.color&&0===e.right.color||(t=!1))}),t}testBlackHeightProperty(t){let e=0,n=0,o=0;if(0===t.color&&e++,n=t.left!==this.nil_node?this.testBlackHeightProperty(t.left):1,o=t.right!==this.nil_node?this.testBlackHeightProperty(t.right):1,n!==o)throw new Error("Red-black height property violated");return e+=n,e}},Ia=class extends Set{constructor(t){super(t),this.index=new Sa,this.forEach(t=>this.index.insert(t))}add(t){let e=this.size;const{key:n,value:o}=t,i=n||t.box,s=o||t;return super.add(s),this.size>e&&this.index.insert(i,s),this}delete(t){const{key:e,value:n}=t,o=e||t.box,i=n||t;let s=super.delete(i);return s&&this.index.remove(o,i),s}clear(){super.clear(),this.index=new Sa}search(t){return this.index.search(t)}hit(t){let e=new Fs.Box(t.x-1,t.y-1,t.x+1,t.y+1);return this.index.search(e).filter(e=>t.on(e))}svg(){return[...this].reduce((t,e)=>t+e.svg(),"")}};Fs.PlanarSet=Ia;var Ma=class{get name(){throw ks.CANNOT_INVOKE_ABSTRACT_METHOD}get box(){throw ks.CANNOT_INVOKE_ABSTRACT_METHOD}clone(){throw ks.CANNOT_INVOKE_ABSTRACT_METHOD}translate(...t){return this.transform((new xa).translate(...t))}rotate(t,e=new Fs.Point){return this.transform((new xa).rotate(t,e.x,e.y))}scale(t,e){return this.transform((new xa).scale(t,e))}transform(...t){throw ks.CANNOT_INVOKE_ABSTRACT_METHOD}toJSON(){return Object.assign({},this,{name:this.name})}svg(t={}){throw ks.CANNOT_INVOKE_ABSTRACT_METHOD}};Fs.Point=class t extends Ma{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length&&t[0]instanceof Array&&2===t[0].length){let e=t[0];if("number"==typeof e[0]&&"number"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length&&t[0]instanceof Object&&"point"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1])return this.x=t[0],void(this.y=t[1]);throw ks.ILLEGAL_PARAMETERS}}get box(){return new Fs.Box(this.x,this.y,this.x,this.y)}clone(){return new Fs.Point(this.x,this.y)}get vertices(){return[this.clone()]}equalTo(t){return Fs.Utils.EQ(this.x,t.x)&&Fs.Utils.EQ(this.y,t.y)}lessThan(t){return!!Fs.Utils.LT(this.y,t.y)||!(!Fs.Utils.EQ(this.y,t.y)||!Fs.Utils.LT(this.x,t.x))}transform(t){return new Fs.Point(t.transform([this.x,this.y]))}projectionOn(t){if(this.equalTo(t.pt))return this.clone();let e=new Fs.Vector(this,t.pt);if(Fs.Utils.EQ_0(e.cross(t.norm)))return t.pt.clone();let n=e.dot(t.norm),o=t.norm.multiply(n);return this.translate(o)}leftTo(t){let e=new Fs.Vector(t.pt,this);return Fs.Utils.GT(e.dot(t.norm),0)}distanceTo(e){if(e instanceof t){let t=e.x-this.x,n=e.y-this.y;return[Math.sqrt(t*t+n*n),new Fs.Segment(this,e)]}return e instanceof Fs.Line?Fs.Distance.point2line(this,e):e instanceof Fs.Circle?Fs.Distance.point2circle(this,e):e instanceof Fs.Segment?Fs.Distance.point2segment(this,e):e instanceof Fs.Arc?Fs.Distance.point2arc(this,e):e instanceof Fs.Polygon?Fs.Distance.point2polygon(this,e):e instanceof Fs.PlanarSet?Fs.Distance.shape2planarSet(this,e):e instanceof Fs.Multiline?Fs.Distance.shape2multiline(this,e):void 0}on(t){if(t instanceof Fs.Point)return this.equalTo(t);if(t.contains&&t.contains instanceof Function)return t.contains(this);throw Fs.Errors.UNSUPPORTED_SHAPE_TYPE}get name(){return"point"}svg(t={}){const e=t.r??3;return`\n<circle cx="${this.x}" cy="${this.y}" r="${e}"\n ${Ws({fill:"red",...t})} />`}};var _a=(...t)=>new Fs.Point(...t);Fs.point=_a;Fs.Vector=class extends Ma{constructor(...t){if(super(),this.x=0,this.y=0,0!==t.length){if(1===t.length&&t[0]instanceof Array&&2===t[0].length){let e=t[0];if("number"==typeof e[0]&&"number"==typeof e[1])return this.x=e[0],void(this.y=e[1])}if(1===t.length&&t[0]instanceof Object&&"vector"===t[0].name){let{x:e,y:n}=t[0];return this.x=e,void(this.y=n)}if(1===t.length&&t[0]instanceof Object&&"segment"===t[0].name){let{start:e,end:n}=t[0];return this.x=n.x-e.x,void(this.y=n.y-e.y)}if(2===t.length){let e=t[0],n=t[1];if("number"==typeof e&&"number"==typeof n)return this.x=e,void(this.y=n);if(e instanceof Fs.Point&&n instanceof Fs.Point)return this.x=n.x-e.x,void(this.y=n.y-e.y)}throw ks.ILLEGAL_PARAMETERS}}clone(){return new Fs.Vector(this.x,this.y)}get slope(){let t=Math.atan2(this.y,this.x);return t<0&&(t=2*Math.PI+t),t}get length(){return Math.sqrt(this.dot(this))}isZeroLength(){return Fs.Utils.EQ_0(this.length)}equalTo(t){return Fs.Utils.EQ(this.x,t.x)&&Fs.Utils.EQ(this.y,t.y)}multiply(t){return new Fs.Vector(t*this.x,t*this.y)}dot(t){return this.x*t.x+this.y*t.y}cross(t){return this.x*t.y-this.y*t.x}normalize(){if(this.isZeroLength())throw ks.ZERO_DIVISION;return new Fs.Vector(this.x/this.length,this.y/this.length)}rotate(t,e=new Fs.Point){if(0===e.x&&0===e.y)return this.transform((new xa).rotate(t));throw ks.OPERATION_IS_NOT_SUPPORTED}transform(t){return new Fs.Vector(t.transform([this.x,this.y]))}rotate90CCW(){return new Fs.Vector(-this.y,this.x)}rotate90CW(){return new Fs.Vector(this.y,-this.x)}invert(){return new Fs.Vector(-this.x,-this.y)}add(t){return new Fs.Vector(this.x+t.x,this.y+t.y)}subtract(t){return new Fs.Vector(this.x-t.x,this.y-t.y)}angleTo(t){let e=this.normalize(),n=t.normalize(),o=Math.atan2(e.cross(n),e.dot(n));return o<0&&(o+=2*Math.PI),o}projectionOn(t){let e=t.normalize(),n=this.dot(e);return e.multiply(n)}get name(){return"vector"}};var Na=(...t)=>new Fs.Vector(...t);Fs.vector=Na;Fs.Segment=class t extends Ma{constructor(...t){if(super(),this.ps=new Fs.Point,this.pe=new Fs.Point,0!==t.length){if(1===t.length&&t[0]instanceof Array&&4===t[0].length){let e=t[0];return this.ps=new Fs.Point(e[0],e[1]),void(this.pe=new Fs.Point(e[2],e[3]))}if(1===t.length&&t[0]instanceof Object&&"segment"===t[0].name){let{ps:e,pe:n}=t[0];return this.ps=new Fs.Point(e.x,e.y),void(this.pe=new Fs.Point(n.x,n.y))}if(!(1===t.length&&t[0]instanceof Fs.Point)){if(2===t.length&&t[0]instanceof Fs.Point&&t[1]instanceof Fs.Point)return this.ps=t[0].clone(),void(this.pe=t[1].clone());if(4===t.length)return this.ps=new Fs.Point(t[0],t[1]),void(this.pe=new Fs.Point(t[2],t[3]));throw ks.ILLEGAL_PARAMETERS}this.ps=t[0].clone()}}clone(){return new Fs.Segment(this.start,this.end)}get start(){return this.ps}get end(){return this.pe}get vertices(){return[this.ps.clone(),this.pe.clone()]}get length(){return this.start.distanceTo(this.end)[0]}get slope(){return new Fs.Vector(this.start,this.end).slope}get box(){return new Fs.Box(Math.min(this.start.x,this.end.x),Math.min(this.start.y,this.end.y),Math.max(this.start.x,this.end.x),Math.max(this.start.y,this.end.y))}equalTo(t){return this.ps.equalTo(t.ps)&&this.pe.equalTo(t.pe)}contains(t){return Fs.Utils.EQ_0(this.distanceToPoint(t))}intersect(t){return t instanceof Fs.Point?this.contains(t)?[t]:[]:t instanceof Fs.Line?Zs(this,t):t instanceof Fs.Ray?gr(t,this):t instanceof Fs.Segment?qs(this,t):t instanceof Fs.Circle?Ks(this,t):t instanceof Fs.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=qs(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof Fs.Arc?Qs(this,t):t instanceof Fs.Polygon?ar(this,t):t instanceof Fs.Multiline?Pr(this,t):void 0}distanceTo(t){if(t instanceof Fs.Point){let[e,n]=Fs.Distance.point2segment(t,this);return n=n.reverse(),[e,n]}if(t instanceof Fs.Circle){let[e,n]=Fs.Distance.segment2circle(this,t);return[e,n]}if(t instanceof Fs.Line){let[e,n]=Fs.Distance.segment2line(this,t);return[e,n]}if(t instanceof Fs.Segment){let[e,n]=Fs.Distance.segment2segment(this,t);return[e,n]}if(t instanceof Fs.Arc){let[e,n]=Fs.Distance.segment2arc(this,t);return[e,n]}if(t instanceof Fs.Polygon){let[e,n]=Fs.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof Fs.PlanarSet){let[e,n]=Fs.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof Fs.Multiline)return Fs.Distance.shape2multiline(this,t)}tangentInStart(){return new Fs.Vector(this.start,this.end).normalize()}tangentInEnd(){return new Fs.Vector(this.end,this.start).normalize()}reverse(){return new t(this.end,this.start)}split(t){return this.start.equalTo(t)?[null,this.clone()]:this.end.equalTo(t)?[this.clone(),null]:[new Fs.Segment(this.start,t),new Fs.Segment(t,this.end)]}middle(){return new Fs.Point((this.start.x+this.end.x)/2,(this.start.y+this.end.y)/2)}pointAtLength(t){if(t>this.length||t<0)return null;if(0==t)return this.start;if(t==this.length)return this.end;let e=t/this.length;return new Fs.Point((this.end.x-this.start.x)*e+this.start.x,(this.end.y-this.start.y)*e+this.start.y)}distanceToPoint(t){let[e,...n]=Fs.Distance.point2segment(t,this);return e}definiteIntegral(t=0){return(this.end.x-this.start.x)*(this.start.y-t+(this.end.y-t))/2}transform(e=new Fs.Matrix){return new t(this.ps.transform(e),this.pe.transform(e))}isZeroLength(){return this.ps.equalTo(this.pe)}sortPoints(t){return new Fs.Line(this.start,this.end).sortPoints(t)}get name(){return"segment"}svg(t={}){return`\n<line x1="${this.start.x}" y1="${this.start.y}" x2="${this.end.x}" y2="${this.end.y}" ${Ws(t)} />`}};var Ca=(...t)=>new Fs.Segment(...t);Fs.segment=Ca;var{vector:Ta}=Fs;Fs.Line=class t extends Ma{constructor(...e){if(super(),this.pt=new Fs.Point,this.norm=new Fs.Vector(0,1),0!==e.length){if(1===e.length&&e[0]instanceof Object&&"line"===e[0].name){let{pt:t,norm:n}=e[0];return this.pt=new Fs.Point(t),void(this.norm=new Fs.Vector(n))}if(2===e.length){let n=e[0],o=e[1];if(n instanceof Fs.Point&&o instanceof Fs.Point)return this.pt=n,this.norm=t.points2norm(n,o),void(this.norm.dot(Ta(this.pt.x,this.pt.y))>=0&&this.norm.invert());if(n instanceof Fs.Point&&o instanceof Fs.Vector){if(Fs.Utils.EQ_0(o.x)&&Fs.Utils.EQ_0(o.y))throw ks.ILLEGAL_PARAMETERS;return this.pt=n.clone(),this.norm=o.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(Ta(this.pt.x,this.pt.y))>=0&&this.norm.invert())}if(n instanceof Fs.Vector&&o instanceof Fs.Point){if(Fs.Utils.EQ_0(n.x)&&Fs.Utils.EQ_0(n.y))throw ks.ILLEGAL_PARAMETERS;return this.pt=o.clone(),this.norm=n.clone(),this.norm=this.norm.normalize(),void(this.norm.dot(Ta(this.pt.x,this.pt.y))>=0&&this.norm.invert())}}throw ks.ILLEGAL_PARAMETERS}}clone(){return new Fs.Line(this.pt,this.norm)}get start(){}get end(){}get length(){return Number.POSITIVE_INFINITY}get box(){return new Fs.Box(Number.NEGATIVE_INFINITY,Number.NEGATIVE_INFINITY,Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY)}get middle(){}get slope(){return new Fs.Vector(this.norm.y,-this.norm.x).slope}get standard(){return[this.norm.x,this.norm.y,this.norm.dot(Ta(this.pt.x,this.pt.y))]}parallelTo(t){return Fs.Utils.EQ_0(this.norm.cross(t.norm))}incidentTo(t){return this.parallelTo(t)&&this.pt.on(t)}contains(t){if(this.pt.equalTo(t))return!0;let e=new Fs.Vector(this.pt,t);return Fs.Utils.EQ_0(this.norm.dot(e))}coord(t){return Ta(t.x,t.y).cross(this.norm)}intersect(t){return t instanceof Fs.Point?this.contains(t)?[t]:[]:t instanceof Fs.Line?Vs(this,t):t instanceof Fs.Ray?xr(t,this):t instanceof Fs.Circle?Hs(this,t):t instanceof Fs.Box?Us(this,t):t instanceof Fs.Segment?Zs(t,this):t instanceof Fs.Arc?Gs(this,t):t instanceof Fs.Polygon?hr(this,t):t instanceof Fs.Multiline?Pr(this,t):void 0}distanceTo(t){if(t instanceof Fs.Point){let[e,n]=Fs.Distance.point2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof Fs.Circle){let[e,n]=Fs.Distance.circle2line(t,this);return n=n.reverse(),[e,n]}if(t instanceof Fs.Segment){let[e,n]=Fs.Distance.segment2line(t,this);return[e,n.reverse()]}if(t instanceof Fs.Arc){let[e,n]=Fs.Distance.arc2line(t,this);return[e,n.reverse()]}if(t instanceof Fs.Polygon){let[e,n]=Fs.Distance.shape2polygon(this,t);return[e,n]}}split(t){if(t instanceof Fs.Point)return[new Fs.Ray(t,this.norm),new Fs.Ray(t,this.norm)];{let e=new Fs.Multiline([this]),n=this.sortPoints(t);return e.split(n),e.toShapes()}}rotate(t,e=new Fs.Point){return new Fs.Line(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new Fs.Line(this.pt.transform(t),this.norm.clone())}sortPoints(t){return t.slice().sort((t,e)=>this.coord(t)<this.coord(e)?-1:this.coord(t)>this.coord(e)?1:0)}get name(){return"line"}svg(t,e={}){let n=Us(this,t);if(0===n.length)return"";let o=n[0],i=2===n.length?n[1]:n.find(t=>!t.equalTo(o));return void 0===i&&(i=o),new Fs.Segment(o,i).svg(e)}static points2norm(t,e){if(t.equalTo(e))throw ks.ILLEGAL_PARAMETERS;return new Fs.Vector(t,e).normalize().rotate90CCW()}};var Ea=(...t)=>new Fs.Line(...t);Fs.line=Ea;Fs.Circle=class extends Ma{constructor(...t){if(super(),this.pc=new Fs.Point,this.r=1,1===t.length&&t[0]instanceof Object&&"circle"===t[0].name){let{pc:e,r:n}=t[0];this.pc=new Fs.Point(e),this.r=n}else{let[e,n]=[...t];e&&e instanceof Fs.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n)}}clone(){return new Fs.Circle(this.pc.clone(),this.r)}get center(){return this.pc}get box(){return new Fs.Box(this.pc.x-this.r,this.pc.y-this.r,this.pc.x+this.r,this.pc.y+this.r)}contains(t){return t instanceof Fs.Point?Fs.Utils.LE(t.distanceTo(this.center)[0],this.r):t instanceof Fs.Segment?Fs.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&Fs.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof Fs.Arc?0===this.intersect(t).length&&Fs.Utils.LE(t.start.distanceTo(this.center)[0],this.r)&&Fs.Utils.LE(t.end.distanceTo(this.center)[0],this.r):t instanceof Fs.Circle?0===this.intersect(t).length&&Fs.Utils.LE(t.r,this.r)&&Fs.Utils.LE(t.center.distanceTo(this.center)[0],this.r):void 0}toArc(t=!0){return new Fs.Arc(this.center,this.r,Math.PI,-Math.PI,t)}scale(t,e){if(t!==e)throw ks.OPERATION_IS_NOT_SUPPORTED;if(0!==this.pc.x||0!==this.pc.y)throw ks.OPERATION_IS_NOT_SUPPORTED;return new Fs.Circle(this.pc,this.r*t)}transform(t=new Fs.Matrix){return new Fs.Circle(this.pc.transform(t),this.r)}intersect(t){return t instanceof Fs.Point?this.contains(t)?[t]:[]:t instanceof Fs.Line?Hs(t,this):t instanceof Fs.Ray?yr(t,this):t instanceof Fs.Segment?Ks(t,this):t instanceof Fs.Circle?tr(t,this):t instanceof Fs.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=Ks(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof Fs.Arc?nr(t,this):t instanceof Fs.Polygon?lr(this,t):t instanceof Fs.Multiline?Pr(this,t):void 0}distanceTo(t){if(t instanceof Fs.Point){let[e,n]=Fs.Distance.point2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof Fs.Circle){let[e,n]=Fs.Distance.circle2circle(this,t);return[e,n]}if(t instanceof Fs.Line){let[e,n]=Fs.Distance.circle2line(this,t);return[e,n]}if(t instanceof Fs.Segment){let[e,n]=Fs.Distance.segment2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof Fs.Arc){let[e,n]=Fs.Distance.arc2circle(t,this);return n=n.reverse(),[e,n]}if(t instanceof Fs.Polygon){let[e,n]=Fs.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof Fs.PlanarSet){let[e,n]=Fs.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof Fs.Multiline){let[e,n]=Fs.Distance.shape2multiline(this,t);return[e,n]}}get name(){return"circle"}svg(t={}){return`\n<circle cx="${this.pc.x}" cy="${this.pc.y}" r="${this.r}"\n ${Ws({fill:"none",...t})} />`}};Fs.circle=(...t)=>new Fs.Circle(...t);Fs.Arc=class extends Ma{constructor(...t){if(super(),this.pc=new Fs.Point,this.r=1,this.startAngle=0,this.endAngle=2*Math.PI,this.counterClockwise=!0,0!==t.length)if(1===t.length&&t[0]instanceof Object&&"arc"===t[0].name){let{pc:e,r:n,startAngle:o,endAngle:i,counterClockwise:s}=t[0];this.pc=new Fs.Point(e.x,e.y),this.r=n,this.startAngle=o,this.endAngle=i,this.counterClockwise=s}else{let[e,n,o,i,s]=[...t];e&&e instanceof Fs.Point&&(this.pc=e.clone()),void 0!==n&&(this.r=n),void 0!==o&&(this.startAngle=o),void 0!==i&&(this.endAngle=i),void 0!==s&&(this.counterClockwise=s)}}clone(){return new Fs.Arc(this.pc.clone(),this.r,this.startAngle,this.endAngle,this.counterClockwise)}get sweep(){let t=this.startAngle,e=this.endAngle;if(Fs.Utils.EQ(Math.abs(t-e),Fs.PIx2))return Fs.PIx2;Math.abs(t)>Fs.PIx2&&(t-=Math.trunc(t/Fs.PIx2)*Fs.PIx2),t<0&&(t+=Fs.PIx2),Math.abs(e)>Fs.PIx2&&(e-=Math.trunc(e/Fs.PIx2)*Fs.PIx2),e<0&&(e+=Fs.PIx2);let n=this.counterClockwise?e-t:t-e;return n<0&&(n+=Fs.PIx2),n}get start(){return new Fs.Point(this.pc.x+this.r,this.pc.y).rotate(this.startAngle,this.pc)}get end(){return new Fs.Point(this.pc.x+this.r,this.pc.y).rotate(this.endAngle,this.pc)}get center(){return this.pc.clone()}get vertices(){return[this.start.clone(),this.end.clone()]}get length(){return Math.abs(this.sweep*this.r)}get box(){let t=this.breakToFunctional().reduce((t,e)=>t.merge(e.start.box),new Fs.Box);return t=t.merge(this.end.box),t}contains(t){if(!Fs.Utils.EQ(this.pc.distanceTo(t)[0],this.r))return!1;if(t.equalTo(this.start))return!0;let e=new Fs.Vector(this.pc,t).slope,n=new Fs.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise);return Fs.Utils.LE(n.length,this.length)}split(t){if(this.start.equalTo(t))return[null,this.clone()];if(this.end.equalTo(t))return[this.clone(),null];let e=new Fs.Vector(this.pc,t).slope;return[new Fs.Arc(this.pc,this.r,this.startAngle,e,this.counterClockwise),new Fs.Arc(this.pc,this.r,e,this.endAngle,this.counterClockwise)]}middle(){let t=this.counterClockwise?this.startAngle+this.sweep/2:this.startAngle-this.sweep/2;return new Fs.Arc(this.pc,this.r,this.startAngle,t,this.counterClockwise).end}pointAtLength(t){if(t>this.length||t<0)return null;if(0===t)return this.start;if(t===this.length)return this.end;let e=t/this.length,n=this.counterClockwise?this.startAngle+this.sweep*e:this.startAngle-this.sweep*e;return new Fs.Arc(this.pc,this.r,this.startAngle,n,this.counterClockwise).end}chordHeight(){return(1-Math.cos(Math.abs(this.sweep/2)))*this.r}intersect(t){return t instanceof Fs.Point?this.contains(t)?[t]:[]:t instanceof Fs.Line?Gs(t,this):t instanceof Fs.Ray?mr(t,this):t instanceof Fs.Circle?nr(this,t):t instanceof Fs.Segment?Qs(t,this):t instanceof Fs.Box?function(t,e){let n=[];for(let o of e.toSegments()){let e=Qs(o,t);for(let t of e)n.push(t)}return n}(this,t):t instanceof Fs.Arc?er(this,t):t instanceof Fs.Polygon?cr(this,t):t instanceof Fs.Multiline?Pr(this,t):void 0}distanceTo(t){if(t instanceof Fs.Point){let[e,n]=Fs.Distance.point2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof Fs.Circle){let[e,n]=Fs.Distance.arc2circle(this,t);return[e,n]}if(t instanceof Fs.Line){let[e,n]=Fs.Distance.arc2line(this,t);return[e,n]}if(t instanceof Fs.Segment){let[e,n]=Fs.Distance.segment2arc(t,this);return n=n.reverse(),[e,n]}if(t instanceof Fs.Arc){let[e,n]=Fs.Distance.arc2arc(this,t);return[e,n]}if(t instanceof Fs.Polygon){let[e,n]=Fs.Distance.shape2polygon(this,t);return[e,n]}if(t instanceof Fs.PlanarSet){let[e,n]=Fs.Distance.shape2planarSet(this,t);return[e,n]}if(t instanceof Fs.Multiline)return Fs.Distance.shape2multiline(this,t)}breakToFunctional(){let t=[],e=[0,Math.PI/2,Math.PI,3*Math.PI/2],n=this.startAngle,o=this.endAngle;Fs.Utils.EQ(Math.abs(n-o),Fs.PIx2)&&(o=n),Math.abs(n)>Fs.PIx2&&(n-=Math.trunc(n/Fs.PIx2)*Fs.PIx2),n<0&&(n+=Fs.PIx2),Math.abs(o)>Fs.PIx2&&(o-=Math.trunc(o/Fs.PIx2)*Fs.PIx2),o<0&&(o+=Fs.PIx2);let i,s,r,a=n;this.counterClockwise?(s=Math.ceil(n/(Math.PI/2))%4,r=1):(s=Math.floor(n/(Math.PI/2))%4,r=-1);for(let o=0,c=s;o<4;o++,c=(c+r+4)%4){if(i=e[c],i===a)continue;let o=this.counterClockwise?i-n:n-i;if(o<0&&(o+=Fs.PIx2),o>this.sweep)break;t.push(new Fs.Arc(this.pc,this.r,a,i,this.counterClockwise)),a=i}return 0===t.length?(t.push(this),t):(i=o,a!==i&&t.push(new Fs.Arc(this.pc,this.r,a,i,this.counterClockwise)),t)}tangentInStart(){let t=new Fs.Vector(this.pc,this.start),e=this.counterClockwise?Math.PI/2:-Math.PI/2;return t.rotate(e).normalize()}tangentInEnd(){let t=new Fs.Vector(this.pc,this.end),e=this.counterClockwise?-Math.PI/2:Math.PI/2;return t.rotate(e).normalize()}reverse(){return new Fs.Arc(this.pc,this.r,this.endAngle,this.startAngle,!this.counterClockwise)}transform(t=new Fs.Matrix){let e=this.start.transform(t),n=this.end.transform(t),o=this.pc.transform(t),i=this.counterClockwise;return t.a*t.d<0&&(i=!i),Fs.Arc.arcSE(o,e,n,i)}static arcSE(t,e,n,o){let{vector:i}=Fs,s=i(t,e).slope,r=i(t,n).slope;Fs.Utils.EQ(s,r)&&(r+=2*Math.PI,o=!0);let a=i(t,e).length;return new Fs.Arc(t,a,s,r,o)}definiteIntegral(t=0){return this.breakToFunctional().reduce((e,n)=>e+n.circularSegmentDefiniteIntegral(t),0)}circularSegmentDefiniteIntegral(t){let e=new Fs.Segment(this.start,this.end).definiteIntegral(t),n=Fs.Utils.EQ(this.sweep,Fs.PIx2)?0:this.circularSegmentArea();return this.counterClockwise?e-n:e+n}circularSegmentArea(){return.5*this.r*this.r*(this.sweep-Math.sin(this.sweep))}sortPoints(t){let{vector:e}=Fs;return t.slice().sort((t,n)=>{let o=e(this.pc,t).slope,i=e(this.pc,n).slope;return o<i?-1:o>i?1:0})}get name(){return"arc"}svg(t={}){let e=this.sweep<=Math.PI?"0":"1",n=this.counterClockwise?"1":"0";if(Fs.Utils.EQ(this.sweep,2*Math.PI)){return new Fs.Circle(this.pc,this.r).svg(t)}return`\n<path d="M${this.start.x},${this.start.y}\n A${this.r},${this.r} 0 ${e},${n} ${this.end.x},${this.end.y}"\n ${Ws({fill:"none",...t})} />`}};Fs.arc=(...t)=>new Fs.Arc(...t);Fs.Box=class t extends Ma{constructor(t=void 0,e=void 0,n=void 0,o=void 0){super(),this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}clone(){return new t(this.xmin,this.ymin,this.xmax,this.ymax)}get low(){return new Fs.Point(this.xmin,this.ymin)}get high(){return new Fs.Point(this.xmax,this.ymax)}get max(){return this.clone()}get center(){return new Fs.Point((this.xmin+this.xmax)/2,(this.ymin+this.ymax)/2)}get width(){return Math.abs(this.xmax-this.xmin)}get height(){return Math.abs(this.ymax-this.ymin)}get box(){return this.clone()}not_intersect(t){return this.xmax<t.xmin||this.xmin>t.xmax||this.ymax<t.ymin||this.ymin>t.ymax}intersect(t){return!this.not_intersect(t)}merge(e){return new t(void 0===this.xmin?e.xmin:Math.min(this.xmin,e.xmin),void 0===this.ymin?e.ymin:Math.min(this.ymin,e.ymin),void 0===this.xmax?e.xmax:Math.max(this.xmax,e.xmax),void 0===this.ymax?e.ymax:Math.max(this.ymax,e.ymax))}less_than(t){return!!this.low.lessThan(t.low)||!(!this.low.equalTo(t.low)||!this.high.lessThan(t.high))}equal_to(t){return this.low.equalTo(t.low)&&this.high.equalTo(t.high)}output(){return this.clone()}comparable_less_than(t,e){return t.lessThan(e)}set(t,e,n,o){this.xmin=t,this.ymin=e,this.xmax=n,this.ymax=o}extend(e){return e<=0?this.clone():new t(this.xmin-e,this.ymin-e,this.xmax+e,this.ymax+e)}toPoints(){return[new Fs.Point(this.xmin,this.ymin),new Fs.Point(this.xmax,this.ymin),new Fs.Point(this.xmax,this.ymax),new Fs.Point(this.xmin,this.ymax)]}toSegments(){let t=this.toPoints();return[new Fs.Segment(t[0],t[1]),new Fs.Segment(t[1],t[2]),new Fs.Segment(t[2],t[3]),new Fs.Segment(t[3],t[0])]}rotate(t,e=new Fs.Point){throw ks.OPERATION_IS_NOT_SUPPORTED}transform(e=new Fs.Matrix){return this.toPoints().map(t=>t.transform(e)).reduce((t,e)=>t.merge(e.box),new t)}contains(t){return t instanceof Fs.Point?t.x>=this.xmin&&t.x<=this.xmax&&t.y>=this.ymin&&t.y<=this.ymax:t instanceof Fs.Segment?t.vertices.every(t=>this.contains(t)):t instanceof Fs.Box?t.toSegments().every(t=>this.contains(t)):t instanceof Fs.Circle?this.contains(t.box):t instanceof Fs.Arc?t.vertices.every(t=>this.contains(t))&&this.toSegments().every(e=>0===Qs(e,t).length):!(t instanceof Fs.Line||t instanceof Fs.Ray)&&(t instanceof Fs.Multiline?t.toShapes().every(t=>this.contains(t)):t instanceof Fs.Polygon?this.contains(t.box):void 0)}distanceTo(t){const e=this.toSegments().map(e=>e.distanceTo(t));let n=[Number.MAX_SAFE_INTEGER,null];return e.forEach(t=>{t[0]<n[0]&&(n=t)}),n}get name(){return"box"}svg(t={}){const e=this.xmax-this.xmin,n=this.ymax-this.ymin;return`\n<rect x="${this.xmin}" y="${this.ymin}" width="${e}" height="${n}"\n ${Ws({fill:"none",...t})} />`}};Fs.box=(...t)=>new Fs.Box(...t);Fs.Edge=class{constructor(t){this.shape=t,this.next=void 0,this.prev=void 0,this.face=void 0,this.arc_length=0,this.bvStart=void 0,this.bvEnd=void 0,this.bv=void 0,this.overlap=void 0}get start(){return this.shape.start}get end(){return this.shape.end}get length(){return this.shape.length}get box(){return this.shape.box}get isSegment(){return this.shape instanceof Fs.Segment}get isArc(){return this.shape instanceof Fs.Arc}get isLine(){return this.shape instanceof Fs.Line}get isRay(){return this.shape instanceof Fs.Ray}middle(){return this.shape.middle()}pointAtLength(t){return this.shape.pointAtLength(t)}contains(t){return this.shape.contains(t)}setInclusion(t){if(void 0!==this.bv)return this.bv;if(this.shape instanceof Fs.Line||this.shape instanceof Fs.Ray)return this.bv=Fs.OUTSIDE,this.bv;if(void 0===this.bvStart&&(this.bvStart=ha(t,this.start)),void 0===this.bvEnd&&(this.bvEnd=ha(t,this.end)),this.bvStart===Fs.OUTSIDE||this.bvEnd==Fs.OUTSIDE)this.bv=Fs.OUTSIDE;else if(this.bvStart===Fs.INSIDE||this.bvEnd==Fs.INSIDE)this.bv=Fs.INSIDE;else{let e=ha(t,this.middle());this.bv=e}return this.bv}setOverlap(t){let e,n=this.shape,o=t.shape;n instanceof Fs.Segment&&o instanceof Fs.Segment?n.start.equalTo(o.start)&&n.end.equalTo(o.end)?e=Fs.OVERLAP_SAME:n.start.equalTo(o.end)&&n.end.equalTo(o.start)&&(e=Fs.OVERLAP_OPPOSITE):(n instanceof Fs.Arc&&o instanceof Fs.Arc||n instanceof Fs.Segment&&o instanceof Fs.Arc||n instanceof Fs.Arc&&o instanceof Fs.Segment)&&(n.start.equalTo(o.start)&&n.end.equalTo(o.end)&&n.middle().equalTo(o.middle())?e=Fs.OVERLAP_SAME:n.start.equalTo(o.end)&&n.end.equalTo(o.start)&&n.middle().equalTo(o.middle())&&(e=Fs.OVERLAP_OPPOSITE)),void 0===this.overlap&&(this.overlap=e),void 0===t.overlap&&(t.overlap=e)}svg(){if(this.shape instanceof Fs.Segment)return` L${this.shape.end.x},${this.shape.end.y}`;if(this.shape instanceof Fs.Arc){let t,e=this.shape,n=e.counterClockwise?"1":"0";if(Fs.Utils.EQ(e.sweep,2*Math.PI)){let o=e.counterClockwise?1:-1,i=new Fs.Arc(e.pc,e.r,e.startAngle,e.startAngle+o*Math.PI,e.counterClockwise),s=new Fs.Arc(e.pc,e.r,e.startAngle+o*Math.PI,e.endAngle,e.counterClockwise);return t="0",` A${i.r},${i.r} 0 ${t},${n} ${i.end.x},${i.end.y}\n A${s.r},${s.r} 0 ${t},${n} ${s.end.x},${s.end.y}`}return t=e.sweep<=Math.PI?"0":"1",` A${e.r},${e.r} 0 ${t},${n} ${e.end.x},${e.end.y}`}}toJSON(){return this.shape.toJSON()}};var wa=class extends $s{constructor(t,e){super(t,e),this.setCircularLinks()}setCircularLinks(){this.isEmpty()||(this.last.next=this.first,this.first.prev=this.last)}[Symbol.iterator](){let t;return{next:()=>{let e=t||this.first,n=!this.first||!!t&&t===this.first;return t=e?e.next:void 0,{value:e,done:n}}}}append(t){return super.append(t),this.setCircularLinks(),this}insert(t,e){return super.insert(t,e),this.setCircularLinks(),this}remove(t){return super.remove(t),this}};Fs.Face=class t extends wa{constructor(e,...n){if(super(),this._box=void 0,this._orientation=void 0,0!==n.length){if(1===n.length)if(n[0]instanceof Array){let o=n[0];if(0===o.length)return;if(o.every(t=>t instanceof Fs.Point)){let n=t.points2segments(o);this.shapes2face(e.edges,n)}else if(o.every(t=>t instanceof Array&&2===t.length)){let n=o.map(t=>new Fs.Point(t[0],t[1])),i=t.points2segments(n);this.shapes2face(e.edges,i)}else if(o.every(t=>t instanceof Fs.Segment||t instanceof Fs.Arc))this.shapes2face(e.edges,o);else if(o.every(t=>"segment"===t.name||"arc"===t.name)){let t=[];for(let e of o){let n;n="segment"===e.name?new Fs.Segment(e):new Fs.Arc(e),t.push(n)}this.shapes2face(e.edges,t)}}else if(n[0]instanceof t){let t=n[0];this.first=t.first,this.last=t.last;for(let n of t)e.edges.add(n)}else if(n[0]instanceof Fs.Circle)this.shapes2face(e.edges,[n[0].toArc(Ts)]);else if(n[0]instanceof Fs.Box){let t=n[0];this.shapes2face(e.edges,[new Fs.Segment(new Fs.Point(t.xmin,t.ymin),new Fs.Point(t.xmax,t.ymin)),new Fs.Segment(new Fs.Point(t.xmax,t.ymin),new Fs.Point(t.xmax,t.ymax)),new Fs.Segment(new Fs.Point(t.xmax,t.ymax),new Fs.Point(t.xmin,t.ymax)),new Fs.Segment(new Fs.Point(t.xmin,t.ymax),new Fs.Point(t.xmin,t.ymin))])}2===n.length&&n[0]instanceof Fs.Edge&&n[1]instanceof Fs.Edge&&(this.first=n[0],this.last=n[1],this.last.next=this.first,this.first.prev=this.last,this.setArcLength())}}get edges(){return this.toArray()}get vertices(){return this.edges.map(t=>t.shape.start.clone())}get shapes(){return this.edges.map(t=>t.shape.clone())}get box(){if(void 0===this._box){let t=new Fs.Box;for(let e of this)t=t.merge(e.box);this._box=t}return this._box}get perimeter(){return this.last.arc_length+this.last.length}pointAtLength(t){if(t>this.perimeter||t<0)return null;let e=null;for(let n of this)if(t>=n.arc_length&&(n===this.last||t<n.next.arc_length)){e=n.pointAtLength(t-n.arc_length);break}return e}static points2segments(t){let e=[];for(let n=0;n<t.length;n++)t[n].equalTo(t[(n+1)%t.length])||e.push(new Fs.Segment(t[n],t[(n+1)%t.length]));return e}shapes2face(t,e){for(let n of e){let e=new Fs.Edge(n);this.append(e),t.add(e)}}append(t){return super.append(t),this.setOneEdgeArcLength(t),t.face=this,this}insert(t,e){return super.insert(t,e),this.setOneEdgeArcLength(t),t.face=this,this}remove(t){return super.remove(t),this.setArcLength(),this}merge_with_next_edge(t){return t.shape.end.x=t.next.shape.end.x,t.shape.end.y=t.next.shape.end.y,this.remove(t.next),this}reverse(){let t=[],e=this.last;do{e.shape=e.shape.reverse(),t.push(e),e=e.prev}while(e!==this.last);this.first=void 0,this.last=void 0;for(let e of t)void 0===this.first?(e.prev=e,e.next=e,this.first=e,this.last=e):(e.prev=this.last,this.last.next=e,this.last=e,this.last.next=this.first,this.first.prev=this.last),this.setOneEdgeArcLength(e);void 0!==this._orientation&&(this._orientation=void 0,this._orientation=this.orientation())}setArcLength(){for(let t of this)this.setOneEdgeArcLength(t),t.face=this}setOneEdgeArcLength(t){t===this.first?t.arc_length=0:t.arc_length=t.prev.arc_length+t.prev.length}area(){return Math.abs(this.signedArea())}signedArea(){let t=0,e=this.box.ymin;for(let n of this)t+=n.shape.definiteIntegral(e);return t}orientation(){if(void 0===this._orientation){let t=this.signedArea();Fs.Utils.EQ_0(t)?this._orientation=Es.NOT_ORIENTABLE:Fs.Utils.LT(t,0)?this._orientation=Es.CCW:this._orientation=Es.CW}return this._orientation}isSimple(e){return 0===t.getSelfIntersections(this,e,!0).length}static getSelfIntersections(t,e,n=!1){let o=[];for(let i of t){let s=e.search(i.box);for(let e of s){if(i===e)continue;if(e.face!==t)continue;if(i.shape instanceof Fs.Segment&&e.shape instanceof Fs.Segment&&(i.next===e||i.prev===e))continue;let s=i.shape.intersect(e.shape);for(let t of s)if((!t.equalTo(i.start)||!t.equalTo(e.end)||e!==i.prev)&&(!t.equalTo(i.end)||!t.equalTo(e.start)||e!==i.next)&&(o.push(t),n))break;if(o.length>0&&n)break}if(o.length>0&&n)break}return o}findEdgeByPoint(t){let e;for(let n of this)if(!t.equalTo(n.shape.start)&&(t.equalTo(n.shape.end)||n.shape.contains(t))){e=n;break}return e}toPolygon(){return new Fs.Polygon(this.shapes)}toJSON(){return this.edges.map(t=>t.toJSON())}svg(){let t=`M${this.first.start.x},${this.first.start.y}`;for(let e of this)t+=e.svg();return t+=" z",t}};Fs.Ray=class t extends Ma{constructor(...t){if(super(),this.pt=new Fs.Point,this.norm=new Fs.Vector(0,1),0!==t.length&&(t.length>=1&&t[0]instanceof Fs.Point&&(this.pt=t[0].clone()),1!==t.length)){if(!(2===t.length&&t[1]instanceof Fs.Vector))throw ks.ILLEGAL_PARAMETERS;this.norm=t[1].clone()}}clone(){return new t(this.pt,this.norm)}get slope(){return new Fs.Vector(this.norm.y,-this.norm.x).slope}get box(){let t=this.slope;return new Fs.Box(t>Math.PI/2&&t<3*Math.PI/2?Number.NEGATIVE_INFINITY:this.pt.x,t>=0&&t<=Math.PI?this.pt.y:Number.NEGATIVE_INFINITY,t>=Math.PI/2&&t<=3*Math.PI/2?this.pt.x:Number.POSITIVE_INFINITY,t>=Math.PI&&t<=2*Math.PI||0===t?this.pt.y:Number.POSITIVE_INFINITY)}get start(){return this.pt}get end(){}get length(){return Number.POSITIVE_INFINITY}contains(t){if(this.pt.equalTo(t))return!0;let e=new Fs.Vector(this.pt,t);return Fs.Utils.EQ_0(this.norm.dot(e))&&Fs.Utils.GE(e.cross(this.norm),0)}coord(t){return Na(t.x,t.y).cross(this.norm)}split(t){return this.contains(t)?this.pt.equalTo(t)?[this]:[new Fs.Segment(this.pt,t),new Fs.Ray(t,this.norm)]:[]}intersect(t){return t instanceof Fs.Point?this.contains(t)?[t]:[]:t instanceof Fs.Segment?gr(this,t):t instanceof Fs.Arc?mr(this,t):t instanceof Fs.Line?xr(this,t):t instanceof Fs.Ray?(n=t,Vs(fr(e=this),fr(n)).filter(t=>e.contains(t)).filter(t=>n.contains(t))):t instanceof Fs.Circle?yr(this,t):t instanceof Fs.Box?function(t,e){return Us(fr(t),e).filter(e=>t.contains(e))}(this,t):t instanceof Fs.Polygon?vr(this,t):t instanceof Fs.Multiline?Pr(this,t):void 0;var e,n}rotate(t,e=new Fs.Point){return new Fs.Ray(this.pt.rotate(t,e),this.norm.rotate(t))}transform(t){return new Fs.Ray(this.pt.transform(t),this.norm.clone())}get name(){return"ray"}svg(t,e={}){let n=Us(new Fs.Line(this.pt,this.norm),t);return n=n.filter(t=>this.contains(t)),0===n.length||2===n.length?"":new Fs.Segment(this.pt,n[0]).svg(e)}};Fs.ray=(...t)=>new Fs.Ray(...t);var Ra=class t{constructor(){this.faces=new Fs.PlanarSet,this.edges=new Fs.PlanarSet;let t=[...arguments];if(1===t.length&&(t[0]instanceof Array&&t[0].length>0||t[0]instanceof Fs.Circle||t[0]instanceof Fs.Box)){let e=t[0];if(t[0]instanceof Array&&t[0].every(t=>t instanceof Array))if(e.every(t=>t instanceof Array&&2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1]))this.faces.add(new Fs.Face(this,e));else for(let t of e)if(t instanceof Array&&t[0]instanceof Array&&t[0].every(t=>t instanceof Array&&2===t.length&&"number"==typeof t[0]&&"number"==typeof t[1]))for(let e of t)this.faces.add(new Fs.Face(this,e));else this.faces.add(new Fs.Face(this,t));else this.faces.add(new Fs.Face(this,e))}}get box(){return[...this.faces].reduce((t,e)=>t.merge(e.box),new Fs.Box)}get vertices(){return[...this.faces].flatMap(t=>t.vertices)}clone(){let e=new t;for(let t of this.faces)e.addFace(t.shapes);return e}createFromArray(e){const n=new t;return e.forEach(t=>[...t.faces].forEach(t=>n.addFace(t.shapes))),n}isEmpty(){return 0===this.edges.size||0===this.faces.size}isValid(){let t=!0;for(let e of this.faces)if(!e.isSimple(this.edges)){t=!1;break}return t}area(){let t=[...this.faces].reduce((t,e)=>t+e.signedArea(),0);return Math.abs(t)}addFace(...t){let e=new Fs.Face(this,...t);return this.faces.add(e),e}deleteFace(t){for(let e of t)this.edges.delete(e);return this.faces.delete(t)}recreateFaces(){this.faces.clear();for(let t of this.edges)t.face=null;let t,e=!0;for(;e;){e=!1;for(let n of this.edges)if(null===n.face){t=n,e=!0;break}if(e){let e=t;do{e=e.next}while(e.next!==t);this.addFace(t,e)}}}removeChain(t,e,n){if(n.next!==e){for(let o=e;o!==n.next;o=o.next)if(t.remove(o),this.edges.delete(o),t.isEmpty()){this.deleteFace(t);break}}else this.deleteFace(t)}addVertex(t,e){let n=e.shape.split(t);if(null===n[0])return e.prev;if(null===n[1])return e;let o=new Fs.Edge(n[0]),i=e.prev;return e.face.insert(o,i),this.edges.delete(e),this.edges.add(o),e.shape=n[1],this.edges.add(e),o}removeEndVertex(t){const e=t.next;e!==t&&(t.face.merge_with_next_edge(t),this.edges.delete(e))}cut(t){const e=this.splitToIslands().flatMap(e=>e._cutSingleIsland(t)).filter(t=>t.isValid()&&!1===t.isEmpty());return this.createFromArray(e)}_cutSingleIsland(t){let e=this.clone();const n=t.clone();let o,i,s={int_points1:[],int_points2:[],int_points1_sorted:[],int_points2_sorted:[]};for(let t of n.edges)for(let n of e.edges){let e=dr(t,n);for(let o of e)Ir(t,o,s.int_points1),Ir(n,o,s.int_points2)}if(0===s.int_points1.length)return e;s.int_points1_sorted=_r(s.int_points1),s.int_points2_sorted=_r(s.int_points2),Rr(n,s.int_points1_sorted),Rr(e,s.int_points2_sorted),Cr(s),s.int_points1_sorted=_r(s.int_points1),s.int_points2_sorted=_r(s.int_points2),Tr(s.int_points1),Er(s.int_points1,e);for(let t of s.int_points1_sorted)t.edge_before&&t.edge_after&&t.edge_before.bv===t.edge_after.bv&&(s.int_points2[t.id]=-1,t.id=-1);if(s.int_points1=s.int_points1.filter(t=>t.id>=0),s.int_points2=s.int_points2.filter(t=>t.id>=0),s.int_points1.forEach((t,e)=>{t.id=e}),s.int_points2.forEach((t,e)=>{t.id=e}),0===s.int_points1.length)return e;s.int_points1_sorted=_r(s.int_points1),s.int_points2_sorted=_r(s.int_points2);for(let t=1;t<s.int_points1_sorted.length;t++)if(i=s.int_points1_sorted[t],o=s.int_points1_sorted[t-1],i.edge_before&&1===i.edge_before.bv){let t=o.edge_after,r=i.edge_before,a=n.getChain(t,r);Or(s.int_points2[o.id],s.int_points2[i.id],a),a.forEach(t=>e.edges.add(t)),a=a.reverse().map(t=>new Fs.Edge(t.shape.reverse()));for(let t=0;t<a.length-1;t++)a[t].next=a[t+1],a[t+1].prev=a[t];Or(s.int_points2[i.id],s.int_points2[o.id],a),a.forEach(t=>e.edges.add(t))}return e.recreateFaces(),e}cutWithLine(t){let e=new Sr([t]);return this.cut(e)}findEdgeByPoint(t){let e;for(let n of this.faces)if(e=n.findEdgeByPoint(t),void 0!==e)break;return e}splitToIslands(){if(this.isEmpty())return[];let t=this.toArray();t.sort((t,e)=>e.area()-t.area());let e=[...t[0].faces][0].orientation(),n=t.filter(t=>[...t.faces][0].orientation()===e);for(let o of t){let t=[...o.faces][0];if(t.orientation()!==e)for(let e of n)if(t.shapes.every(t=>e.contains(t))){e.addFace(t.shapes);break}}return n}rearrange(){if(this.faces.size<=1)return this.clone();const e=this.splitToIslands(),n=new t;return e.forEach(t=>{t.faces.forEach(t=>n.addFace(t.shapes))}),n}orientation(){return this.isEmpty()?Es.NOT_ORIENTABLE:[...this.faces][0].orientation()}isOuter(t){return t.orientation()===this.orientation()}isMultiPolygon(){let t=0;return this.faces.forEach(e=>{this.isOuter(e)&&t++}),t>1}reverse(){for(let t of this.faces)t.reverse();return this}contains(t){if(t instanceof Fs.Point){let e=ha(this,t);return 1===e||2===e}return pa(this,t)}distanceTo(t){if(t instanceof Fs.Point){let[e,n]=Fs.Distance.point2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof Fs.Circle||t instanceof Fs.Line||t instanceof Fs.Segment||t instanceof Fs.Arc){let[e,n]=Fs.Distance.shape2polygon(t,this);return n=n.reverse(),[e,n]}if(t instanceof Fs.Polygon){let e,n,o=[Number.POSITIVE_INFINITY,new Fs.Segment];for(let i of this.edges){let s=o[0];[e,n]=Fs.Distance.shape2planarSet(i.shape,t.edges,s),Fs.Utils.LT(e,s)&&(o=[e,n])}return o}}intersect(t){return t instanceof Fs.Point?this.contains(t)?[t]:[]:t instanceof Fs.Line?hr(t,this):t instanceof Fs.Ray?vr(t,this):t instanceof Fs.Circle?lr(t,this):t instanceof Fs.Segment?ar(t,this):t instanceof Fs.Arc?cr(t,this):t instanceof Fs.Polygon?function(t,e){let n=[];if(t.isEmpty()||e.isEmpty())return n;if(t.box.not_intersect(e.box))return n;for(let o of t.edges)n=[...n,...ur(o,e)];return n}(t,this):t instanceof Fs.Multiline?function(t,e){let n=[];if(e.isEmpty()||0===t.size)return n;for(let o of t)n=[...n,...ur(o,e)];return n}(t,this):void 0}translate(e){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=>t.translate(e)));return n}rotate(e=0,n=new Fs.Point){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=>t.rotate(e,n)));return o}scale(e,n){let o=new t;for(let t of this.faces)o.addFace(t.shapes.map(t=>t.scale(e,n)));return o}transform(e=new Fs.Matrix){let n=new t;for(let t of this.faces)n.addFace(t.shapes.map(t=>t.transform(e)));return n}toJSON(){return[...this.faces].map(t=>t.toJSON())}toArray(){return[...this.faces].map(t=>t.toPolygon())}dpath(){return[...this.faces].reduce((t,e)=>t+e.svg(),"")}svg(t={}){let e=`\n<path ${Ws({fillRule:"evenodd",fill:"lightcyan",...t})} d="`;for(let t of this.faces)e+=`\n${t.svg()}`;return e+='" >\n</path>',e}};Fs.Polygon=Ra;Fs.polygon=(...t)=>new Fs.Polygon(...t);var{Circle:Oa,Line:Aa,Point:za,Vector:Da,Utils:La}=Fs;Fs.Inversion=class t{constructor(t){this.circle=t}get inversion_circle(){return this.circle}static inversePoint(t,e){const n=new Da(t.pc,e),o=t.r*t.r,i=n.dot(n);return La.EQ_0(i)?new za(Number.POSITIVE_INFINITY,Number.POSITIVE_INFINITY):t.pc.translate(n.multiply(o/i))}static inverseCircle(t,e){const n=t.pc.distanceTo(e.pc)[0];if(La.EQ(n,e.r)){let n=t.r*t.r/(2*e.r),o=new Da(t.pc,e.pc);o=o.normalize();let i=t.pc.translate(o.multiply(n));return new Aa(i,o)}{let n=new Da(t.pc,e.pc),o=t.r*t.r/(n.dot(n)-e.r*e.r),i=t.pc.translate(n.multiply(o)),s=Math.abs(o)*e.r;return new Oa(i,s)}}static inverseLine(t,e){const[n,o]=t.pc.distanceTo(e);if(La.EQ_0(n))return e.clone();{let e=t.r*t.r/(2*n),i=new Da(t.pc,o.end);return i=i.multiply(e/n),new Oa(t.pc.translate(i),e)}}inverse(e){return e instanceof za?t.inversePoint(this.circle,e):e instanceof Oa?t.inverseCircle(this.circle,e):e instanceof Aa?t.inverseLine(this.circle,e):void 0}};Fs.inversion=t=>new Fs.Inversion(t);Fs.Distance=class t{static point2point(t,e){return t.distanceTo(e)}static point2line(t,e){let n=t.projectionOn(e);return[new Fs.Vector(t,n).length,new Fs.Segment(t,n)]}static point2circle(t,e){let[n,o]=t.distanceTo(e.center);if(Fs.Utils.EQ_0(n))return[e.r,new Fs.Segment(t,e.toArc().start)];{let o=Math.abs(n-e.r),i=new Fs.Vector(e.pc,t).normalize().multiply(e.r),s=e.pc.translate(i);return[o,new Fs.Segment(t,s)]}}static point2segment(e,n){if(n.start.equalTo(n.end))return t.point2point(e,n.start);let o,i,s=new Fs.Vector(n.start,n.end),r=new Fs.Vector(n.start,e),a=new Fs.Vector(n.end,e),c=s.dot(r),h=-s.dot(a);if(Fs.Utils.GE(c,0)&&Fs.Utils.GE(h,0)){let t=n.tangentInStart();return o=Math.abs(t.cross(r)),i=n.start.translate(t.multiply(t.dot(r))),[o,new Fs.Segment(e,i)]}return c<0?e.distanceTo(n.start):e.distanceTo(n.end)}static point2arc(e,n){let o,i,s=new Fs.Circle(n.pc,n.r),r=[];return[o,i]=t.point2circle(e,s),i.end.on(n)&&r.push(t.point2circle(e,s)),r.push(t.point2point(e,n.start)),r.push(t.point2point(e,n.end)),t.sort(r),r[0]}static point2edge(e,n){return n.shape instanceof Fs.Segment?t.point2segment(e,n.shape):t.point2arc(e,n.shape)}static segment2line(e,n){let o=e.intersect(n);if(o.length>0)return[0,new Fs.Segment(o[0],o[0])];let i=[];return i.push(t.point2line(e.start,n)),i.push(t.point2line(e.end,n)),t.sort(i),i[0]}static segment2segment(e,n){let o=qs(e,n);if(o.length>0)return[0,new Fs.Segment(o[0],o[0])];let i,s,r=[];return[i,s]=t.point2segment(n.start,e),r.push([i,s.reverse()]),[i,s]=t.point2segment(n.end,e),r.push([i,s.reverse()]),r.push(t.point2segment(e.start,n)),r.push(t.point2segment(e.end,n)),t.sort(r),r[0]}static segment2circle(e,n){let o=e.intersect(n);if(o.length>0)return[0,new Fs.Segment(o[0],o[0])];let i=new Fs.Line(e.ps,e.pe),[s,r]=t.point2line(n.center,i);if(Fs.Utils.GE(s,n.r)&&r.end.on(e))return t.point2circle(r.end,n);{let[o,i]=t.point2circle(e.start,n),[s,r]=t.point2circle(e.end,n);return Fs.Utils.LT(o,s)?[o,i]:[s,r]}}static segment2arc(e,n){let o=e.intersect(n);if(o.length>0)return[0,new Fs.Segment(o[0],o[0])];let i=new Fs.Line(e.ps,e.pe),s=new Fs.Circle(n.pc,n.r),[r,a]=t.point2line(s.center,i);if(Fs.Utils.GE(r,s.r)&&a.end.on(e)){let[e,o]=t.point2circle(a.end,s);if(o.end.on(n))return[e,o]}let c,h,l=[];return l.push(t.point2arc(e.start,n)),l.push(t.point2arc(e.end,n)),[c,h]=t.point2segment(n.start,e),l.push([c,h.reverse()]),[c,h]=t.point2segment(n.end,e),l.push([c,h.reverse()]),t.sort(l),l[0]}static circle2circle(e,n){let o=e.intersect(n);if(o.length>0)return[0,new Fs.Segment(o[0],o[0])];if(e.center.equalTo(n.center)){let o=e.toArc(),i=n.toArc();return t.point2point(o.start,i.start)}{let o=new Fs.Line(e.center,n.center),i=o.intersect(e),s=o.intersect(n),r=[];return r.push(t.point2point(i[0],s[0])),r.push(t.point2point(i[0],s[1])),r.push(t.point2point(i[1],s[0])),r.push(t.point2point(i[1],s[1])),t.sort(r),r[0]}}static circle2line(e,n){let o=e.intersect(n);if(o.length>0)return[0,new Fs.Segment(o[0],o[0])];let[i,s]=t.point2line(e.center,n),[r,a]=t.point2circle(s.end,e);return a=a.reverse(),[r,a]}static arc2line(e,n){let o=n.intersect(e);if(o.length>0)return[0,new Fs.Segment(o[0],o[0])];let i=new Fs.Circle(e.center,e.r),[s,r]=t.point2line(i.center,n);if(!Fs.Utils.GE(s,i.r)){let o=[];return o.push(t.point2line(e.start,n)),o.push(t.point2line(e.end,n)),t.sort(o),o[0]}{let[n,o]=t.point2circle(r.end,i);if(o.end.on(e))return[n,o]}}static arc2circle(e,n){let o=e.intersect(n);if(o.length>0)return[0,new Fs.Segment(o[0],o[0])];let i=new Fs.Circle(e.center,e.r),[s,r]=t.circle2circle(i,n);if(r.start.on(e))return[s,r];{let o=[];return o.push(t.point2circle(e.start,n)),o.push(t.point2circle(e.end,n)),t.sort(o),o[0]}}static arc2arc(e,n){let o=e.intersect(n);if(o.length>0)return[0,new Fs.Segment(o[0],o[0])];let i=new Fs.Circle(e.center,e.r),s=new Fs.Circle(n.center,n.r),[r,a]=t.circle2circle(i,s);if(a.start.on(e)&&a.end.on(n))return[r,a];{let o,i,s=[];return[o,i]=t.point2arc(e.start,n),i.end.on(n)&&s.push([o,i]),[o,i]=t.point2arc(e.end,n),i.end.on(n)&&s.push([o,i]),[o,i]=t.point2arc(n.start,e),i.end.on(e)&&s.push([o,i.reverse()]),[o,i]=t.point2arc(n.end,e),i.end.on(e)&&s.push([o,i.reverse()]),[o,i]=t.point2point(e.start,n.start),s.push([o,i]),[o,i]=t.point2point(e.start,n.end),s.push([o,i]),[o,i]=t.point2point(e.end,n.start),s.push([o,i]),[o,i]=t.point2point(e.end,n.end),s.push([o,i]),t.sort(s),s[0]}}static point2polygon(e,n){let o=[Number.POSITIVE_INFINITY,new Fs.Segment];for(let i of n.edges){let[n,s]=t.point2edge(e,i);Fs.Utils.LT(n,o[0])&&(o=[n,s])}return o}static shape2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new Fs.Segment];for(let o of e.edges){let[e,i]=t.distanceTo(o.shape);Fs.Utils.LT(e,n[0])&&(n=[e,i])}return n}static polygon2polygon(t,e){let n=[Number.POSITIVE_INFINITY,new Fs.Segment];for(let o of t.edges)for(let t of e.edges){let[e,i]=o.shape.distanceTo(t.shape);Fs.Utils.LT(e,n[0])&&(n=[e,i])}return n}static box2box_minmax(t,e){let n=Math.max(Math.max(t.xmin-e.xmax,0),Math.max(e.xmin-t.xmax,0)),o=Math.max(Math.max(t.ymin-e.ymax,0),Math.max(e.ymin-t.ymax,0)),i=n*n+o*o,s=t.merge(e),r=s.xmax-s.xmin,a=s.ymax-s.ymin;return[i,r*r+a*a]}static minmax_tree_process_level(e,n,o,i){let s,r;for(let a of n){[s,r]=t.box2box_minmax(e.box,a.item.key);for(let t of a.item.values)t instanceof Fs.Edge?i.insert([s,r],t.shape):i.insert([s,r],t);Fs.Utils.LT(r,o)&&(o=r)}if(0===n.length)return o;let a=[...n.map(t=>t.left.isNil()?void 0:t.left).filter(t=>void 0!==t),...n.map(t=>t.right.isNil()?void 0:t.right).filter(t=>void 0!==t)].filter(n=>{let[i,s]=t.box2box_minmax(e.box,n.max);return Fs.Utils.LE(i,o)});return o=t.minmax_tree_process_level(e,a,o,i)}static minmax_tree(e,n,o){let i=new Sa,s=[n.index.root],r=o<Number.POSITIVE_INFINITY?o*o:Number.POSITIVE_INFINITY;return r=t.minmax_tree_process_level(e,s,r,i),i}static minmax_tree_calc_distance(e,n,o){let i,s;if(null!=n&&!n.isNil()){if([i,s]=t.minmax_tree_calc_distance(e,n.left,o),s)return[i,s];if(Fs.Utils.LT(i[0],Math.sqrt(n.item.key.low)))return[i,!0];let[r,a]=t.distanceToArray(e,n.item.values);return Fs.Utils.LT(r,i[0])&&(i=[r,a]),[i,s]=t.minmax_tree_calc_distance(e,n.right,i),[i,s]}return[o,!1]}static shape2planarSet(e,n,o=Number.POSITIVE_INFINITY){let i=[o,new Fs.Segment],s=!1;if(n instanceof Fs.PlanarSet){let r=t.minmax_tree(e,n,o);[i,s]=t.minmax_tree_calc_distance(e,r.root,i)}return i}static sort(t){t.sort((t,e)=>Fs.Utils.LT(t[0],e[0])?-1:Fs.Utils.GT(t[0],e[0])?1:0)}static distance(t,e){return t.distanceTo(e)}static distanceToArray(t,e){let n=[Number.POSITIVE_INFINITY,new Fs.Segment];for(let o of e){let[e,i]=t.distanceTo(o);Fs.Utils.LT(e,n[0])&&(n=[e,i])}return n}static shape2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new Fs.Segment];for(let i of n){let[n,s]=t.distance(e,i.shape);Fs.Utils.LT(n,o[0])&&(o=[n,s])}return o}static multiline2multiline(e,n){let o=[Number.POSITIVE_INFINITY,new Fs.Segment];for(let i of e)for(let e of n){let[n,s]=t.distance(i.shape,e.shape);Fs.Utils.LT(n,o[0])&&(o=[n,s])}return o}};var{Multiline:Ya,Point:Xa,Segment:Fa,Polygon:ka}=Fs;function $a(t){return new Xa(t.split(" ").map(Number))}function Ba(t){return t.split(", ").map($a)}function ja(t){const e=Ba(t);let n=[];for(let t=0;t<e.length-1;t++)n.push(new Fa(e[t],e[t+1]));return new Ya(n)}function Wa(t){const e=t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), ("),n=new ka;let o;return e.forEach((t,e)=>{let i=t.split(", ").map(t=>new Xa(t.split(" ").map(Number)));const s=n.addFace(i);0===e?o=s.orientation():s.orientation()===o&&s.reverse()}),n}function Va(t){if(t.startsWith("POLYGON")){return Wa(t.replace(/^POLYGON /,""))}return function(t){const e=t.split(/\)\), \(\(/).map(t=>"(("+t+"))").map(Wa),n=new ka;return e.reduce((t,e)=>[...t,...e?.faces],[]).forEach(t=>n.addFace([...t?.shapes])),n}(t.replace(/^MULTIPOLYGON \(\(\((.*)\)\)\)$/,"$1"))}function Ha(t){return t.split("\n")?.every(t=>t.includes("POINT"))}function Ua(t){return t.split("\n")?.every(t=>t.includes("LINESTRING"))}Fs.isWktString=function(t){return t.startsWith("POINT")||Ha(t)||t.startsWith("LINESTRING")||Ua(t)||t.startsWith("MULTILINESTRING")||t.startsWith("POLYGON")||t.startsWith("MULTIPOINT")||t.startsWith("MULTIPOLYGON")||t.startsWith("GEOMETRYCOLLECTION")},Fs.parseWKT=function t(e){if(e.startsWith("POINT")){return $a(e.replace(/^POINT \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTIPOINT")){return Ba(e.replace(/^MULTIPOINT \(/,"").replace(/\)$/,""))}if(e.startsWith("LINESTRING")){return ja(e.replace(/^LINESTRING \(/,"").replace(/\)$/,""))}if(e.startsWith("MULTILINESTRING")){return function(t){return t.replace(/\(\(/,"").replace(/\)\)$/,"").split("), (").map(ja)}(e.replace(/^MULTILINESTRING /,""))}if(e.startsWith("POLYGON")||e.startsWith("MULTIPOLYGON"))return Va(e);if(e.startsWith("GEOMETRYCOLLECTION")){const n=/(?<type>POINT|LINESTRING|POLYGON|MULTIPOINT|MULTILINESTRING|MULTIPOLYGON) \((?:[^\(\)]|\([^\)]*\))*\)/g,o=e.match(n);o[0].startsWith("GEOMETRYCOLLECTION")&&(o[0]=o[0].replace("GEOMETRYCOLLECTION (",""));return o.map(t).map(t=>t instanceof Array?t:[t]).reduce((t,e)=>[...t,...e],[])}return Ha(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map($a)}(e):Ua(e)?function(t){return t.split("\n").map(t=>t.match(/\(([^)]+)\)/)[1]).map(ja).reduce((t,e)=>[...t,...e],[])}(e):[]},Fs.BooleanOperations=na,Fs.Relations=ya;var Ga,Za,qa,Ja=(Ga=gi(),Za=1,qa=null!=Ga?qo(ti(Ga)):{},((t,e,n,o)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let i of Qo(e))ei.call(t,i)||i===n||Jo(t,i,{get:()=>e[i],enumerable:!(o=Ko(e,i))||o.enumerable});return t})(!Za&&Ga&&Ga.__esModule?qa:Jo(qa,"default",{value:Ga,enumerable:!0}),Ga)),Ka=Object.create,Qa=Object.defineProperty,tc=Object.getOwnPropertyDescriptor,ec=Object.getOwnPropertyNames,nc=Object.getPrototypeOf,oc=Object.prototype.hasOwnProperty,ic=(t,e)=>function(){return e||(0,t[ec(t)[0]])((e={exports:{}}).exports,e),e.exports},sc=(t,e,n)=>(n=null!=t?Ka(nc(t)):{},((t,e,n,o)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let i of ec(e))oc.call(t,i)||i===n||Qa(t,i,{get:()=>e[i],enumerable:!(o=tc(e,i))||o.enumerable});return t})(!e&&t&&t.__esModule?n:Qa(n,"default",{value:t,enumerable:!0}),t)),rc=ic({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),ac=ic({"node_modules/kind-of/index.js"(t,e){var n=rc(),o=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=o.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),cc=ic({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(n[e(o,t[o])||o]=t[o]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),hc=ic({"node_modules/deep-rename-keys/index.js"(t,e){var n=ac(),o=cc();e.exports=function t(e,i){var s=n(e);if("object"!==s&&"array"!==s)throw new Error("expected an object");var r=[];for(var a in"object"===s&&(e=o(e,i),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,i):r[a]=c}return r}}}),lc=ic({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,o="~";function i(){}function s(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(o=!1)),r.prototype.eventNames=function(){var t,e,i=[];if(0===this._eventsCount)return i;for(e in t=this._events)n.call(t,e)&&i.push(o?e.slice(1):e);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},r.prototype.listeners=function(t,e){var n=o?o+t:t,i=this._events[n];if(e)return!!i;if(!i)return[];if(i.fn)return[i.fn];for(var s=0,r=i.length,a=new Array(r);s<r;s++)a[s]=i[s].fn;return a},r.prototype.emit=function(t,e,n,i,s,r){var a=o?o+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,i),!0;case 5:return l.fn.call(l.context,e,n,i,s),!0;case 6:return l.fn.call(l.context,e,n,i,s,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,i);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var i=new s(e,n||this),r=o?o+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],i]:this._events[r].push(i):(this._events[r]=i,this._eventsCount++),this},r.prototype.once=function(t,e,n){var i=new s(e,n||this,!0),r=o?o+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],i]:this._events[r].push(i):(this._events[r]=i,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,s){var r=o?o+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new i:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||s&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new i:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||s&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new i:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=o?o+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new i:delete this._events[e])):(this._events=new i,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=o,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),dc=ic({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var o=lc(),i=function(){},s={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:s,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,g,m,y;t=Object.assign({debug:!1},t);var x=new o,v=s.data,b="",P="",S="",I="",M="",_="",N=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var o={type:e,value:n};t.debug&&console.log("emit:",o),x.emit("data",o)}};x.stateMachine=(n(y={},s.data,(n(e={},r.lt,function(){b.trim()&&N(a.text,b),P="",M=!1,v=s.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,s.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(N(a.text,b.slice(0,-3)),b="",v=s.data)})),n(y,s.tagBegin,(n(h={},r.space,i),n(h,r.char,function(t){P=t,v=s.tagName}),n(h,r.slash,function(){P="",M=!0}),h)),n(y,s.tagName,(n(l={},r.space,function(){M?v=s.tagEnd:(v=s.attributeNameStart,N(a.openTag,P))}),n(l,r.gt,function(){N(M?a.closeTag:a.openTag,P),b="",v=s.data}),n(l,r.slash,function(){v=s.tagEnd,N(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=s.cdata,b="",P="")}),l)),n(y,s.tagEnd,(n(d={},r.gt,function(){N(a.closeTag,P),b="",v=s.data}),n(d,r.char,i),d)),n(y,s.attributeNameStart,(n(u={},r.char,function(t){S=t,v=s.attributeName}),n(u,r.gt,function(){b="",v=s.data}),n(u,r.space,i),n(u,r.slash,function(){M=!0,v=s.tagEnd}),u)),n(y,s.attributeName,(n(p={},r.space,function(){v=s.attributeNameEnd}),n(p,r.equal,function(){N(a.attributeName,S),v=s.attributeValueBegin}),n(p,r.gt,function(){I="",N(a.attributeName,S),N(a.attributeValue,I),b="",v=s.data}),n(p,r.slash,function(){M=!0,I="",N(a.attributeName,S),N(a.attributeValue,I),v=s.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,s.attributeNameEnd,(n(f={},r.space,i),n(f,r.equal,function(){N(a.attributeName,S),v=s.attributeValueBegin}),n(f,r.gt,function(){I="",N(a.attributeName,S),N(a.attributeValue,I),b="",v=s.data}),n(f,r.char,function(t){I="",N(a.attributeName,S),N(a.attributeValue,I),S=t,v=s.attributeName}),f)),n(y,s.attributeValueBegin,(n(g={},r.space,i),n(g,r.quote,function(t){_=t,I="",v=s.attributeValue}),n(g,r.gt,function(){N(a.attributeValue,I=""),b="",v=s.data}),n(g,r.char,function(t){_="",I=t,v=s.attributeValue}),g)),n(y,s.attributeValue,(n(m={},r.space,function(t){_?I+=t:(N(a.attributeValue,I),v=s.attributeNameStart)}),n(m,r.quote,function(t){_===t?(N(a.attributeValue,I),v=s.attributeNameStart):I+=t}),n(m,r.gt,function(t){_?I+=t:(N(a.attributeValue,I),b="",v=s.data)}),n(m,r.slash,function(t){_?I+=t:(N(a.attributeValue,I),M=!0,v=s.tagEnd)}),n(m,r.char,function(t){I+=t}),m)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],o=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];o(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),uc=ic({"node_modules/xml-reader/dist/reader.js"(t,e){var n=lc(),o=dc(),i=o.Type,s={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:s.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case i.openTag:if(null===c)(c=a).name=n.value;else{var o=r({name:n.value,parent:c});c.children.push(o),c=o}break;case i.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case i.text:c&&c.children.push(r({type:s.text,value:n.value,parent:t.parentNodes?c:null}));break;case i.attributeName:h=n.value,c.attributes[h]="";break;case i.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=o.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),o=void 0;return n.on("done",function(t){o=t}),n.parse(t),o},create:a,NodeType:s}}}),{cos:pc,sin:fc,PI:gc}=Math,{tan:mc}=Math;sc(hc()),sc(uc());function yc(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.infiniteLines)for(const n of t.infiniteLines)n.step=e;if(t.polygons)for(const n of t.polygons)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var xc=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function vc(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var bc=class extends xc{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,o=this.firstIterationOfStage[e.solverName]||0,i=this.iterations,s=e.solverName===this.getCurrentStageName()?i-o:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:s,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(yc(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const o=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const o=this[e.solverName],i=o?.visualize();return i?(yc(i,n+t),i):null}).filter(Boolean));return 0===o.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(yc(n,o.length+t+1),o.push(n)),1===o.length?o[0]:{points:o.flatMap(t=>t.points||[]),rects:o.flatMap(t=>t.rects||[]),lines:o.flatMap(t=>t.lines||[]),circles:o.flatMap(t=>t.circles||[]),texts:o.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},Pc=t=>{const{o:e,a:n,b:o}=t;return(n.x-e.x)*(o.y-e.y)-(n.y-e.y)*(o.x-e.x)},Sc=(t,e)=>{const n=[...new Set(t)].map(t=>{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=>null!==t);if(n.sort((t,e)=>t.x-e.x||t.y-e.y),n.length<=2)return n.map(t=>t.i);const o=[],i=[];for(const t of n){for(;o.length>=2;){const e=o[o.length-2],n=o[o.length-1];if(!e||!n||Pc({o:e,a:n,b:t})>1e-10)break;o.pop()}o.push(t)}for(let t=n.length-1;t>=0;t--){const e=n[t];if(e){for(;i.length>=2;){const t=i[i.length-2],n=i[i.length-1];if(!t||!n||Pc({o:t,a:n,b:e})>1e-10)break;i.pop()}i.push(e)}}return o.pop(),i.pop(),o.concat(i).map(t=>t.i)},Ic=t=>void 0!==t,Mc=class extends xc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.pts.map(t=>{return e=t,n=this.input.bounds,{x:Math.min(n.maxX,Math.max(n.minX,e.x)),y:Math.min(n.maxY,Math.max(n.minY,e.y))};var e,n}),{regions:e,hulls:n}={regions:(o={...this.input,pts:t}).cells.map(t=>t.map(t=>o.pts[t]).filter(Ic)),hulls:o.cells.map(t=>Sc(t,o.pts).map(t=>o.pts[t]).filter(Ic))};var o;this.output={pts:t,validTris:this.input.validTris,regions:e,hulls:n,depths:this.input.depths},this.stats={regions:e.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output;return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.regions.flatMap(t=>t.flatMap((e,n)=>{const o=t[(n+1)%t.length];return o?[{points:[e,o],strokeColor:"#0f766e"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`regions: ${t.regions.length}`,color:"#1f2937"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},_c=t=>{const{polygon:e,clearance:n,verticesOnly:o=!1}=t,i=e.points,s=i.length;if(s<3)return[];const r=new Ra(i.map(t=>_a(t.x,t.y))).orientation()===Es.CCW,a=[];for(let t=0;t<s;t++){const e=i[t],o=i[(t+1)%s],c=Na(o.x-e.x,o.y-e.y);if(0===c.length){a.push(Ea(_a(e.x,e.y),Na(1,0)));continue}const h=c.normalize(),l=r?Na(h.y,-h.x):Na(-h.y,h.x),d=_a(e.x+n*l.x,e.y+n*l.y);a.push(Ea(d,l))}const c=[];for(let t=0;t<s;t++){const e=a[(t-1+s)%s],n=a[t],o=e.intersect(n);if(o.length>0){const t=o[0];c.push({x:t.x,y:t.y})}else c.push({x:n.pt.x,y:n.pt.y})}if(o)return c;const h=[];for(let t=0;t<s;t++){const e=c[t],n=c[(t+1)%s],o=Ca(_a(e.x,e.y),_a(n.x,n.y)).length,i=Math.max(2,Math.ceil(o/20));for(let t=0;t<i;t++){const o=t/i;h.push({x:e.x+o*(n.x-e.x),y:e.y+o*(n.y-e.y)})}}return h},Nc=t=>{const{localX:e,localY:n,rect:o}=t,i=Math.cos(o.ccwRotation),s=Math.sin(o.ccwRotation);return{x:o.center.x+e*i-n*s,y:o.center.y+e*s+n*i}},Cc=t=>{const{bounds:e,vias:n,clearance:o,rects:i,polygons:s=[],viaSegments:r=24}=t,a=[],{minX:c,maxX:h,minY:l,maxY:d}=e;a.push({x:c,y:l},{x:h,y:l},{x:h,y:d},{x:c,y:d});for(let t=1;t<10;t++){const e=t/10;a.push({x:c+e*(h-c),y:l}),a.push({x:h,y:l+e*(d-l)}),a.push({x:h-e*(h-c),y:d}),a.push({x:c,y:d-e*(d-l)})}for(const t of n){const e=t.diameter/2+o;for(let n=0;n<r;n++){const o=2*Math.PI*n/r;a.push({x:t.center.x+e*Math.cos(o),y:t.center.y+e*Math.sin(o)})}}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=Math.max(2,Math.ceil(Math.max(2*e,2*n)/20));for(let o=0;o<i;o++){const s=o/i;a.push(Nc({localX:2*s*e-e,localY:-n,rect:t})),a.push(Nc({localX:e,localY:2*s*n-n,rect:t})),a.push(Nc({localX:e-2*s*e,localY:n,rect:t})),a.push(Nc({localX:-e,localY:n-2*s*n,rect:t}))}}for(const t of s){if(t.points.length<3)continue;const e=_c({polygon:t,clearance:o});a.push(...e)}return a.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))},Tc=t=>new Ra(t.map(t=>_a(t.x,t.y))),Ec=t=>{const e=[];for(const n of t.faces){const t=[];for(const e of n.vertices)t.push({x:e.x,y:e.y});t.length>=3&&e.push(t)}return e},wc=(t,e,n)=>{const o=e.length;e.push(...t);const i=t.length;for(let t=0;t<i;t++)n.push([o+t,o+(t+1)%i])},Rc=t=>{const{bounds:e,vias:n,clearance:o,rects:i,polygons:s=[],viaSegments:r=8}=t,a=[],c=[],h=[],{minX:l,maxX:d,minY:u,maxY:p}=e,f=10,g=[];for(let t=0;t<f;t++){const e=t/f;g.push({x:l+e*(d-l),y:u})}for(let t=0;t<f;t++){const e=t/f;g.push({x:d,y:u+e*(p-u)})}for(let t=0;t<f;t++){const e=t/f;g.push({x:d-e*(d-l),y:p})}for(let t=0;t<f;t++){const e=t/f;g.push({x:l,y:p-e*(p-u)})}h.push(c.length),wc(g,a,c);const m=[];for(const t of n){const e=t.diameter/2+o,n=[];for(let o=0;o<r;o++){const i=2*Math.PI*o/r;n.push({x:t.center.x+e*Math.cos(i),y:t.center.y+e*Math.sin(i)})}m.push(n)}for(const t of i){const e=t.width/2+o,n=t.height/2+o,i=[Nc({localX:-e,localY:-n,rect:t}),Nc({localX:e,localY:-n,rect:t}),Nc({localX:e,localY:n,rect:t}),Nc({localX:-e,localY:n,rect:t})];m.push(i)}for(const t of s){if(t.points.length<3)continue;const e=_c({polygon:t,clearance:o,verticesOnly:!0});m.push(e)}const y=(t=>{if(t.length<=1)return t;try{let e=t.map(Tc);for(let t=0;t<2;t++){const t=[],n=new Set;for(let o=0;o<e.length;o++){if(n.has(o))continue;let i=e[o];for(let t=o+1;t<e.length;t++){if(n.has(t))continue;const o=i.box,s=e[t].box;if(!(o.xmin>s.xmax+1e-6||o.xmax<s.xmin-1e-6||o.ymin>s.ymax+1e-6||o.ymax<s.ymin-1e-6))try{const o=na.unify(i,e[t]);o.faces.size>0&&(i=o,n.add(t))}catch{}}t.push(i),n.add(o)}e=t}const n=[];for(const t of e){const e=Ec(t);n.push(...e)}return n.length>0?n:t}catch{return t}})(m);for(const t of y)h.push(c.length),wc(t,a,c);const x=((t,e,n)=>{const o=new Array(e.length);for(let t=0;t<e.length;t++)for(let e=n.length-1;e>=0;e--)if(t>=n[e]){o[t]=e;break}const i=new Map,s=t.slice();for(let t=0;t<e.length;t++)for(let n=t+1;n<e.length;n++){if(o[t]===o[n])continue;const[r,a]=e[t],[c,h]=e[n],l=s[r],d=s[a],u=s[c],p=s[h],f=d.x-l.x,g=d.y-l.y,m=p.x-u.x,y=p.y-u.y,x=f*y-g*m;if(Math.abs(x)<1e-10)continue;const v=((u.x-l.x)*y-(u.y-l.y)*m)/x,b=((u.x-l.x)*g-(u.y-l.y)*f)/x;if(v>1e-6&&v<.999999&&b>1e-6&&b<.999999){const e=l.x+v*f,o=l.y+v*g,r=s.length;s.push({x:e,y:o}),i.has(t)||i.set(t,[]),i.get(t).push({t:v,idx:r}),i.has(n)||i.set(n,[]),i.get(n).push({t:b,idx:r})}}if(0===i.size)return{pts:t,constraintEdges:e,hadCrossings:!1};const r=[];for(let t=0;t<e.length;t++){const n=i.get(t);if(!n||0===n.length){r.push(e[t]);continue}n.sort((t,e)=>t.t-e.t);const[o,s]=e[t];let a=o;for(const t of n)r.push([a,t.idx]),a=t.idx;r.push([a,s])}return{pts:s,constraintEdges:r,hadCrossings:!0}})(a,c,h);return{pts:x.pts.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)})),constraintEdges:x.constraintEdges,hadCrossings:x.hadCrossings}},Oc=class extends xc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=this.input.polygons??[];if(!1!==this.input.useConstrainedDelaunay){const o=Rc({bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n,viaSegments:this.input.viaSegments});this.output={pts:o.pts,constraintEdges:o.constraintEdges,hadCrossings:o.hadCrossings}}else this.output={pts:Cc({bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n,viaSegments:this.input.viaSegments})};this.stats={points:this.output.pts.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=(this.output?.pts??[]).map(t=>({x:t.x,y:t.y,color:"#2563eb"}));return{points:t,lines:[],rects:[],circles:(this.input.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2+this.input.clearance,stroke:"#ef4444"})),texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`sample points: ${t.length}`,color:"#1f2937"}]}}},Ac=t=>{const{p:e,a:n,b:o}=t,i=o.x-n.x,s=o.y-n.y,r=i*i+s*s;if(r<1e-10)return Math.hypot(e.x-n.x,e.y-n.y);let a=((e.x-n.x)*i+(e.y-n.y)*s)/r;return a=Math.max(0,Math.min(1,a)),Math.hypot(e.x-n.x-a*i,e.y-n.y-a*s)},zc=(t,e)=>{if(t.length<=3)return 0;const n=Sc(t,e),o=new Set(n),i=n.map(t=>e[t]).filter(t=>Boolean(t));let s=0;for(const n of t){if(o.has(n))continue;const t=e[n];if(!t)continue;let r=Number.POSITIVE_INFINITY;for(let e=0;e<i.length;e++){const n=i[e],o=i[(e+1)%i.length];n&&o&&(r=Math.min(r,Ac({p:t,a:n,b:o})))}s=Math.max(s,r)}return s},Dc=(t,e)=>t<e?1e5*t+e:1e5*e+t,Lc=(t,e)=>{const n=t.map((e,n)=>[e,t[(n+1)%t.length]]),o=e.map((t,n)=>[t,e[(n+1)%e.length]]),i=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,s]of o)void 0!==s&&t===s&&e===n&&i.add(Dc(t,e));if(0===i.size)return null;const s=[];for(const[t,e]of n)void 0!==e&&(i.has(Dc(t,e))||s.push([t,e]));for(const[t,e]of o)void 0!==e&&(i.has(Dc(t,e))||s.push([t,e]));if(0===s.length)return null;const r=new Map;for(const[t,e]of s)r.set(t,e);const a=s[0]?.[0];if(void 0===a)return null;const c=[a];let h=r.get(a),l=0;for(;void 0!==h&&h!==a&&l++<s.length+5;)c.push(h),h=r.get(h);return h!==a||c.length!==s.length?null:c},Yc=(t,e)=>t<e?1e5*t+e:1e5*e+t,Xc=(t,e)=>t<e?1e5*t+e:1e5*e+t,Fc=class extends xc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=!1!==this.input.usePolyanyaMerge?(t=>{const{triangles:e,pts:n}=t;if(!e.length)return{cells:[],depths:[]};const o=e.length,i=e.map(([t,e,o])=>{const i=n[t],s=n[e],r=n[o];return i&&s&&r&&Pc({o:i,a:s,b:r})<0?[t,o,e]:[t,e,o]}),s=new Array(o).fill(null);for(let t=0;t<o;t++)s[t]=new Map;function r(){for(let t=0;t<s.length;t++)s[t]&&s[t].clear();const t=new Map;for(let e=0;e<i.length;e++){const n=i[e];if(n)for(let o=0;o<n.length;o++){const i=n[o],r=n[(o+1)%n.length],a=Xc(i,r),c=t.get(a);c?(s[e].set(o,{neighbor:c.cellIdx,neighborEdge:c.edgePos}),s[c.cellIdx].set(c.edgePos,{neighbor:e,neighborEdge:o})):t.set(a,{cellIdx:e,edgePos:o})}}}function a(t){let e=0;for(let o=0;o<t.length;o++){const i=n[t[o]],s=n[t[(o+1)%t.length]];e+=i.x*s.y-s.x*i.y}return Math.abs(e)/2}function c(t,e){const n=i[t],o=s[t],r=n.length;let a=-1;for(const[t,n]of o)if(n.neighbor===e){a=t;break}if(-1===a)return null;let c=a;for(;;){const t=(c-1+r)%r;if(t===a)break;const n=o.get(t);if(!n||n.neighbor!==e)break;c=t}let h=a;for(;;){const t=(h+1)%r;if(t===c)break;const n=o.get(t);if(!n||n.neighbor!==e)break;h=t}return{firstK:c,lastK:h,sharedCount:(h-c+r)%r+1}}function h(t,e){const o=i[t],s=i[e],r=c(t,e);if(!r)return!1;const{firstK:a,lastK:h,sharedCount:l}=r,d=o.length,u=s.length,p=o[a],f=o[(h+1)%d];let g=-1;for(let t=0;t<u;t++)if(s[t]===p){g=t;break}if(-1===g)return!1;const m=(g-l+u)%u;if(s[m]!==f)return!1;const y=n[o[(a-1+d)%d]],x=n[p],v=n[s[(g+1)%u]];if(Pc({o:y,a:x,b:v})<-1e-8)return!1;const b=n[s[(m-1+u)%u]],P=n[f],S=n[o[(h+2)%d]];return!(Pc({o:b,a:P,b:S})<-1e-8)}function l(t,e){const n=i[t],o=i[e],s=c(t,e),{firstK:r,lastK:a,sharedCount:h}=s,l=n.length,d=o.length,u=n[r],p=n[(a+1)%l];let f=-1;for(let t=0;t<d;t++)if(o[t]===u){f=t;break}const g=[];g.push(u);const m=d-h-1;for(let t=1;t<=m;t++)g.push(o[(f+t)%d]);g.push(p);const y=l-h-1;for(let t=2;t<=y+1;t++)g.push(n[(a+t)%l]);i[t]=g,i[e]=null}r();let d=!0;for(;d;){d=!1,r();for(let t=0;t<i.length;t++){if(!i[t])continue;const e=s[t],n=new Set;for(const[,t]of e)i[t.neighbor]&&n.add(t.neighbor);if(1===n.size){const e=n.values().next().value;h(t,e)&&(l(t,e),d=!0)}}}r();const u=new Array(i.length).fill(0);for(let t=0;t<i.length;t++)i[t]&&(u[t]=a(i[t]));const p=[];function f(t){p.push(t);let e=p.length-1;for(;e>0;){const t=e-1>>1;if(p[t].area>=p[e].area)break;const n=p[t];p[t]=p[e],p[e]=n,e=t}}function g(){if(0===p.length)return;const t=p[0],e=p.pop();if(p.length>0){p[0]=e;let t=0;for(;;){let e=t;const n=2*t+1,o=2*t+2;if(n<p.length&&p[n].area>p[e].area&&(e=n),o<p.length&&p[o].area>p[e].area&&(e=o),e===t)break;const i=p[t];p[t]=p[e],p[e]=i,t=e}}return t}const m=new Set;for(let t=0;t<i.length;t++){if(!i[t])continue;const e=s[t],n=new Set;for(const[,t]of e)i[t.neighbor]&&n.add(t.neighbor);for(const e of n){const n=t<e?1e5*t+e:1e5*e+t;m.has(n)||(m.add(n),h(t,e)&&f({area:u[t]+u[e],xIdx:t,yIdx:e}))}}for(;p.length>0;){const t=g(),{xIdx:e,yIdx:n}=t;if(!i[e]||!i[n])continue;const o=u[e]+u[n];if(Math.abs(o-t.area)>1e-10){h(e,n)&&f({area:o,xIdx:e,yIdx:n});continue}if(!h(e,n))continue;l(e,n),u[e]=a(i[e]),r();const c=s[e],d=new Set;for(const[,t]of c)i[t.neighbor]&&d.add(t.neighbor);for(const t of d)h(e,t)&&f({area:u[e]+u[t],xIdx:e,yIdx:t})}const y=i.filter(t=>null!==t),x=y.map(()=>0);return{cells:y,depths:x}})({triangles:this.input.validTris,pts:this.input.pts}):(t=>{const{triangles:e,pts:n,concavityTolerance:o}=t;if(!e.length)return{cells:[],depths:[]};const i=e.map(([t,e,o])=>{const i=n[t],s=n[e],r=n[o];return i&&s&&r&&Pc({o:i,a:s,b:r})<0?[t,o,e]:[t,e,o]});let s=!0,r=0;for(;s&&r++<800;){s=!1;const t=new Map,e=i.map(()=>new Set);for(let n=0;n<i.length;n++){const o=i[n];if(o)for(let i=0;i<o.length;i++){const s=o[i],r=o[(i+1)%o.length];if(void 0===s||void 0===r)continue;const a=Yc(s,r);if(t.has(a)){const o=t.get(a);void 0!==o&&(e[n]?.add(o),e[o]?.add(n))}else t.set(a,n)}}let r=-1,a=-1,c=null,h=Number.POSITIVE_INFINITY;for(let t=0;t<i.length;t++){const s=e[t];if(s)for(const e of s){if(e<=t)continue;const s=Lc(i[t]??[],i[e]??[]);if(!s)continue;const l=zc(s,n);l<=o+1e-6&&l<h&&(h=l,r=t,a=e,c=s)}}if(r<0||a<0||!c)break;i[r]=c,i.splice(a,1),s=!0}const a=i.map(t=>zc(t,n));return{cells:i,depths:a}})({triangles:this.input.validTris,pts:this.input.pts,concavityTolerance:this.input.concavityTolerance});this.output={pts:this.input.pts,bounds:this.input.bounds,validTris:this.input.validTris,cells:t.cells,depths:t.depths},this.stats={mergedCells:t.cells.length,maxDepth:t.depths.length?Math.max(...t.depths):0},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.cells??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.flatMap(t=>t.flatMap((e,n)=>{const o=this.input.pts[e],i=t[(n+1)%t.length],s=void 0===i?void 0:this.input.pts[i];return o&&s?[{points:[o,s],strokeColor:"#10b981"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`merged cells: ${t.length}`,color:"#1f2937"}]}}},kc=t=>{const{a:e,b:n,c:o}=t,i=2*(e.x*(n.y-o.y)+n.x*(o.y-e.y)+o.x*(e.y-n.y));if(Math.abs(i)<1e-10)return{x:0,y:0,r2:1e18};const s=e.x*e.x+e.y*e.y,r=n.x*n.x+n.y*n.y,a=o.x*o.x+o.y*o.y,c=(s*(n.y-o.y)+r*(o.y-e.y)+a*(e.y-n.y))/i,h=(s*(o.x-n.x)+r*(e.x-o.x)+a*(n.x-e.x))/i;return{x:c,y:h,r2:(e.x-c)**2+(e.y-h)**2}},$c=(t,e,n)=>[t.a,t.b,t.c].includes(e)&&[t.a,t.b,t.c].includes(n),Bc=t=>{const{px:e,py:n,polygonPoints:o,clearance:i}=t;if(o.length<3)return!1;const s=o.map(t=>_a(t.x,t.y)),r=[];for(let t=0;t<s.length;t++){const e=s[t],n=s[(t+1)%s.length];r.push(Ca(e,n))}const a=new Ra;a.addFace(r);const c=_a(e,n);if(a.contains(c))return!0;const[h]=a.distanceTo(c);return h<i-.1},jc=t=>{const{triangles:e,pts:n,bounds:o,vias:i,clearance:s,rects:r,polygons:a}=t;return e.filter(([t,e,c])=>{const h=n[t],l=n[e],d=n[c];if(!h||!l||!d)return!1;if(!(t=>{const{px:e,py:n,bounds:o,vias:i,clearance:s,rects:r,polygons:a}=t,{minX:c,maxX:h,minY:l,maxY:d}=o,u=1e-6*Math.max(h-c,d-l,1);if(e<c-u||e>h+u||n<l-u||n>d+u)return!1;for(const t of i){const o=t.diameter/2+s,i=Math.max(0,o-u);if((e-t.center.x)**2+(n-t.center.y)**2<i*i)return!1}for(const t of r){const o=t.width/2+s,i=t.height/2+s,r=Math.max(0,o-u),a=Math.max(0,i-u),c=e-t.center.x,h=n-t.center.y,l=Math.cos(t.ccwRotation),d=Math.sin(t.ccwRotation),p=c*l+h*d,f=-c*d+h*l;if(Math.abs(p)<r&&Math.abs(f)<a)return!1}for(const t of a)if(Bc({px:e,py:n,polygonPoints:t.points,clearance:s}))return!1;return!0})({px:(h.x+l.x+d.x)/3,py:(h.y+l.y+d.y)/3,bounds:o,vias:i,clearance:s,rects:r,polygons:a}))return!1;if(a.length>0){const t=[h,l,d,{x:(h.x+l.x)/2,y:(h.y+l.y)/2},{x:(l.x+d.x)/2,y:(l.y+d.y)/2},{x:(d.x+h.x)/2,y:(d.y+h.y)/2}];for(const e of t)for(const t of a)if(Bc({px:e.x,py:e.y,polygonPoints:t.points,clearance:s}))return!1}return!0})},Wc=class extends xc{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=this.input.polygons??[];let o;if(!1!==this.input.useConstrainedDelaunay&&this.input.constraintEdges){const i=((t,e)=>{const n=t.map(t=>[t.x,t.y]);return(0,Ja.default)(n,e,{exterior:!1})})(this.input.pts,this.input.constraintEdges);o=t.length>0||e.length>0||n.length>0?jc({triangles:i,pts:this.input.pts,bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n}):i}else{const i=(t=>{const e=t.map((t,e)=>({...t,i:e}));if(e.length<3)return[];let n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,s=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),o=Math.min(o,t.y),i=Math.max(i,t.x),s=Math.max(s,t.y);const r=Math.max(i-n,s-o)||1,a=(n+i)/2,c=(o+s)/2,h={x:a-30*r,y:c-r,i:-1},l={x:a,y:c+30*r,i:-2},d={x:a+30*r,y:c-r,i:-3};let u=[{a:h,b:l,c:d,cc:kc({a:h,b:l,c:d})}];for(const t of e){const e=u.filter(e=>{const n=t.x-e.cc.x,o=t.y-e.cc.y;return n*n+o*o<e.cc.r2+1e-6}),n=new Set(e),o=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[i,s]of n){let n=!1;for(const o of e)if(o!==t&&$c(o,i,s)){n=!0;break}n||o.push([i,s])}}u=u.filter(t=>!n.has(t));for(const[e,n]of o)u.push({a:e,b:n,c:t,cc:kc({a:e,b:n,c:t})})}return u.filter(t=>t.a.i>=0&&t.b.i>=0&&t.c.i>=0).map(t=>[t.a.i,t.b.i,t.c.i])})(this.input.pts);o=jc({triangles:i,pts:this.input.pts,bounds:this.input.bounds,vias:t,clearance:this.input.clearance,rects:e,polygons:n})}this.output={pts:this.input.pts,bounds:this.input.bounds,validTris:o},this.stats={validTriangles:o.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.validTris??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#2563eb"})),lines:t.flatMap(([t,e,n])=>{const o=this.input.pts[t],i=this.input.pts[e],s=this.input.pts[n];return o&&i&&s?[{points:[o,i],strokeColor:"#64748b"},{points:[i,s],strokeColor:"#64748b"},{points:[s,o],strokeColor:"#64748b"}]:[]}),rects:[],circles:[],texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`valid triangles: ${t.length}`,color:"#1f2937"}]}}},Vc=class extends bc{pipelineDef=[vc("generatePoints",Oc,t=>[t.inputProblem]),vc("triangulate",Wc,t=>{const e=t.getStageOutput("generatePoints");if(!e)throw new Error("generatePoints output missing");return[{pts:e.pts,bounds:t.inputProblem.bounds,vias:t.inputProblem.vias,rects:t.inputProblem.rects,polygons:t.inputProblem.polygons,clearance:t.inputProblem.clearance,useConstrainedDelaunay:t.inputProblem.useConstrainedDelaunay,constraintEdges:e.constraintEdges,hadCrossings:e.hadCrossings}]}),vc("mergeCells",Fc,t=>{const e=t.getStageOutput("triangulate");if(!e)throw new Error("triangulate output missing");return[{pts:e.pts,bounds:e.bounds,validTris:e.validTris,concavityTolerance:t.inputProblem.concavityTolerance,usePolyanyaMerge:t.inputProblem.usePolyanyaMerge}]}),vc("buildRegions",Mc,t=>{const e=t.getStageOutput("mergeCells");if(!e)throw new Error("mergeCells output missing");return[e]})];getConstructorParams(){return[this.inputProblem]}getOutput(){return this.getStageOutput("buildRegions")??null}visualize(){const t=this.getOutput();if(!t)return{points:[],lines:[],rects:[],circles:[],texts:[]};const e=this.inputProblem.bounds.maxX-this.inputProblem.bounds.minX,n=this.inputProblem.bounds.maxY-this.inputProblem.bounds.minY,o=Math.max(e,n,Number.EPSILON),i=Math.max(1,400/o),s=-this.inputProblem.bounds.minX*i,r=-this.inputProblem.bounds.minY*i,a=t=>({x:t.x*i+s,y:t.y*i+r}),c=(this.inputProblem.polygons??[]).flatMap(t=>{const e=t.points;return e.map((t,n)=>{const o=e[(n+1)%e.length];return{points:[a(t),a(o)],strokeColor:"#ff9f43",strokeWidth:2}})}),h=(this.inputProblem.rects??[]).flatMap(t=>{const e=t.width/2,n=t.height/2,o=Math.cos(t.ccwRotation),i=Math.sin(t.ccwRotation),s=[{lx:-e,ly:-n},{lx:e,ly:-n},{lx:e,ly:n},{lx:-e,ly:n}].map(({lx:e,ly:n})=>({x:t.center.x+e*o-n*i,y:t.center.y+e*i+n*o}));return s.map((t,e)=>{const n=s[(e+1)%s.length];return{points:[a(t),a(n)],strokeColor:"#ff6b6b",strokeWidth:2}})});return{points:t.pts.map(t=>({...a(t),color:"#38b6ff"})),lines:[...t.regions.flatMap(t=>t.map((e,n)=>{const o=t[(n+1)%t.length]??e;return{points:[a(e),a(o)],strokeColor:"#4ecb82"}})),...c,...h],rects:[],circles:(this.inputProblem.vias??[]).map(t=>({center:a(t.center),radius:t.diameter/2*i,stroke:"#ff6b6b"})),texts:[{x:8,y:16,text:`regions=${t.regions.length}`,color:"#ffffff"}]}}};function Hc(t,e,n,o,i){const s=e.x-t.x,r=e.y-t.y,a=o.x-n.x,c=o.y-n.y,h=s*c-r*a,l=Math.sqrt(s*s+r*r),d=Math.sqrt(a*a+c*c);if(l<i||d<i)return!1;if(Math.abs(h)/(l*d)>i)return!1;const u=n.x-t.x,p=n.y-t.y;return Math.abs(s*p-r*u)/l<i}function Uc(t,e,n){const o=n.x-e.x,i=n.y-e.y,s=o*o+i*i;if(s<1e-12){return{t:0,distance:Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2)}}const r=((t.x-e.x)*o+(t.y-e.y)*i)/s,a=e.x+r*o,c=e.y+r*i;return{t:r,distance:Math.sqrt((t.x-a)**2+(t.y-c)**2)}}function Gc(t,e,n,o){const i=Math.min(t,e),s=Math.max(t,e),r=Math.min(n,o),a=Math.max(n,o),c=Math.max(i,r),h=Math.min(s,a);return h-c<1e-6?null:{from:c,to:h}}function Zc(t,e,n=.01){const o=[];for(let i=0;i<t.length;i++){const s=t[i],r=t[(i+1)%t.length];for(let t=0;t<e.length;t++){const i=e[t],a=e[(t+1)%e.length];if(!Hc(s,r,i,a,n))continue;const c=Uc(i,s,r),h=Uc(a,s,r);if(c.distance>n||h.distance>n)continue;const l=Gc(0,1,c.t,h.t);if(!l)continue;const d=r.x-s.x,u=r.y-s.y,p={x:s.x+l.from*d,y:s.y+l.from*u},f={x:s.x+l.to*d,y:s.y+l.to*u};o.push({from:p,to:f})}}return o}function qc(t,e=.4){const n=t.to.x-t.from.x,o=t.to.y-t.from.y,i=Math.sqrt(n*n+o*o);if(i<.001)return[];const s=Math.max(1,Math.floor(i/e)),r=[];for(let e=0;e<s;e++){const i=(e+.5)/s;r.push({x:t.from.x+i*n,y:t.from.y+i*o})}return r}function Jc(t,e=.001){if(t.length<=1)return t;const n=[t[0]];for(let o=1;o<t.length;o++){const i=n[n.length-1],s=t[o];Math.sqrt((s.x-i.x)**2+(s.y-i.y)**2)>e&&n.push(s)}if(n.length>1){const t=n[0],o=n[n.length-1];Math.sqrt((o.x-t.x)**2+(o.y-t.y)**2)<e&&n.pop()}return n}function Kc(t){let e=1/0,n=-1/0,o=1/0,i=-1/0;for(const s of t)s.x<e&&(e=s.x),s.x>n&&(n=s.x),s.y<o&&(o=s.y),s.y>i&&(i=s.y);return{minX:e,maxX:n,minY:o,maxY:i}}function Qc(t){let e=0,n=0;for(const o of t)e+=o.x,n+=o.y;return{x:e/t.length,y:n/t.length}}function th(t,e,n){return{regionId:t,ports:[],d:{bounds:Kc(e),center:Qc(e),polygon:e,isPad:!1,isViaRegion:n?.isViaRegion}}}function eh(t){if(0===t.length)return[];const e=t.reduce((t,e)=>e.position.y>t.position.y?e:t),n=t.reduce((t,e)=>e.position.y<t.position.y?e:t),o=t.reduce((t,e)=>e.position.x<t.position.x?e:t),i=t.reduce((t,e)=>e.position.x>t.position.x?e:t),s={xStart:e.position.x-e.diameter/2,xEnd:e.position.x+e.diameter/2,y:e.position.y+e.diameter/2},r={xStart:n.position.x-n.diameter/2,xEnd:n.position.x+n.diameter/2,y:n.position.y-n.diameter/2},a={x:o.position.x-o.diameter/2,yStart:o.position.y-o.diameter/2,yEnd:o.position.y+o.diameter/2},c={x:i.position.x+i.diameter/2,yStart:i.position.y-i.diameter/2,yEnd:i.position.y+i.diameter/2};return Jc([{x:s.xStart,y:s.y},{x:s.xEnd,y:s.y},{x:c.x,y:c.yEnd},{x:c.x,y:c.yStart},{x:r.xEnd,y:r.y},{x:r.xStart,y:r.y},{x:a.x,y:a.yStart},{x:a.x,y:a.yEnd}])}function nh(t,e,n,o){return t.map(t=>({viaId:`${o}:${t.viaId}`,diameter:t.diameter,position:{x:t.position.x+e,y:t.position.y+n}}))}function oh(t,e,n,o){return t.map(t=>({routeId:`${o}:${t.routeId}`,fromPort:`${o}:${t.fromPort}`,toPort:`${o}:${t.toPort}`,layer:t.layer,segments:t.segments.map(t=>({x:t.x+e,y:t.y+n}))}))}function ih(t){const e=t.lastIndexOf(":v:");return-1===e?null:t.slice(e+3)}function sh(t,e){const n=t.indexOf(":");return-1===n?`${e}:${t}`:`${e}${t.slice(n)}`}function rh(t,e,n){return t.map(t=>({x:t.x+e,y:t.y+n}))}function ah(t){return[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}]}function ch(t){if(t.length<3)return{top:null,bottom:null,left:null,right:null};const e=Kc(t),n=.001;let o=null,i=null,s=null,r=null;for(let a=0;a<t.length;a++){const c=t[a],h=t[(a+1)%t.length];Math.abs(c.y-e.maxY)<n&&Math.abs(h.y-e.maxY)<n&&(o={x:(c.x+h.x)/2,y:e.maxY}),Math.abs(c.y-e.minY)<n&&Math.abs(h.y-e.minY)<n&&(i={x:(c.x+h.x)/2,y:e.minY}),Math.abs(c.x-e.minX)<n&&Math.abs(h.x-e.minX)<n&&(s={x:e.minX,y:(c.y+h.y)/2}),Math.abs(c.x-e.maxX)<n&&Math.abs(h.x-e.maxX)<n&&(r={x:e.maxX,y:(c.y+h.y)/2})}return{top:o,bottom:i,left:s,right:r}}function hh(t,e,n=.1){if(0===t.length)return t;const o=Kc(t),i=o.minX-e.minX,s=e.maxX-o.maxX,r=o.minY-e.minY,a=e.maxY-o.maxY,c=i>0&&i<n,h=s>0&&s<n,l=r>0&&r<n,d=a>0&&a<n;if(!(c||h||l||d))return t;return Jc(t.map(t=>{let n=t.x,i=t.y;return c&&Math.abs(t.x-o.minX)<.001&&(n=e.minX),h&&Math.abs(t.x-o.maxX)<.001&&(n=e.maxX),l&&Math.abs(t.y-o.minY)<.001&&(i=e.minY),d&&Math.abs(t.y-o.maxY)<.001&&(i=e.maxY),{x:n,y:i}}))}function lh(t,e){let n=!1;const o=e.length;for(let i=0,s=o-1;i<o;s=i++){const o=e[i].x,r=e[i].y,a=e[s].x,c=e[s].y;if(Math.abs((t.y-r)*(a-o)-(t.x-o)*(c-r))<.001&&t.x>=Math.min(o,a)-.001&&t.x<=Math.max(o,a)+.001&&t.y>=Math.min(r,c)-.001&&t.y<=Math.max(r,c)+.001)return!0;if(r>t.y!=c>t.y){const e=(a-o)*(t.y-r)/(c-r)+o;t.x<e&&(n=!n)}}return n}function dh(t,e){for(const n of e)if(n.d.polygon&&lh(t,n.d.polygon))return n;return null}function uh(t,e,n){const o=t.regions.filter(t=>t.polygon.length>=3),i=new Map(o.map(t=>[t.regionId,t])),s=o.filter(t=>t.isViaRegion).map(t=>({templateRegionId:t.regionId,netName:t.netName??ih(t.regionId)??"unknown",polygon:t.polygon,bounds:t.bounds,center:t.center})),r=o.filter(t=>!t.isViaRegion).map(t=>({templateRegionId:t.regionId,polygon:t.polygon,bounds:t.bounds,center:t.center}));let a=[];if(function(t){return Array.isArray(t.ports)}(t)){const e=[];for(const n of t.ports){const t=i.get(n.region1Id),o=i.get(n.region2Id);if(!t||!o)throw new Error(`Baked via tile port ${n.portId} references missing regions (${n.region1Id}, ${n.region2Id}).`);t.isViaRegion||o.isViaRegion||e.push({templatePortId:n.portId,templateRegion1Id:n.region1Id,templateRegion2Id:n.region2Id,position:n.position})}a=e}return{viaRegions:s,convexRegions:r,internalPorts:a,tileWidth:e,tileHeight:n}}function ph(t){const e=t.tileWidth??t.tileSize??t.viaTile.tileWidth,n=t.tileHeight??t.tileSize??t.viaTile.tileHeight;if(void 0===e||void 0===n)throw new Error("tileWidth and tileHeight must be provided either in opts or in viaTile");const o=t.portPitch??.4,i=t.clearance??.1,s=t.concavityTolerance??0,{bounds:r,viaTile:a}=t,{viasByNet:c,routeSegments:h}=a,l=r.maxX-r.minX,d=r.maxY-r.minY,u=Math.floor(l/e),p=Math.floor(d/n),f=[],g=[],m={viasByNet:{},routeSegments:[]},y=[],x=[],v=u*e,b=p*n,P=r.minX+(l-v)/2,S=r.minY+(d-b)/2,I=P+v,M=S+b,_=e/2,N=n/2;let C=0;const T=new Set,E=(t,e,n,o)=>{const i=(s=o.x,r=o.y,`${s.toFixed(4)},${r.toFixed(4)}`);var s,r;if(T.has(i))return null;T.add(i);const a={portId:t,region1:e,region2:n,d:{x:o.x,y:o.y}};return e.ports.push(a),n.ports.push(a),g.push(a),a};let w=null;p>0&&u>0&&(w=function(t){return"regions"in t&&Array.isArray(t.regions)}(a)?uh(a,e,n):function(t,e,n,o,i){const s=e/2,r=n/2,a={minX:-s,maxX:s,minY:-r,maxY:r},c=[];for(const[e,n]of Object.entries(t.viasByNet)){if(0===n.length)continue;const t=eh(n);0!==t.length&&c.push({templateRegionId:`t0_0:v:${e}`,netName:e,polygon:t,bounds:Kc(t),center:Qc(t)})}const h=c.map(t=>({points:hh(t.polygon,a)})),l=new Vc({bounds:a,polygons:h,clearance:o,concavityTolerance:i});l.solve();const d=l.getOutput();if(!d)throw new Error("ConvexRegionsSolver failed to compute unit tile regions");return{viaRegions:c,convexRegions:d.regions.map((t,e)=>({templateRegionId:`t0_0:convex:${e}`,polygon:t,bounds:Kc(t),center:Qc(t)})),internalPorts:[],tileWidth:e,tileHeight:n}}(a,e,n,i,s));const R=Boolean(w&&w.internalPorts.length>0);if(p>0&&u>0&&w)for(let t=0;t<p;t++)for(let o=0;o<u;o++){const i=P+o*e+_,s=S+t*n+N,r=`t${t}_${o}`,a=new Map;for(const t of w.viaRegions){const e=rh(t.polygon,i,s),n=th(sh(t.templateRegionId,r),e,{isViaRegion:!0});y.push(n),f.push(n),a.set(t.templateRegionId,n)}for(const t of w.convexRegions){const e=rh(t.polygon,i,s),n=th(sh(t.templateRegionId,r),e);x.push(n),f.push(n),a.set(t.templateRegionId,n)}if(R)for(const t of w.internalPorts){const e=a.get(t.templateRegion1Id),n=a.get(t.templateRegion2Id);if(!e||!n)throw new Error(`Missing region for baked port template ${t.templatePortId} in tile ${r}.`);E(`${r}:baked:${t.templatePortId}:${C++}`,e,n,{x:t.position.x+i,y:t.position.y+s})}for(const[t,e]of Object.entries(c)){if(0===e.length)continue;const n=nh(e,i,s,r);m.viasByNet[t]||(m.viasByNet[t]=[]),m.viasByNet[t].push(...n)}m.routeSegments.push(...oh(h,i,s,r))}const O=[],A=r.maxY-M,z=S-r.minY,D=P-r.minX,L=r.maxX-I,Y=Math.max(A,z)>=Math.max(D,L),X=Y?r.minX:P,F=Y?r.maxX:I,k=Y?r.minX:P,$=Y?r.maxX:I,B=Y?S:r.minY,j=Y?M:r.maxY,W=Y?S:r.minY,V=Y?M:r.maxY;if(A>.001){const t=F-X,e=Math.max(A,o),n=Math.max(1,Math.floor(t/e)),i=t/n;for(let t=0;t<n;t++){const e=th(`filler:top:${t}`,ah({minX:X+t*i,maxX:X+(t+1)*i,minY:M,maxY:r.maxY}));O.push(e),f.push(e)}}if(z>.001){const t=$-k,e=Math.max(z,o),n=Math.max(1,Math.floor(t/e)),i=t/n;for(let t=0;t<n;t++){const e=th(`filler:bottom:${t}`,ah({minX:k+t*i,maxX:k+(t+1)*i,minY:r.minY,maxY:S}));O.push(e),f.push(e)}}if(D>.001){const t=j-B,e=Math.max(D,o),n=Math.max(1,Math.floor(t/e)),i=t/n;for(let t=0;t<n;t++){const e=th(`filler:left:${t}`,ah({minX:r.minX,maxX:P,minY:B+t*i,maxY:B+(t+1)*i}));O.push(e),f.push(e)}}if(L>.001){const t=V-W,e=Math.max(L,o),n=Math.max(1,Math.floor(t/e)),i=t/n;for(let t=0;t<n;t++){const e=th(`filler:right:${t}`,ah({minX:I,maxX:r.maxX,minY:W+t*i,maxY:W+(t+1)*i}));O.push(e),f.push(e)}}if(w&&p>0&&u>0&&!R){const t=w.convexRegions.length;for(let e=0;e<p;e++)for(let n=0;n<u;n++){const s=(e*u+n)*t;for(let r=0;r<t;r++)for(let a=r+1;a<t;a++){const t=x[s+r],c=x[s+a],h=Zc(t.d.polygon,c.d.polygon,2*i);for(const i of h){const s=qc(i,o);for(const o of s)E(`t${e}_${n}:convex:${r}-${a}:${C++}`,t,c,o)}}}}if(w&&p>0&&u>0){const t=w.convexRegions.length,i=w.viaRegions.length,s=Math.floor(n/o),r=[];for(let t=0;t<s;t++)r.push((t+.5)*o-N);const a=Math.floor(e/o),c=[];for(let t=0;t<a;t++)c.push((t+.5)*o-_);for(let o=0;o<p;o++)for(let s=0;s<u;s++){const a=o*u+s,h=a*t,l=a*i,d=P+s*e+_,f=S+o*n+N,g=[...x.slice(h,h+t),...y.slice(l,l+i)];if(s+1<u){const e=o*u+(s+1),n=e*t,a=e*i,c=[...x.slice(n,n+t),...y.slice(a,a+i)],h=d+_;for(const t of r){const e=f+t,n={x:h+.01,y:e},i=dh({x:h-.01,y:e},g),r=dh(n,c);i&&r&&E(`tile:${o}_${s}-${o}_${s+1}:${C++}`,i,r,{x:h,y:e})}}if(o+1<p){const e=(o+1)*u+s,n=e*t,r=e*i,a=[...x.slice(n,n+t),...y.slice(r,r+i)],h=f+N;for(const t of c){const e=d+t,n={x:e,y:h+.01},i=dh({x:e,y:h-.01},g),r=dh(n,a);i&&r&&E(`tile:${o}_${s}-${o+1}_${s}:${C++}`,i,r,{x:e,y:h})}}}}const H=new Map;for(const t of O){H.set(t.regionId,[]);const e=t.d.bounds,n=e.maxX-e.minX,s=e.maxY-e.minY,r=n>s,a=r?n:s,c=(Math.max(1,Math.floor(a/o)),2*i),h=t.regionId.startsWith("filler:top:"),l=t.regionId.startsWith("filler:bottom:"),d=t.regionId.startsWith("filler:left:"),u=t.regionId.startsWith("filler:right:"),p=[...x,...y];for(const n of p){const i=n.d.bounds,s=.001;let a,p,f=!1,g=null,m=null;if(r){const t=Math.max(e.minX,i.minX);Math.min(e.maxX,i.maxX)>t+s&&(h?(f=Math.abs(i.maxY-e.minY)<c,m=e.minY):l&&(f=Math.abs(i.minY-e.maxY)<c,m=e.maxY))}else{const t=Math.max(e.minY,i.minY);Math.min(e.maxY,i.maxY)>t+s&&(d?(f=Math.abs(i.minX-e.maxX)<c,g=e.maxX):u&&(f=Math.abs(i.maxX-e.minX)<c,g=e.minX))}if(!f)continue;r?(a=Math.max(e.minX,i.minX),p=Math.min(e.maxX,i.maxX)):(a=Math.max(e.minY,i.minY),p=Math.min(e.maxY,i.maxY));const y=p-a;if(y<s)continue;const x=Math.max(1,Math.floor(y/o)),v=y/x;for(let s=0;s<x;s++){let c;if(r){c={x:a+(s+.5)*v,y:m}}else{c={x:g,y:a+(s+.5)*v}}if(n.d.polygon){let t;if(h){const n=e.minY-i.maxY+.01;t={x:c.x,y:c.y-n}}else if(l){const n=i.minY-e.maxY+.01;t={x:c.x,y:c.y+n}}else if(d){const n=i.minX-e.maxX+.01;t={x:c.x+n,y:c.y}}else{const n=e.minX-i.maxX+.01;t={x:c.x-n,y:c.y}}if(!lh(t,n.d.polygon))continue}const u=H.get(t.regionId);u.some(t=>Math.sqrt((c.x-t.x)**2+(c.y-t.y)**2)<o)||(u.push(c),E(`filler:${n.regionId}-${t.regionId}:${C++}`,n,t,c))}}}for(let t=0;t<O.length;t++)for(let e=t+1;e<O.length;e++){const n=O[t],i=O[e],s=Zc(n.d.polygon,i.d.polygon,.01);for(const t of s){const e=Math.sqrt((t.to.x-t.from.x)**2+(t.to.y-t.from.y)**2);if(e<.01)continue;let s;s=e<o?[{x:(t.from.x+t.to.x)/2,y:(t.from.y+t.to.y)/2}]:qc(t,o);for(const t of s)E(`filler:${n.regionId}-${i.regionId}:${C++}`,n,i,t)}}const U=f.filter(t=>!t.d.isViaRegion),G=new Set;for(const t of y){const e=ch(t.d.polygon),n=t.d.bounds,o=["top","bottom","left","right"];for(const i of o){const o=e[i];if(!o)continue;const s=`${t.regionId}:${i}`;if(G.has(s))continue;const r=.2,a=r;let c;switch(i){case"top":c={x:o.x,y:n.maxY+a};break;case"bottom":c={x:o.x,y:n.minY-a};break;case"left":c={x:n.minX-a,y:o.y};break;case"right":c={x:n.maxX+a,y:o.y}}for(const e of U){const a=e.d.bounds;let h=!1;switch(i){case"top":h=Math.abs(a.minY-n.maxY)<r&&a.minX<o.x&&a.maxX>o.x;break;case"bottom":h=Math.abs(a.maxY-n.minY)<r&&a.minX<o.x&&a.maxX>o.x;break;case"left":h=Math.abs(a.maxX-n.minX)<r&&a.minY<o.y&&a.maxY>o.y;break;case"right":h=Math.abs(a.minX-n.maxX)<r&&a.minY<o.y&&a.maxY>o.y}if(h&&(e.d.polygon&&lh(c,e.d.polygon))){E(`via-side:${t.regionId}:${i}:${C++}`,t,e,o),G.add(s);break}}}}return{regions:f,ports:g,viaTile:m,tileCount:{rows:p,cols:u}}}var fh={viasByNet:{net1:[{viaId:"14ee4bf1-e7e7-4351-ad16-ba1a8aac0af3",diameter:.3,position:{x:.815244,y:-.055081}},{viaId:"8a898812-db2b-4b81-899d-f953b3222f9a",diameter:.3,position:{x:-.528763,y:.676055}}],net3:[{viaId:"13cd75da-d582-4eed-bc2c-fee6fa78bc6a",diameter:.3,position:{x:-.808222,y:-.726499}},{viaId:"9f188f9d-bce8-46c7-b9e8-542b8599d48d",diameter:.3,position:{x:.901143,y:.437488}}],net4:[{viaId:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",diameter:.3,position:{x:-.029,y:.691542}},{viaId:"37a70467-7553-415f-8ad7-8b88a5e56ca8",diameter:.3,position:{x:-.824388,y:.272808}},{viaId:"6d182b7d-a260-427b-8c43-a09409422252",diameter:.3,position:{x:.075,y:-.806274}}],net5:[{viaId:"346c301a-f2b4-44d7-b975-5438ddaa0bde",diameter:.3,position:{x:.517145,y:-.456503}},{viaId:"c54b4b94-90e0-4240-97ef-883cf097d79d",diameter:.3,position:{x:.471002,y:.692404}},{viaId:"f3cb916e-b0fd-4c5e-b14b-3779f4f9bd01",diameter:.3,position:{x:-.833162,y:-.227118}}]},routeSegments:[{routeId:"net1:route_0",fromPort:"14ee4bf1-e7e7-4351-ad16-ba1a8aac0af3",toPort:"8a898812-db2b-4b81-899d-f953b3222f9a",layer:"bottom",segments:[{x:.815244,y:-.055081},{x:.893145,y:-.132982},{x:.893145,y:-.753669},{x:.465539,y:-1.181274},{x:-.113744,y:-1.181274},{x:-.4,y:-.895018},{x:-.4,y:.547292},{x:-.528763,y:.676055}]},{routeId:"net3:route_0",fromPort:"13cd75da-d582-4eed-bc2c-fee6fa78bc6a",toPort:"9f188f9d-bce8-46c7-b9e8-542b8599d48d",layer:"bottom",segments:[{x:-.808222,y:-.726499},{x:-.808222,y:-.912474},{x:-.238422,y:-1.482274},{x:.590217,y:-1.482274},{x:1.36382,y:-.708672},{x:1.36382,y:-.001202},{x:.92513,y:.437488},{x:.901143,y:.437488}]},{routeId:"net4:route_0",fromPort:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",toPort:"6d182b7d-a260-427b-8c43-a09409422252",layer:"bottom",segments:[{x:-.029,y:.691542},{x:.075,y:.587542},{x:.075,y:-.806274}]},{routeId:"net4:route_1",fromPort:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",toPort:"37a70467-7553-415f-8ad7-8b88a5e56ca8",layer:"bottom",segments:[{x:-.029,y:.691542},{x:-.029,y:.778747},{x:-.352308,y:1.102055},{x:-.705218,y:1.102055},{x:-.954763,y:.85251},{x:-.954763,y:.403183},{x:-.824388,y:.272808}]},{routeId:"net5:route_0",fromPort:"346c301a-f2b4-44d7-b975-5438ddaa0bde",toPort:"c54b4b94-90e0-4240-97ef-883cf097d79d",layer:"bottom",segments:[{x:.517145,y:-.456503},{x:.389244,y:-.328602},{x:.389244,y:.610646},{x:.471002,y:.692404}]},{routeId:"net5:route_1",fromPort:"c54b4b94-90e0-4240-97ef-883cf097d79d",toPort:"f3cb916e-b0fd-4c5e-b14b-3779f4f9bd01",layer:"bottom",segments:[{x:.471002,y:.692404},{x:.471002,y:1.111132},{x:.129079,y:1.453055},{x:-.850606,y:1.453055},{x:-1.305763,y:.997899},{x:-1.305763,y:.151728},{x:-.926917,y:-.227118},{x:-.833162,y:-.227118}]}],tileWidth:2.9695829999999996,tileHeight:3.2353289999999997,regions:[{regionId:"t0_0:v:net1",polygon:[{x:-.678763,y:.826055},{x:-.37876299999999996,y:.826055},{x:.965244,y:.094919},{x:.965244,y:-.20508099999999999},{x:.665244,y:-.20508099999999999},{x:-.678763,y:.5260549999999999}],bounds:{minX:-.678763,maxX:.965244,minY:-.20508099999999999,maxY:.826055},center:{x:.1432405,y:.31048699999999996},isViaRegion:!0,netName:"net1"},{regionId:"t0_0:v:net3",polygon:[{x:.751143,y:.587488},{x:1.051143,y:.587488},{x:1.051143,y:.28748799999999997},{x:-.658222,y:-.876499},{x:-.958222,y:-.876499},{x:-.958222,y:-.576499}],bounds:{minX:-.958222,maxX:1.051143,minY:-.876499,maxY:.587488},center:{x:.046460500000000036,y:-.1445055},isViaRegion:!0,netName:"net3"},{regionId:"t0_0:v:net4",polygon:[{x:-.179,y:.841542},{x:.121,y:.841542},{x:.22499999999999998,y:-.656274},{x:.22499999999999998,y:-.9562740000000001},{x:-.075,y:-.9562740000000001},{x:-.974388,y:.122808},{x:-.974388,y:.42280799999999996}],bounds:{minX:-.974388,maxX:.22499999999999998,minY:-.9562740000000001,maxY:.841542},center:{x:-.23311085714285715,y:-.04858885714285716},isViaRegion:!0,netName:"net4"},{regionId:"t0_0:v:net5",polygon:[{x:.321002,y:.842404},{x:.6210019999999999,y:.842404},{x:.667145,y:-.30650299999999997},{x:.667145,y:-.606503},{x:.36714499999999994,y:-.606503},{x:-.983162,y:-.37711799999999995},{x:-.983162,y:-.07711799999999999}],bounds:{minX:-.983162,maxX:.667145,minY:-.606503,maxY:.842404},center:{x:.09673071428571425,y:-.04127671428571427},isViaRegion:!0,netName:"net5"},{regionId:"t0_0:convex:0",polygon:[{x:-1.058219,y:-.9764970000000001},{x:-1.4847905,y:-1.2941295999999998},{x:-1.4847914999999998,y:-1.6176644999999998},{x:-1.1878351999999999,y:-1.6176644999999998},{x:-.8908758999999999,y:-1.6176644999999998},{x:-.5939165999999999,y:-1.6176635},{x:-.29695730000000004,y:-1.6176624999999998},{x:-.6274055486066086,y:-.976498}],bounds:{minX:-1.4847914999999998,maxX:-.29695730000000004,minY:-1.6176644999999998,maxY:-.9764970000000001},center:{x:-.9530989435758261,y:-1.4169305124999998},isViaRegion:!1},{regionId:"t0_0:convex:1",polygon:[{x:-.12183239333000057,y:-1.056275},{x:-.3472980954230426,y:-.7857599839936004},{x:-.6274055486066086,y:-.976498},{x:-.29695730000000004,y:-1.6176624999999998},{x:2e-6,y:-1.6176644999999998}],bounds:{minX:-.6274055486066086,maxX:2e-6,minY:-1.6176644999999998,maxY:-.7857599839936004},center:{x:-.2786982674719304,y:-1.21077199679872},isViaRegion:!1},{regionId:"t0_0:convex:2",polygon:[{x:2e-6,y:-1.6176644999999998},{x:.324999,y:-1.0562760000000002},{x:-.12183239333000057,y:-1.056275}],bounds:{minX:-.12183239333000057,maxX:.324999,minY:-1.6176644999999998,maxY:-1.056275},center:{x:.0677228688899998,y:-1.2434051666666666},isViaRegion:!1},{regionId:"t0_0:convex:3",polygon:[{x:.8908728999999999,y:-1.6176635},{x:1.1878322,y:-1.6176624999999998},{x:1.4847914999999998,y:-1.2941325999999997},{x:1.4847914999999998,y:-.9705986999999998},{x:1.4847914999999998,y:-.6470648},{x:.7671479999999999,y:-.706503},{x:.324999,y:-1.0562760000000002},{x:2e-6,y:-1.6176644999999998},{x:.2969613,y:-1.6176644999999998},{x:.5939135999999998,y:-1.6176644999999998}],bounds:{minX:2e-6,maxX:1.4847914999999998,minY:-1.6176644999999998,maxY:-.6470648},center:{x:.85161035,y:-1.2762894599999999},isViaRegion:!1},{regionId:"t0_0:convex:4",polygon:[{x:1.1878322,y:-1.6176624999999998},{x:1.4847914999999998,y:-1.6176644999999998},{x:1.4847914999999998,y:-1.2941325999999997}],bounds:{minX:1.1878322,maxX:1.4847914999999998,minY:-1.6176644999999998,maxY:-1.2941325999999997},center:{x:1.3858050666666666,y:-1.5098198666666665},isViaRegion:!1},{regionId:"t0_0:convex:5",polygon:[{x:1.065245,y:-.305083},{x:.7671469999999999,y:-.30508199999999996},{x:.7671479999999999,y:-.706503},{x:1.4847914999999998,y:-.6470648},{x:1.4847884999999998,y:-.3235308999999998}],bounds:{minX:.7671469999999999,maxX:1.4847914999999998,minY:-.706503,maxY:-.30508199999999996},center:{x:1.113824,y:-.4574527399999999},isViaRegion:!1},{regionId:"t0_0:convex:6",polygon:[{x:1.4847894999999998,y:-2e-6},{x:1.065244,y:.15436033275504174},{x:1.065245,y:-.305083},{x:1.4847884999999998,y:-.3235308999999998}],bounds:{minX:1.065244,maxX:1.4847894999999998,minY:-.3235308999999998,maxY:.15436033275504174},center:{x:1.2750167499999998,y:-.11856389181123951},isViaRegion:!1},{regionId:"t0_0:convex:7",polygon:[{x:1.151141,y:.234599693035695},{x:1.4847894999999998,y:-2e-6},{x:1.4847905,y:.3235318999999998},{x:1.4847914999999998,y:.6470657999999998},{x:1.4847914999999998,y:.9705997000000003},{x:1.15114,y:.687487}],bounds:{minX:1.15114,maxX:1.4847914999999998,minY:-2e-6,maxY:.9705997000000003},center:{x:1.3735739999999999,y:.47721368217261584},isViaRegion:!1},{regionId:"t0_0:convex:8",polygon:[{x:.7170683669341472,y:.942406},{x:1.4847914999999998,y:.9705997000000003},{x:1.4847914999999998,y:1.2941335999999999},{x:1.4847914999999998,y:1.6176624999999998},{x:1.1878301999999998,y:1.6176635},{x:.8908729,y:1.6176644999999998},{x:.5939155999999999,y:1.6176644999999998},{x:.2969583,y:1.6176644999999998},{x:.28929422081219347,y:.942405}],bounds:{minX:.28929422081219347,maxX:1.4847914999999998,minY:.942405,maxY:1.6176644999999998},center:{x:.9367015653051488,y:1.3597626444444444},isViaRegion:!1},{regionId:"t0_0:convex:9",polygon:[{x:1e-6,y:1.6176624999999998},{x:-.20371678480848432,y:.94154},{x:.21429632417207728,y:.941541},{x:.2969583,y:1.6176644999999998}],bounds:{minX:-.20371678480848432,maxX:.2969583,minY:.94154,maxY:1.6176644999999998},center:{x:.07688470984089824,y:1.279602},isViaRegion:!1},{regionId:"t0_0:convex:10",polygon:[{x:-.2969563,y:1.6176635},{x:-.3533204384162378,y:.926056},{x:-.2942159061220332,y:.8939010379109219},{x:-.20371678480848432,y:.94154},{x:1e-6,y:1.6176624999999998}],bounds:{minX:-.3533204384162378,maxX:1e-6,minY:.8939010379109219,maxY:1.6176635},center:{x:-.22964168586935108,y:1.1993646075821842},isViaRegion:!1},{regionId:"t0_0:convex:11",polygon:[{x:-.3533204384162378,y:.926056},{x:-.2969563,y:1.6176635},{x:-.5939135999999998,y:1.6176644999999998},{x:-.8908778999999998,y:1.6176644999999998},{x:-.778761,y:.926055}],bounds:{minX:-.8908778999999998,maxX:-.2969563,minY:.926055,maxY:1.6176644999999998},center:{x:-.5827658476832476,y:1.3410207},isViaRegion:!1},{regionId:"t0_0:convex:12",polygon:[{x:-.778761,y:.926055},{x:-.8908778999999998,y:1.6176644999999998},{x:-1.1878351999999999,y:1.6176644999999998},{x:-1.4847914999999998,y:1.6176624999999998},{x:-1.4847914999999998,y:1.2941306},{x:-1.4847905,y:.9705986999999998},{x:-1.4847894999999998,y:.6470668},{x:-1.4847884999999998,y:.3235348999999998},{x:-1.0743880000000001,y:.4831719103506663},{x:-.778762,y:.6388054302654751}],bounds:{minX:-1.4847914999999998,maxX:-.778761,minY:.3235348999999998,maxY:1.6176644999999998},center:{x:-1.21345756,y:1.013635484061614},isViaRegion:!1},{regionId:"t0_0:convex:13",polygon:[{x:-1.4847884999999998,y:.3235348999999998},{x:-1.4847914999999998,y:-2e-6},{x:-1.074389,y:.08660027443180957},{x:-1.0743880000000001,y:.4831719103506663}],bounds:{minX:-1.4847914999999998,maxX:-1.0743880000000001,minY:-2e-6,maxY:.4831719103506663},center:{x:-1.27958925,y:.22332627119561893},isViaRegion:!1},{regionId:"t0_0:convex:14",polygon:[{x:-1.083165,y:-.025267833873400588},{x:-1.4847914999999998,y:-2e-6},{x:-1.4847914999999998,y:-.32353389999999976},{x:-1.4847914999999998,y:-.6470657999999998},{x:-1.083159,y:-.4615640153219094}],bounds:{minX:-1.4847914999999998,maxX:-1.083159,minY:-.6470657999999998,maxY:-2e-6},center:{x:-1.3241397,y:-.29148670983906194},isViaRegion:!1},{regionId:"t0_0:convex:15",polygon:[{x:-1.4847914999999998,y:-.6470657999999998},{x:-1.4847914999999998,y:-.9705977000000002},{x:-1.4847905,y:-1.2941295999999998},{x:-1.058219,y:-.9764970000000001},{x:-1.058225,y:-.5236126930356947}],bounds:{minX:-1.4847914999999998,maxX:-1.058219,minY:-1.2941295999999998,maxY:-.5236126930356947},center:{x:-1.3141634999999998,y:-.8823805586071389},isViaRegion:!1},{regionId:"t0_0:convex:16",polygon:[{x:-1.083159,y:-.4615640153219094},{x:-1.4847914999999998,y:-.6470657999999998},{x:-1.058225,y:-.5236126930356947},{x:-.9902729041136373,y:-.47734432068720295}],bounds:{minX:-1.4847914999999998,maxX:-.9902729041136373,minY:-.6470657999999998,maxY:-.4615640153219094},center:{x:-1.1541121010284092,y:-.5273967072612017},isViaRegion:!1},{regionId:"t0_0:convex:17",polygon:[{x:-1.074389,y:.08660027443180957},{x:-1.4847914999999998,y:-2e-6},{x:-1.083165,y:-.025267833873400588},{x:-1.0189109931810225,y:.020035791667712174}],bounds:{minX:-1.4847914999999998,maxX:-1.0189109931810225,minY:-.025267833873400588,maxY:.08660027443180957},center:{x:-1.1653141232952557,y:.020341558056530287},isViaRegion:!1},{regionId:"t0_0:convex:18",polygon:[{x:.28929422081219347,y:.942405},{x:.2969583,y:1.6176644999999998},{x:.21429632417207728,y:.941541},{x:.2177404023152286,y:.8919545237301704}],bounds:{minX:.21429632417207728,maxX:.2969583,minY:.8919545237301704,maxY:1.6176644999999998},center:{x:.25457231182487483,y:1.0983912559325426},isViaRegion:!1},{regionId:"t0_0:convex:19",polygon:[{x:1.15114,y:.687487},{x:1.4847914999999998,y:.9705997000000003},{x:.7170683669341472,y:.942406},{x:.7273074358013402,y:.687486}],bounds:{minX:.7170683669341472,maxX:1.4847914999999998,minY:.687486,maxY:.9705997000000003},center:{x:1.020076825683872,y:.821994675},isViaRegion:!1},{regionId:"t0_0:convex:20",polygon:[{x:1.065244,y:.15436033275504174},{x:1.4847894999999998,y:-2e-6},{x:1.151141,y:.234599693035695},{x:1.0474881564581504,y:.16401791733667992}],bounds:{minX:1.0474881564581504,maxX:1.4847894999999998,minY:-2e-6,maxY:.234599693035695},center:{x:1.1871656641145374,y:.13824398578185415},isViaRegion:!1},{regionId:"t0_0:convex:21",polygon:[{x:.7671479999999999,y:-.706503},{x:.35870860067449234,y:-.706502},{x:.324999,y:-1.0562760000000002}],bounds:{minX:.324999,maxX:.7671479999999999,minY:-1.0562760000000002,maxY:-.706502},center:{x:.48361853355816414,y:-.8230936666666668},isViaRegion:!1},{regionId:"t0_0:convex:22",polygon:[{x:.35870860067449234,y:-.706502},{x:.32499799999999995,y:-.7007742019305844},{x:.324999,y:-1.0562760000000002}],bounds:{minX:.32499799999999995,maxX:.35870860067449234,minY:-1.0562760000000002,maxY:-.7007742019305844},center:{x:.3362352002248308,y:-.8211840673101948},isViaRegion:!1}],ports:[{portId:"t0_0:convex:0-1:0",region1Id:"t0_0:convex:0",region2Id:"t0_0:convex:1",position:{x:-.46218142430330433,y:-1.2970802499999998}},{portId:"t0_0:convex:0-15:1",region1Id:"t0_0:convex:0",region2Id:"t0_0:convex:15",position:{x:-1.27150475,y:-1.1353133}},{portId:"t0_0:convex:1-2:2",region1Id:"t0_0:convex:1",region2Id:"t0_0:convex:2",position:{x:-.06091519666500028,y:-1.33696975}},{portId:"t0_0:convex:2-3:3",region1Id:"t0_0:convex:2",region2Id:"t0_0:convex:3",position:{x:.1625005,y:-1.33697025}},{portId:"t0_0:convex:3-4:4",region1Id:"t0_0:convex:3",region2Id:"t0_0:convex:4",position:{x:1.33631185,y:-1.4558975499999998}},{portId:"t0_0:convex:3-5:5",region1Id:"t0_0:convex:3",region2Id:"t0_0:convex:5",position:{x:1.1259697499999999,y:-.6767839}},{portId:"t0_0:convex:3-21:6",region1Id:"t0_0:convex:3",region2Id:"t0_0:convex:21",position:{x:.5460735,y:-.8813895}},{portId:"t0_0:convex:5-6:7",region1Id:"t0_0:convex:5",region2Id:"t0_0:convex:6",position:{x:1.2750167499999998,y:-.31430694999999986}},{portId:"t0_0:convex:6-20:8",region1Id:"t0_0:convex:6",region2Id:"t0_0:convex:20",position:{x:1.2750167499999998,y:.07717916637752087}},{portId:"t0_0:convex:7-19:9",region1Id:"t0_0:convex:7",region2Id:"t0_0:convex:19",position:{x:1.31796575,y:.8290433500000001}},{portId:"t0_0:convex:7-20:10",region1Id:"t0_0:convex:7",region2Id:"t0_0:convex:20",position:{x:1.3179652499999999,y:.1172988465178475}},{portId:"t0_0:convex:8-9:11",region1Id:"t0_0:convex:8",region2Id:"t0_0:convex:9",position:{x:.29312626040609674,y:1.28003475}},{portId:"t0_0:convex:8-19:14",region1Id:"t0_0:convex:8",region2Id:"t0_0:convex:19",position:{x:1.1009299334670735,y:.9565028500000001}},{portId:"t0_0:convex:9-10:15",region1Id:"t0_0:convex:9",region2Id:"t0_0:convex:10",position:{x:-.10185789240424216,y:1.2796012499999998}},{portId:"t0_0:convex:9-18:16",region1Id:"t0_0:convex:9",region2Id:"t0_0:convex:18",position:{x:.256231599283678,y:1.2845454430699506}},{portId:"t0_0:convex:9-18:17",region1Id:"t0_0:convex:9",region2Id:"t0_0:convex:18",position:{x:.2556273120860386,y:1.27960275}},{portId:"t0_0:convex:10-11:18",region1Id:"t0_0:convex:10",region2Id:"t0_0:convex:11",position:{x:-.3251383692081189,y:1.27185975}},{portId:"t0_0:convex:11-12:19",region1Id:"t0_0:convex:11",region2Id:"t0_0:convex:12",position:{x:-.8348194499999999,y:1.27185975}},{portId:"t0_0:convex:12-13:20",region1Id:"t0_0:convex:12",region2Id:"t0_0:convex:13",position:{x:-1.27958825,y:.403353405175333}},{portId:"t0_0:convex:13-17:21",region1Id:"t0_0:convex:13",region2Id:"t0_0:convex:17",position:{x:-1.27959025,y:.04329913721590478}},{portId:"t0_0:convex:14-15:22",region1Id:"t0_0:convex:14",region2Id:"t0_0:convex:15",position:{x:-1.2855100382914353,y:-.5550237794956899}},{portId:"t0_0:convex:14-16:23",region1Id:"t0_0:convex:14",region2Id:"t0_0:convex:16",position:{x:-1.28397525,y:-.5543149076609546}},{portId:"t0_0:convex:14-17:25",region1Id:"t0_0:convex:14",region2Id:"t0_0:convex:17",position:{x:-1.2839782499999999,y:-.012634916936700293}},{portId:"t0_0:convex:15-16:26",region1Id:"t0_0:convex:15",region2Id:"t0_0:convex:16",position:{x:-1.274726872016046,y:-.5862707516595418}},{portId:"t0_0:convex:15-16:27",region1Id:"t0_0:convex:15",region2Id:"t0_0:convex:16",position:{x:-1.27150825,y:-.5853392465178473}},{portId:"t0_0:convex:21-22:28",region1Id:"t0_0:convex:21",region2Id:"t0_0:convex:22",position:{x:.34185380033724616,y:-.8813890000000001}},{portId:"via-side:t0_0:v:net1:top:30",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:11",position:{x:-.528763,y:.826055}},{portId:"via-side:t0_0:v:net1:bottom:31",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:5",position:{x:.815244,y:-.20508099999999999}},{portId:"via-side:t0_0:v:net1:left:32",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:12",position:{x:-.678763,y:.676055}},{portId:"via-side:t0_0:v:net1:right:33",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:6",position:{x:.965244,y:-.05508099999999999}},{portId:"via-side:t0_0:v:net3:top:34",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:19",position:{x:.901143,y:.587488}},{portId:"via-side:t0_0:v:net3:bottom:35",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:0",position:{x:-.808222,y:-.876499}},{portId:"via-side:t0_0:v:net3:left:36",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:15",position:{x:-.958222,y:-.726499}},{portId:"via-side:t0_0:v:net3:right:37",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:7",position:{x:1.051143,y:.437488}},{portId:"via-side:t0_0:v:net4:top:38",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:9",position:{x:-.028999999999999998,y:.841542}},{portId:"via-side:t0_0:v:net4:bottom:39",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:2",position:{x:.07499999999999998,y:-.9562740000000001}},{portId:"via-side:t0_0:v:net4:left:40",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:13",position:{x:-.974388,y:.272808}},{portId:"via-side:t0_0:v:net4:right:41",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:21",position:{x:.22499999999999998,y:-.806274}},{portId:"via-side:t0_0:v:net5:top:42",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:8",position:{x:.471002,y:.842404}},{portId:"via-side:t0_0:v:net5:bottom:43",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:21",position:{x:.517145,y:-.606503}},{portId:"via-side:t0_0:v:net5:left:44",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:14",position:{x:-.983162,y:-.227118}},{portId:"via-side:t0_0:v:net5:right:45",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:5",position:{x:.667145,y:-.456503}}]},gh=[{viaRegionName:"via-tile-3-regions",viaTile:{viasByNet:{net1:[{viaId:"1b0111be-ce08-409a-80b7-5006cb5e2c5b",diameter:.3,position:{x:-.396773,y:.05144}},{viaId:"2f36dd01-8bf4-49dc-b86b-22c27e4cb7bf",diameter:.3,position:{x:-.04486,y:-.267596}}],net2:[{viaId:"51af4ca3-53f4-4a03-914b-6dba63eb8c4a",diameter:.3,position:{x:.39936,y:.600815}},{viaId:"b602bfde-3ed8-4f47-9fa7-5baa7a8a9ec4",diameter:.3,position:{x:-.563329,y:-.420006}}],net3:[{viaId:"095a83cb-28a7-472c-95fe-bfb08db097f5",diameter:.3,position:{x:-.070756,y:.430539}},{viaId:"e8d75a9d-5b0e-4158-8d39-01b264e49299",diameter:.3,position:{x:.280866,y:.111752}}]},routeSegments:[{routeId:"net1:route_0",fromPort:"1b0111be-ce08-409a-80b7-5006cb5e2c5b",toPort:"2f36dd01-8bf4-49dc-b86b-22c27e4cb7bf",layer:"bottom",segments:[{x:-.396773,y:.05144},{x:-.363896,y:.05144},{x:-.04486,y:-.267596}]},{routeId:"net2:route_0",fromPort:"51af4ca3-53f4-4a03-914b-6dba63eb8c4a",toPort:"b602bfde-3ed8-4f47-9fa7-5baa7a8a9ec4",layer:"bottom",segments:[{x:.39936,y:.600815},{x:.681866,y:.318309},{x:.681866,y:-.10797},{x:.12124,y:-.668596},{x:-.314739,y:-.668596},{x:-.563329,y:-.420006}]},{routeId:"net3:route_0",fromPort:"095a83cb-28a7-472c-95fe-bfb08db097f5",toPort:"e8d75a9d-5b0e-4158-8d39-01b264e49299",layer:"bottom",segments:[{x:-.070756,y:.430539},{x:-.037921,y:.430539},{x:.280866,y:.111752}]}],tileWidth:1.6201949999999998,tileHeight:1.6444109999999998,regions:[{regionId:"t0_0:v:net1",polygon:[{x:-.546773,y:.20144},{x:-.246773,y:.20144},{x:.10514,y:-.117596},{x:.10514,y:-.41759599999999997},{x:-.19485999999999998,y:-.41759599999999997},{x:-.546773,y:-.09856}],bounds:{minX:-.546773,maxX:.10514,minY:-.41759599999999997,maxY:.20144},center:{x:-.22081649999999997,y:-.108078},isViaRegion:!0,netName:"net1"},{regionId:"t0_0:v:net2",polygon:[{x:.24936,y:.750815},{x:.54936,y:.750815},{x:.54936,y:.45081499999999997},{x:-.41332899999999995,y:-.570006},{x:-.713329,y:-.570006},{x:-.713329,y:-.27000599999999997}],bounds:{minX:-.713329,maxX:.54936,minY:-.570006,maxY:.750815},center:{x:-.0819845,y:.0904045},isViaRegion:!0,netName:"net2"},{regionId:"t0_0:v:net3",polygon:[{x:-.220756,y:.580539},{x:.079244,y:.580539},{x:.43086599999999997,y:.261752},{x:.43086599999999997,y:-.03824799999999999},{x:.130866,y:-.03824799999999999},{x:-.220756,y:.280539}],bounds:{minX:-.220756,maxX:.43086599999999997,minY:-.03824799999999999,maxY:.580539},center:{x:.10505499999999997,y:.2711455},isViaRegion:!0,netName:"net3"},{regionId:"t0_0:convex:0",polygon:[{x:-.6480799999999999,y:-.8222054999999999},{x:-.4860594999999999,y:-.8222054999999999},{x:-.32403899999999997,y:-.8222044999999999},{x:-.3701817305825413,y:-.670007},{x:-.8100964999999999,y:-.6700079999999999},{x:-.8100974999999999,y:-.8222054999999999}],bounds:{minX:-.8100974999999999,maxX:-.32403899999999997,minY:-.8222054999999999,maxY:-.670007},center:{x:-.5747590384304234,y:-.7714726666666666},isViaRegion:!1},{regionId:"t0_0:convex:1",polygon:[{x:-.16201849999999998,y:-.8222035},{x:-.22645191931396433,y:-.5175979999999999},{x:-.3701817305825413,y:-.670007},{x:-.32403899999999997,y:-.8222044999999999}],bounds:{minX:-.3701817305825413,maxX:-.16201849999999998,minY:-.8222044999999999,maxY:-.5175979999999999},center:{x:-.2706727874741264,y:-.70800325},isViaRegion:!1},{regionId:"t0_0:convex:2",polygon:[{x:2e-6,y:-.8222054999999999},{x:.16202249999999999,y:-.8222054999999999},{x:.324036,y:-.8222054999999999},{x:.20513699999999999,y:-.517594},{x:-.22645191931396433,y:-.5175979999999999},{x:-.16201849999999998,y:-.8222035}],bounds:{minX:-.22645191931396433,maxX:.324036,minY:-.8222054999999999,maxY:-.517594},center:{x:.05045451344767262,y:-.7206686666666666},isViaRegion:!1},{regionId:"t0_0:convex:3",polygon:[{x:.8100974999999999,y:-.32888120000000004},{x:.8100944999999999,y:-.1644390999999999},{x:.5308679999999999,y:-.13824799999999998},{x:.205143,y:-.13824699999999998},{x:.20513699999999999,y:-.517594},{x:.324036,y:-.8222054999999999},{x:.48605649999999995,y:-.8222044999999999},{x:.6480769999999999,y:-.8222035},{x:.8100974999999999,y:-.6577654},{x:.8100974999999999,y:-.4933232999999999}],bounds:{minX:.20513699999999999,maxX:.8100974999999999,minY:-.8222054999999999,maxY:-.13824699999999998},center:{x:.5639704499999999,y:-.49051114999999995},isViaRegion:!1},{regionId:"t0_0:convex:4",polygon:[{x:.6480769999999999,y:-.8222035},{x:.8100974999999999,y:-.8222054999999999},{x:.8100974999999999,y:-.6577654}],bounds:{minX:.6480769999999999,maxX:.8100974999999999,minY:-.8222054999999999,maxY:-.6577654},center:{x:.7560906666666666,y:-.7673914666666667},isViaRegion:!1},{regionId:"t0_0:convex:5",polygon:[{x:.8100974999999999,y:.3288821999999998},{x:.6493599999999999,y:.411097723794497},{x:.530867,y:.28544946055995296},{x:.5308679999999999,y:-.13824799999999998},{x:.8100944999999999,y:-.1644390999999999},{x:.8100955,y:-2e-6},{x:.8100964999999999,y:.1644400999999999}],bounds:{minX:.530867,maxX:.8100974999999999,minY:-.1644390999999999,maxY:.411097723794497},center:{x:.7073541428571428,y:.12674005490777857},isViaRegion:!1},{regionId:"t0_0:convex:6",polygon:[{x:.6493599999999999,y:.411097723794497},{x:.8100974999999999,y:.3288821999999998},{x:.8100974999999999,y:.4933243000000001},{x:.8100974999999999,y:.6577664},{x:.8100974999999999,y:.8222035},{x:.649358,y:.8222054999999999}],bounds:{minX:.649358,maxX:.8100974999999999,minY:.3288821999999998,maxY:.8222054999999999},center:{x:.7565179999999999,y:.5892466039657495},isViaRegion:!1},{regionId:"t0_0:convex:7",polygon:[{x:1e-6,y:.8222035},{x:-.027378080330350014,y:.680539},{x:.11004202589152173,y:.8222054999999999}],bounds:{minX:-.027378080330350014,maxX:.11004202589152173,minY:.680539,maxY:.8222054999999999},center:{x:.027554981853723907,y:.7749826666666667},isViaRegion:!1},{regionId:"t0_0:convex:8",polygon:[{x:-.027378080330350014,y:.680539},{x:1e-6,y:.8222035},{x:-.16201749999999998,y:.8222044999999999},{x:-.324036,y:.8222054999999999},{x:-.32075300000000007,y:.680538}],bounds:{minX:-.324036,maxX:1e-6,minY:.680538,maxY:.8222054999999999},center:{x:-.16683671606607003,y:.7655380999999999},isViaRegion:!1},{regionId:"t0_0:convex:9",polygon:[{x:-.32075300000000007,y:.680538},{x:-.324036,y:.8222054999999999},{x:-.4860614999999999,y:.8222054999999999},{x:-.6480799999999999,y:.8222054999999999},{x:-.8100974999999999,y:.8222035},{x:-.8100974999999999,y:.6577633999999999},{x:-.8100964999999999,y:.4933232999999999},{x:-.8100955,y:.3288832},{x:-.64677,y:.30143800000000004},{x:-.3951083951938174,y:.30143900000000007},{x:-.32075400000000004,y:.3780859678974683}],bounds:{minX:-.8100974999999999,maxX:-.32075300000000007,minY:.30143800000000004,maxY:.8222054999999999},center:{x:-.580177263199438,y:.5845718970815881},isViaRegion:!1},{regionId:"t0_0:convex:10",polygon:[{x:-.8100955,y:.3288832},{x:-.8100944999999999,y:.1644430999999999},{x:-.64677,y:.30143800000000004}],bounds:{minX:-.8100955,maxX:-.64677,minY:.1644430999999999,maxY:.3288832},center:{x:-.7556533333333334,y:.26492143333333334},isViaRegion:!1},{regionId:"t0_0:convex:11",polygon:[{x:-.646771,y:.04199388419849993},{x:-.64677,y:.30143800000000004},{x:-.8100944999999999,y:.1644430999999999},{x:-.8100974999999999,y:-2e-6},{x:-.8100974999999999,y:-.12637992705088938}],bounds:{minX:-.8100974999999999,maxX:-.64677,minY:-.12637992705088938,maxY:.30143800000000004},center:{x:-.7447660999999999,y:.0762986114295221},isViaRegion:!1}],ports:[{portId:"t0_0:convex:1-2:0",region1Id:"t0_0:convex:1",region2Id:"t0_0:convex:2",position:{x:-.19423520965698216,y:-.6699007499999999}},{portId:"t0_0:convex:2-3:1",region1Id:"t0_0:convex:2",region2Id:"t0_0:convex:3",position:{x:.2645865,y:-.6698997499999999}},{portId:"t0_0:convex:3-4:2",region1Id:"t0_0:convex:3",region2Id:"t0_0:convex:4",position:{x:.7290872499999999,y:-.7399844499999999}},{portId:"t0_0:convex:3-5:3",region1Id:"t0_0:convex:3",region2Id:"t0_0:convex:5",position:{x:.6704812499999999,y:-.15134354999999994}},{portId:"t0_0:convex:10-11:4",region1Id:"t0_0:convex:10",region2Id:"t0_0:convex:11",position:{x:-.72843225,y:.23294054999999997}},{portId:"via-side:t0_0:v:net1:top:5",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:9",position:{x:-.396773,y:.20144}},{portId:"via-side:t0_0:v:net1:bottom:6",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:2",position:{x:-.04485999999999999,y:-.41759599999999997}},{portId:"via-side:t0_0:v:net1:left:7",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:11",position:{x:-.546773,y:.05144000000000001}},{portId:"via-side:t0_0:v:net1:right:8",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:3",position:{x:.10514,y:-.267596}},{portId:"via-side:t0_0:v:net2:bottom:9",region1Id:"t0_0:v:net2",region2Id:"t0_0:convex:0",position:{x:-.563329,y:-.570006}},{portId:"via-side:t0_0:v:net2:right:10",region1Id:"t0_0:v:net2",region2Id:"t0_0:convex:6",position:{x:.54936,y:.600815}},{portId:"via-side:t0_0:v:net3:top:11",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:8",position:{x:-.07075600000000001,y:.580539}},{portId:"via-side:t0_0:v:net3:bottom:12",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:3",position:{x:.280866,y:-.03824799999999999}},{portId:"via-side:t0_0:v:net3:left:13",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:9",position:{x:-.220756,y:.430539}},{portId:"via-side:t0_0:v:net3:right:14",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:5",position:{x:.43086599999999997,y:.11175199999999999}}]}},{viaRegionName:"via-tile-4-regions",viaTile:fh},{viaRegionName:"via-tile-5-regions",viaTile:{viasByNet:{net1:[{viaId:"14ee4bf1-e7e7-4351-ad16-ba1a8aac0af3",diameter:.3,position:{x:.778514,y:-.012215}},{viaId:"8a898812-db2b-4b81-899d-f953b3222f9a",diameter:.3,position:{x:-.770591,y:.97317}}],net2:[{viaId:"1f552ada-e01a-4230-b5f5-0006595b14d5",diameter:.3,position:{x:1.014826,y:.42842}},{viaId:"6987544a-501f-4711-bdff-dc583936a21c",diameter:.3,position:{x:-.854951,y:-.884286}}],net3:[{viaId:"13cd75da-d582-4eed-bc2c-fee6fa78bc6a",diameter:.3,position:{x:-1.067887,y:-.431891}},{viaId:"9f188f9d-bce8-46c7-b9e8-542b8599d48d",diameter:.3,position:{x:.695984,y:.813573}}],net4:[{viaId:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",diameter:.3,position:{x:-.273716,y:1.029009}},{viaId:"37a70467-7553-415f-8ad7-8b88a5e56ca8",diameter:.3,position:{x:-1.062855,y:.56748}},{viaId:"6d182b7d-a260-427b-8c43-a09409422252",diameter:.3,position:{x:.04738,y:-.678598}}],net5:[{viaId:"346c301a-f2b4-44d7-b975-5438ddaa0bde",diameter:.3,position:{x:.462204,y:-.39945}},{viaId:"c54b4b94-90e0-4240-97ef-883cf097d79d",diameter:.3,position:{x:.22363,y:.977538}},{viaId:"f3cb916e-b0fd-4c5e-b14b-3779f4f9bd01",diameter:.3,position:{x:-1.047736,y:.067706}}]},routeSegments:[{routeId:"net1:route_0",fromPort:"14ee4bf1-e7e7-4351-ad16-ba1a8aac0af3",toPort:"8a898812-db2b-4b81-899d-f953b3222f9a",layer:"bottom",segments:[{x:.778514,y:-.012215},{x:.863204,y:-.096905},{x:.863204,y:-.56555},{x:.349156,y:-1.079598},{x:-.11872,y:-1.079598},{x:-.35362,y:-.844698},{x:-.35362,y:-.818517},{x:-.646736,y:-.525401},{x:-.646736,y:.849315},{x:-.770591,y:.97317}]},{routeId:"net2:route_0",fromPort:"1f552ada-e01a-4230-b5f5-0006595b14d5",toPort:"6987544a-501f-4711-bdff-dc583936a21c",layer:"bottom",segments:[{x:1.014826,y:.42842},{x:1.179514,y:.263732},{x:1.179514,y:-.674918},{x:.473834,y:-1.380598},{x:-.358639,y:-1.380598},{x:-.854951,y:-.884286}]},{routeId:"net3:route_0",fromPort:"13cd75da-d582-4eed-bc2c-fee6fa78bc6a",toPort:"9f188f9d-bce8-46c7-b9e8-542b8599d48d",layer:"bottom",segments:[{x:-1.067887,y:-.431891},{x:-1.255951,y:-.619955},{x:-1.255951,y:-1.050386},{x:-.624739,y:-1.681598},{x:.598512,y:-1.681598},{x:1.480514,y:-.799596},{x:1.480514,y:.529832},{x:1.180926,y:.82942},{x:.711831,y:.82942},{x:.695984,y:.813573}]},{routeId:"net4:route_0",fromPort:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",toPort:"37a70467-7553-415f-8ad7-8b88a5e56ca8",layer:"bottom",segments:[{x:-.273716,y:1.029009},{x:-.273716,y:1.043395},{x:-.604491,y:1.37417},{x:-.936691,y:1.37417},{x:-1.171591,y:1.13927},{x:-1.171591,y:.676216},{x:-1.062855,y:.56748}]},{routeId:"net4:route_1",fromPort:"2ef3b96b-58c4-4150-b5d1-e90f74b92b25",toPort:"6d182b7d-a260-427b-8c43-a09409422252",layer:"bottom",segments:[{x:-.273716,y:1.029009},{x:-.273716,y:-.357502},{x:.04738,y:-.678598}]},{routeId:"net5:route_0",fromPort:"346c301a-f2b4-44d7-b975-5438ddaa0bde",toPort:"c54b4b94-90e0-4240-97ef-883cf097d79d",layer:"bottom",segments:[{x:.462204,y:-.39945},{x:.22363,y:-.160876},{x:.22363,y:.977538}]},{routeId:"net5:route_1",fromPort:"c54b4b94-90e0-4240-97ef-883cf097d79d",toPort:"f3cb916e-b0fd-4c5e-b14b-3779f4f9bd01",layer:"bottom",segments:[{x:.22363,y:.977538},{x:.22363,y:1.098763},{x:-.352777,y:1.67517},{x:-1.061369,y:1.67517},{x:-1.472591,y:1.263948},{x:-1.472591,y:.410116},{x:-1.130181,y:.067706},{x:-1.047736,y:.067706}]}],tileWidth:3.253105,tileHeight:3.656768,regions:[{regionId:"t0_0:v:net1",polygon:[{x:-.920591,y:1.12317},{x:-.620591,y:1.12317},{x:.9285140000000001,y:.137785},{x:.9285140000000001,y:-.162215},{x:.628514,y:-.162215},{x:-.920591,y:.82317}],bounds:{minX:-.920591,maxX:.9285140000000001,minY:-.162215,maxY:1.12317},center:{x:.003961500000000007,y:.4804775000000001},isViaRegion:!0,netName:"net1"},{regionId:"t0_0:v:net2",polygon:[{x:.864826,y:.57842},{x:1.164826,y:.57842},{x:1.164826,y:.27842},{x:-.704951,y:-1.034286},{x:-1.004951,y:-1.034286},{x:-1.004951,y:-.734286}],bounds:{minX:-1.004951,maxX:1.164826,minY:-1.034286,maxY:.57842},center:{x:.07993750000000006,y:-.22793300000000002},isViaRegion:!0,netName:"net2"},{regionId:"t0_0:v:net3",polygon:[{x:.545984,y:.963573},{x:.8459840000000001,y:.963573},{x:.8459840000000001,y:.663573},{x:-.917887,y:-.581891},{x:-1.217887,y:-.581891},{x:-1.217887,y:-.281891}],bounds:{minX:-1.217887,maxX:.8459840000000001,minY:-.581891,maxY:.963573},center:{x:-.18595149999999996,y:.19084099999999996},isViaRegion:!0,netName:"net3"},{regionId:"t0_0:v:net4",polygon:[{x:-.423716,y:1.179009},{x:-.12371600000000002,y:1.179009},{x:.19738,y:-.528598},{x:.19738,y:-.8285980000000001},{x:-.10261999999999999,y:-.8285980000000001},{x:-1.212855,y:.41747999999999996},{x:-1.212855,y:.71748}],bounds:{minX:-1.212855,maxX:.19738,minY:-.8285980000000001,maxY:1.179009},center:{x:-.38300028571428574,y:.18674057142857142},isViaRegion:!0,netName:"net4"},{regionId:"t0_0:v:net5",polygon:[{x:.07363,y:1.127538},{x:.37363,y:1.127538},{x:.612204,y:-.24945000000000003},{x:.612204,y:-.54945},{x:.31220400000000004,y:-.54945},{x:-1.197736,y:-.08229399999999999},{x:-1.197736,y:.217706}],bounds:{minX:-1.197736,maxX:.612204,minY:-.54945,maxY:1.127538},center:{x:-.0588,y:.14887685714285714},isViaRegion:!0,netName:"net5"},{regionId:"t0_0:convex:0",polygon:[{x:-1.104954,y:-1.1342880000000002},{x:-1.6265515000000001,y:-1.4627051999999998},{x:-1.6265525,y:-1.828384},{x:-1.301244,y:-1.828384},{x:-.9759325,y:-1.828384},{x:-.6506210000000001,y:-1.828383},{x:-.32530949999999986,y:-1.828382},{x:-.67334963343571,y:-1.134284}],bounds:{minX:-1.6265525,maxX:-.32530949999999986,minY:-1.828384,maxY:-1.134284},center:{x:-1.0355643291794636,y:-1.609149275},isViaRegion:!1},{regionId:"t0_0:convex:1",polygon:[{x:-.14745539353012446,y:-.928598},{x:-.2370859277013201,y:-.8279985835953872},{x:-.67334963343571,y:-1.134284},{x:-.32530949999999986,y:-1.828382},{x:2e-6,y:-1.828384}],bounds:{minX:-.67334963343571,maxX:2e-6,minY:-1.828384,maxY:-.8279985835953872},center:{x:-.2766396909334309,y:-1.3095293167190776},isViaRegion:!1},{regionId:"t0_0:convex:2",polygon:[{x:.29738,y:-.9285990000000001},{x:-.14745539353012446,y:-.928598},{x:2e-6,y:-1.828384},{x:.3253134999999998,y:-1.828384}],bounds:{minX:-.14745539353012446,maxX:.3253134999999998,minY:-1.828384,maxY:-.928598},center:{x:.11881002661746884,y:-1.37849125},isViaRegion:!1},{regionId:"t0_0:convex:3",polygon:[{x:.9759295000000004,y:-1.828383},{x:1.301241,y:-1.828382},{x:1.6265525,y:-1.4627082},{x:1.6265525,y:-1.0970304},{x:1.6265525,y:-.7313526},{x:.712202,y:-.649448},{x:.297379,y:-.6494519999999999},{x:.29738,y:-.9285990000000001},{x:.3253134999999998,y:-1.828384},{x:.6506179999999999,y:-1.828384}],bounds:{minX:.297379,maxX:1.6265525,minY:-1.828384,maxY:-.649448},center:{x:.94397205,y:-1.28321232},isViaRegion:!1},{regionId:"t0_0:convex:4",polygon:[{x:1.301241,y:-1.828382},{x:1.6265525,y:-1.828384},{x:1.6265525,y:-1.4627082}],bounds:{minX:1.301241,maxX:1.6265525,minY:-1.828384,maxY:-1.4627082},center:{x:1.5181153333333333,y:-1.7064914},isViaRegion:!1},{regionId:"t0_0:convex:5",polygon:[{x:1.0285170000000001,y:-.262215},{x:.712201,y:-.262214},{x:.712202,y:-.649448},{x:1.6265525,y:-.7313526},{x:1.6265495,y:-.3656747999999999}],bounds:{minX:.712201,maxX:1.6265525,minY:-.7313526,maxY:-.262214},center:{x:1.1412044000000001,y:-.45418088},isViaRegion:!1},{regionId:"t0_0:convex:6",polygon:[{x:1.6265505,y:-2e-6},{x:1.6265515000000001,y:.36567579999999994},{x:1.264827,y:.22644042974475398},{x:1.0285160000000002,y:.06053491775321725},{x:1.0285170000000001,y:-.262215},{x:1.6265495,y:-.3656747999999999}],bounds:{minX:1.0285160000000002,maxX:1.6265515000000001,minY:-.3656747999999999,maxY:.36567579999999994},center:{x:1.3669185833333335,y:.004126557916328553},isViaRegion:!1},{regionId:"t0_0:convex:7",polygon:[{x:1.264826,y:.678422},{x:1.264827,y:.22644042974475398},{x:1.6265515000000001,y:.36567579999999994},{x:1.6265525,y:.7313536}],bounds:{minX:1.264826,maxX:1.6265525,minY:.22644042974475398,maxY:.7313536},center:{x:1.4456892499999998,y:.5004729574361885},isViaRegion:!1},{regionId:"t0_0:convex:8",polygon:[{x:1.6265525,y:1.0970314},{x:.9459820000000001,y:1.063573},{x:.945983,y:.678421},{x:1.264826,y:.678422},{x:1.6265525,y:.7313536}],bounds:{minX:.9459820000000001,maxX:1.6265525,minY:.678421,maxY:1.0970314},center:{x:1.2819791999999999,y:.8497602000000001},isViaRegion:!1},{regionId:"t0_0:convex:9",polygon:[{x:.4577960301822552,y:1.22754},{x:.5142343492649757,y:1.0635720000000002},{x:.9459820000000001,y:1.063573},{x:1.6265525,y:1.0970314},{x:1.6265525,y:1.4627092},{x:1.6265525,y:1.828382},{x:1.301239,y:1.828383},{x:.9759295,y:1.828384},{x:.6506200000000001,y:1.828384},{x:.32531049999999984,y:1.828384}],bounds:{minX:.32531049999999984,maxX:1.6265525,minY:1.0635720000000002,maxY:1.828384},center:{x:1.0050768879447232,y:1.5056342600000001},isViaRegion:!1},{regionId:"t0_0:convex:10",polygon:[{x:-.04076829030879819,y:1.2790080000000001},{x:-.02247520650291584,y:1.1817306460139294},{x:.041535316582505054,y:1.227539},{x:.32531049999999984,y:1.828384},{x:1e-6,y:1.828382}],bounds:{minX:-.04076829030879819,maxX:.32531049999999984,minY:1.1817306460139294,maxY:1.828384},center:{x:.06072066395415817,y:1.4690087292027858},isViaRegion:!1},{regionId:"t0_0:convex:11",polygon:[{x:.32531049999999984,y:1.828384},{x:.041535316582505054,y:1.227539},{x:.4577960301822552,y:1.22754}],bounds:{minX:.041535316582505054,maxX:.4577960301822552,minY:1.227539,maxY:1.828384},center:{x:.27488061558825333,y:1.427821},isViaRegion:!1},{regionId:"t0_0:convex:12",polygon:[{x:-.04076829030879819,y:1.2790080000000001},{x:1e-6,y:1.828382},{x:-.32530849999999983,y:1.828383},{x:-.6506179999999999,y:1.828384},{x:-.4508136525377509,y:1.279007}],bounds:{minX:-.6506179999999999,maxX:1e-6,minY:1.279007,maxY:1.828384},center:{x:-.2935014885693098,y:1.6086328},isViaRegion:!1},{regionId:"t0_0:convex:13",polygon:[{x:-.9759345000000004,y:1.828384},{x:-1.301244,y:1.828384},{x:-1.020589,y:1.22317},{x:-.5914781273848957,y:1.223171},{x:-.6506179999999999,y:1.828384}],bounds:{minX:-1.301244,maxX:-.5914781273848957,minY:1.22317,maxY:1.828384},center:{x:-.9079727254769793,y:1.5862986},isViaRegion:!1},{regionId:"t0_0:convex:14",polygon:[{x:-1.6265525,y:1.4627062000000002},{x:-1.6265515000000001,y:1.0970304},{x:-1.312855,y:.7748397948423481},{x:-1.02059,y:.9457717862849203},{x:-1.020589,y:1.22317},{x:-1.301244,y:1.828384},{x:-1.6265525,y:1.828382}],bounds:{minX:-1.6265525,maxX:-1.020589,minY:.7748397948423481,maxY:1.828384},center:{x:-1.3621335000000003,y:1.3086120258753238},isViaRegion:!1},{regionId:"t0_0:convex:15",polygon:[{x:-1.6265505,y:.7313546000000001},{x:-1.312856,y:.379395159306606},{x:-1.312855,y:.7748397948423481},{x:-1.6265515000000001,y:1.0970304}],bounds:{minX:-1.6265515000000001,maxX:-1.312855,minY:.379395159306606,maxY:1.0970304},center:{x:-1.4697032500000002,y:.7456549885372385},isViaRegion:!1},{regionId:"t0_0:convex:16",polygon:[{x:-1.6265525,y:-2e-6},{x:-1.6265525,y:-.3656777999999999},{x:-1.3178860000000001,y:-.23008248432450779},{x:-1.297733,y:-.15603295102834283},{x:-1.297739,y:.2691114016192869},{x:-1.6265495,y:.3656787999999999}],bounds:{minX:-1.6265525,maxX:-1.297733,minY:-.3656777999999999,maxY:.3656787999999999},center:{x:-1.4655020833333332,y:-.01950083895559393},isViaRegion:!1},{regionId:"t0_0:convex:17",polygon:[{x:-1.6265525,y:-.3656777999999999},{x:-1.317887,y:-.68189},{x:-1.3178860000000001,y:-.23008248432450779}],bounds:{minX:-1.6265525,maxX:-1.3178860000000001,minY:-.68189,maxY:-.23008248432450779},center:{x:-1.4207751666666668,y:-.4258834281081692},isViaRegion:!1},{regionId:"t0_0:convex:18",polygon:[{x:-1.317887,y:-.68189},{x:-1.6265525,y:-.3656777999999999},{x:-1.6265525,y:-.7313536},{x:-1.6265525,y:-1.0970294000000003},{x:-1.6265515000000001,y:-1.4627051999999998},{x:-1.104954,y:-1.1342880000000002}],bounds:{minX:-1.6265525,maxX:-1.104954,minY:-1.4627051999999998,maxY:-.3656777999999999},center:{x:-1.488175,y:-.9121573333333334},isViaRegion:!1},{regionId:"t0_0:convex:19",polygon:[{x:-1.2388222238680076,y:-.17426049624915768},{x:-1.297733,y:-.15603295102834283},{x:-1.3178860000000001,y:-.23008248432450779}],bounds:{minX:-1.3178860000000001,maxX:-1.2388222238680076,minY:-.23008248432450779,maxY:-.15603295102834283},center:{x:-1.284813741289336,y:-.18679197720066942},isViaRegion:!1},{regionId:"t0_0:convex:20",polygon:[{x:-1.312856,y:.379395159306606},{x:-1.6265505,y:.7313546000000001},{x:-1.6265495,y:.3656787999999999},{x:-1.297739,y:.2691114016192869},{x:-1.2469689855126633,y:.30544440514072957}],bounds:{minX:-1.6265505,maxX:-1.2469689855126633,minY:.2691114016192869,maxY:.7313546000000001},center:{x:-1.4221327971025326,y:.4101968732133245},isViaRegion:!1},{regionId:"t0_0:convex:21",polygon:[{x:-.4508136525377509,y:1.279007},{x:-.6506179999999999,y:1.828384},{x:-.5914781273848957,y:1.223171},{x:-.5698356477081257,y:1.2094014117272271}],bounds:{minX:-.6506179999999999,maxX:-.4508136525377509,minY:1.2094014117272271,maxY:1.828384},center:{x:-.5656863569076931,y:1.3849908529318067},isViaRegion:!1},{regionId:"t0_0:convex:22",polygon:[{x:.4577960301822552,y:1.22754},{x:.48926113449838465,y:1.0459332516952444},{x:.5142343492649757,y:1.0635720000000002}],bounds:{minX:.4577960301822552,maxX:.5142343492649757,minY:1.0459332516952444,maxY:1.22754},center:{x:.4870971713152052,y:1.1123484172317482},isViaRegion:!1},{regionId:"t0_0:convex:23",polygon:[{x:-1.104954,y:-1.1342880000000002},{x:-1.104953,y:-.6823094297447541},{x:-1.317887,y:-.68189}],bounds:{minX:-1.317887,maxX:-1.104953,minY:-1.1342880000000002,maxY:-.68189},center:{x:-1.1759313333333334,y:-.8328291432482514},isViaRegion:!1},{regionId:"t0_0:convex:24",polygon:[{x:-1.104953,y:-.6823094297447541},{x:-1.104357426244828,y:-.681891},{x:-1.317887,y:-.68189}],bounds:{minX:-1.317887,maxX:-1.104357426244828,minY:-.6823094297447541,maxY:-.68189},center:{x:-1.1757324754149427,y:-.6820301432482513},isViaRegion:!1}],ports:[{portId:"t0_0:convex:0-1:0",region1Id:"t0_0:convex:0",region2Id:"t0_0:convex:1",position:{x:-.4993295667178549,y:-1.481333}},{portId:"t0_0:convex:0-18:1",region1Id:"t0_0:convex:0",region2Id:"t0_0:convex:18",position:{x:-1.36575275,y:-1.2984966}},{portId:"t0_0:convex:1-2:2",region1Id:"t0_0:convex:1",region2Id:"t0_0:convex:2",position:{x:-.036862348382531114,y:-1.6034375}},{portId:"t0_0:convex:1-2:3",region1Id:"t0_0:convex:1",region2Id:"t0_0:convex:2",position:{x:-.11059104514759335,y:-1.1535445}},{portId:"t0_0:convex:2-3:4",region1Id:"t0_0:convex:2",region2Id:"t0_0:convex:3",position:{x:.31833012499999985,y:-1.60343775}},{portId:"t0_0:convex:2-3:5",region1Id:"t0_0:convex:2",region2Id:"t0_0:convex:3",position:{x:.30436337499999994,y:-1.15354525}},{portId:"t0_0:convex:3-4:6",region1Id:"t0_0:convex:3",region2Id:"t0_0:convex:4",position:{x:1.46389675,y:-1.6455451}},{portId:"t0_0:convex:3-5:7",region1Id:"t0_0:convex:3",region2Id:"t0_0:convex:5",position:{x:1.397964875,y:-.71087645}},{portId:"t0_0:convex:3-5:8",region1Id:"t0_0:convex:3",region2Id:"t0_0:convex:5",position:{x:.9407896250000001,y:-.66992415}},{portId:"t0_0:convex:5-6:9",region1Id:"t0_0:convex:5",region2Id:"t0_0:convex:6",position:{x:1.32753325,y:-.31394489999999997}},{portId:"t0_0:convex:6-7:10",region1Id:"t0_0:convex:6",region2Id:"t0_0:convex:7",position:{x:1.44568925,y:.296058114872377}},{portId:"t0_0:convex:7-8:11",region1Id:"t0_0:convex:7",region2Id:"t0_0:convex:8",position:{x:1.44568925,y:.7048878000000001}},{portId:"t0_0:convex:8-9:12",region1Id:"t0_0:convex:8",region2Id:"t0_0:convex:9",position:{x:1.28626725,y:1.0803022000000002}},{portId:"t0_0:convex:9-11:13",region1Id:"t0_0:convex:9",region2Id:"t0_0:convex:11",position:{x:.39155326509112753,y:1.527962}},{portId:"t0_0:convex:10-11:14",region1Id:"t0_0:convex:10",region2Id:"t0_0:convex:11",position:{x:.18342290829125246,y:1.5279615}},{portId:"t0_0:convex:10-12:15",region1Id:"t0_0:convex:10",region2Id:"t0_0:convex:12",position:{x:-.020383645154399093,y:1.553695}},{portId:"t0_0:convex:12-21:16",region1Id:"t0_0:convex:12",region2Id:"t0_0:convex:21",position:{x:-.5507158262688754,y:1.5536955}},{portId:"t0_0:convex:13-14:17",region1Id:"t0_0:convex:13",region2Id:"t0_0:convex:14",position:{x:-1.1609165,y:1.5257770000000002}},{portId:"t0_0:convex:13-21:18",region1Id:"t0_0:convex:13",region2Id:"t0_0:convex:21",position:{x:-.6210480636924478,y:1.5257775}},{portId:"t0_0:convex:14-15:19",region1Id:"t0_0:convex:14",region2Id:"t0_0:convex:15",position:{x:-1.4697032500000002,y:.935935097421174}},{portId:"t0_0:convex:15-20:20",region1Id:"t0_0:convex:15",region2Id:"t0_0:convex:20",position:{x:-1.46970325,y:.555374879653303}},{portId:"t0_0:convex:16-17:21",region1Id:"t0_0:convex:16",region2Id:"t0_0:convex:17",position:{x:-1.4722192500000002,y:-.29788014216225384}},{portId:"t0_0:convex:16-20:22",region1Id:"t0_0:convex:16",region2Id:"t0_0:convex:20",position:{x:-1.4621442500000001,y:.3173951008096434}},{portId:"t0_0:convex:17-18:23",region1Id:"t0_0:convex:17",region2Id:"t0_0:convex:18",position:{x:-1.47221975,y:-.5237839}},{portId:"t0_0:convex:18-23:24",region1Id:"t0_0:convex:18",region2Id:"t0_0:convex:23",position:{x:-1.2114205,y:-.9080890000000001}},{portId:"t0_0:convex:23-24:25",region1Id:"t0_0:convex:23",region2Id:"t0_0:convex:24",position:{x:-1.21142,y:-.6820997148723771}},{portId:"via-side:t0_0:v:net1:top:27",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:13",position:{x:-.770591,y:1.12317}},{portId:"via-side:t0_0:v:net1:bottom:28",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:5",position:{x:.778514,y:-.162215}},{portId:"via-side:t0_0:v:net1:left:29",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:14",position:{x:-.920591,y:.97317}},{portId:"via-side:t0_0:v:net1:right:30",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:6",position:{x:.9285140000000001,y:-.012215000000000004}},{portId:"via-side:t0_0:v:net2:top:31",region1Id:"t0_0:v:net2",region2Id:"t0_0:convex:8",position:{x:1.014826,y:.57842}},{portId:"via-side:t0_0:v:net2:bottom:32",region1Id:"t0_0:v:net2",region2Id:"t0_0:convex:0",position:{x:-.854951,y:-1.034286}},{portId:"via-side:t0_0:v:net2:left:33",region1Id:"t0_0:v:net2",region2Id:"t0_0:convex:23",position:{x:-1.004951,y:-.884286}},{portId:"via-side:t0_0:v:net2:right:34",region1Id:"t0_0:v:net2",region2Id:"t0_0:convex:7",position:{x:1.164826,y:.42842}},{portId:"via-side:t0_0:v:net3:top:35",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:9",position:{x:.695984,y:.963573}},{portId:"via-side:t0_0:v:net3:left:36",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:17",position:{x:-1.217887,y:-.431891}},{portId:"via-side:t0_0:v:net3:right:37",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:8",position:{x:.8459840000000001,y:.813573}},{portId:"via-side:t0_0:v:net4:top:38",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:12",position:{x:-.273716,y:1.179009}},{portId:"via-side:t0_0:v:net4:bottom:39",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:2",position:{x:.047380000000000005,y:-.8285980000000001}},{portId:"via-side:t0_0:v:net4:left:40",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:15",position:{x:-1.212855,y:.56748}},{portId:"via-side:t0_0:v:net4:right:41",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:3",position:{x:.19738,y:-.678598}},{portId:"via-side:t0_0:v:net5:top:42",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:11",position:{x:.22363,y:1.127538}},{portId:"via-side:t0_0:v:net5:bottom:43",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:3",position:{x:.462204,y:-.54945}},{portId:"via-side:t0_0:v:net5:left:44",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:16",position:{x:-1.197736,y:.06770600000000002}},{portId:"via-side:t0_0:v:net5:right:45",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:5",position:{x:.612204,y:-.39945}}]}},{viaRegionName:"via-tile-6-regions",viaTile:{viasByNet:{net1:[{viaId:"afbcad2b-4805-48e1-aa34-1f4472329d76",diameter:.3,position:{x:.648081,y:-.653655}},{viaId:"d31e4843-afe8-4699-8221-70cba52d9589",diameter:.3,position:{x:.082317,y:.912692}}],net2:[{viaId:"096f26d0-a555-4492-94da-865de1f8e6e6",diameter:.3,position:{x:1.336913,y:.267523}},{viaId:"71432b8b-1d41-4586-88f8-1dd9c542b47b",diameter:.3,position:{x:-.651699,y:-1.264802}}],net3:[{viaId:"833f3d74-7403-4d5b-8999-848795f1be47",diameter:.3,position:{x:-.652635,y:-.2648}},{viaId:"ff5f1055-a4f7-4a85-a790-4769e4eea87b",diameter:.3,position:{x:.58222,y:.92265}}],net4:[{viaId:"6e2c4dc3-f43d-4f13-bff3-c0e08585ceb1",diameter:.3,position:{x:-.15182,y:-1.253675}},{viaId:"b11b8fa4-a804-42b8-8de3-4416f00feda9",diameter:.3,position:{x:-.650488,y:.235198}}],net5:[{viaId:"bd0008ee-fb87-4f6a-922b-14f6d989ee78",diameter:.3,position:{x:-.305576,y:.59719}},{viaId:"cd839c31-ee5e-47be-973e-a4e0fd041bae",diameter:.3,position:{x:.251735,y:-.95847}}],net6:[{viaId:"aa3a0b88-786d-4e3a-9cf4-ab924faca4e9",diameter:.3,position:{x:-.65095,y:-.7648}},{viaId:"c0f2259e-7d00-43c3-bfa3-183bc4286c46",diameter:.3,position:{x:.971187,y:.608473}}]},routeSegments:[{routeId:"net1:route_0",fromPort:"afbcad2b-4805-48e1-aa34-1f4472329d76",toPort:"d31e4843-afe8-4699-8221-70cba52d9589",layer:"bottom",segments:[{x:.648081,y:-.653655},{x:.648081,y:.268604},{x:.082317,y:.834368},{x:.082317,y:.912692}]},{routeId:"net2:route_0",fromPort:"096f26d0-a555-4492-94da-865de1f8e6e6",toPort:"71432b8b-1d41-4586-88f8-1dd9c542b47b",layer:"bottom",segments:[{x:1.336913,y:.267523},{x:1.336913,y:-.531923},{x:.214161,y:-1.654675},{x:-.31792,y:-1.654675},{x:-.651699,y:-1.320896},{x:-.651699,y:-1.264802}]},{routeId:"net3:route_0",fromPort:"833f3d74-7403-4d5b-8999-848795f1be47",toPort:"ff5f1055-a4f7-4a85-a790-4769e4eea87b",layer:"bottom",segments:[{x:-.652635,y:-.2648},{x:-.71759,y:-.2648},{x:-1.051488,y:.069098},{x:-1.051488,y:.418378},{x:-.156174,y:1.313692},{x:.248417,y:1.313692},{x:.58222,y:.979889},{x:.58222,y:.92265}]},{routeId:"net4:route_0",fromPort:"6e2c4dc3-f43d-4f13-bff3-c0e08585ceb1",toPort:"b11b8fa4-a804-42b8-8de3-4416f00feda9",layer:"bottom",segments:[{x:-.15182,y:-1.253675},{x:-.15182,y:-.198515},{x:-.585533,y:.235198},{x:-.650488,y:.235198}]},{routeId:"net5:route_0",fromPort:"bd0008ee-fb87-4f6a-922b-14f6d989ee78",toPort:"cd839c31-ee5e-47be-973e-a4e0fd041bae",layer:"bottom",segments:[{x:-.305576,y:.59719},{x:.14918,y:.142434},{x:.14918,y:-.855915},{x:.251735,y:-.95847}]},{routeId:"net6:route_0",fromPort:"aa3a0b88-786d-4e3a-9cf4-ab924faca4e9",toPort:"c0f2259e-7d00-43c3-bfa3-183bc4286c46",layer:"bottom",segments:[{x:-.65095,y:-.7648},{x:-.75509,y:-.7648},{x:-1.402488,y:-.117402},{x:-1.402488,y:.563766},{x:-.301563,y:1.664692},{x:.442633,y:1.664692},{x:1.023297,y:1.084028},{x:1.023297,y:.660583},{x:.971187,y:.608473}]}],tileWidth:3.1144009999999995,tileHeight:3.619367,regions:[{regionId:"t0_0:v:net1",polygon:[{x:-.067683,y:1.062692},{x:.232317,y:1.062692},{x:.798081,y:-.503655},{x:.798081,y:-.803655},{x:.498081,y:-.803655},{x:-.067683,y:.7626919999999999}],bounds:{minX:-.067683,maxX:.798081,minY:-.803655,maxY:1.062692},center:{x:.365199,y:.12951849999999998},isViaRegion:!0,netName:"net1"},{regionId:"t0_0:v:net2",polygon:[{x:1.186913,y:.417523},{x:1.486913,y:.417523},{x:1.486913,y:.11752300000000002},{x:-.501699,y:-1.414802},{x:-.801699,y:-1.414802},{x:-.801699,y:-1.114802}],bounds:{minX:-.801699,maxX:1.486913,minY:-1.414802,maxY:.417523},center:{x:.3426069999999999,y:-.49863949999999996},isViaRegion:!0,netName:"net2"},{regionId:"t0_0:v:net3",polygon:[{x:.43221999999999994,y:1.0726499999999999},{x:.73222,y:1.0726499999999999},{x:.73222,y:.77265},{x:-.5026349999999999,y:-.41479999999999995},{x:-.802635,y:-.41479999999999995},{x:-.802635,y:-.11479999999999999}],bounds:{minX:-.802635,maxX:.73222,minY:-.41479999999999995,maxY:1.0726499999999999},center:{x:-.035207500000000023,y:.32892499999999997},isViaRegion:!0,netName:"net3"},{regionId:"t0_0:v:net4",polygon:[{x:-.800488,y:.385198},{x:-.5004879999999999,y:.385198},{x:-.001820000000000016,y:-1.1036750000000002},{x:-.001820000000000016,y:-1.403675},{x:-.30182,y:-1.403675},{x:-.800488,y:.085198}],bounds:{minX:-.800488,maxX:-.001820000000000016,minY:-1.403675,maxY:.385198},center:{x:-.40115399999999996,y:-.5092385},isViaRegion:!0,netName:"net4"},{regionId:"t0_0:v:net5",polygon:[{x:-.455576,y:.74719},{x:-.15557600000000002,y:.74719},{x:.40173499999999995,y:-.80847},{x:.40173499999999995,y:-1.10847},{x:.10173499999999999,y:-1.10847},{x:-.455576,y:.44719}],bounds:{minX:-.455576,maxX:.40173499999999995,minY:-1.10847,maxY:.74719},center:{x:-.026920500000000014,y:-.18064000000000002},isViaRegion:!0,netName:"net5"},{regionId:"t0_0:v:net6",polygon:[{x:.821187,y:.7584730000000001},{x:1.121187,y:.7584730000000001},{x:1.121187,y:.458473},{x:-.50095,y:-.9148000000000001},{x:-.80095,y:-.9148000000000001},{x:-.80095,y:-.6148}],bounds:{minX:-.80095,maxX:1.121187,minY:-.9148000000000001,maxY:.7584730000000001},center:{x:.16011849999999997,y:-.07816350000000001},isViaRegion:!0,netName:"net6"},{regionId:"t0_0:convex:0",polygon:[{x:-1.2457623999999998,y:-1.8096835},{x:-.9343212999999998,y:-1.8096835},{x:-.6228802,y:-1.8096825},{x:-.9016970000000001,y:-1.5148},{x:-1.5571994999999998,y:-1.4477448000000002},{x:-1.5572004999999998,y:-1.8096835}],bounds:{minX:-1.5572004999999998,maxX:-.6228802,minY:-1.8096835,maxY:-1.4477448000000002},center:{x:-1.1365101499999999,y:-1.7002129666666665},isViaRegion:!1},{regionId:"t0_0:convex:1",polygon:[{x:-.6228802,y:-1.8096825},{x:-.3114390999999998,y:-1.8096815},{x:-.468569740192827,y:-1.514801},{x:-.9016970000000001,y:-1.5148}],bounds:{minX:-.9016970000000001,maxX:-.3114390999999998,minY:-1.8096825,maxY:-1.5148},center:{x:-.5761465100482067,y:-1.6622412500000001},isViaRegion:!1},{regionId:"t0_0:convex:2",polygon:[{x:-.3737878658736271,y:-1.503676},{x:-.3114390999999998,y:-1.8096815},{x:2e-6,y:-1.8096835},{x:.31144309999999975,y:-1.8096835},{x:.09817799999999999,y:-1.5036770000000002}],bounds:{minX:-.3737878658736271,maxX:.31144309999999975,minY:-1.8096835,maxY:-1.503676},center:{x:-.055120773174725454,y:-1.6872803},isViaRegion:!1},{regionId:"t0_0:convex:3",polygon:[{x:.5017379999999999,y:-1.2084690000000002},{x:.09817699999999999,y:-1.208468},{x:.09817799999999999,y:-1.5036770000000002},{x:.31144309999999975,y:-1.8096835},{x:.6228771999999998,y:-1.8096835}],bounds:{minX:.09817699999999999,maxX:.6228771999999998,minY:-1.8096835,maxY:-1.208468},center:{x:.32648265999999987,y:-1.5079962000000002},isViaRegion:!1},{regionId:"t0_0:convex:4",polygon:[{x:.9343183000000003,y:-1.8096825},{x:1.2457593999999999,y:-1.8096815},{x:1.5572004999999998,y:-1.4477478},{x:1.5572004999999998,y:-1.0858101},{x:.898082,y:-.903656},{x:.5017369999999999,y:-.903655},{x:.5017379999999999,y:-1.2084690000000002},{x:.6228771999999998,y:-1.8096835}],bounds:{minX:.5017369999999999,maxX:1.5572004999999998,minY:-1.8096835,maxY:-.903655},center:{x:.9773641124999999,y:-1.372298175},isViaRegion:!1},{regionId:"t0_0:convex:5",polygon:[{x:1.2457593999999999,y:-1.8096815},{x:1.5572004999999998,y:-1.8096835},{x:1.5572004999999998,y:-1.4477478}],bounds:{minX:1.2457593999999999,maxX:1.5572004999999998,minY:-1.8096835,maxY:-1.4477478},center:{x:1.4533867999999996,y:-1.6890376},isViaRegion:!1},{regionId:"t0_0:convex:6",polygon:[{x:1.5572004999999998,y:-.7238724},{x:1.5571974999999998,y:-.3619347},{x:.898081,y:-.4976807126365452},{x:.898082,y:-.903656},{x:1.5572004999999998,y:-1.0858101}],bounds:{minX:.898081,maxX:1.5572004999999998,minY:-1.0858101,maxY:-.3619347},center:{x:1.2935522999999998,y:-.714590782527309},isViaRegion:!1},{regionId:"t0_0:convex:7",polygon:[{x:1.5571974999999998,y:-.3619347},{x:1.5572004999999998,y:-.007131531126714692},{x:.898081,y:-.4976807126365452}],bounds:{minX:.898081,maxX:1.5572004999999998,minY:-.4976807126365452,maxY:-.007131531126714692},center:{x:1.337493,y:-.28891564792108665},isViaRegion:!1},{regionId:"t0_0:convex:8",polygon:[{x:1.5572004999999998,y:.7238733999999998},{x:1.5572004999999998,y:1.0858111},{x:1.22119,y:.858472}],bounds:{minX:1.22119,maxX:1.5572004999999998,minY:.7238733999999998,maxY:1.0858111},center:{x:1.4451969999999996,y:.8893854999999999},isViaRegion:!1},{regionId:"t0_0:convex:9",polygon:[{x:1.5572004999999998,y:.7238733999999998},{x:1.22119,y:.858472},{x:1.221184,y:.517523},{x:1.5572004999999998,y:.5175249999999999}],bounds:{minX:1.221184,maxX:1.5572004999999998,minY:.517523,maxY:.858472},center:{x:1.3891937499999998,y:.65434835},isViaRegion:!1},{regionId:"t0_0:convex:10",polygon:[{x:.8322189999999999,y:1.17265},{x:.8322219999999999,y:.8584710000000001},{x:1.22119,y:.858472},{x:1.5572004999999998,y:1.0858111},{x:1.5572004999999998,y:1.4477488000000003}],bounds:{minX:.8322189999999999,maxX:1.5572004999999998,minY:.8584710000000001,maxY:1.4477488000000003},center:{x:1.2000064,y:1.08463058},isViaRegion:!1},{regionId:"t0_0:convex:11",polygon:[{x:.8322189999999999,y:1.17265},{x:1.5572004999999998,y:1.4477488000000003},{x:1.5572004999999998,y:1.8096815},{x:1.2457573999999998,y:1.8096825},{x:.9343182999999998,y:1.8096835},{x:.6228792,y:1.8096835},{x:.3114400999999998,y:1.8096835},{x:.39193830311295386,y:1.172649}],bounds:{minX:.3114400999999998,maxX:1.5572004999999998,minY:1.172649,maxY:1.8096835},center:{x:.9316191628891191,y:1.6051827875},isViaRegion:!1},{regionId:"t0_0:convex:12",polygon:[{x:1e-6,y:1.8096815},{x:-.167681,y:1.162693},{x:.30252337094105375,y:1.1626940000000001},{x:.3114400999999998,y:1.8096835}],bounds:{minX:-.167681,maxX:.3114400999999998,minY:1.162693,maxY:1.8096835},center:{x:.11157086773526338,y:1.486188},isViaRegion:!1},{regionId:"t0_0:convex:13",polygon:[{x:1e-6,y:1.8096815},{x:-.3114380999999998,y:1.8096825},{x:-.167681,y:1.162693}],bounds:{minX:-.3114380999999998,maxX:1e-6,minY:1.162693,maxY:1.8096825},center:{x:-.15970603333333325,y:1.594019},isViaRegion:!1},{regionId:"t0_0:convex:14",polygon:[{x:-.6228771999999998,y:1.8096835},{x:-.555576,y:.847189},{x:-.167682,y:.84719},{x:-.167681,y:1.162693},{x:-.3114380999999998,y:1.8096825}],bounds:{minX:-.6228771999999998,maxX:-.167681,minY:.847189,maxY:1.8096835},center:{x:-.3650508599999999,y:1.2952876},isViaRegion:!1},{regionId:"t0_0:convex:15",polygon:[{x:-.555576,y:.847189},{x:-.6228771999999998,y:1.8096835},{x:-.9343233000000002,y:1.8096835},{x:-1.2457623999999998,y:1.8096835},{x:-1.5572004999999998,y:1.8096815},{x:-1.5572004999999998,y:1.4477458},{x:-1.5571994999999998,y:1.0858101},{x:-1.5571984999999997,y:.7238744},{x:-.9004899999999999,y:.4852},{x:-.555577,y:.485196}],bounds:{minX:-1.5572004999999998,maxX:-.555576,minY:.485196,maxY:1.8096835},center:{x:-1.1043404899999998,y:1.23137473},isViaRegion:!1},{regionId:"t0_0:convex:16",polygon:[{x:-1.5571984999999997,y:.7238744},{x:-1.5571974999999998,y:.3619387},{x:-.9004899999999999,y:.4852}],bounds:{minX:-1.5571984999999997,maxX:-.9004899999999999,minY:.3619387,maxY:.7238744},center:{x:-1.338295333333333,y:.5236710333333333},isViaRegion:!1},{regionId:"t0_0:convex:17",polygon:[{x:-.9004909999999999,y:.06889752588522823},{x:-.9004899999999999,y:.4852},{x:-1.5571974999999998,y:.3619387},{x:-1.5572004999999998,y:-2e-6}],bounds:{minX:-1.5572004999999998,maxX:-.9004899999999999,minY:-2e-6,maxY:.4852},center:{x:-1.2288447499999997,y:.22900855647130705},isViaRegion:!1},{regionId:"t0_0:convex:18",polygon:[{x:-1.5572004999999998,y:-.3619377},{x:-1.5572004999999998,y:-.7238733999999998},{x:-.9026339999999999,y:-.5148019999999999},{x:-.902633,y:-.07222869307447181},{x:-1.5572004999999998,y:-2e-6}],bounds:{minX:-1.5572004999999998,maxX:-.902633,minY:-.7238733999999998,maxY:-2e-6},center:{x:-1.2953736999999999,y:-.33456875861489427},isViaRegion:!1},{regionId:"t0_0:convex:19",polygon:[{x:-.900952,y:-1.0148000000000001},{x:-.9009510000000001,y:-.568434282045964},{x:-1.5572004999999998,y:-.7238733999999998},{x:-1.5572004999999998,y:-1.0858091}],bounds:{minX:-1.5572004999999998,maxX:-.9009510000000001,minY:-1.0858091,maxY:-.568434282045964},center:{x:-1.2290759999999998,y:-.848229195511491},isViaRegion:!1},{regionId:"t0_0:convex:20",polygon:[{x:-.901696,y:-1.0656152955659204},{x:-1.5572004999999998,y:-1.0858091},{x:-1.5571994999999998,y:-1.4477448000000002},{x:-.9016970000000001,y:-1.5148}],bounds:{minX:-1.5572004999999998,maxX:-.901696,minY:-1.5148,maxY:-1.0656152955659204},center:{x:-1.22944825,y:-1.2784922988914802},isViaRegion:!1},{regionId:"t0_0:convex:21",polygon:[{x:-.468569740192827,y:-1.514801},{x:-.3114390999999998,y:-1.8096815},{x:-.3737878658736271,y:-1.503676},{x:-.38971616264549963,y:-1.4561149001487406}],bounds:{minX:-.468569740192827,maxX:-.3114390999999998,minY:-1.8096815,maxY:-1.4561149001487406},center:{x:-.3858782171779884,y:-1.5710683500371854},isViaRegion:!1},{regionId:"t0_0:convex:22",polygon:[{x:-.900952,y:-1.0148000000000001},{x:-1.5572004999999998,y:-1.0858091},{x:-.901696,y:-1.0656152955659204},{x:-.8357578110570957,y:-1.014801}],bounds:{minX:-1.5572004999999998,maxX:-.8357578110570957,minY:-1.0858091,maxY:-1.0148000000000001},center:{x:-1.0489015777642738,y:-1.0452563488914801},isViaRegion:!1},{regionId:"t0_0:convex:23",polygon:[{x:-.9026339999999999,y:-.5148019999999999},{x:-1.5572004999999998,y:-.7238733999999998},{x:-.9009510000000001,y:-.568434282045964},{x:-.8375949529611417,y:-.514798}],bounds:{minX:-1.5572004999999998,maxX:-.8375949529611417,minY:-.7238733999999998,maxY:-.514798},center:{x:-1.0495951132402852,y:-.5804769205114909},isViaRegion:!1},{regionId:"t0_0:convex:24",polygon:[{x:-.9004909999999999,y:.06889752588522823},{x:-1.5572004999999998,y:-2e-6},{x:-.902633,y:-.07222869307447181},{x:-.865256043353791,y:-.03628656661060304}],bounds:{minX:-1.5572004999999998,maxX:-.865256043353791,minY:-.07222869307447181,maxY:.06889752588522823},center:{x:-1.0563951358384478,y:-.009904933449961658},isViaRegion:!1},{regionId:"t0_0:convex:25",polygon:[{x:.39193830311295386,y:1.172649},{x:.3114400999999998,y:1.8096835},{x:.30252337094105375,y:1.1626940000000001},{x:.3228996394549733,y:1.1062606316768617}],bounds:{minX:.30252337094105375,maxX:.39193830311295386,minY:1.1062606316768617,maxY:1.8096835},center:{x:.33220035337724513,y:1.3128217829192155},isViaRegion:!1}],ports:[{portId:"t0_0:convex:0-1:0",region1Id:"t0_0:convex:0",region2Id:"t0_0:convex:1",position:{x:-.7622886,y:-1.6622412500000001}},{portId:"t0_0:convex:0-20:1",region1Id:"t0_0:convex:0",region2Id:"t0_0:convex:20",position:{x:-1.22944825,y:-1.4812724}},{portId:"t0_0:convex:1-21:2",region1Id:"t0_0:convex:1",region2Id:"t0_0:convex:21",position:{x:-.3900044200964134,y:-1.6622412500000001}},{portId:"t0_0:convex:2-3:3",region1Id:"t0_0:convex:2",region2Id:"t0_0:convex:3",position:{x:.20481054999999987,y:-1.65668025}},{portId:"t0_0:convex:2-21:4",region1Id:"t0_0:convex:2",region2Id:"t0_0:convex:21",position:{x:-.3426134829368135,y:-1.65667875}},{portId:"t0_0:convex:3-4:5",region1Id:"t0_0:convex:3",region2Id:"t0_0:convex:4",position:{x:.5623075999999998,y:-1.5090762500000001}},{portId:"t0_0:convex:4-5:6",region1Id:"t0_0:convex:4",region2Id:"t0_0:convex:5",position:{x:1.4014799499999997,y:-1.62871465}},{portId:"t0_0:convex:4-6:7",region1Id:"t0_0:convex:4",region2Id:"t0_0:convex:6",position:{x:1.22764125,y:-.99473305}},{portId:"t0_0:convex:6-7:8",region1Id:"t0_0:convex:6",region2Id:"t0_0:convex:7",position:{x:1.22763925,y:-.4298077063182726}},{portId:"t0_0:convex:8-9:9",region1Id:"t0_0:convex:8",region2Id:"t0_0:convex:9",position:{x:1.3891952499999998,y:.7911727}},{portId:"t0_0:convex:8-10:10",region1Id:"t0_0:convex:8",region2Id:"t0_0:convex:10",position:{x:1.3891952499999998,y:.9721415499999999}},{portId:"t0_0:convex:10-11:11",region1Id:"t0_0:convex:10",region2Id:"t0_0:convex:11",position:{x:1.19470975,y:1.3101994000000001}},{portId:"t0_0:convex:11-12:12",region1Id:"t0_0:convex:11",region2Id:"t0_0:convex:12",position:{x:.35160563047796883,y:1.4918276021563592}},{portId:"t0_0:convex:11-25:13",region1Id:"t0_0:convex:11",region2Id:"t0_0:convex:25",position:{x:.3516892015564768,y:1.49116625}},{portId:"t0_0:convex:12-13:15",region1Id:"t0_0:convex:12",region2Id:"t0_0:convex:13",position:{x:-.08384,y:1.48618725}},{portId:"t0_0:convex:12-25:16",region1Id:"t0_0:convex:12",region2Id:"t0_0:convex:25",position:{x:.307058811859238,y:1.4917813404964075}},{portId:"t0_0:convex:12-25:17",region1Id:"t0_0:convex:12",region2Id:"t0_0:convex:25",position:{x:.30698173547052676,y:1.4861887500000002}},{portId:"t0_0:convex:13-14:18",region1Id:"t0_0:convex:13",region2Id:"t0_0:convex:14",position:{x:-.2395595499999999,y:1.48618775}},{portId:"t0_0:convex:14-15:19",region1Id:"t0_0:convex:14",region2Id:"t0_0:convex:15",position:{x:-.6060518999999999,y:1.569059875}},{portId:"t0_0:convex:14-15:20",region1Id:"t0_0:convex:14",region2Id:"t0_0:convex:15",position:{x:-.5724012999999999,y:1.087812625}},{portId:"t0_0:convex:15-16:21",region1Id:"t0_0:convex:15",region2Id:"t0_0:convex:16",position:{x:-1.2288442499999999,y:.6045372}},{portId:"t0_0:convex:16-17:22",region1Id:"t0_0:convex:16",region2Id:"t0_0:convex:17",position:{x:-1.2288437499999998,y:.42356935}},{portId:"t0_0:convex:17-24:23",region1Id:"t0_0:convex:17",region2Id:"t0_0:convex:24",position:{x:-1.2288457499999998,y:.03444776294261411}},{portId:"t0_0:convex:18-19:24",region1Id:"t0_0:convex:18",region2Id:"t0_0:convex:19",position:{x:-1.2369259236689427,y:-.621576300991815}},{portId:"t0_0:convex:18-23:25",region1Id:"t0_0:convex:18",region2Id:"t0_0:convex:23",position:{x:-1.2299172499999997,y:-.6193376999999998}},{portId:"t0_0:convex:18-24:27",region1Id:"t0_0:convex:18",region2Id:"t0_0:convex:24",position:{x:-1.22991675,y:-.03611534653723591}},{portId:"t0_0:convex:19-20:28",region1Id:"t0_0:convex:19",region2Id:"t0_0:convex:20",position:{x:-1.2321613530099345,y:-1.050638372306859}},{portId:"t0_0:convex:19-22:29",region1Id:"t0_0:convex:19",region2Id:"t0_0:convex:22",position:{x:-1.2290762499999999,y:-1.0503045500000001}},{portId:"t0_0:convex:19-23:31",region1Id:"t0_0:convex:19",region2Id:"t0_0:convex:23",position:{x:-1.2290757499999998,y:-.6461538410229819}},{portId:"t0_0:convex:20-22:33",region1Id:"t0_0:convex:20",region2Id:"t0_0:convex:22",position:{x:-1.22944825,y:-1.0757121977829602}},{portId:"via-side:t0_0:v:net1:top:35",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:12",position:{x:.082317,y:1.062692}},{portId:"via-side:t0_0:v:net1:bottom:36",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:4",position:{x:.648081,y:-.803655}},{portId:"via-side:t0_0:v:net1:left:37",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:14",position:{x:-.067683,y:.912692}},{portId:"via-side:t0_0:v:net1:right:38",region1Id:"t0_0:v:net1",region2Id:"t0_0:convex:6",position:{x:.798081,y:-.653655}},{portId:"via-side:t0_0:v:net2:top:39",region1Id:"t0_0:v:net2",region2Id:"t0_0:convex:9",position:{x:1.336913,y:.417523}},{portId:"via-side:t0_0:v:net2:bottom:40",region1Id:"t0_0:v:net2",region2Id:"t0_0:convex:1",position:{x:-.651699,y:-1.414802}},{portId:"via-side:t0_0:v:net2:left:41",region1Id:"t0_0:v:net2",region2Id:"t0_0:convex:20",position:{x:-.801699,y:-1.264802}},{portId:"via-side:t0_0:v:net3:top:42",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:11",position:{x:.58222,y:1.0726499999999999}},{portId:"via-side:t0_0:v:net3:left:43",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:18",position:{x:-.802635,y:-.2648}},{portId:"via-side:t0_0:v:net3:right:44",region1Id:"t0_0:v:net3",region2Id:"t0_0:convex:10",position:{x:.73222,y:.92265}},{portId:"via-side:t0_0:v:net4:top:45",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:15",position:{x:-.650488,y:.385198}},{portId:"via-side:t0_0:v:net4:bottom:46",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:2",position:{x:-.15182,y:-1.403675}},{portId:"via-side:t0_0:v:net4:left:47",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:17",position:{x:-.800488,y:.235198}},{portId:"via-side:t0_0:v:net4:right:48",region1Id:"t0_0:v:net4",region2Id:"t0_0:convex:3",position:{x:-.001820000000000016,y:-1.253675}},{portId:"via-side:t0_0:v:net5:top:49",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:14",position:{x:-.305576,y:.74719}},{portId:"via-side:t0_0:v:net5:bottom:50",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:3",position:{x:.251735,y:-1.10847}},{portId:"via-side:t0_0:v:net5:left:51",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:15",position:{x:-.455576,y:.59719}},{portId:"via-side:t0_0:v:net5:right:52",region1Id:"t0_0:v:net5",region2Id:"t0_0:convex:4",position:{x:.40173499999999995,y:-.95847}},{portId:"via-side:t0_0:v:net6:top:53",region1Id:"t0_0:v:net6",region2Id:"t0_0:convex:10",position:{x:.971187,y:.7584730000000001}},{portId:"via-side:t0_0:v:net6:left:54",region1Id:"t0_0:v:net6",region2Id:"t0_0:convex:19",position:{x:-.80095,y:-.7648}},{portId:"via-side:t0_0:v:net6:right:55",region1Id:"t0_0:v:net6",region2Id:"t0_0:convex:9",position:{x:1.121187,y:.608473}}]}}],mh=t=>Math.round(100*t)/100,yh=(t,e,n)=>(n.y-t.y)*(e.x-t.x)>(e.y-t.y)*(n.x-t.x),xh=(t,e,n,o)=>yh(t,n,o)!==yh(e,n,o)&&yh(t,e,n)!==yh(t,e,o),vh=t=>{let e=0;for(let n=0;n<t.length;n++)for(let o=n+1;o<t.length;o++)xh(t[n].start,t[n].end,t[o].start,t[o].end)&&e++;return e},bh=(t,e)=>{const n=Object.values(e.viaTile.viasByNet).reduce((t,e)=>t+e.length,0),o=Object.keys(e.viaTile.viasByNet).length,i=e.viaTile.routeSegments.length,s=(t=>{const e=[];for(const n of Object.values(t.viasByNet))for(const t of n)e.push(t.position);for(const n of t.routeSegments)for(const t of n.segments)e.push(t);if(0===e.length)return{width:1,height:1};const n=Math.min(...e.map(t=>t.x)),o=Math.max(...e.map(t=>t.x)),i=Math.min(...e.map(t=>t.y)),s=Math.max(...e.map(t=>t.y));return{width:Math.max(o-n,.01),height:Math.max(s-i,.01)}})(e.viaTile),r=Math.max(e.viaTile.tileWidth&&e.viaTile.tileHeight?e.viaTile.tileWidth*e.viaTile.tileHeight:s.width*s.height,.01),a=Math.max(t.graphWidthMm*t.graphHeightMm,.01),c=t.intersectionCount/Math.max(t.connectionCount,1),h=t.connectionCount/a,l=1.2*t.connectionCount+1.5*t.intersectionCount+5*c+40*h,d=3.1*n+2.4*i+.5*o+1/r*4.5,u=(m=(d-l)/3.2,p=1/(1+Math.exp(-m)),f=0,g=1,Math.max(f,Math.min(g,p)));var p,f,g,m;const y=Math.max(0,(d-l)/Math.max(l,1)),x=Math.max(0,(l-d)/Math.max(l,1)),v=120*t.connectionCount+140*t.intersectionCount+900*y+6e3*x;return{viaRegionName:e.viaRegionName,predictedReliability:u,estimatedIterationCost:v,capacityScore:d,requiredCapacityScore:l,acceptedAsReliable:u>=.9}},Ph=(t,e)=>{const n=(t.xyConnections&&t.xyConnections.length>0?t.xyConnections:e).slice();let o=t.graphWidthMm,i=t.graphHeightMm,s=t.connectionCount,r=t.intersectionCount;if(t.sample){const e=(t=>{const e=t.connections??[],n=new Map((t.connectionRegions??[]).map(t=>[t.regionId,t.d.center])),o=[];for(const t of e){const e=n.get(t.startRegionId),i=n.get(t.endRegionId);e&&i&&o.push({connectionId:t.connectionId,start:e,end:i})}return o})(t.sample);if(0===n.length&&e.length>0&&n.push(...e),s||(s=t.sample.connections?.length??n.length),null==r&&(r=t.sample.config?.numCrossings??(n.length>0?vh(n):0)),null==o||null==i){const e=(t=>{const e=t.connectionRegions??[];if(0===e.length)return null;const n=Math.min(...e.map(t=>t.d.bounds.minX)),o=Math.max(...e.map(t=>t.d.bounds.maxX)),i=Math.min(...e.map(t=>t.d.bounds.minY));return{widthMm:o-n,heightMm:Math.max(...e.map(t=>t.d.bounds.maxY))-i}})(t.sample);e&&(o=o??e.widthMm,i=i??e.heightMm)}}if(n.length>0){const t=(t=>{if(0===t.length)throw new Error("Cannot calculate bounds from empty connections array");let e=1/0,n=-1/0,o=1/0,i=-1/0;for(const s of t)e=Math.min(e,s.start.x,s.end.x),n=Math.max(n,s.start.x,s.end.x),o=Math.min(o,s.start.y,s.end.y),i=Math.max(i,s.start.y,s.end.y);return{minX:e,maxX:n,minY:o,maxY:i}})(n);o=o??t.maxX-t.minX,i=i??t.maxY-t.minY,s=s??n.length,r=r??vh(n)}if(null==o||null==i||null==s||null==r)throw new Error("Insufficient graph input. Provide width/height/connections/intersections, or pass xyConnections.");return{graphWidthMm:mh(o),graphHeightMm:mh(i),connectionCount:s,intersectionCount:r}},Sh=(t,e)=>{const n=((t,e=[],n=gh)=>{if(0===n.length)throw new Error("No via-tile candidates provided");const o=t.xyConnections&&t.xyConnections.length>0?t.xyConnections:e,i=Ph(t,o),s=n.map(t=>bh(i,t)).sort((t,e)=>{if(t.acceptedAsReliable!==e.acceptedAsReliable)return t.acceptedAsReliable?-1:1;if(t.acceptedAsReliable&&e.acceptedAsReliable){if(t.estimatedIterationCost!==e.estimatedIterationCost)return t.estimatedIterationCost-e.estimatedIterationCost}else if(t.predictedReliability!==e.predictedReliability)return e.predictedReliability-t.predictedReliability;return t.estimatedIterationCost-e.estimatedIterationCost}),r=(t=>{const e=t.graphWidthMm*t.graphHeightMm;return t.graphWidthMm>22?"via-tile-4-regions":t.intersectionCount<=20?t.intersectionCount<=17?"via-tile-5-regions":t.graphWidthMm<=12.6?"via-tile-3-regions":"via-tile-4-regions":e<=246.01?"via-tile-3-regions":"via-tile-5-regions"})(i),a=s.find(t=>t.viaRegionName===r);return a?{recommendedViaRegionName:a.viaRegionName,inputFeatures:i,candidates:[a,...s.filter(t=>t.viaRegionName!==r)]}:{recommendedViaRegionName:s[0].viaRegionName,inputFeatures:i,candidates:s}})(t,e),o=gh.find(t=>t.viaRegionName===n.recommendedViaRegionName);return o?.viaTile??fh};function Ih(t,e,n){const o=(i=e,Boolean(i&&"object"==typeof i&&"viasByNet"in i&&"routeSegments"in i)?e:Sh({...e??{},xyConnections:e?.xyConnections??t},t));var i;const s=function(t){if(0===t.length)throw new Error("Cannot calculate bounds from empty connections array");let e=1/0,n=-1/0,o=1/0,i=-1/0;for(const s of t)e=Math.min(e,s.start.x,s.end.x),n=Math.max(n,s.start.x,s.end.x),o=Math.min(o,s.start.y,s.end.y),i=Math.max(i,s.start.y,s.end.y);return{minX:e,maxX:n,minY:o,maxY:i}}(t),{regions:r,ports:a,viaTile:c,tileCount:h}=ph({viaTile:o,bounds:s,tileWidth:n?.tileWidth??o.tileWidth,tileHeight:n?.tileHeight??o.tileHeight,tileSize:n?.tileSize,portPitch:n?.portPitch,clearance:n?.clearance,concavityTolerance:n?.concavityTolerance}),l=((t,e)=>{const n=[...t.regions],o=[...t.ports],i=[];for(const s of e){const{start:e,end:r,connectionId:a}=s,c=Ki(`conn:${a}:start`,e.x,e.y);n.push(c);const h=Ki(`conn:${a}:end`,r.x,r.y);n.push(h);const l=Cs({x:e.x,y:e.y,regions:t.regions});if(l){const t=Ji(`conn:${a}:start-port`,c,l.region,l.portPosition);o.push(t)}const d=Cs({x:r.x,y:r.y,regions:t.regions});if(d){const t=Ji(`conn:${a}:end-port`,h,d.region,d.portPosition);o.push(t)}const u={connectionId:a,mutuallyConnectedNetworkId:a,startRegion:c,endRegion:h};i.push(u)}return{regions:n,ports:o,connections:i}})({regions:r,ports:a},t);return{...l,viaTile:c,tileCount:h}}var Mh=class extends Dn{getSolverName(){return"FixedTopologyHighDensityIntraNodeSolver"}constructorParams;nodeWithPortPoints;colorMap;traceWidth;connMap;rootConnectionNameByConnectionId=new Map;lastActiveSubSolver=null;solvedRoutes=[];vias=[];tiledViasByNet={};constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.connMap=t.connMap,this.MAX_ITERATIONS=24411*(t.effort??1),0===Object.keys(this.colorMap).length&&(this.colorMap=(t=>{const e=["#e6194b","#3cb44b","#ffe119","#4363d8","#f58231","#911eb4","#46f0f0","#f032e6","#bcf60c","#fabebe"],n={},o=new Set;for(const e of t.portPoints)o.add(e.connectionName);let i=0;for(const t of Array.from(o))n[t]=e[i%e.length],i++;return n})(this.nodeWithPortPoints))}getConstructorParams(){return this.constructorParams}_getViaTileDiameter(t){for(const e of Object.values(t.viasByNet))if(e.length>0)return e[0].diameter;return.3}_initializeGraph(){const t=new Map;for(const e of this.nodeWithPortPoints.portPoints){const n=t.get(e.connectionName);n?n.points.push(e):t.set(e.connectionName,{points:[e],rootConnectionName:e.rootConnectionName})}this.rootConnectionNameByConnectionId.clear();const e=[];for(const[n,o]of t.entries())o.points.length<2||(this.rootConnectionNameByConnectionId.set(n,o.rootConnectionName),e.push({connectionId:n,start:{x:o.points[0].x,y:o.points[0].y},end:{x:o.points[o.points.length-1].x,y:o.points[o.points.length-1].y}}));if(0===e.length)return null;const n=Ih(e);return this.tiledViasByNet=n.viaTile.viasByNet??{},new _s({inputGraph:{regions:n.regions,ports:n.ports},inputConnections:n.connections,viaTile:n.viaTile})}_step(){let t=this.activeSubSolver;if(!t){if(t=this._initializeGraph(),!t)return void(this.solved=!0);this.activeSubSolver=t,this.lastActiveSubSolver=t}t.step(),t.solved?(this._processResults(t),this.lastActiveSubSolver=t,this.activeSubSolver=null,this.solved=!0):t.failed&&(this.error=t.error,this.lastActiveSubSolver=t,this.activeSubSolver=null,this.failed=!0)}_upsertGlobalVia(t,e,n,o){const i=`${e.x.toFixed(4)},${e.y.toFixed(4)}`;t.has(i)||t.set(i,{center:{x:e.x,y:e.y},diameter:n,connectedTo:new Set}),t.get(i).connectedTo.add(o)}_upsertRouteViaRegion(t,e,n,o,i){t.some(t=>Math.abs(t.center.x-e.x)<.01&&Math.abs(t.center.y-e.y)<.01)||t.push({viaRegionId:i,center:{x:e.x,y:e.y},diameter:n,connectedTo:[o]})}_appendRoutePoint(t,e){const n=t[t.length-1];n&&Math.abs(n.x-e.x)<=1e-6&&Math.abs(n.y-e.y)<=1e-6&&n.z===e.z||t.push(e)}_parseViaRegionNetName(t){const e=t.lastIndexOf(":v:");if(-1!==e)return t.slice(e+3);const n=t.lastIndexOf(":");return-1===n?t:t.slice(n+1)}_parseViaRegionTilePrefix(t){const e=t.lastIndexOf(":v:");return e<=0?null:t.slice(0,e)}_selectViasForTraversedRegion(t,e){const n=this._parseViaRegionNetName(e.regionId);if(!n)return[];const o=t.viasByNet[n];if(!o||0===o.length)return[];const i=this._parseViaRegionTilePrefix(e.regionId);if(!i)return o;const s=o.filter(t=>t.viaId.startsWith(`${i}:`));return s.length>0?s:o}_findNearestVia(t,e){let n=null,o=1/0;for(const i of t){const t=i.position.x-e.x,s=i.position.y-e.y,r=t*t+s*s;r<o&&(o=r,n=i)}return n}_getBottomRoutePointsBetweenVias(t,e,n,o){if(n.viaId===o.viaId)return[n.position];const i=new Set(e.map(t=>t.viaId)),s=t.routeSegments.filter(t=>"bottom"===t.layer&&t.segments.length>=2&&i.has(t.fromPort)&&i.has(t.toPort)),r=new Map,a=(t,e,n)=>{r.has(t)||r.set(t,[]),r.get(t).push({to:e,points:n})};for(const t of s)a(t.fromPort,t.toPort,t.segments),a(t.toPort,t.fromPort,[...t.segments].reverse());const c=[n.viaId],h=new Set([n.viaId]),l=new Map;for(;c.length>0;){const t=c.shift();if(t===o.viaId)break;for(const e of r.get(t)??[])h.has(e.to)||(h.add(e.to),l.set(e.to,{from:t,points:e.points}),c.push(e.to))}if(!l.has(o.viaId))return null;const d=[];let u=o.viaId;for(;u!==n.viaId;){const t=l.get(u);if(!t)return null;d.push(t.points),u=t.from}d.reverse();const p=[];for(const t of d)for(const e of t){const t=p[p.length-1];(!t||Math.abs(t.x-e.x)>1e-6||Math.abs(t.y-e.y)>1e-6)&&p.push(e)}return p.length>0?p:null}_appendViaUsage(t,e,n,o,i){i&&(this._upsertGlobalVia(t,i.position,i.diameter,n),this._upsertRouteViaRegion(e,i.position,i.diameter,n,o))}_processResults(t){this.solvedRoutes=[];const e=t.viaTile,n=e?this._getViaTileDiameter(e):.3,o=new Map;for(const i of t.solvedRoutes){const t=i.connection.connectionId,s=this.rootConnectionNameByConnectionId.get(t),r=[],a=[],c=i.path;if(0===c.length)continue;const h=c[0].port;this._appendRoutePoint(r,{x:h.d.x,y:h.d.y,z:0});for(let n=1;n<c.length;n++){const i=c[n-1],s=c[n],h={x:i.port.d.x,y:i.port.d.y},l={x:s.port.d.x,y:s.port.d.y},d=s.lastRegion;if(!d?.d?.isViaRegion||!e){this._appendRoutePoint(r,{x:l.x,y:l.y,z:0});continue}const u=this._selectViasForTraversedRegion(e,d);if(0===u.length){this._appendRoutePoint(r,{x:l.x,y:l.y,z:0});continue}const p=this._findNearestVia(u,h),f=this._findNearestVia(u,l);if(!p||!f){this._appendRoutePoint(r,{x:l.x,y:l.y,z:0});continue}const g=this._getBottomRoutePointsBetweenVias(e,u,p,f);if(g&&0!==g.length){this._appendViaUsage(o,a,t,d.regionId,p),this._appendViaUsage(o,a,t,d.regionId,f),this._appendRoutePoint(r,{x:p.position.x,y:p.position.y,z:0}),this._appendRoutePoint(r,{x:p.position.x,y:p.position.y,z:1});for(const t of g)this._appendRoutePoint(r,{x:t.x,y:t.y,z:1});this._appendRoutePoint(r,{x:f.position.x,y:f.position.y,z:1}),this._appendRoutePoint(r,{x:f.position.x,y:f.position.y,z:0}),this._appendRoutePoint(r,{x:l.x,y:l.y,z:0})}else this._appendRoutePoint(r,{x:l.x,y:l.y,z:0})}const l=a.map(t=>({x:t.center.x,y:t.center.y}));this.solvedRoutes.push({connectionName:t,rootConnectionName:s,traceThickness:this.traceWidth,viaDiameter:a.length>0?Math.max(...a.map(t=>t.diameter)):n,route:r,vias:l,viaRegions:a})}let i=0;this.vias=Array.from(o.values()).map(t=>({viaRegionId:"via_"+i++,center:t.center,diameter:t.diameter,connectedTo:Array.from(t.connectedTo)}))}getOutput(){return this.solvedRoutes}getOutputVias(){return this.vias}visualize(){return this.activeSubSolver?this.activeSubSolver.visualize():this.lastActiveSubSolver?this.lastActiveSubSolver.visualize():super.visualize()}},_h=class extends io{getSolverName(){return"HyperSingleIntraNodeSolver"}constructorParams;solvedRoutes=[];nodeWithPortPoints;connMap;effort;constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.connMap=t.connMap,this.constructorParams=t,this.effort=t.effort??1,this.MAX_ITERATIONS=1e7*this.effort,this.GREEDY_MULTIPLIER=5,this.MIN_SUBSTEPS=100}getCombinationDefs(){return[["multiHeadPolyLine"],["majorCombinations","orderings6","cellSizeFactor"],["noVias"],["orderings50"],["flipTraceAlignmentDirection","orderings6"],["closedFormSingleTrace"],["highDensityA01"],["highDensityA02"],["fixedTopologyHighDensityIntraNodeSolver"]]}getHyperParameterDefs(){return[{name:"majorCombinations",possibleValues:[{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:2,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROXIMITY_VD:10,MISALIGNED_DIST_PENALTY_FACTOR:5},{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:.5,FUTURE_CONNECTION_PROXIMITY_VD:5,MISALIGNED_DIST_PENALTY_FACTOR:2},{FUTURE_CONNECTION_PROX_TRACE_PENALTY_FACTOR:10,FUTURE_CONNECTION_PROX_VIA_PENALTY_FACTOR:1,FUTURE_CONNECTION_PROXIMITY_VD:5,MISALIGNED_DIST_PENALTY_FACTOR:10,VIA_PENALTY_FACTOR_2:1}]},{name:"orderings6",possibleValues:[{SHUFFLE_SEED:0},{SHUFFLE_SEED:1},{SHUFFLE_SEED:2},{SHUFFLE_SEED:3},{SHUFFLE_SEED:4},{SHUFFLE_SEED:5}]},{name:"cellSizeFactor",possibleValues:[{CELL_SIZE_FACTOR:.5},{CELL_SIZE_FACTOR:1}]},{name:"flipTraceAlignmentDirection",possibleValues:[{FLIP_TRACE_ALIGNMENT_DIRECTION:!0}]},{name:"noVias",possibleValues:[{CELL_SIZE_FACTOR:2,VIA_PENALTY_FACTOR_2:10}]},{name:"orderings50",possibleValues:Array.from({length:20},(t,e)=>({SHUFFLE_SEED:100+e}))},{name:"closedFormSingleTrace",possibleValues:[{CLOSED_FORM_SINGLE_TRANSITION:!0}]},{name:"multiHeadPolyLine",possibleValues:[{MULTI_HEAD_POLYLINE_SOLVER:!0,SEGMENTS_PER_POLYLINE:6,BOUNDARY_PADDING:.05},{MULTI_HEAD_POLYLINE_SOLVER:!0,SEGMENTS_PER_POLYLINE:6,BOUNDARY_PADDING:-.05,ITERATION_PENALTY:1e4,MINIMUM_FINAL_ACCEPTANCE_GAP:.001}]},{name:"highDensityA01",possibleValues:[{HIGH_DENSITY_A01:!0}]},{name:"fixedTopologyHighDensityIntraNodeSolver",possibleValues:[{FIXED_TOPOLOGY_HIGH_DENSITY_INTRA_NODE_SOLVER:!0}]},{name:"highDensityA02",possibleValues:[{HIGH_DENSITY_A02:!0}]}]}computeG(t){return t instanceof Go||t instanceof Zo?t.iterations/1e6:t?.hyperParameters?.MULTI_HEAD_POLYLINE_SOLVER?1e3+((t.hyperParameters?.ITERATION_PENALTY??0)+t.iterations)/1e4+1e4*(t.hyperParameters.SEGMENTS_PER_POLYLINE-3):t.iterations/1e4}computeH(t){return 1-(t.progress||0)}generateSolver(t){if(t.HIGH_DENSITY_A01){const e=new Go({nodeWithPortPoints:this.nodeWithPortPoints,cellSizeMm:.1,viaDiameter:this.constructorParams.viaDiameter??.3,viaMinDistFromBorder:.15,traceMargin:.15,traceThickness:this.constructorParams.traceWidth??.15,hyperParameters:{shuffleSeed:t.SHUFFLE_SEED??0}});return e.MAX_ITERATIONS=1e7,e}if(t.HIGH_DENSITY_A02){const e=new Zo({nodeWithPortPoints:this.nodeWithPortPoints,outerGridCellSize:.1,outerGridCellThickness:2,innerGridCellSize:.4,viaDiameter:this.constructorParams.viaDiameter??.3,viaMinDistFromBorder:.15,traceMargin:.15,enableDeferredConflictRepair:!0,maxDeferredRepairPasses:48,edgePenaltyStrength:.2,traceThickness:.1,hyperParameters:{greedyMultiplier:1.2,shuffleSeed:t.SHUFFLE_SEED??0,ripCost:1}});return e.MAX_ITERATIONS=2e7*this.effort,e}return t.CLOSED_FORM_TWO_TRACE_SAME_LAYER?new ro({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.CLOSED_FORM_TWO_TRACE_TRANSITION_CROSSING?new vo({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.CLOSED_FORM_SINGLE_TRANSITION?new bo({nodeWithPortPoints:this.nodeWithPortPoints,viaDiameter:this.constructorParams.viaDiameter}):t.MULTI_HEAD_POLYLINE_SOLVER?new Uo({nodeWithPortPoints:this.nodeWithPortPoints,connMap:this.connMap,hyperParameters:t,viaDiameter:this.constructorParams.viaDiameter}):t.FIXED_TOPOLOGY_HIGH_DENSITY_INTRA_NODE_SOLVER?new Mh({nodeWithPortPoints:this.nodeWithPortPoints,connMap:this.connMap,colorMap:this.constructorParams.colorMap,traceWidth:this.constructorParams.traceWidth,effort:this.effort}):new oo({...this.constructorParams,hyperParameters:t})}onSolve(t){let e;e=t.solver instanceof Go||t.solver instanceof Zo?t.solver.getOutput():t.solver.solvedRoutes,this.solvedRoutes=e.map(t=>{const e=this.nodeWithPortPoints.portPoints.find(e=>e.connectionName===t.connectionName);return e?.rootConnectionName?{...t,rootConnectionName:e.rootConnectionName}:t})}},Nh=class extends Dn{getSolverName(){return"HighDensitySolver"}unsolvedNodePortPoints;routes;colorMap;defaultViaDiameter=.3;defaultTraceThickness=.15;viaDiameter;traceWidth;effort;failedSolvers;activeSubSolver=null;connMap;constructor({nodePortPoints:t,colorMap:e,connMap:n,viaDiameter:o,traceWidth:i,effort:s}){super(),this.unsolvedNodePortPoints=t,this.colorMap=e??{},this.connMap=n,this.routes=[],this.failedSolvers=[],this.effort=s??1,this.MAX_ITERATIONS=1e7*this.effort,this.viaDiameter=o??this.defaultViaDiameter,this.traceWidth=i??this.defaultTraceThickness}_step(){if(this.updateCacheStats(),this.activeSubSolver)return this.activeSubSolver.step(),this.activeSubSolver.solved?(this.routes.push(...this.activeSubSolver.solvedRoutes),this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSolvers.push(this.activeSubSolver),this.activeSubSolver=null),void this.updateCacheStats();if(0===this.unsolvedNodePortPoints.length)return this.failedSolvers.length>0?(this.solved=!1,this.failed=!0,this.error=`Failed to solve ${this.failedSolvers.length} nodes, ${this.failedSolvers.slice(0,5).map(t=>t.nodeWithPortPoints.capacityMeshNodeId)}. err0: ${this.failedSolvers[0].error}.`,void this.updateCacheStats()):(this.solved=!0,void this.updateCacheStats());const t=this.unsolvedNodePortPoints.pop();this.activeSubSolver=new _h({nodeWithPortPoints:t,colorMap:this.colorMap,connMap:this.connMap,viaDiameter:this.viaDiameter,traceWidth:this.traceWidth,effort:this.effort}),this.updateCacheStats()}updateCacheStats(){const t=Se();this.stats.intraNodeCacheHits=t.cacheHits,this.stats.intraNodeCacheMisses=t.cacheMisses}visualize(){let t={lines:[],points:[],rects:[],circles:[]};for(const e of this.routes){const n=jn(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const o of n)t.lines.push({points:o.points,label:o.connectionName,strokeColor:0===o.z?o.color:Mn(o.color,.75),layer:`z${o.z}`,strokeWidth:e.traceThickness,strokeDash:0!==o.z?"10, 5":void 0});for(const n of e.vias)t.circles.push({center:n,layer:"z0,1",radius:e.viaDiameter/2,fill:this.colorMap[e.connectionName],label:`${e.connectionName} via`})}for(const e of this.failedSolvers){const n=e.nodeWithPortPoints,o=.1*n.width,i=.1*n.height;t.rects.push({center:{x:n.center.x-o/2,y:n.center.y-i/2},layer:"did_not_connect",width:o,height:i,fill:"red",label:`Failed: ${n.capacityMeshNodeId}`});const s={};for(const t of n.portPoints)s[t.connectionName]||(s[t.connectionName]=[]),s[t.connectionName].push({x:t.x,y:t.y,z:t.z});for(const[e,n]of Object.entries(s))for(let e=0;e<n.length-1;e++){const o=n[e],i=n[e+1];t.lines.push({points:[o,i],strokeColor:"red",strokeDash:"10, 5",layer:"did_not_connect"})}}return this.activeSubSolver&&(t=Bn(t,this.activeSubSolver.visualize())),t}};function Ch(t,e){const n=[],o=e.filter(t=>t._containsTarget),i=new Map;for(const s of t.connections){const t=[];for(const n of s.pointsToConnect){let i=e[0],s=Number.MAX_VALUE;for(const t of o){const e=Math.sqrt((t.center.x-n.x)**2+(t.center.y-n.y)**2);e<s&&(s=e,i=t)}t.push(i)}if(t.length<2)throw new Error(`Not enough nodes for connection "${s.name}", only ${t.length} found`);i.set(s.name,t.map(t=>t.capacityMeshNodeId)),n.push({connection:s,nodeIds:[t[0].capacityMeshNodeId,t[t.length-1].capacityMeshNodeId],straightLineDistance:F(t[0].center,t[t.length-1].center)})}return{unshuffledConnectionsWithResults:n,connectionNameToGoalNodeIds:i}}function Th(t,e){const n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),o=e.map(t=>(t.width+t.height)/2).filter(t=>Number.isFinite(t)&&t>0),i=o.length>0?o.reduce((t,e)=>t+e,0)/o.length:1,s=e.filter(t=>t._offBoardConnectionId),r=new Map,a=new Map,c=new Map;for(const t of e)a.set(t.capacityMeshNodeId,[]),c.set(t.capacityMeshNodeId,[]);for(const t of e)for(const e of t.portPoints){r.set(e.portPointId,e);for(const t of e.connectionNodeIds){const n=a.get(t);n&&!n.some(t=>t.portPointId===e.portPointId)&&n.push(e)}}const{unshuffledConnectionsWithResults:h,connectionNameToGoalNodeIds:l}=Ch(t,e);return{nodeMap:n,avgNodePitch:i,offBoardNodes:s,portPointMap:r,nodePortPointsMap:a,nodeAssignedPortPoints:c,unshuffledConnectionsWithResults:h,connectionNameToGoalNodeIds:l}}function Eh(t,e,n,o,i){const s=n-e,r=i-o,a=1e-6;if(Math.abs(t.y-i)<a)return t.x-e;if(Math.abs(t.x-n)<a)return s+(i-t.y);if(Math.abs(t.y-o)<a)return s+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*s+r+(t.y-o);const c=Math.abs(t.y-i),h=Math.abs(t.x-n),l=Math.abs(t.y-o),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(s,t.x-e)):u===h?s+Math.max(0,Math.min(r,i-t.y)):u===l?s+r+Math.max(0,Math.min(s,n-t.x)):2*s+r+Math.max(0,Math.min(r,t.y-o))}function wh(t,e,n=1e-6){return Math.abs(t-e)<n}function Rh(t){if(t.length<2)return 0;const e=t.map(([t,e])=>t<e?[t,e]:[e,t]);let n=0;for(let t=0;t<e.length;t++){const[o,i]=e[t];for(let s=t+1;s<e.length;s++){const[t,r]=e[s];wh(o,t)||wh(o,r)||wh(i,t)||wh(i,r)||(o<t&&t<i&&i<r||t<o&&o<r&&r<i)&&n++}}return n}var Oh=t=>{const e=t.center.x-t.width/2,n=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2,s=new Map;for(const e of t.portPoints){const t=s.get(e.connectionName)??[];t.some(t=>t.x===e.x&&t.y===e.y&&t.z===e.z)||t.push({x:e.x,y:e.y,z:e.z}),s.set(e.connectionName,t)}const r=new Map,a=[];let c=0;for(const[t,h]of s){if(h.length<2)continue;const t=h[0],s=h[1],l=Eh(t,e,n,o,i),d=Eh(s,e,n,o,i);if(t.z===s.z){const e=t.z,n=r.get(e)??[];n.push([l,d]),r.set(e,n)}else c++,a.push([l,d])}let h=0;for(const[t,e]of r)h+=Rh(e);return{numSameLayerCrossings:h,numEntryExitLayerChanges:c,numTransitionPairCrossings:Rh(a)}},Ah=(t,e=1,n={})=>{const o=n.viaDiameter??.3,i="width"in t?t.width:t,s=n.obstacleMargin??.2,r="height"in t&&"number"==typeof t.height?t.height:i,a=Math.min(i,r)/(o+s),c=(Math.sqrt(i*r)*Math.min(1.2,Math.max(.85,a**.05))/(o/2+s)/2)**1.1*e;return 1===t.availableZ?.length&&c>1?1:c},zh=(t,e=.5,n=16)=>{let o=0,i=t;for(;o<n;){if(Ah({width:i})<=e)break;i/=2,o++}return Math.max(1,o)},Dh=(t,e,n,o)=>{if(t?._containsTarget)return 0;if(1===(t.availableZ?.length??2)&&(e>0||n>0||o>0))return 1;return((.82*e+.41*n+.2*o)/2)**1.1/Ah(t)};function Lh(t,e,n){let o=0;const i=n?.NODE_MAX_PF??.99999;for(const n of t){const t=e.get(n.capacityMeshNodeId);if(!t)continue;if(t._containsTarget)continue;const s=Oh(n),r=Math.min(Dh(t,s.numSameLayerCrossings,s.numEntryExitLayerChanges,s.numTransitionPairCrossings),i);o+=Math.log(1-r)}return o}function Yh(t,e){if(e._containsTarget)return 0;const n=Oh(t);return Dh(e,n.numSameLayerCrossings,n.numEntryExitLayerChanges,n.numTransitionPairCrossings)}function Xh(t,e,n,o,i){const s=n-e,r=i-o,a=1e-6;if(Math.abs(t.y-i)<a)return t.x-e;if(Math.abs(t.x-n)<a)return s+(i-t.y);if(Math.abs(t.y-o)<a)return s+r+(n-t.x);if(Math.abs(t.x-e)<a)return 2*s+r+(t.y-o);const c=Math.abs(t.y-i),h=Math.abs(t.x-n),l=Math.abs(t.y-o),d=Math.abs(t.x-e),u=Math.min(c,h,l,d);return u===c?Math.max(0,Math.min(s,t.x-e)):u===h?s+Math.max(0,Math.min(r,i-t.y)):u===l?s+r+Math.max(0,Math.min(s,n-t.x)):2*s+r+Math.max(0,Math.min(r,t.y-o))}var Fh=1.6*3.2,kh=(t,e)=>{const n=Math.ceil(e/2),o=Math.min(t.width,t.height),i=Math.max(t.width,t.height),s=(Math.floor(o/1.6)+.1)*(Math.floor(i/3.2)+.1)/Fh;return Math.min(1,n/s)};function $h(t,e,n,o){const i=e.x-n/2,s=e.x+n/2,r=e.y-o/2,a=e.y+o/2,c=Math.abs(t.y-a),h=Math.abs(t.x-s),l=Math.abs(t.y-r),d=Math.abs(t.x-i),u=Math.min(c,h,l,d);return u>.001?"interior":u===c?"top":u===h?"right":u===l?"bottom":"left"}function Bh(t,e,n,o,i){const s=$h(t,n,o,i),r=$h(e,n,o,i);return"interior"!==s&&s===r}function jh(t,e,n,o,i){const s=$h(t,n,o,i);let r;if("top"===s||"bottom"===s){const n=o;r=Math.abs(e.x-t.x)/n}else{const n=i;r=Math.abs(e.y-t.y)/n}r=Math.min(1,Math.max(0,r));const a=(t.x+e.x)/2,c=(t.y+e.y)/2;return{x:a+(n.x-a)*r,y:c+(n.y-c)*r}}function Wh(t){return"computeNodePf"in t&&"function"==typeof t.computeNodePf}function Vh(t){const e={lines:[],points:[],rects:[],circles:[]};for(const n of t.inputNodes){let o=0,i=0,s={numSameLayerCrossings:0,numEntryExitLayerChanges:0,numTransitionPairCrossings:0},r=0;if(Wh(t)){o=t.computeNodePf(n),i=t.nodeMemoryPfMap.get(n.capacityMeshNodeId)??0;const e=t.buildNodeWithPortPointsForCrossing(n);s=Oh(e);const a=new Set,c=t.nodeAssignedPortPoints.get(n.capacityMeshNodeId)??[];for(const t of c)t.connectionName&&a.add(t.connectionName);r=a.size}else{o=t.nodePfMap.get(n.capacityMeshNodeId)??0;const e=t.nodeAssignedPortPoints.get(n.capacityMeshNodeId)??[],i={capacityMeshNodeId:n.capacityMeshNodeId,center:n.center,width:n.width,height:n.height,portPoints:e,availableZ:n.availableZ};s=Oh(i);const a=new Set;for(const t of e)t.connectionName&&a.add(t.connectionName);r=a.size}const a=Math.min(255,Math.floor(512*o)),c=Math.max(0,255-Math.floor(512*o));let h=`rgba(${a}, ${c}, ${c}, ${o<.001?"0.1":"0.3"})`;n._containsObstacle&&(h="rgba(255, 0, 0, 0.3)"),n._offBoardConnectedCapacityMeshNodeIds?.length&&(h="rgba(255, 165, 0, 0.3)"),e.rects.push({center:n.center,width:n.width-.2,height:n.height-.2,layer:`z${n.availableZ.join(",")}`,fill:h,label:`${n.capacityMeshNodeId}\npf: ${o.toFixed(3)}, memPf: ${i.toFixed(3)}\nC#: ${r}\nxSame: ${s.numSameLayerCrossings}, xLC: ${s.numEntryExitLayerChanges}, xTransition: ${s.numTransitionPairCrossings}\nobCmid: ${n._offBoardConnectedCapacityMeshNodeIds?.join(",")}\nobs: ${n._containsObstacle?"yes":"no"}`})}if(Wh(t))for(const[n,o]of t.portPointMap){const i=t.assignedPortPoints.get(n),s=i?t.colorMap[i.connectionName]??"blue":"rgba(150, 150, 150, 0.5)";e.circles.push({center:{x:o.x,y:o.y},radius:.05,fill:s,layer:`z${o.z}`,label:[n,`conn: ${i?.connectionName}`,`cd: ${o.distToCentermostPortOnZ}`,`connects: ${o.connectionNodeIds.join(",")}`,`rootConn: ${i?.rootConnectionName}`].filter(Boolean).join("\n")})}const n=Wh(t)?t.connectionsWithResults:t.connectionResults;for(const o of n){if(!o.path)continue;const n=o.connection,i=t.colorMap[n.name]??"blue",s=[];for(const t of o.path)s.push({x:t.point.x,y:t.point.y,z:t.z,nodeId:t.currentNodeId});for(let n=0;n<s.length-1;n++){const o=s[n],r=s[n+1],a=o.z===r.z,c=o.z;let h;h=a?0===c?void 0:"10 5":"3 3 10";const l=o.nodeId?t.nodeMap.get(o.nodeId):null;if(l&&Bh(o,r,l.center,l.width,l.height)){const t=jh(o,r,l.center,l.width,l.height);e.lines.push({points:[{x:o.x,y:o.y},{x:t.x,y:t.y}],strokeColor:i,strokeDash:h}),e.lines.push({points:[{x:t.x,y:t.y},{x:r.x,y:r.y}],strokeColor:i,strokeDash:h})}else e.lines.push({points:[{x:o.x,y:o.y},{x:r.x,y:r.y}],strokeColor:i,strokeDash:h})}}if(Wh(t)&&!t.solved&&t.candidates&&t.candidates.length>0){const n=t.currentConnection,o=n?t.colorMap[n.connection.name]??"blue":"blue";if(n){const[i,s]=n.nodeIds,r=t.nodeMap.get(i),a=t.nodeMap.get(s),c=n.connection.pointsToConnect[0],h=n.connection.pointsToConnect[n.connection.pointsToConnect.length-1];if(r&&a){const t=c?{x:c.x,y:c.y}:r.center,i=h?{x:h.x,y:h.y}:a.center;e.lines.push({points:[t,i],strokeColor:Mn(o,.5),strokeDash:"5 5"}),e.points.push({x:t.x,y:t.y,color:o,label:[`Start: ${n.connection.name}`,`${n.connection.rootConnectionName}`].join("\n")}),e.points.push({x:i.x,y:i.y,color:o,label:[`End: ${n.connection.name}`,`${n.connection.rootConnectionName}`].join("\n")}),e.circles.push({center:i,radius:.08,stroke:o,label:`Goal: ${n.connection.name}`})}}const i=[...t.candidates].sort((t,e)=>t.f-e.f).slice(0,1);for(const s of i){const i=[];let r=s;for(;r;)i.unshift({x:r.point.x,y:r.point.y,z:r.z,lastMoveWasOffBoard:r.lastMoveWasOffBoard,nodeId:r.currentNodeId}),r=r.prevCandidate;for(let n=0;n<i.length-1;n++){const s=i[n],r=i[n+1],a=s.z===r.z,c=s.z;let h;h=r.lastMoveWasOffBoard?"2 2":a?0===c?void 0:"10 5":"3 3 10";const l=s.nodeId?t.nodeMap.get(s.nodeId):null,d=.02*s.z;if(l&&Bh(s,r,l.center,l.width,l.height)){const t=jh(s,r,l.center,l.width,l.height);e.lines.push({points:[{x:s.x+d,y:s.y+d},{x:t.x+d,y:t.y+d}],strokeColor:Mn(o,.25),strokeDash:h}),e.lines.push({points:[{x:t.x+d,y:t.y+d},{x:r.x+d,y:r.y+d}],strokeColor:Mn(o,.25),strokeDash:h})}else e.lines.push({points:[{x:s.x+d,y:s.y+d},{x:r.x+d,y:r.y+d}],strokeColor:Mn(o,.25),strokeDash:h})}if(i.length>=1){const r=i[i.length-1];let a=0,c=0,h=0,l=0,d=0,u=0;const p=t.nodeMap.get(s.prevCandidate?.currentNodeId);if(p&&s.prevCandidate&&s.portPoint&&n){const e=n.connection.name,o={x:s.prevCandidate.point.x,y:s.prevCandidate.point.y,z:s.prevCandidate.z,connectionName:e},i={x:s.portPoint.x,y:s.portPoint.y,z:s.portPoint.z,connectionName:e},r=t.buildNodeWithPortPointsForCrossing(p,[o,i]),f=Mo(r);h=f.numSameLayerCrossings,l=f.numTransitionPairCrossings,d=f.numEntryExitLayerChanges;const g=t.capacityMeshNodeMap.get(p.capacityMeshNodeId);g&&(c=t.JUMPER_PF_FN_ENABLED&&1===p.availableZ.length?kh(g,h):Dh(g,h,d,l),a=c**2*t.NODE_PF_FACTOR),u=s.prevCandidate.g>0?s.g-s.prevCandidate.g:s.g}if(!n)continue;const[f,g]=n.nodeIds,m=t.nodeMap.get(g),y=m?Math.sqrt((r.x-m.center.x)**2+(r.y-m.center.y)**2):0,x=t.avgNodePitch>0?y/t.avgNodePitch:0,v=x*t.BASE_CANDIDATE_COST,b=t.nodeMemoryPfMap.get(s.currentNodeId)??0,P=-Math.log(1-b)*t.MEMORY_PF_FACTOR;e.circles.push({center:r,radius:.03,fill:Mn(o,.25),layer:`z${s.z}`,label:[`f: ${s.f.toFixed(2)}`,`g: ${s.g.toFixed(2)} (nodeDelta: ${u.toFixed(2)})`,`h: ${s.h.toFixed(2)}`,` dist: ${y.toFixed(2)}`,` estHops: ${x.toFixed(1)}`,` estStepCost: ${v.toFixed(2)}`,` memRiskCost: ${P.toFixed(2)}`,`z: ${s.z}`,`node: ${s.currentNodeId}`,`Cost(Pf): ${a.toFixed(3)}`,`Pf: ${c.toFixed(3)}`,`xSame: ${h}, xTrans: ${l}, xLC: ${d}`,`routeOffBoard=${t.currentConnectionShouldRouteOffBoard}`,`offBoardTouched=${s.hasTouchedOffBoardNode??!1}`,`lastMoveWasOffBoard=${s.lastMoveWasOffBoard??!1}`].join("\n")})}}}return e}function Hh(t,e,n){let o=0;const i=n?.NODE_MAX_PF??.99999;for(const n of t){const t=e.get(n.capacityMeshNodeId);if(!t)continue;if(t._containsTarget)continue;const s=Oh(n),r=Math.min(kh(t,s.numSameLayerCrossings),i);o+=Math.log(1-r)}return o}var Uh=class extends Dn{constructor(t){super(),this.input=t;const{simpleRouteJson:e,capacityMeshNodes:n,inputNodes:o,colorMap:i,nodeMemoryPfMap:s,hyperParameters:r,precomputedInitialParams:a,fixedRoutes:c}=t;if(this.input=structuredClone(t),this.MAX_ITERATIONS=1e8,this.simpleRouteJson=e,this.inputNodes=o,this.colorMap=i??{},this.capacityMeshNodeMap=new Map(n.map(t=>[t.capacityMeshNodeId,t])),this.nodeMemoryPfMap=s??new Map,this.hyperParameters=r??{},a){this.nodeMap=a.nodeMap,this.avgNodePitch=a.avgNodePitch,this.offBoardNodes=a.offBoardNodes,this.portPointMap=a.portPointMap,this.nodePortPointsMap=a.nodePortPointsMap,this.connectionNameToGoalNodeIds=a.connectionNameToGoalNodeIds;const{nodeAssignedPortPoints:t}=function(t){const e=new Map;for(const[n,o]of t.nodeAssignedPortPoints)e.set(n,[...o]);return{nodeAssignedPortPoints:e}}(a);this.nodeAssignedPortPoints=t,this.connectionsWithResults=Un(structuredClone(a.unshuffledConnectionsWithResults),this.hyperParameters.SHUFFLE_SEED??0)}else{this.nodeMap=new Map(o.map(t=>[t.capacityMeshNodeId,t]));const t=o.map(t=>(t.width+t.height)/2).filter(t=>Number.isFinite(t)&&t>0);this.avgNodePitch=t.length>0?t.reduce((t,e)=>t+e,0)/t.length:1,this.offBoardNodes=o.filter(t=>t._offBoardConnectionId),this.portPointMap=new Map,this.nodePortPointsMap=new Map;for(const t of o)this.nodePortPointsMap.set(t.capacityMeshNodeId,[]),this.nodeAssignedPortPoints.set(t.capacityMeshNodeId,[]);for(const t of o)for(const e of t.portPoints){this.portPointMap.set(e.portPointId,e);for(const t of e.connectionNodeIds){const n=this.nodePortPointsMap.get(t);n&&!n.some(t=>t.portPointId===e.portPointId)&&n.push(e)}}const{connectionsWithResults:e,connectionNameToGoalNodeIds:n}=this.getConnectionsWithNodes();this.connectionsWithResults=e,this.connectionNameToGoalNodeIds=n}if(c&&c.length>0)for(const t of c)if(this.connectionsWithResults.push(t),t.portPoints)for(const e of t.portPoints)e.portPointId&&this.assignedPortPoints.set(e.portPointId,{connectionName:e.connectionName,rootConnectionName:e.rootConnectionName});for(const t of this.connectionsWithResults)t.path?this.processedConnectionQueue.push(t):this.unprocessedConnectionQueue.push(t);this.totalConnectionCount=this.connectionsWithResults.length}getSolverName(){return"PortPointPathingSolver"}hyperParameters;simpleRouteJson;inputNodes;nodeMap;nodePortPointsMap;portPointMap;connectionsWithResults=[];failedConnection=null;assignedPortPoints=new Map;nodeAssignedPortPoints=new Map;PORT_POINT_REUSE_FACTOR=1e3;BASE_COST_FOR_NOT_GOING_OFF_BOARD=100;get NODE_PF_FACTOR(){return this.hyperParameters.NODE_PF_FACTOR??50}get RANDOM_WALK_DISTANCE(){return this.hyperParameters.RANDOM_WALK_DISTANCE??0}get MEMORY_PF_FACTOR(){return this.hyperParameters.MEMORY_PF_FACTOR??0}get CENTER_OFFSET_FOCUS_SHIFT(){return this.hyperParameters.CENTER_OFFSET_FOCUS_SHIFT??0}get RANDOM_COST_MAGNITUDE(){return this.hyperParameters.RANDOM_COST_MAGNITUDE??0}get BASE_CANDIDATE_COST(){return this.hyperParameters.BASE_CANDIDATE_COST??0}get NODE_PF_MAX_PENALTY(){return this.hyperParameters.NODE_PF_MAX_PENALTY??1e4}get FORCE_CENTER_FIRST(){return this.hyperParameters.FORCE_CENTER_FIRST??!0}get FORCE_OFF_BOARD_FREQUENCY(){return 0===this.offBoardNodes.length?0:this.hyperParameters.FORCE_OFF_BOARD_FREQUENCY??0}get FORCE_OFF_BOARD_SEED(){return this.hyperParameters.FORCE_OFF_BOARD_SEED??0}get NODE_MAX_PF(){return Math.min(.99999,1-Math.exp(-this.NODE_PF_MAX_PENALTY))}get CENTER_OFFSET_DIST_PENALTY_FACTOR(){return this.hyperParameters.CENTER_OFFSET_DIST_PENALTY_FACTOR??0}get STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR(){return this.hyperParameters.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR??0}colorMap;get GREEDY_MULTIPLIER(){return this.hyperParameters.GREEDY_MULTIPLIER??1.3}MAX_CANDIDATES_IN_MEMORY=5e3;get MAX_ITERATIONS_PER_PATH(){return this.hyperParameters.MAX_ITERATIONS_PER_PATH??1e4}ITERATIONS_PER_MM_FOR_PATH=30;BASE_ITERATIONS_PER_PATH=1e4;get RIPPING_ENABLED(){return this.hyperParameters.RIPPING_ENABLED??!1}get RIPPING_PF_THRESHOLD(){const t=this.hyperParameters.START_RIPPING_PF_THRESHOLD,e=this.hyperParameters.END_RIPPING_PF_THRESHOLD;if(void 0!==t&&void 0!==e){const n=this.MAX_RIPS;return t+(n>0?this.totalRipCount/n:0)*(e-t)}return this.hyperParameters.RIPPING_PF_THRESHOLD??.3}get MAX_RIPS(){return this.hyperParameters.MAX_RIPS??100}get RANDOM_RIP_FRACTION(){return this.hyperParameters.RANDOM_RIP_FRACTION??0}get JUMPER_PF_FN_ENABLED(){return this.hyperParameters.JUMPER_PF_FN_ENABLED??!1}jumpersPerMmSquared=.1;testedRipConnections=new Map;totalRipCount=0;get MIN_ALLOWED_BOARD_SCORE(){return this.hyperParameters.MIN_ALLOWED_BOARD_SCORE??-1e4}nodeMemoryPfMap;unprocessedConnectionQueue=[];processedConnectionQueue=[];currentConnection=null;totalConnectionCount=0;currentPathIterations=0;candidates;visitedPortPoints;connectionNameToGoalNodeIds;capacityMeshNodeMap;avgNodePitch;currentConnectionShouldRouteOffBoard=!1;activeCandidateStraightLineDistance;offBoardNodes=[];baseNodeCostCache=new Map;getConstructorParams(){return this.input}clearCostCaches(){this.baseNodeCostCache.clear()}clampPf(t){return Number.isFinite(t)?Math.min(Math.max(t,0),.999999):.999999}pfToFailureCost(t){const e=this.clampPf(t);return e>=this.NODE_MAX_PF?this.NODE_PF_MAX_PENALTY:-Math.log(1-e)}getBaseNodeFailureCost(t){const e=this.baseNodeCostCache.get(t);if(null!=e)return e;const n=this.nodeMap.get(t);if(!n)return 0;const o=this.computeNodePf(n),i=this.pfToFailureCost(o);return this.baseNodeCostCache.set(t,i),i}computeBoardScore(){const t=this.getNodesWithPortPoints();return this.JUMPER_PF_FN_ENABLED?Hh(t,this.capacityMeshNodeMap):Lh(t,this.capacityMeshNodeMap)}getMaxIterationsForCurrentPath(){const t=this.activeCandidateStraightLineDistance??0;return Math.min(this.BASE_ITERATIONS_PER_PATH+this.ITERATIONS_PER_MM_FOR_PATH*t,this.MAX_ITERATIONS_PER_PATH)}getNodeDeltaFailureCostForSegment(t,e,n){const o=this.nodeMap.get(t);if(!o)return 0;const i=this.getBaseNodeFailureCost(t),s=this.computeNodePf(o,[e,n]),r=this.pfToFailureCost(s),a=Math.max(0,r-i);return s>=this.NODE_MAX_PF?this.NODE_PF_MAX_PENALTY:a*this.NODE_PF_FACTOR}getConnectionsWithNodes(){const{unshuffledConnectionsWithResults:t,connectionNameToGoalNodeIds:e}=Ch(this.simpleRouteJson,this.inputNodes);return{connectionsWithResults:Un(t,this.hyperParameters.SHUFFLE_SEED??0),connectionNameToGoalNodeIds:e}}buildNodeWithPortPointsForCrossing(t,e){const n=this.nodeAssignedPortPoints.get(t.capacityMeshNodeId)??[],o=e?[...n,...e]:n;return{capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:o,availableZ:t.availableZ}}computeNodePf(t,e){if(t._containsTarget)return 0;const n=this.buildNodeWithPortPointsForCrossing(t,e),o=Oh(n);return this.JUMPER_PF_FN_ENABLED&&1===t.availableZ.length?kh(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),o.numSameLayerCrossings):Dh(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.numTransitionPairCrossings)}getPortPointReusePenalty(t,e){const n=this.assignedPortPoints.get(t);return n?e===n.rootConnectionName?0:this.PORT_POINT_REUSE_FACTOR:0}getOtherNodeId(t,e){const[n,o]=t.connectionNodeIds;return n===e?o:o===e?n:null}computeG(t,e,n,o,i){const s=t.currentNodeId,r=t.point,a={x:r.x,y:r.y,z:t.z,connectionName:o,rootConnectionName:i},c={x:e.x,y:e.y,z:e.z,connectionName:o,rootConnectionName:i},h=this.getNodeDeltaFailureCostForSegment(s,a,c);return t.g+h}computeGToEndTarget(t,e,n,o){const i=t.currentNodeId,s={x:t.point.x,y:t.point.y,z:t.z,connectionName:n,rootConnectionName:o},r={x:e.x,y:e.y,z:t.z,connectionName:n,rootConnectionName:o},a=this.getNodeDeltaFailureCostForSegment(i,s,r);return t.g+a}computeDistanceToNearestOffBoardNode(t){if(0===this.offBoardNodes.length)return 1/0;let e=1/0;for(const n of this.offBoardNodes){const o=F(t,n.center);o<e&&(e=o)}return e}computeH(t,e,n,o,i,s){if(this.RANDOM_WALK_DISTANCE>0&&i<this.RANDOM_WALK_DISTANCE)return 0;if(this.currentConnectionShouldRouteOffBoard&&!s)return this.BASE_COST_FOR_NOT_GOING_OFF_BOARD+this.computeDistanceToNearestOffBoardNode(t);const r=this.nodeMap.get(n);if(!r)return 0;const a=F(t,r.center),c=this.avgNodePitch>0?a/this.avgNodePitch:0,h=this.clampPf(this.nodeMemoryPfMap.get(e)??0),l=this.pfToFailureCost(h)*this.MEMORY_PF_FACTOR,d=c*this.BASE_CANDIDATE_COST,u=this.CENTER_OFFSET_DIST_PENALTY_FACTOR*t.distToCentermostPortOnZ**2;let p=0;if(this.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR>0&&this.currentConnection){const e=X(t,this.currentConnection.connection.pointsToConnect[0],this.currentConnection.connection.pointsToConnect[1]);p=this.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR*e}return a+d+l+u+p}getVisitedPortPointKey(t,e){return this.currentConnectionShouldRouteOffBoard&&e?`${t}:touched_off_board`:t}getAvailableExitPortPoints(t,e){const n=this.currentConnection?.connection.rootConnectionName,o=this.nodePortPointsMap.get(t)??[],i=[];for(const t of o){const o=this.getVisitedPortPointKey(t.portPointId,e);if(this.visitedPortPoints?.has(o))continue;const s=this.assignedPortPoints.get(t.portPointId);s&&s?.rootConnectionName!==n||i.push(t)}return i}getAvailableExitPortPointsWithOmissions(t,e,n){const o=this.nodePortPointsMap.get(t)??[],i=this.currentConnection?.connection.rootConnectionName,s=new Map;for(const e of o){const o=this.getVisitedPortPointKey(e.portPointId,n);if(this.visitedPortPoints?.has(o))continue;const i=this.getOtherNodeId(e,t);if(!i)continue;this.nodeMap.get(i);const r=`${i}|${e.z}`,a=s.get(r)??[];a.push(e),s.set(r,a)}const r=[];for(const[,t]of s){t.sort((t,e)=>t.distToCentermostPortOnZ-e.distToCentermostPortOnZ);const e=t[0];if(!e)continue;const n=this.assignedPortPoints.get(e.portPointId),o=n&&n.rootConnectionName===i;if(!n||o){r.push(e);continue}const s=[...t].sort((t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y),a=[];let c=[];for(const t of s){const e=this.assignedPortPoints.get(t.portPointId);!e||e.rootConnectionName===i?c.push(t):c.length>0&&(a.push(c),c=[])}c.length>0&&a.push(c);for(const t of a){const e=Math.floor(t.length/2);r.push(t[e])}}return r}getAvailableExitPortPointsForOffboardConnection(t,e){const n=this.nodeMap.get(t);if(!n)return[];const o=this.currentConnection?.connection.rootConnectionName,i=[];for(const s of n?._offBoardConnectedCapacityMeshNodeIds??[]){if(s===t)continue;if(!this.nodeMap.get(s))continue;const n=this.nodePortPointsMap.get(s)??[];for(const t of n){const n=this.getVisitedPortPointKey(t.portPointId,e);if(this.visitedPortPoints?.has(n))continue;const r=this.assignedPortPoints.get(t.portPointId);r&&r.rootConnectionName!==o||i.push({...t,throughNodeId:s})}}return i}canTravelThroughObstacle(t,e,n){const o=this.connectionNameToGoalNodeIds.get(e);return o?.includes(t.capacityMeshNodeId)||Boolean(t._offBoardConnectionId)}isAtEndGoal(t,e){return t===e}getBacktrackedPath(t){const e=[];let n=t;for(;n;){if(n.lastMoveWasOffBoard&&n.throughNodeId){const t=this.nodeMap.get(n.throughNodeId),o=n.prevCandidate?this.nodeMap.get(n.prevCandidate.currentNodeId):null;e.push(n),t&&e.push({prevCandidate:null,portPoint:null,currentNodeId:n.throughNodeId,point:t.center,z:n.z,f:0,g:0,h:0,distanceTraveled:0}),o&&o._offBoardConnectionId&&e.push({prevCandidate:null,portPoint:null,currentNodeId:n.prevCandidate.currentNodeId,point:o.center,z:n.z,f:0,g:0,h:0,distanceTraveled:0})}else e.push(n);n=n.prevCandidate}return e.reverse()}assignPortPointsForPath(t,e,n){const o=[];for(let i=0;i<t.length;i++){const s=t[i];if(!s.portPoint){const r=0===i,a=i===t.length-1;if(!r&&!a){const t={x:s.point.x,y:s.point.y,z:s.z,connectionName:e,rootConnectionName:n};o.push(t);const i=this.nodeAssignedPortPoints.get(s.currentNodeId)??[];i.push(t),this.nodeAssignedPortPoints.set(s.currentNodeId,i)}continue}const r=s.portPoint;this.assignedPortPoints.set(r.portPointId,{connectionName:e,rootConnectionName:n});const a={portPointId:r.portPointId,x:r.x,y:r.y,z:r.z,connectionName:e,rootConnectionName:n};o.push(a);for(const t of r.connectionNodeIds){const e=this.nodeAssignedPortPoints.get(t)??[];e.push(a),this.nodeAssignedPortPoints.set(t,e)}}const i=Array.from(new Set(t.map(t=>t.currentNodeId)));for(const t of i){const o=this.nodeMap.get(t);if(o&&o._offBoardConnectionId)for(const t of o?._offBoardConnectedCapacityMeshNodeIds??[]){const o=this.nodePortPointsMap.get(t)??[];for(const t of o)this.assignedPortPoints.set(t.portPointId,{connectionName:e,rootConnectionName:n})}}return o}addTargetPointsToNodes(t,e){const n=t[0],o=t[t.length-1],i=e.pointsToConnect[0],s=e.pointsToConnect[e.pointsToConnect.length-1];if(n&&i){const t=this.nodeAssignedPortPoints.get(n.currentNodeId)??[];t.push({x:i.x,y:i.y,z:n.z,connectionName:e.name,rootConnectionName:e.rootConnectionName}),this.nodeAssignedPortPoints.set(n.currentNodeId,t)}if(o&&s){const t=this.nodeAssignedPortPoints.get(o.currentNodeId)??[];t.push({x:s.x,y:s.y,z:o.z,connectionName:e.name,rootConnectionName:e.rootConnectionName}),this.nodeAssignedPortPoints.set(o.currentNodeId,t)}}isPortPointInPathChain(t,e){let n=t;for(;n;){if(n.portPoint?.portPointId===e)return!0;n=n.prevCandidate}return!1}isNodeInPathChain(t,e){let n=t;for(;n;){if(n.currentNodeId===e)return!0;n=n.prevCandidate}return!1}_step(){if(this.currentConnection||(this.currentConnection=this.unprocessedConnectionQueue.shift()??null),!this.currentConnection){const t=this.computeBoardScore();return this.stats={boardScore:t,totalRipCount:this.totalRipCount},t<this.MIN_ALLOWED_BOARD_SCORE?(this.failedConnection=null,this.failed=!0,void(this.error=`Board score ${t.toFixed(2)} is less than MIN_ALLOWED_BOARD_SCORE ${this.MIN_ALLOWED_BOARD_SCORE.toFixed(2)}`)):void(this.solved=!0)}const t=this.currentConnection;this.activeCandidateStraightLineDistance=t.straightLineDistance,this.currentPathIterations++;const e=this.getMaxIterationsForCurrentPath();if(this.currentPathIterations>e)return this.failedConnection=t,this.processedConnectionQueue.push(t),this.currentConnection=null,this.candidates=null,this.visitedPortPoints=null,this.currentPathIterations=0,this.failed=!0,void(this.error=`Exceeded max iterations for path (${e}) on connection ${t.connection.name}`);const[n,o]=t.nodeIds,i=this.nodeMap.get(n),s=this.nodeMap.get(o);if(!i||!s)return this.processedConnectionQueue.push(t),this.currentConnection=null,void(this.currentPathIterations=0);const r=t.connection.name,a=t.connection.rootConnectionName,c=t.connection.pointsToConnect[0];if(!this.candidates){if(this.clearCostCaches(),this.FORCE_OFF_BOARD_FREQUENCY>0){const t=Vn(17*(this.hyperParameters.SHUFFLE_SEED??0)+this.FORCE_OFF_BOARD_SEED+this.processedConnectionQueue.length);this.currentConnectionShouldRouteOffBoard=t()<this.FORCE_OFF_BOARD_FREQUENCY}else this.currentConnectionShouldRouteOffBoard=!1;this.candidates=[],this.visitedPortPoints=new Set;for(const t of i.availableZ){const e=c?{x:c.x,y:c.y}:i.center,s=this.computeH({...e,distToCentermostPortOnZ:0},n,o,t,0,!1),r=0+s*this.GREEDY_MULTIPLIER;this.candidates.push({prevCandidate:null,portPoint:null,currentNodeId:n,point:e,z:t,f:r,g:0,h:s,distanceTraveled:0,hasTouchedOffBoardNode:!1})}}this.candidates.sort((t,e)=>t.f-e.f);let h,l=this.candidates.shift();for(;l?.portPoint&&this.visitedPortPoints;){const t=this.getVisitedPortPointKey(l.portPoint.portPointId,l.hasTouchedOffBoardNode);if(!this.visitedPortPoints.has(t))break;l=this.candidates.shift()}if(this.candidates.length>this.MAX_CANDIDATES_IN_MEMORY&&this.candidates.splice(this.MAX_CANDIDATES_IN_MEMORY,this.candidates.length-this.MAX_CANDIDATES_IN_MEMORY),!l)return this.error=`Ran out of candidates on connection ${r}`,this.failedConnection=t,this.processedConnectionQueue.push(t),this.currentConnection=null,this.candidates=null,this.visitedPortPoints=null,this.currentPathIterations=0,void(this.failed=!0);if(l.portPoint&&this.visitedPortPoints){const t=this.getVisitedPortPointKey(l.portPoint.portPointId,l.hasTouchedOffBoardNode);this.visitedPortPoints.add(t)}if(this.isAtEndGoal(l.currentNodeId,o)){const e=t.connection.pointsToConnect[t.connection.pointsToConnect.length-1],n=e?{x:e.x,y:e.y}:s.center,i=this.computeGToEndTarget(l,n,r,a),c={prevCandidate:l,portPoint:null,currentNodeId:o,point:n,z:l.z,g:i,h:0,f:i,distanceTraveled:l.distanceTraveled+F(l.point,n)},h=this.getBacktrackedPath(c);return t.path=h,t.portPoints=this.assignPortPointsForPath(h,r,a),this.addTargetPointsToNodes(h,t.connection),this.clearCostCaches(),this.RIPPING_ENABLED&&this.processRippingForPath(h,r),this.processedConnectionQueue.push(t),this.currentConnection=null,this.progress=this.processedConnectionQueue.length/this.totalConnectionCount,this.candidates=null,this.visitedPortPoints=null,void(this.currentPathIterations=0)}const d=this.nodeMap.get(l.currentNodeId);h=d?._offBoardConnectionId?this.getAvailableExitPortPointsForOffboardConnection(l.currentNodeId,l.hasTouchedOffBoardNode):this.FORCE_CENTER_FIRST?this.getAvailableExitPortPointsWithOmissions(l.currentNodeId,o,l.hasTouchedOffBoardNode):this.getAvailableExitPortPoints(l.currentNodeId,l.hasTouchedOffBoardNode);for(const t of h){if(this.isPortPointInPathChain(l,t.portPointId))continue;if(this.visitedPortPoints?.has(t.portPointId))continue;const e=this.getOtherNodeId(t,t.throughNodeId??l.currentNodeId);if(!e)continue;if(this.isNodeInPathChain(l,e))continue;const n="throughNodeId"in t?t.throughNodeId:void 0,i=n?this.nodeMap.get(n):null,s=this.nodeMap.get(e);if(!s)continue;if(s._containsObstacle&&!this.canTravelThroughObstacle(s,r,a))continue;const c=this.computeG(l,t,e,r,a);if(!this.RIPPING_ENABLED&&c>-this.MIN_ALLOWED_BOARD_SCORE)continue;const h=l.distanceTraveled+F(l.point,t),u=l.hasTouchedOffBoardNode||Boolean(s._offBoardConnectionId),p=this.computeH(t,e,o,t.z,h,u),f=c+p*this.GREEDY_MULTIPLIER,g=Boolean(d?._offBoardConnectionId)&&Boolean(i?._offBoardConnectionId);this.candidates.push({prevCandidate:l,portPoint:t,currentNodeId:e,point:{x:t.x,y:t.y},z:t.z,f:f,g:c,h:p,distanceTraveled:h,lastMoveWasOffBoard:g,throughNodeId:g?n:void 0,hasTouchedOffBoardNode:u||Boolean(s._offBoardConnectionId)||Boolean(d?._offBoardConnectionId)})}}getNodesWithPortPoints(){const t=[];for(const e of this.inputNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];n.length>0&&t.push({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ})}return t}getConnectionsInNode(t,e){const n=[],o=new Set;for(const i of this.connectionsWithResults)if(i.path&&i.connection.name!==e&&!o.has(i.connection.name))for(const e of i.path)if(e.currentNodeId===t){n.push(i),o.add(i.connection.name);break}return n}computeNodePfWithoutConnection(t,e){if(t._containsTarget)return{pf:0,totalCrossings:0};const n=(this.nodeAssignedPortPoints.get(t.capacityMeshNodeId)??[]).filter(t=>t.connectionName!==e),o={capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:n,availableZ:t.availableZ},i=Oh(o),s=i.numSameLayerCrossings+i.numEntryExitLayerChanges+i.numTransitionPairCrossings;return{pf:Dh(this.capacityMeshNodeMap.get(t.capacityMeshNodeId),i.numSameLayerCrossings,i.numEntryExitLayerChanges,i.numTransitionPairCrossings),totalCrossings:s}}computeNodeCrossings(t){if(t._containsTarget)return 0;const e=this.buildNodeWithPortPointsForCrossing(t),n=Oh(e);return n.numSameLayerCrossings+n.numEntryExitLayerChanges+n.numTransitionPairCrossings}ripConnection(t){const e=t.connection.name;for(const[t,n]of this.assignedPortPoints.entries())n.connectionName===e&&this.assignedPortPoints.delete(t);for(const[t,n]of this.nodeAssignedPortPoints.entries()){const o=n.filter(t=>t.connectionName!==e);this.nodeAssignedPortPoints.set(t,o)}t.path=void 0,t.portPoints=void 0}requeueConnection(t){this.totalRipCount++;const e=this.processedConnectionQueue.indexOf(t);if(-1!==e)return this.processedConnectionQueue.splice(e,1),this.unprocessedConnectionQueue.push(t),!0;const n=this.unprocessedConnectionQueue.indexOf(t);return-1!==n&&(this.unprocessedConnectionQueue.splice(n,1),this.unprocessedConnectionQueue.unshift(t)),!0}processRippingForPath(t,e){const n=Array.from(new Set(t.map(t=>t.currentNodeId)));let o=!1;for(const t of n){if(this.totalRipCount>this.MAX_RIPS)break;const n=this.nodeMap.get(t);if(!n)continue;let i=this.computeNodePf(n);if(i<=this.RIPPING_PF_THRESHOLD)continue;this.testedRipConnections.has(t)||this.testedRipConnections.set(t,new Set);const s=this.testedRipConnections.get(t),r=Un(this.getConnectionsInNode(t,e),(this.hyperParameters.SHUFFLE_SEED??0)+this.processedConnectionQueue.length);for(const t of r){if(i<=this.RIPPING_PF_THRESHOLD)break;const e=t.connection.name;s.add(e);const{pf:r}=this.computeNodePfWithoutConnection(n,e);this.ripConnection(t);if(!this.requeueConnection(t))return;i=r,o=!0,this.clearCostCaches()}}o&&this.RANDOM_RIP_FRACTION>0&&this.processRandomRipping(e)}processRandomRipping(t){const e=this.processedConnectionQueue.filter(e=>void 0!==e.path&&e.connection.name!==t);if(0===e.length)return;const n=Math.max(1,Math.floor(this.RANDOM_RIP_FRACTION*e.length)),o=Un(e,(this.hyperParameters.SHUFFLE_SEED??0)+this.totalRipCount+this.processedConnectionQueue.length);for(let t=0;t<n&&t<o.length&&!(this.totalRipCount>this.MAX_RIPS);t++){const e=o[t];this.ripConnection(e);if(!this.requeueConnection(e))return;this.clearCostCaches()}}visualize(){let t={};if(this.failed){const e=this.failedConnection?.connection.pointsToConnect[0],n=this.failedConnection?.connection.pointsToConnect[1];e&&n&&(t={lines:[{points:[e,n],label:`Failed Connection ${this.failedConnection?.connection.name}`,strokeWidth:1,strokeColor:"red",strokeDash:[2,2]}]})}return I(Vh(this),t)}},Gh=class extends io{getSolverName(){return"HyperPortPointPathingSolver"}params;precomputedInitialParams;constructor(t){super(),this.params=t,this.MAX_ITERATIONS=1e8,this.GREEDY_MULTIPLIER=1.2,this.MIN_SUBSTEPS=50,this.precomputedInitialParams=t.precomputedInitialParams??Th(t.simpleRouteJson,t.inputNodes)}getHyperParameterDefs(){const t=this.params.numShuffleSeeds??50;return[{name:"SHUFFLE_SEED",possibleValues:Array.from({length:t},(t,e)=>({SHUFFLE_SEED:e+1700*(this.params.hyperParameters?.SHUFFLE_SEED??0)}))}]}getCombinationDefs(){return[["SHUFFLE_SEED"]]}generateSolver(t){return new Uh({simpleRouteJson:this.params.simpleRouteJson,capacityMeshNodes:this.params.capacityMeshNodes,inputNodes:this.params.inputNodes,colorMap:this.params.colorMap,nodeMemoryPfMap:this.params.nodeMemoryPfMap,hyperParameters:{...this.params.hyperParameters,...t,MIN_ALLOWED_BOARD_SCORE:this.params.minAllowedBoardScore??t.MIN_ALLOWED_BOARD_SCORE??this.params.hyperParameters?.MIN_ALLOWED_BOARD_SCORE},precomputedInitialParams:this.precomputedInitialParams,fixedRoutes:this.params.fixedRoutes})}computeG(t){return-t.computeBoardScore()}computeH(t){const e=t.progress||0;if(e<.1)return 0;return-(t.computeBoardScore()/e)*(1-e)}getNodesWithPortPoints(){if(this.winningSolver)return this.winningSolver.getNodesWithPortPoints();const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.getNodesWithPortPoints():[]}get connectionsWithResults(){if(this.winningSolver)return this.winningSolver.connectionsWithResults;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.connectionsWithResults:[]}get inputNodes(){if(this.winningSolver)return this.winningSolver.inputNodes;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.inputNodes:this.params.inputNodes}get nodeMap(){if(this.winningSolver)return this.winningSolver.nodeMap;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.nodeMap:new Map(this.params.inputNodes.map(t=>[t.capacityMeshNodeId,t]))}get assignedPortPoints(){if(this.winningSolver)return this.winningSolver.assignedPortPoints;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.assignedPortPoints:new Map}get nodeAssignedPortPoints(){if(this.winningSolver)return this.winningSolver.nodeAssignedPortPoints;const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.nodeAssignedPortPoints:new Map}computeBoardScore(){if(this.winningSolver)return this.winningSolver.computeBoardScore();const t=this.getSupervisedSolverWithBestFitness();return t?t.solver.computeBoardScore():0}onSolve(t){this.stats={...t.solver.stats,winningHyperParameters:this.winningSolver?.hyperParameters}}visualize(){return this.winningSolver?this.winningSolver.visualize():super.visualize()}};function Zh(t){let e=t;return()=>{e+=1831565813;let t=e;return t=Math.imul(t^t>>>15,1|t),t^=t+Math.imul(t^t>>>7,61|t),((t^t>>>14)>>>0)/4294967296}}var qh=[{SHUFFLE_SEED:100,NODE_PF_FACTOR:100,NODE_PF_MAX_PENALTY:100,MEMORY_PF_FACTOR:0,EXPANSION_DEGREES:10,FORCE_CENTER_FIRST:!0,FORCE_OFF_BOARD_FREQUENCY:0,CENTER_OFFSET_DIST_PENALTY_FACTOR:0}],Jh=class extends Dn{getSolverName(){return"MultiSectionPortPointOptimizer"}simpleRouteJson;inputNodes;capacityMeshNodes;capacityMeshEdges;colorMap;nodeMap;capacityMeshNodeMap;connectionResults;assignedPortPoints;nodeAssignedPortPoints;sections=[];activeSubSolver=null;currentSection=null;sectionScoreBeforeOptimization=0;currentSectionCenterNodeId=null;currentScheduleIndex=0;nodePfMap=new Map;attemptsToFixNode=new Map;sectionAttempts=0;MAX_ATTEMPTS_PER_NODE=100;MAX_SECTION_ATTEMPTS=15;ACCEPTABLE_PF=.05;FRACTION_TO_REPLACE=.2;JUMPER_PF_FN_ENABLED=!1;SHUFFLE_SEEDS_PER_SECTION=null;ALWAYS_RIP_INTERSECTIONS=!0;effort=1;HYPERPARAMETER_SCHEDULE=qh;constructor(t){super(),this.MAX_ITERATIONS=1e6,this.simpleRouteJson=t.simpleRouteJson,this.inputNodes=t.inputNodes,this.capacityMeshNodes=t.capacityMeshNodes,this.capacityMeshEdges=t.capacityMeshEdges,this.colorMap=t.colorMap??{},this.effort=t.effort??1,void 0!==t.FRACTION_TO_REPLACE&&(this.FRACTION_TO_REPLACE=t.FRACTION_TO_REPLACE),void 0!==t.ALWAYS_RIP_INTERSECTIONS&&(this.ALWAYS_RIP_INTERSECTIONS=t.ALWAYS_RIP_INTERSECTIONS),void 0!==t.MAX_ATTEMPTS_PER_NODE&&(this.MAX_ATTEMPTS_PER_NODE=t.MAX_ATTEMPTS_PER_NODE),void 0!==t.MAX_SECTION_ATTEMPTS&&(this.MAX_SECTION_ATTEMPTS=t.MAX_SECTION_ATTEMPTS),void 0!==t.HYPERPARAMETER_SCHEDULE&&(this.HYPERPARAMETER_SCHEDULE=t.HYPERPARAMETER_SCHEDULE),this.JUMPER_PF_FN_ENABLED=t.JUMPER_PF_FN_ENABLED??this.JUMPER_PF_FN_ENABLED,this.SHUFFLE_SEEDS_PER_SECTION=t.SHUFFLE_SEEDS_PER_SECTION,this.nodeMap=new Map(t.inputNodes.map(t=>[t.capacityMeshNodeId,t])),this.capacityMeshNodeMap=new Map(t.capacityMeshNodes.map(t=>[t.capacityMeshNodeId,t])),this.connectionResults=[...t.initialConnectionResults],this.assignedPortPoints=new Map(t.initialAssignedPortPoints),this.nodeAssignedPortPoints=new Map(t.initialNodeAssignedPortPoints),this.nodePfMap=this.computeInitialPfMap();const e=this.computeBoardScore();this.stats.successfulOptimizations=0,this.stats.failedOptimizations=0,this.stats.nodesExamined=0,this.stats.sectionAttempts=0,this.stats.sectionScores={},this.stats.initialBoardScore=e,this.stats.currentBoardScore=e,this.stats.errors=0}computeInitialPfMap(){const t=new Map;for(const e of this.capacityMeshNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];if(0===n.length)continue;const o={capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ},i=this.JUMPER_PF_FN_ENABLED&&1===e.availableZ.length?kh(e,Oh(o).numSameLayerCrossings):Yh(o,e);t.set(e.capacityMeshNodeId,i)}return t}computeBoardScore(){const t=this.getNodesWithPortPoints();return this.computeScoreForNodes(t)}computeScoreForNodes(t){return this.JUMPER_PF_FN_ENABLED?Hh(t,this.capacityMeshNodeMap):Lh(t,this.capacityMeshNodeMap)}recomputePfForNodes(t){for(const e of t){const t=this.capacityMeshNodeMap.get(e);if(!t)continue;const n=this.nodeAssignedPortPoints.get(e)??[];if(0===n.length){this.nodePfMap.set(e,0);continue}const o={capacityMeshNodeId:e,center:t.center,width:t.width,height:t.height,portPoints:n,availableZ:t.availableZ},i=this.JUMPER_PF_FN_ENABLED&&1===t.availableZ.length?kh(t,Oh(o).numSameLayerCrossings):Yh(o,t);this.nodePfMap.set(e,i)}}getCreatePortPointSectionInput(){return{inputNodes:this.inputNodes,capacityMeshNodes:this.capacityMeshNodes,capacityMeshEdges:this.capacityMeshEdges,nodeMap:this.nodeMap,connectionResults:this.connectionResults}}createSection(t){return function(t,e){const{inputNodes:n,capacityMeshNodes:o,capacityMeshEdges:i,connectionResults:s}=t,{centerOfSectionCapacityNodeId:r,expansionDegrees:a}=e,c=new Map;for(const t of i){const[e,n]=t.nodeIds;c.has(e)||c.set(e,new Set),c.has(n)||c.set(n,new Set),c.get(e).add(n),c.get(n).add(e)}const h=new Set,l=new Set,d=[];for(d.push({nodeId:r,depth:0}),l.add(r);d.length>0;){const{nodeId:t,depth:e}=d.shift();if(h.add(t),e<a){const n=c.get(t)??new Set;for(const t of n)l.has(t)||(l.add(t),d.push({nodeId:t,depth:e+1}))}}const u=n.filter(t=>h.has(t.capacityMeshNodeId)),p=o.filter(t=>h.has(t.capacityMeshNodeId)),f=[],g=[];for(const t of i){const[e,n]=t.nodeIds,o=h.has(e),i=h.has(n);o&&i?f.push(t):(o||i)&&g.push(t)}const m=u.map(t=>{const e=t.portPoints.filter(t=>{const[e,n]=t.connectionNodeIds,o=h.has(e),i=h.has(n);return o||i});return{...t,portPoints:e}}),y=function(t,e){const n=[];for(const o of t){if(!o.path||0===o.path.length)continue;const t=o.connection.name,i=o.connection.rootConnectionName,s=[];for(let t=0;t<o.path.length;t++){const n=o.path[t];e.has(n.currentNodeId)&&s.push(t)}if(0===s.length)continue;const r=s[0],a=s[s.length-1];let c=r,h=a;if(r>0){const t=o.path[0].currentNodeId;(o.nodeIds[0]===t||o.nodeIds[1]===t)&&(c=0)}if(a<o.path.length-1){const t=o.path.length-1,e=o.path[t].currentNodeId;(o.nodeIds[0]===e||o.nodeIds[1]===e)&&(h=t)}const l=o.path.slice(c,h+1),d=c>0,u=h<o.path.length-1;n.push({connectionName:t,rootConnectionName:i,points:l.map(t=>({x:t.point.x,y:t.point.y,z:t.z,nodeId:t.currentNodeId,portPointId:t.portPoint?.portPointId})),originalStartIndex:c,originalEndIndex:h,hasEntryFromOutside:d,hasExitToOutside:u})}return n}(s??[],h);return{centerNodeId:r,expansionDegrees:a,nodeIds:h,inputNodes:m,capacityMeshNodes:p,internalEdges:f,boundaryEdges:g,sectionPaths:y}}(this.getCreatePortPointSectionInput(),t)}getSectionNodesWithPortPoints(t){const e=[];for(const n of t.nodeIds){const t=this.nodeMap.get(n),o=this.capacityMeshNodeMap.get(n);if(!t||!o)continue;const i=this.nodeAssignedPortPoints.get(n)??[];i.length>0&&e.push({capacityMeshNodeId:n,center:t.center,width:t.width,height:t.height,portPoints:i,availableZ:t.availableZ})}return e}getNodesWithPortPoints(){const t=[];for(const e of this.inputNodes){const n=this.nodeAssignedPortPoints.get(e.capacityMeshNodeId)??[];n.length>0&&t.push({capacityMeshNodeId:e.capacityMeshNodeId,center:e.center,width:e.width,height:e.height,portPoints:n,availableZ:e.availableZ})}return t}findHighestPfNode(){let t=null,e=0;for(const[n,o]of this.nodePfMap.entries()){o*(1-(this.attemptsToFixNode.get(n)??0)/this.MAX_ATTEMPTS_PER_NODE)**2>e&&(e=o,t=n)}return!t||e<this.ACCEPTABLE_PF?null:t}currentSectionCutPathInfo=new Map;currentSectionKeptPortPoints=new Map;currentSectionFixedRoutes=[];determineConnectionsToRip(t,e){const n=31337*this.sectionAttempts,o=Zh(n);if(this.FRACTION_TO_REPLACE>=1)return new Set(e);const i=function(t,e){const n=Zh(e),o=[...t];for(let t=o.length-1;t>0;t--){const e=Math.floor(n()*(t+1));[o[t],o[e]]=[o[e],o[t]]}return o}(e,n),s=Math.max(1,Math.ceil(i.length*this.FRACTION_TO_REPLACE)),r=new Set(i.slice(0,s));if(this.ALWAYS_RIP_INTERSECTIONS){const n=function(t){const{section:e,nodePfMap:n,capacityMeshNodeMap:o,nodeAssignedPortPoints:i,acceptablePf:s}=t,r=[];for(const t of e.nodeIds){if((n.get(t)??0)<=s)continue;const e=o.get(t);if(!e)continue;const a=i.get(t)??[];if(a.length<2)continue;const c=e.center.x-e.width/2,h=e.center.x+e.width/2,l=e.center.y-e.height/2,d=e.center.y+e.height/2,u=new Map;for(const t of a){const e=u.get(t.connectionName)??[];e.some(e=>e.x===t.x&&e.y===t.y&&e.z===t.z)||e.push({x:t.x,y:t.y,z:t.z}),u.set(t.connectionName,e)}const p=new Map;for(const[t,e]of u){if(e.length<2)continue;const n=e[0],o=e[1];if(n.z!==o.z)continue;const i=Xh(n,c,h,l,d),s=Xh(o,c,h,l,d),r=n.z,a=p.get(r)??[];a.push({connectionName:t,t1:i,t2:s}),p.set(r,a)}const f=1e-6;for(const[,t]of p){const e=t.map(t=>({connectionName:t.connectionName,a:Math.min(t.t1,t.t2),b:Math.max(t.t1,t.t2)}));for(let t=0;t<e.length;t++){const{connectionName:n,a:o,b:i}=e[t];for(let s=t+1;s<e.length;s++){const{connectionName:t,a:a,b:c}=e[s];Math.abs(o-a)<f||Math.abs(o-c)<f||Math.abs(i-a)<f||Math.abs(i-c)<f||(o<a&&a<i&&i<c||a<o&&o<c&&c<i)&&r.push([n,t])}}}}return r}({section:t,nodePfMap:this.nodePfMap,capacityMeshNodeMap:this.capacityMeshNodeMap,nodeAssignedPortPoints:this.nodeAssignedPortPoints,acceptablePf:this.ACCEPTABLE_PF});for(const[t,i]of n){if(r.has(t)||r.has(i))continue;const n=e.includes(t),s=e.includes(i);if(n&&s){const e=o()<.5;r.add(e?t:i)}else n?r.add(t):s&&r.add(i)}}return this.stats.lastRipCount=r.size,r}createSectionSimpleRouteJson(t){const e=[];this.currentSectionCutPathInfo.clear(),this.currentSectionKeptPortPoints.clear(),this.currentSectionFixedRoutes=[];const n=[],o=[];for(const e of this.connectionResults){if(!e.path||0===e.path.length)continue;const[i,s]=e.nodeIds,r=t.nodeIds.has(i),a=t.nodeIds.has(s);r&&a&&(o.push(e),n.push(e.connection.name))}const i=[];for(const e of t.sectionPaths){if(!e.hasEntryFromOutside&&!e.hasExitToOutside)continue;if(e.points.length<2)continue;const t=this.connectionResults.find(t=>t.connection.name===e.connectionName);t&&(i.push({sectionPath:e,originalResult:t}),n.includes(e.connectionName)||n.push(e.connectionName))}const s=this.determineConnectionsToRip(t,n);for(const t of o)s.has(t.connection.name)&&e.push(t.connection);for(const{sectionPath:t,originalResult:n}of i){if(!s.has(t.connectionName))continue;const o=`__cut__${t.connectionName}__${t.originalStartIndex}`;this.colorMap[o]=this.colorMap[t.connectionName];const i=t.points[0],r=t.points[t.points.length-1],a={name:o,rootConnectionName:t.rootConnectionName??t.connectionName,pointsToConnect:[{x:i.x,y:i.y,layers:[`layer${i.z+1}`]},{x:r.x,y:r.y,layers:[`layer${r.z+1}`]}]};e.push(a),this.currentSectionCutPathInfo.set(o,{sectionPath:t,originalConnectionResult:n})}const r=new Set(n.filter(t=>!s.has(t)));if(r.size>0){for(const e of t.nodeIds){const t=(this.nodeAssignedPortPoints.get(e)??[]).filter(t=>r.has(t.connectionName));t.length>0&&this.currentSectionKeptPortPoints.set(e,t)}for(const t of o)r.has(t.connection.name)&&this.currentSectionFixedRoutes.push(t);for(const{sectionPath:t,originalResult:e}of i)if(r.has(t.connectionName)){const n={connection:{name:t.connectionName,rootConnectionName:t.rootConnectionName,pointsToConnect:e.connection.pointsToConnect},path:t.points.map(t=>({prevCandidate:null,portPoint:null,currentNodeId:t.nodeId,point:{x:t.x,y:t.y},z:t.z,f:0,g:0,h:0,distanceTraveled:0})),portPoints:t.points.map(e=>({portPointId:e.portPointId,x:e.x,y:e.y,z:e.z,connectionName:t.connectionName,rootConnectionName:t.rootConnectionName})),nodeIds:e.nodeIds,straightLineDistance:e.straightLineDistance};this.currentSectionFixedRoutes.push(n)}}return{...this.simpleRouteJson,connections:e}}prepareSectionInputNodesForCutPaths(t){const e=new Set;for(const[,t]of this.currentSectionCutPathInfo.entries()){const{sectionPath:n}=t;if(0===n.points.length)continue;const o=n.points[0].nodeId;e.add(o);const i=n.points[n.points.length-1].nodeId;e.add(i)}return t.inputNodes.map(t=>e.has(t.capacityMeshNodeId)?{...t,_containsTarget:!0}:t)}getHyperParametersForScheduleIndex(t,e){const n=this.HYPERPARAMETER_SCHEDULE[t];return{...n,SHUFFLE_SEED:(n.SHUFFLE_SEED??0)+17*e}}createSectionSolver(t){const e=this.createSectionSimpleRouteJson(t),n=this.prepareSectionInputNodesForCutPaths(t),o=Th(e,n);for(const[t,e]of this.currentSectionKeptPortPoints){const n=o.nodeAssignedPortPoints.get(t)??[];o.nodeAssignedPortPoints.set(t,[...n,...e])}return new Gh({simpleRouteJson:e,inputNodes:n,capacityMeshNodes:t.capacityMeshNodes,colorMap:this.colorMap,nodeMemoryPfMap:this.nodePfMap,numShuffleSeeds:this.SHUFFLE_SEEDS_PER_SECTION??2*e.connections.length*this.effort,hyperParameters:{...this.getHyperParametersForScheduleIndex(this.currentScheduleIndex,this.sectionAttempts)},precomputedInitialParams:o,fixedRoutes:this.currentSectionFixedRoutes})}reattachSection(t,e,n,o){const i=[],s=[];for(const t of e)t.connection.name.startsWith("__cut__")?s.push(t):i.push(t);const r=new Set(i.map(t=>t.connection.name));this.connectionResults=this.connectionResults.filter(t=>!r.has(t.connection.name)),this.connectionResults.push(...i);for(const[e,n]of this.nodeAssignedPortPoints.entries()){if(!t.nodeIds.has(e))continue;const o=n.filter(t=>!r.has(t.connectionName));this.nodeAssignedPortPoints.set(e,o)}for(const[t,e]of this.assignedPortPoints.entries())r.has(e.connectionName)&&this.assignedPortPoints.delete(t);for(const e of s){const n=this.currentSectionCutPathInfo.get(e.connection.name);if(!n||!e.path)continue;const{sectionPath:o,originalConnectionResult:i}=n,s=i.path;if(!s)continue;const r=o.connectionName;for(const[e,n]of this.nodeAssignedPortPoints.entries()){const o=n.filter(n=>n.connectionName!==r||!t.nodeIds.has(e));this.nodeAssignedPortPoints.set(e,o)}const a=s.slice(0,o.originalStartIndex),c=s.slice(o.originalEndIndex+1),h=[];let l=a.length>0?a[a.length-1]:null;for(const t of e.path){const e={...t,prevCandidate:l};h.push(e),l=e}if(c.length>0&&h.length>0&&(c[0]={...c[0],prevCandidate:h[h.length-1]}),i.path=[...a,...h,...c],e.portPoints)for(const n of e.portPoints){const e={...n,connectionName:r,rootConnectionName:o.rootConnectionName??r};for(const o of t.inputNodes)for(const t of o.portPoints)if(Math.abs(t.x-n.x)<.001&&Math.abs(t.y-n.y)<.001&&t.z===n.z){for(const n of t.connectionNodeIds){const t=this.nodeAssignedPortPoints.get(n)??[];t.push(e),this.nodeAssignedPortPoints.set(n,t)}break}}}for(const[t,e]of n.entries())e.connectionName.startsWith("__cut__")||this.assignedPortPoints.set(t,e);for(const[t,e]of o.entries()){const n=e.filter(t=>!t.connectionName.startsWith("__cut__"));if(n.length>0){const e=this.nodeAssignedPortPoints.get(t)??[];this.nodeAssignedPortPoints.set(t,[...e,...n])}}}_step(){if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved||this.activeSubSolver.failed){if(this.activeSubSolver.failed){if(this.currentScheduleIndex++,this.activeSubSolver.error&&this.stats.errors++,this.currentScheduleIndex<this.HYPERPARAMETER_SCHEDULE.length&&this.currentSectionCenterNodeId){const t=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:this.currentSectionCenterNodeId,expansionDegrees:t.EXPANSION_DEGREES}),this.activeSubSolver=this.createSectionSolver(this.currentSection)}else this.stats.failedOptimizations++,this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0;return}const t=this.activeSubSolver.getNodesWithPortPoints().map(t=>({...t,portPoints:t.portPoints.map(t=>{if(t.connectionName.startsWith("__cut__")){const e=t.connectionName.slice(7),n=e.lastIndexOf("__"),o=n>=0?e.slice(0,n):e;return{...t,connectionName:o}}return t})})),e=new Set;for(const n of t)for(const t of n.portPoints)e.add(t.connectionName);const n=this.getSectionNodesWithPortPoints(this.currentSection).map(t=>({...t,portPoints:t.portPoints.filter(t=>e.has(t.connectionName))})).filter(t=>t.portPoints.length>0),o=this.computeScoreForNodes(n),i=this.computeScoreForNodes(t),s=`attempt${this.sectionAttempts}`;if(this.stats.lastSectionScore=i,i>o){const t=this.stats.currentBoardScore;this.stats.lastBoardScore=t;const e=[...this.connectionResults],n=new Map(this.assignedPortPoints),o=new Map(Array.from(this.nodeAssignedPortPoints.entries()).map(([t,e])=>[t,[...e]]));this.reattachSection(this.currentSection,this.activeSubSolver.connectionsWithResults,this.activeSubSolver.assignedPortPoints,this.activeSubSolver.nodeAssignedPortPoints),this.recomputePfForNodes(this.currentSection.nodeIds);const i=this.computeBoardScore();this.stats.sectionScores[s]=i,i>t?(this.stats.successfulOptimizations++,this.stats.currentBoardScore=i):(this.connectionResults=e,this.assignedPortPoints=n,this.nodeAssignedPortPoints=o,this.recomputePfForNodes(this.currentSection.nodeIds),this.stats.failedOptimizations++),this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0}else if(this.currentScheduleIndex++,this.currentScheduleIndex<this.HYPERPARAMETER_SCHEDULE.length&&this.currentSectionCenterNodeId){const t=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:this.currentSectionCenterNodeId,expansionDegrees:t.EXPANSION_DEGREES}),this.activeSubSolver=this.createSectionSolver(this.currentSection)}else this.stats.failedOptimizations++,this.activeSubSolver=null,this.currentSection=null,this.currentSectionCenterNodeId=null,this.currentScheduleIndex=0}return}if(this.sectionAttempts>=this.MAX_SECTION_ATTEMPTS)return void(this.solved=!0);const t=this.findHighestPfNode();if(!t)return void(this.solved=!0);this.sectionAttempts++,this.stats.sectionAttempts=this.sectionAttempts,this.stats.nodesExamined++,this.attemptsToFixNode.set(t,(this.attemptsToFixNode.get(t)??0)+1),this.currentSectionCenterNodeId=t,this.currentScheduleIndex=0;const e=this.HYPERPARAMETER_SCHEDULE[this.currentScheduleIndex];this.currentSection=this.createSection({centerOfSectionCapacityNodeId:t,expansionDegrees:e.EXPANSION_DEGREES});const n=this.getSectionNodesWithPortPoints(this.currentSection);this.sectionScoreBeforeOptimization=this.computeScoreForNodes(n);if(0===this.createSectionSimpleRouteJson(this.currentSection).connections.length)return this.currentSection=null,void(this.currentSectionCenterNodeId=null);this.activeSubSolver=this.createSectionSolver(this.currentSection)}computeProgress(){return this.sectionAttempts/this.MAX_SECTION_ATTEMPTS}visualize(){return this.solved?Vh(this):this.activeSubSolver?this.activeSubSolver.visualize():this.currentSection?function(t,e){const n={lines:[],points:[],rects:[],circles:[]};for(const e of t.inputNodes){const o=e.capacityMeshNodeId===t.centerNodeId,i=o?"rgba(0, 200, 0, 0.3)":"rgba(200, 200, 200, 0.3)";n.rects.push({center:e.center,width:.9*e.width,height:.9*e.height,layer:`z${e.availableZ.join(",")}`,fill:i,label:`${e.capacityMeshNodeId}${o?" (CENTER)":""}`})}for(const e of t.inputNodes)for(const t of e.portPoints){const e="rgba(150, 150, 150, 0.5)";n.circles.push({center:{x:t.x,y:t.y},radius:.05,fill:e,layer:`z${t.z}`,label:[t.portPointId,`cd: ${t.distToCentermostPortOnZ}`,`connects: ${t.connectionNodeIds.join(",")}`].filter(Boolean).join("\n")})}for(const o of t.sectionPaths){const t=e?.[o.connectionName]??"blue";for(let e=0;e<o.points.length-1;e++){const i=o.points[e],s=o.points[e+1],r=i.z===s.z,a=i.z;let c;c=r?0===a?"5 5":"10 5":"3 3 10",n.lines.push({points:[{x:i.x,y:i.y},{x:s.x,y:s.y}],strokeColor:t,strokeDash:c})}}return n}(this.currentSection,this.colorMap):Vh(this)}},Kh=class{parent={};constructor(t){for(const e of t)this.parent[e]=e}find(t){return this.parent[t]===t?t:this.parent[t]=this.find(this.parent[t])}union(t,e){const n=this.find(t),o=this.find(e);n!==o&&(this.parent[o]=n)}getGroup(t){const e=this.find(t),n=[];for(const t in this.parent)this.find(t)===e&&n.push(t);return n}},Qh=class{point;left=null;right=null;constructor(t){this.point=t}},tl=class{root=null;constructor(t){t.length>0&&(this.root=this.buildTree(t,0))}buildTree(t,e){const n=e%2==0?"x":"y";t.sort((t,e)=>t[n]-e[n]);const o=Math.floor(t.length/2),i=new Qh(t[o]);return o>0&&(i.left=this.buildTree(t.slice(0,o),e+1)),o<t.length-1&&(i.right=this.buildTree(t.slice(o+1),e+1)),i}findNearestNeighbor(t){if(!this.root)throw new Error("Tree is empty");const e=this.root.point,n=this.distance(t,e);return this.nearestNeighborSearch(this.root,t,0,e,n),e}nearestNeighborSearch(t,e,n,o,i){if(!t)return o;const s=n%2?"x":"y",r=this.distance(e,t.point);r<i&&(o=t.point,i=r);const a=e[s]-t.point[s],c=a<=0?t.left:t.right,h=a<=0?t.right:t.left;return o=this.nearestNeighborSearch(c,e,n+1,o,i),i=this.distance(e,o),Math.abs(a)<i&&(o=this.nearestNeighborSearch(h,e,n+1,o,i)),o}findKNearestNeighbors(t,e){if(!this.root)return[];const n=[];return this.kNearestNeighborSearch(this.root,t,0,n,e),n.sort((t,e)=>t.distance-e.distance).slice(0,e).map(t=>t.point)}kNearestNeighborSearch(t,e,n,o,i){if(!t)return;const s=n%2?"x":"y",r=this.distance(e,t.point);o.push({point:t.point,distance:r});const a=e[s]-t.point[s],c=a<=0?t.left:t.right,h=a<=0?t.right:t.left;this.kNearestNeighborSearch(c,e,n+1,o,i);let l=1/0;o.length>=i&&(o.sort((t,e)=>t.distance-e.distance),l=o[i-1]?.distance||1/0),(Math.abs(a)<l||o.length<i)&&this.kNearestNeighborSearch(h,e,n+1,o,i)}distance(t,e){return Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2)}},el=class{parent=new Map;rank=new Map;constructor(t){for(const e of t){const t=this.pointToKey(e);this.parent.set(t,t),this.rank.set(t,0)}}pointToKey(t){return`${t.x},${t.y}`}find(t){const e=this.pointToKey(t);if(!this.parent.has(e))throw new Error(`Point ${e} not found in DisjointSet`);let n=e;for(;n!==this.parent.get(n);)n=this.parent.get(n);let o=e;for(;o!==n;){const t=this.parent.get(o);this.parent.set(o,n),o=t}return n}union(t,e){const n=this.find(t),o=this.find(e);if(n===o)return!1;const i=this.rank.get(n)||0,s=this.rank.get(o)||0;return i<s?this.parent.set(n,o):i>s?this.parent.set(o,n):(this.parent.set(o,n),this.rank.set(n,i+1)),!0}};function nl(t){if(t.length<=1)return[];const e=[...t],n=new tl(e),o=[],i=Math.min(10,t.length-1);for(const t of e){const e=n.findKNearestNeighbors(t,i+1);for(const n of e){if(t.x===n.x&&t.y===n.y)continue;const e=Math.sqrt((t.x-n.x)**2+(t.y-n.y)**2);o.push({from:t,to:n,weight:e})}}o.sort((t,e)=>t.weight-e.weight);const s=new el(e),r=[];for(const t of o)if(s.union(t.from,t.to)&&(r.push(t),r.length===e.length-1))break;return r}function ol(t){if(t.pointId)return t.pointId;let e="";var n;return"layer"in(n=t)&&"string"==typeof n.layer?e=t.layer:Nn(t)&&t.layers&&(e=t.layers.sort().join("-")),`${t.x.toFixed(4)},${t.y.toFixed(4)},${e}`}var il=class extends Dn{constructor(t,e={}){super(),this.ogSrj=t,this.colorMap=e,this.unprocessedConnections=function(t){if(0===t.length)return[];const e=t.map((t,e)=>`conn_${e}`),n=new Kh(e),o=new Map;t.forEach((t,e)=>{const n=`conn_${e}`;t.pointsToConnect.forEach(t=>{const e=ol(t);o.has(e)||o.set(e,[]),o.get(e).push(n)})});for(const t of o.values())if(t.length>1){const e=t[0];for(let o=1;o<t.length;o++)n.union(e,t[o])}const i=new Map;t.forEach((t,e)=>{const o=`conn_${e}`,s=n.find(o);i.has(s)||i.set(s,[]),i.get(s).push(t)});const s=[];for(const t of i.values()){if(1===t.length){s.push(t[0]);continue}const e=new Map,n=new Set;let o=!1;const i=[],r=new Set;let a;t.forEach(t=>{t.pointsToConnect.forEach(t=>e.set(ol(t),t)),n.add(t.name),t.isOffBoard&&(o=!0),t.externallyConnectedPointIds&&i.push(...t.externallyConnectedPointIds),t.netConnectionName&&r.add(t.netConnectionName),void 0===a&&void 0!==t.nominalTraceWidth&&(a=t.nominalTraceWidth)});const c={name:Array.from(n).join("__"),mergedConnectionNames:Array.from(n),pointsToConnect:Array.from(e.values()),isOffBoard:o,externallyConnectedPointIds:i.length>0?i:void 0,netConnectionName:r.size>0?Array.from(r).join("__"):void 0,nominalTraceWidth:a};s.push(c)}return s}([...t.connections]),this.newConnections=[]}getSolverName(){return"NetToPointPairsSolver"}unprocessedConnections;newConnections;_step(){if(0===this.unprocessedConnections.length)return void(this.solved=!0);const t=this.unprocessedConnections.pop(),e=t.externallyConnectedPointIds??[],n=new Map;e.forEach((t,e)=>t.forEach(t=>n.set(t,e)));const o=(t,e)=>{if(!t.pointId||!e.pointId)return!1;const o=n.get(t.pointId),i=n.get(e.pointId);return void 0!==o&&o===i};if(2===t.pointsToConnect.length){if(o(t.pointsToConnect[0],t.pointsToConnect[1]))return;return void this.newConnections.push({...t,rootConnectionName:t.name})}const i=nl(t.pointsToConnect);let s=0;for(const e of i)o(e.from,e.to)||this.newConnections.push({pointsToConnect:[e.from,e.to],name:`${t.name}_mst${s++}`,rootConnectionName:t.name,mergedConnectionNames:t.mergedConnectionNames,netConnectionName:t.netConnectionName})}getNewSimpleRouteJson(){return{...structuredClone(this.ogSrj),connections:structuredClone(this.newConnections)}}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Net To Point Pairs Visualization"};return this.unprocessedConnections.forEach(e=>{e.pointsToConnect.forEach(n=>{t.points.push({x:n.x,y:n.y,color:"red",label:e.name})});const n=e.pointsToConnect.length**2,o=Vn(0),i=new Set;for(let s=0;s<Math.max(n,2*e.pointsToConnect.length);s++){const n=Math.floor(o()*e.pointsToConnect.length),s=Math.floor(o()*e.pointsToConnect.length);i.has(`${n}-${s}`)||(i.add(`${n}-${s}`),t.lines.push({points:[e.pointsToConnect[n],e.pointsToConnect[s]],strokeColor:"rgba(255,0,0,0.25)"}))}}),this.newConnections.forEach(e=>{const n=this.colorMap?.[e.name]||"blue";e.pointsToConnect.forEach(o=>{t.points.push({x:o.x,y:o.y,color:n,label:e.name})});for(let o=0;o<e.pointsToConnect.length-1;o++)for(let i=o+1;i<e.pointsToConnect.length;i++)t.lines.push({points:[e.pointsToConnect[o],e.pointsToConnect[i]],strokeColor:n})}),t}},sl=class extends il{constructor(t,e={}){const n=t.connections.flatMap(t=>t.pointsToConnect),o=new Map;for(const t of n)t.pointId&&o.set(t.pointId,t);const i=n.map(t=>t.pointId).filter(t=>!!t),s=new Kh(i),r=[];for(const e of t.connections)e.isOffBoard?e.pointsToConnect.length>=2&&e.pointsToConnect[0].pointId&&e.pointsToConnect[1].pointId&&s.union(e.pointsToConnect[0].pointId,e.pointsToConnect[1].pointId):r.push(e);super({...t,connections:r},e),this.ogSrj=t,this.colorMap=e,this.connectionPointDsu=s,this.connectionPointMap=o,this.ogSrj=t}getSolverName(){return"NetToPointPairsSolver2_OffBoardConnection"}connectionPointDsu;connectionPointMap;_findBestConnectionPointsFromDisjointSets(t,e){if(!t.pointId||!e.pointId)return{pointsToConnect:[t,e]};const n=this.connectionPointDsu.getGroup(t.pointId).map(t=>this.connectionPointMap.get(t)),o=this.connectionPointDsu.getGroup(e.pointId).map(t=>this.connectionPointMap.get(t));let i=t,s=e,r=1/0;for(const t of n)for(const e of o){const n=Math.sqrt(Math.pow(t.x-e.x,2)+Math.pow(t.y-e.y,2));n<r&&(r=n,i=t,s=e)}return{pointsToConnect:[i,s]}}_step(){if(0===this.unprocessedConnections.length)return void(this.solved=!0);const t=this.unprocessedConnections.pop(),e=t.externallyConnectedPointIds??[],n=new Map;e.forEach((t,e)=>t.forEach(t=>n.set(t,e)));const o=(t,e)=>{if(!t.pointId||!e.pointId)return!1;const o=n.get(t.pointId),i=n.get(e.pointId);return void 0!==o&&o===i};if(2===t.pointsToConnect.length){if(o(t.pointsToConnect[0],t.pointsToConnect[1]))return;const e=this._findBestConnectionPointsFromDisjointSets(t.pointsToConnect[0],t.pointsToConnect[1]);return void this.newConnections.push({...t,pointsToConnect:e.pointsToConnect,rootConnectionName:t.name})}const i=nl(t.pointsToConnect);let s=0;for(const e of i){if(o(e.from,e.to))continue;const n=this._findBestConnectionPointsFromDisjointSets(e.from,e.to);this.newConnections.push({pointsToConnect:n.pointsToConnect,name:`${t.name}_mst${s++}`,rootConnectionName:t.name,mergedConnectionNames:t.mergedConnectionNames,netConnectionName:t.netConnectionName})}}},rl=class{netMap;idToNetMap;constructor(t){this.netMap=t,this.idToNetMap={};for(const[e,n]of Object.entries(t))for(const t of n)this.idToNetMap[t]=e}addConnections(t){for(const e of t){const t=new Set;for(const n of e){const e=this.idToNetMap[n];e&&t.add(e)}let n;if(0===t.size)n=`connectivity_net${Object.keys(this.netMap).length}`,this.netMap[n]=[];else if(1===t.size)n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;else{n=t.values().next().value??`connectivity_net${Object.keys(this.netMap).length}`;for(const e of t)if(e!==n){const t=this.netMap[n],o=this.netMap[e];if(t&&o){t.push(...o),this.netMap[e]=t;for(const e of t)this.idToNetMap[e]=n}}}for(const t of e){const e=this.netMap[n];e&&!e.includes(t)&&e.push(t),this.idToNetMap[t]=n}}}getIdsConnectedToNet(t){return this.netMap[t]||[]}getNetConnectedToId(t){return this.idToNetMap[t]}areIdsConnected(t,e){if(t===e)return!0;const n=this.getNetConnectedToId(t);if(!n)return!1;const o=this.getNetConnectedToId(e);return!!o&&(n===o||o===t||o===t)}areAllIdsConnected(t){if(0===t.length)return!0;const e=this.getNetConnectedToId(t[0]);if(!e)return!1;for(const n of t){const t=this.getNetConnectedToId(n);if(void 0===t)return!1;if(t!==e)return!1}return!0}};function al(t,e={}){const n=[],o=[],i=e.color??"gray",s=e.label,r=En[t.footprint]??En["0603"],a=t.end.x-t.start.x,c=t.end.y-t.start.y,h=Math.abs(a)>Math.abs(c),l=h?r.padLength:r.padWidth,d=h?r.padWidth:r.padLength;return n.push({center:t.start,width:l,height:d,fill:Mn(i,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:s?`${s} (start)`:void 0}),n.push({center:t.end,width:l,height:d,fill:Mn(i,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper",label:s?`${s} (end)`:void 0}),o.push({points:[t.start,t.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*r.padWidth,layer:"jumper-body"}),{rects:n,lines:o}}function cl(t,e={}){const n={rects:[],lines:[]};for(const o of t){const{rects:t,lines:i}=al(o,e);n.rects.push(...t),n.lines.push(...i)}return n}var hl=1e5,ll=.001,dl=class extends Dn{getSolverName(){return"SingleHighDensityRouteStitchSolver"}mergedHdRoute;remainingHdRoutes;start;end;colorMap;constructor(t){if(super(),this.remainingHdRoutes=[...t.hdRoutes],this.colorMap=t.colorMap??{},0===t.hdRoutes.length){this.start=t.start,this.end=t.end;const e=[{x:t.start.x,y:t.start.y,z:t.start.z}],n=[];return t.start.z!==t.end.z&&(e.push({x:t.start.x,y:t.start.y,z:t.end.z}),n.push({x:t.start.x,y:t.start.y})),e.push({x:t.end.x,y:t.end.y,z:t.end.z}),this.mergedHdRoute={connectionName:t.connectionName,rootConnectionName:t.hdRoutes[0]?.rootConnectionName,route:e,vias:n,jumpers:[],viaDiameter:t.defaultViaDiameter??.3,traceThickness:t.defaultTraceThickness??.15},void(this.solved=!0)}let e=1/0,n=t.hdRoutes[0],o="start-to-end";for(const i of t.hdRoutes){const s=i.route[0],r=i.route[i.route.length-1],a=F(t.start,s),c=F(t.start,r),h=F(t.end,s),l=F(t.end,r),d=Math.min(a,c,h,l);d<e&&(e=d,n=i,o=Math.min(h,l)<Math.min(a,c)?"end-to-start":"start-to-end")}"start-to-end"===o?(this.start=t.start,this.end=t.end):(this.start=t.end,this.end=t.start);const i=n.route[0],s=n.route[n.route.length-1],r=F(this.start,i)<=F(this.start,s)?i:s;this.mergedHdRoute={connectionName:t.connectionName,rootConnectionName:n.rootConnectionName,route:[{x:this.start.x,y:this.start.y,z:r.z}],vias:[],jumpers:[],viaDiameter:n.viaDiameter,traceThickness:n.traceThickness}}getDisjointedRoute(){for(const t of this.remainingHdRoutes){if([t.route[0],t.route[t.route.length-1]].some(e=>!this.remainingHdRoutes.some(n=>{if(n===t)return!1;return[n.route[0],n.route[n.route.length-1]].some(t=>t.z===e.z&&F(e,t)<.001)})))return{firstRoute:t}}return{firstRoute:this.remainingHdRoutes[0]}}_step(){if(0===this.remainingHdRoutes.length){const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];return this.mergedHdRoute.route.push({x:this.end.x,y:this.end.y,z:t.z}),void(this.solved=!0)}const t=this.mergedHdRoute.route[this.mergedHdRoute.route.length-1];let e=-1,n="first",o=1/0;for(let i=0;i<this.remainingHdRoutes.length;i++){const s=this.remainingHdRoutes[i],r=s.route[0],a=s.route[s.route.length-1],c=F(t,r),h=F(t,a);let l=1/0;l=t.z===r.z?c<ll?c:hl+c:c<ll?1e3+c:hl+c,l<o&&(o=l,e=i,n="first");let d=1/0;d=t.z===a.z?h<ll?h:hl+h:h<ll?1e3+h:hl+h,d<o&&(o=d,e=i,n="last")}if(-1===e)return void(this.remainingHdRoutes=[]);const i=this.remainingHdRoutes[e];let s;this.remainingHdRoutes.splice(e,1),s="first"===n?i.route:[...i.route].reverse(),s.length>0&&F(t,s[0])<ll&&t.z===s[0].z?this.mergedHdRoute.route.push(...s.slice(1)):this.mergedHdRoute.route.push(...s),this.mergedHdRoute.vias.push(...i.vias),i.jumpers&&this.mergedHdRoute.jumpers.push(...i.jumpers)}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Single High Density Route Stitch Solver"};if(t.points?.push({x:this.start.x,y:this.start.y,color:"green",label:"Start"},{x:this.end.x,y:this.end.y,color:"red",label:"End"}),this.mergedHdRoute&&this.mergedHdRoute.route.length>1){t.lines?.push({points:this.mergedHdRoute.route.map(t=>({x:t.x,y:t.y})),strokeColor:"green"});for(const e of this.mergedHdRoute.route)t.points?.push({x:e.x,y:e.y,color:"green"});for(const e of this.mergedHdRoute.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:this.mergedHdRoute.viaDiameter/2,fill:"green"});if(this.mergedHdRoute.jumpers&&this.mergedHdRoute.jumpers.length>0){const e=cl(this.mergedHdRoute.jumpers,{color:"green",label:this.mergedHdRoute.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const[e,n]of this.remainingHdRoutes.entries()){const o=this.colorMap[n.connectionName]??"gray";n.route.length>1&&t.lines?.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:o});for(let i=0;i<n.route.length;i++){const s=n.route[i];t.points?.push({x:s.x+(e%2-.5)/500+(i%8-4)/1e3,y:s.y+(e%2-.5)/500+(i%8-4)/1e3,color:o,label:`Route ${n.connectionName} ${s===n.route[0]?"First":s===n.route[n.route.length-1]?"Last":""}`})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:o});if(n.jumpers&&n.jumpers.length>0){const e=cl(n.jumpers,{color:o,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}return t}},ul=t=>`${Math.round(100*t.x)},${Math.round(100*t.y)},${Math.round(100*t.z)}`,pl=class extends Dn{getSolverName(){return"MultipleHighDensityRouteStitchSolver"}unsolvedRoutes;activeSolver=null;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;constructor(t){super(),this.colorMap=t.colorMap??{};const e=t.hdRoutes[0];this.defaultTraceThickness=e?.traceThickness??.15,this.defaultViaDiameter=e?.viaDiameter??t.defaultViaDiameter??.3;const n=new rl({}),o=[],i=new Map;for(let e=0;e<t.hdRoutes.length;e++){const n=t.hdRoutes[e],i=n.route[0],s=n.route[n.route.length-1];o.push([`route_island_${e}`,`${n.connectionName}:${ul(i)}`,`${n.connectionName}:${ul(s)}`])}n.addConnections(o);for(const t of o)for(const e of t.slice(1))i.set(e,(i.get(e)??0)+1);this.unsolvedRoutes=[];const s=Array.from(new Set(Object.values(n.idToNetMap)));for(const e of s){const o=n.getIdsConnectedToNet(e),s=t.hdRoutes.filter((t,e)=>o.includes(`route_island_${e}`));if(0===s.length)continue;const r=t.connections.find(t=>t.name===s[0].connectionName),a=s.flatMap(t=>[t.route[0],t.route[t.route.length-1]]),c=[];for(const t of a){const e=`${s[0].connectionName}:${ul(t)}`;1===i.get(e)&&c.push(t)}if(0===c.length){console.log("no possible endpoints, can't stitch");continue}let h,l;2!==c.length?(h={...r.pointsToConnect[0],z:wn(Cn(r.pointsToConnect[0]),t.layerCount)},l={...r.pointsToConnect[1],z:wn(Cn(r.pointsToConnect[1]),t.layerCount)}):(h=c[0],l=c[1],F(h,r.pointsToConnect[1])<F(l,r.pointsToConnect[0])&&([h,l]=[l,h])),this.unsolvedRoutes.push({connectionName:s[0].connectionName,hdRoutes:s,start:h,end:l})}this.MAX_ITERATIONS=1e5}_step(){if(this.activeSolver)return this.activeSolver.step(),void(this.activeSolver.solved?(this.activeSolver instanceof dl&&this.mergedHdRoutes.push(this.activeSolver.mergedHdRoute),this.activeSolver=null):this.activeSolver.failed&&(this.failed=!0,this.error=this.activeSolver.error));const t=this.unsolvedRoutes.pop();t?this.activeSolver=new dl({connectionName:t.connectionName,hdRoutes:t.hdRoutes,start:t.start,end:t.end,colorMap:this.colorMap,defaultTraceThickness:this.defaultTraceThickness,defaultViaDiameter:this.defaultViaDiameter}):this.solved=!0}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Multiple High Density Route Stitch Solver"};if(this.activeSolver){const e=this.activeSolver.visualize();e.points?.length&&t.points?.push(...e.points),e.lines?.length&&t.lines?.push(...e.lines),e.circles?.length&&t.circles?.push(...e.circles),e.rects?.length&&(t.rects||(t.rects=[]),t.rects.push(...e.rects))}for(const[e,n]of this.mergedHdRoutes.entries()){const o=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e<n.route.length-1;e++){const i=n.route[e],s=n.route[e+1],r=0!==i.z?Mn(o,.5):o;t.lines?.push({points:[{x:i.x,y:i.y},{x:s.x,y:s.y}],strokeColor:r,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?Mn(o,.5):o;t.points?.push({x:e.x,y:e.y,color:n})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:o});if(n.jumpers&&n.jumpers.length>0){const e=cl(n.jumpers,{color:o,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.unsolvedRoutes){const n=this.colorMap[e.connectionName]??"gray";t.points?.push({x:e.start.x,y:e.start.y,color:n,label:`${e.connectionName} Start (z=${e.start.z})`},{x:e.end.x,y:e.end.y,color:n,label:`${e.connectionName} End (z=${e.end.z})`}),t.lines?.push({points:[{x:e.start.x,y:e.start.y},{x:e.end.x,y:e.end.y}],strokeColor:n,strokeDash:"2 2"});for(const o of e.hdRoutes){o.route.length>1&&t.lines?.push({points:o.route.map(t=>({x:t.x,y:t.y})),strokeColor:Mn(n,.5),strokeDash:"10 5"});for(const e of o.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:o.viaDiameter/2,fill:n});if(o.jumpers&&o.jumpers.length>0){const e=cl(o.jumpers,{color:n,label:o.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}}return t}},fl=class{tree;constructor(t=9){this.tree=new ot(t)}insert(t,e,n,o,i){this.tree.insert({minX:e,minY:n,maxX:o,maxY:i,data:t})}bulkLoad(t){const e=t.map(({item:t,minX:e,minY:n,maxX:o,maxY:i})=>({minX:e,minY:n,maxX:o,maxY:i,data:t}));this.tree.load(e)}search(t,e,n,o){return this.tree.search({minX:t,minY:e,maxX:n,maxY:o}).map(t=>t.data)}clear(){this.tree.clear()}},gl=class{index;items=[];currentIndex=0;capacity;constructor(t){this.capacity=Math.max(1,t),this.index=new E(this.capacity)}insert(t,e,n,o,i){if(this.currentIndex>=this.index.numItems)throw new Error("Exceeded initial capacity");this.items[this.currentIndex]=t,this.index.add(e,n,o,i),this.currentIndex++}finish(){this.index.finish()}search(t,e,n,o){return this.index.search(t,e,n,o).map(t=>this.items[t]||null).filter(Boolean)}clear(){this.items=[],this.currentIndex=0,this.index=new E(this.capacity)}},ml=class{idx;storage=[];constructor(t="native",e=[]){"flatbush"===t?0===e.length?(this.idx=new fl,t="rbush"):this.idx=new gl(e.length):this.idx="rbush"===t?new fl:new class{shi=new yl(e);insert(t){}search(t,e,n,o){const i=(t+n)/2,s=(e+o)/2,r=n-t,a=o-e;return this.shi.getNodesInArea(i,s,r,a)}clear(){}},e.forEach(t=>this.insert(t)),"flatbush"===t&&e.length>0&&this.idx.finish?.()}insert(t){this.storage.push(t),this.idx.insert(t,t.center.x-t.width/2,t.center.y-t.height/2,t.center.x+t.width/2,t.center.y+t.height/2)}search(t){return this.idx.search(t.minX,t.minY,t.maxX,t.maxY)}searchArea(t,e,n,o){return this.search({minX:t-n/2,minY:e-o/2,maxX:t+n/2,maxY:e+o/2})}},yl=class{constructor(t){this.obstacles=t,this.buckets=new Map;for(let e=0;e<t.length;e++){const n=t[e],o=n.center.x-n.width/2,i=n.center.y-n.height/2,s=n.center.x+n.width/2,r=n.center.y+n.height/2;for(let t=o;t<=s;t+=this.CELL_SIZE)for(let o=i;o<=r;o+=this.CELL_SIZE){const i=this.getBucketKey(t,o),s=this.buckets.get(i);s?s.push([n,e]):this.buckets.set(i,[[n,e]])}}}buckets;CELL_SIZE=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getNodesInArea(t,e,n,o){const i=[],s=new Set,r=e-o/2,a=t+n/2,c=e+o/2;for(let e=t-n/2;e<=a;e+=this.CELL_SIZE)for(let t=r;t<=c;t+=this.CELL_SIZE){const n=this.getBucketKey(e,t),o=this.buckets.get(n)||[];for(const t of o)s.has(t[1])||(s.add(t[1]),i.push(t[0]))}return i}},xl=t=>({minX:Math.min(t[0].x,t[1].x),maxX:Math.max(t[0].x,t[1].x),minY:Math.min(t[0].y,t[1].y),maxY:Math.max(t[0].y,t[1].y)});function vl(t,e){const n=t.x-e.x,o=t.y-e.y;return n*n+o*o}function bl(t,e,n){const o=vl(e,n);if(0===o)return vl(t,e);let i=((t.x-e.x)*(n.x-e.x)+(t.y-e.y)*(n.y-e.y))/o;i=Math.max(0,Math.min(1,i));return vl(t,{x:e.x+i*(n.x-e.x),y:e.y+i*(n.y-e.y)})}function Pl(t,e,n,o){if(D(t,e,n,o))return 0;const i={x:t.x,y:t.y},s={x:e.x,y:e.y},r={x:n.x,y:n.y},a={x:o.x,y:o.y};return Math.min(bl(i,r,a),bl(s,r,a),bl(r,i,s),bl(a,i,s))}var Sl=class{segmentBuckets;viaBuckets;CELL_SIZE;constructor(t,e=1){this.segmentBuckets=new Map,this.viaBuckets=new Map,this.CELL_SIZE=e;for(const e of t)if(e&&e.connectionName){if(e.route&&e.route.length>=2)for(let t=0;t<e.route.length-1;t++){const n=e.route[t],o=e.route[t+1];if(n.x===o.x&&n.y===o.y)continue;if(n.insideJumperPad&&o.insideJumperPad)continue;const i=[n,o],s=xl(i),r={segmentId:`${e.connectionName}-seg-${t}`,segment:i,parentRoute:e},a=Math.floor(s.minX/this.CELL_SIZE),c=Math.floor((s.maxX+1e-9)/this.CELL_SIZE),h=Math.floor(s.minY/this.CELL_SIZE),l=Math.floor((s.maxY+1e-9)/this.CELL_SIZE);for(let t=a;t<=c;t++)for(let e=h;e<=l;e++){const n=`${t}x${e}`;let o=this.segmentBuckets.get(n);o||(o=[],this.segmentBuckets.set(n,o)),o.push(r)}}if(e.vias&&e.vias.length>0)for(let t=0;t<e.vias.length;t++){const n=e.vias[t];if(null==n)continue;const o={viaId:`${e.connectionName}-via-${t}`,x:n.x,y:n.y,parentRoute:e},i=`${Math.floor(n.x/this.CELL_SIZE)}x${Math.floor(n.y/this.CELL_SIZE)}`;let s=this.viaBuckets.get(i);s||(s=[],this.viaBuckets.set(i,s)),s.push(o)}}else console.warn("Skipping route with missing data:",e)}getConflictingRoutesForSegment(t,e,n){const o=xl([t,e]),i=o.minX-n,s=o.minY-n,r=o.maxX+n,a=o.maxY+n,c=Math.floor(i/this.CELL_SIZE),h=Math.floor((r+1e-9)/this.CELL_SIZE),l=Math.floor(s/this.CELL_SIZE),d=Math.floor((a+1e-9)/this.CELL_SIZE),u=new Map,p=new Set,f=new Set,g={x:t.x,y:t.y},m={x:e.x,y:e.y};for(let o=c;o<=h;o++)for(let i=l;i<=d;i++){const s=`${o}x${i}`,r=this.segmentBuckets.get(s);if(r)for(const o of r){if(p.has(o.segmentId))continue;p.add(o.segmentId);const i=o.parentRoute,[s,r]=o.segment,a=n+i.traceThickness/2,c=a*a,h=Pl(t,e,s,r);if(h<c){const t=i.connectionName,e=u.get(t);(!e||h<e.minDistSq)&&u.set(t,{route:i,minDistSq:h})}}const a=this.viaBuckets.get(s);if(a)for(const t of a){if(f.has(t.viaId))continue;f.add(t.viaId);const e=t.parentRoute,o={x:t.x,y:t.y},i=n+e.viaDiameter/2,s=i*i,r=bl(o,g,m);if(r<s){const t=e.connectionName,n=u.get(t);(!n||r<n.minDistSq)&&u.set(t,{route:e,minDistSq:r})}}}const y=[];for(const t of u.values())y.push({conflictingRoute:t.route,distance:Math.sqrt(t.minDistSq)});return y}removeRoute(t){for(const[e,n]of this.segmentBuckets){const o=n.filter(e=>e.parentRoute.connectionName!==t);0===o.length?this.segmentBuckets.delete(e):o.length!==n.length&&this.segmentBuckets.set(e,o)}for(const[e,n]of this.viaBuckets){const o=n.filter(e=>e.parentRoute.connectionName!==t);0===o.length?this.viaBuckets.delete(e):o.length!==n.length&&this.viaBuckets.set(e,o)}}addRoute(t){if(!t||!t.connectionName)return void console.warn("Skipping route with missing data:",t);if(t.route&&t.route.length>=2)for(let e=0;e<t.route.length-1;e++){const n=t.route[e],o=t.route[e+1];if(n.x===o.x&&n.y===o.y)continue;if(n.insideJumperPad&&o.insideJumperPad)continue;const i=[n,o],s=xl(i),r={segmentId:`${t.connectionName}-seg-${e}`,segment:i,parentRoute:t},a=Math.floor(s.minX/this.CELL_SIZE),c=Math.floor((s.maxX+1e-9)/this.CELL_SIZE),h=Math.floor(s.minY/this.CELL_SIZE),l=Math.floor((s.maxY+1e-9)/this.CELL_SIZE);for(let t=a;t<=c;t++)for(let e=h;e<=l;e++){const n=`${t}x${e}`;let o=this.segmentBuckets.get(n);o||(o=[],this.segmentBuckets.set(n,o)),o.push(r)}}if(t.vias&&t.vias.length>0)for(let e=0;e<t.vias.length;e++){const n=t.vias[e];if(null==n)continue;const o={viaId:`${t.connectionName}-via-${e}`,x:n.x,y:n.y,parentRoute:t},i=`${Math.floor(n.x/this.CELL_SIZE)}x${Math.floor(n.y/this.CELL_SIZE)}`;let s=this.viaBuckets.get(i);s||(s=[],this.viaBuckets.set(i,s)),s.push(o)}}getConflictingRoutesNearPoint(t,e){const n=t.x-e,o=t.y-e,i=t.x+e,s=t.y+e,r=Math.floor(n/this.CELL_SIZE),a=Math.floor((i+1e-9)/this.CELL_SIZE),c=Math.floor(o/this.CELL_SIZE),h=Math.floor((s+1e-9)/this.CELL_SIZE),l=new Map,d=new Set,u=new Set;for(let n=r;n<=a;n++)for(let o=c;o<=h;o++){const i=`${n}x${o}`,s=this.segmentBuckets.get(i);if(s)for(const n of s){if(d.has(n.segmentId))continue;d.add(n.segmentId);const o=n.segment[0],i=n.segment[1];if(o.z!==i.z||o.z!==t.z)continue;const s=n.parentRoute,r={x:n.segment[0].x,y:n.segment[0].y},a={x:n.segment[1].x,y:n.segment[1].y},c=e+s.traceThickness/2,h=c*c,u=bl(t,r,a);if(u<h){const t=s.connectionName,e=l.get(t);(!e||u<e.minDistSq)&&l.set(t,{route:s,minDistSq:u})}}const r=this.viaBuckets.get(i);if(r)for(const n of r){if(u.has(n.viaId))continue;u.add(n.viaId);const o=n.parentRoute,i={x:n.x,y:n.y},s=e+o.viaDiameter/2,r=s*s,a=vl(t,i);if(a<r){const t=o.connectionName,e=l.get(t);(!e||a<e.minDistSq)&&l.set(t,{route:o,minDistSq:a})}}}const p=[];for(const t of l.values())p.push({conflictingRoute:t.route,distance:Math.sqrt(t.minDistSq)});return p}},Il=class extends Dn{getSolverName(){return"SingleRouteUselessViaRemovalSolver"}obstacleSHI;hdRouteSHI;unsimplifiedRoute;routeSections;currentSectionIndex;TRACE_THICKNESS=.15;OBSTACLE_MARGIN=.1;constructor(t){super(),this.currentSectionIndex=0,this.obstacleSHI=t.obstacleSHI,this.hdRouteSHI=t.hdRouteSHI,this.unsimplifiedRoute=t.unsimplifiedRoute,this.routeSections=this.breakRouteIntoSections(this.unsimplifiedRoute)}breakRouteIntoSections(t){const e=[],n=t.route;if(0===n.length)return[];let o={startIndex:0,endIndex:-1,z:n[0].z,points:[n[0]]};for(let t=1;t<n.length;t++)n[t].z===o.z?o.points.push(n[t]):(o.endIndex=t-1,e.push(o),o={startIndex:t,endIndex:-1,z:n[t].z,points:[n[t]]});return o.endIndex=n.length-1,e.push(o),e}_step(){if(this.currentSectionIndex>=this.routeSections.length)return void(this.solved=!0);if(0===this.currentSectionIndex&&this.routeSections.length>1){const t=this.routeSections[0],e=this.routeSections[1];if(t.z!==e.z){const n=e.z,o=t.points[0];if(this.canEndpointConnectOnLayer(o.x,o.y,n)&&this.canSectionMoveToLayer({currentSection:t,targetZ:n}))return t.z=n,t.points=t.points.map(t=>({...t,z:n})),void(this.currentSectionIndex=2)}return void this.currentSectionIndex++}if(this.currentSectionIndex===this.routeSections.length-1){if(this.routeSections.length>=2){const t=this.routeSections[this.routeSections.length-1],e=this.routeSections[this.routeSections.length-2];if(t.z!==e.z){const n=e.z,o=t.points[t.points.length-1];this.canEndpointConnectOnLayer(o.x,o.y,n)&&this.canSectionMoveToLayer({currentSection:t,targetZ:n})&&(t.z=n,t.points=t.points.map(t=>({...t,z:n})))}}return void(this.solved=!0)}const t=this.routeSections[this.currentSectionIndex-1],e=this.routeSections[this.currentSectionIndex],n=this.routeSections[this.currentSectionIndex+1];if(t.z!==n.z)return void this.currentSectionIndex++;const o=t.z;if(this.canSectionMoveToLayer({currentSection:e,targetZ:o}))return e.z=o,e.points=e.points.map(t=>({...t,z:o})),void(this.currentSectionIndex+=2);this.currentSectionIndex++}canEndpointConnectOnLayer(t,e,n){const o=this.obstacleSHI.searchArea(t,e,2,2).filter(n=>{if(!n.connectedTo?.includes(this.unsimplifiedRoute.connectionName))return!1;const o=n.width/2+.05,i=n.height/2+.05,s=Math.abs(t-n.center.x)<=o,r=Math.abs(e-n.center.y)<=i;return s&&r});return!(o.length>0)||o.some(t=>t.zLayers?.includes(n))}canSectionMoveToLayer({currentSection:t,targetZ:e}){for(let n=0;n<t.points.length-1;n++){const o={...t.points[n],z:e},i={...t.points[n+1],z:e},s=this.hdRouteSHI.getConflictingRoutesForSegment(o,i,this.TRACE_THICKNESS);for(const{conflictingRoute:t,distance:e}of s)if(t.connectionName!==this.unsimplifiedRoute.connectionName&&e<this.TRACE_THICKNESS+t.traceThickness)return!1;const r={centerX:(o.x+i.x)/2,centerY:(o.y+i.y)/2,width:Math.abs(o.x-i.x),height:Math.abs(o.y-i.y)},a=this.obstacleSHI.searchArea(r.centerX,r.centerY,r.width+2*(this.TRACE_THICKNESS+this.OBSTACLE_MARGIN),r.height+2*(this.TRACE_THICKNESS+this.OBSTACLE_MARGIN));for(const t of a){if(t.connectedTo?.includes(this.unsimplifiedRoute.connectionName))continue;if(t.zLayers?.includes(e)){if(Math.abs(o.x-t.center.x)<.01&&Math.abs(o.y-t.center.y)<.01||Math.abs(i.x-t.center.x)<.01&&Math.abs(i.y-t.center.y)<.01)continue}if(K(o,i,t)<this.TRACE_THICKNESS+this.OBSTACLE_MARGIN)return!1}}return!0}getConstructorParams(){return{obstacleSHI:this.obstacleSHI,hdRouteSHI:this.hdRouteSHI,unsimplifiedRoute:this.unsimplifiedRoute}}getOptimizedHdRoute(){const t=this.routeSections.flatMap(t=>t.points),e=[];for(let n=0;n<t.length-1;n++)t[n].z!==t[n+1].z&&e.push({x:t[n].x,y:t[n].y});return{connectionName:this.unsimplifiedRoute.connectionName,rootConnectionName:this.unsimplifiedRoute.rootConnectionName,route:t,traceThickness:this.unsimplifiedRoute.traceThickness,vias:e,viaDiameter:this.unsimplifiedRoute.viaDiameter,jumpers:this.unsimplifiedRoute.jumpers}}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Single Route Useless Via Removal Solver"};for(let e=0;e<this.routeSections.length;e++){const n=this.routeSections[e];t.lines.push({points:n.points,strokeWidth:this.TRACE_THICKNESS,strokeColor:e===this.currentSectionIndex?"orange":0===n.z?"red":"blue"})}return t}},Ml=(t,e=2)=>{const n=Array.from({length:e},(t,e)=>e);return t.map(t=>{const o=t.zLayers??t.layers?.map(t=>wn(t,e))??n,i=Array.from(new Set(o.filter(t=>t>=0&&t<e)));return{...t,zLayers:i.length>0?i:n}})},_l=class extends Dn{constructor(t){super(),this.input=t,this.input={...t,obstacles:Ml(t.obstacles,t.layerCount)},this.MAX_ITERATIONS=1e6,this.unsimplifiedHdRoutes=t.unsimplifiedHdRoutes,this.optimizedHdRoutes=[],this.unprocessedRoutes=[...t.unsimplifiedHdRoutes],this.obstacleSHI=new ml("flatbush",this.input.obstacles),this.hdRouteSHI=new Sl(this.unsimplifiedHdRoutes)}getSolverName(){return"UselessViaRemovalSolver"}unsimplifiedHdRoutes;optimizedHdRoutes;unprocessedRoutes;activeSubSolver=null;obstacleSHI=null;hdRouteSHI=null;_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.optimizedHdRoutes.push(this.activeSubSolver.getOptimizedHdRoute()),this.activeSubSolver=null):(this.activeSubSolver.failed||this.activeSubSolver.error)&&(this.error=this.activeSubSolver.error,this.failed=!0));const t=this.unprocessedRoutes.shift();t?this.activeSubSolver=new Il({hdRouteSHI:this.hdRouteSHI,obstacleSHI:this.obstacleSHI,unsimplifiedRoute:t}):this.solved=!0}getOptimizedHdRoutes(){return this.optimizedHdRoutes}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Useless Via Removal Solver"};for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const o=e.zLayers?.includes(0),i=e.zLayers?.includes(1);o&&i?n="rgba(128, 0, 128, 0.2)":o?n="rgba(255, 0, 0, 0.2)":i&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.optimizedHdRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888";for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];o.z===i.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:0===o.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${o.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const o=cl(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...o.rects??[]),t.lines.push(...o.lines??[])}}return this.activeSubSolver&&t.lines.push(...this.activeSubSolver.visualize().lines??[]),t}},Nl=class extends Dn{getSolverName(){return"SingleSimplifiedPathSolver"}newRoute;newVias;headIndex=0;tailIndex=0;inputRoute;otherHdRoutes;obstacles;connMap;colorMap;outline;constructor(t){super(),this.inputRoute=t.inputRoute,this.otherHdRoutes=t.otherHdRoutes,this.obstacles=t.obstacles,this.connMap=t.connMap,this.colorMap=t.colorMap,this.outline=t.outline,this.newRoute=[this.inputRoute.route[0]],this.newVias=[]}getConstructorParams(){return{inputRoute:this.inputRoute,otherHdRoutes:this.otherHdRoutes,obstacles:this.obstacles,connMap:this.connMap.netMap,colorMap:this.colorMap,outline:this.outline}}get simplifiedRoute(){return{connectionName:this.inputRoute.connectionName,rootConnectionName:this.inputRoute.rootConnectionName,traceThickness:this.inputRoute.traceThickness,viaDiameter:this.inputRoute.viaDiameter,route:this.newRoute,vias:this.newVias,jumpers:this.inputRoute.jumpers}}isValidPath(t){throw new Error("Not implemented")}_step(){throw new Error("Not implemented")}getVisualsForNewRouteAndObstacles(){const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:"Simplified Path Solver"};for(let e=0;e<this.inputRoute.route.length-1;e++)t.lines.push({points:[{x:this.inputRoute.route[e].x,y:this.inputRoute.route[e].y},{x:this.inputRoute.route[e+1].x,y:this.inputRoute.route[e+1].y}],strokeColor:"rgba(255, 0, 0, 0.8)",strokeDash:1===this.inputRoute.route[e].z?"5, 5":void 0,layer:`z${this.inputRoute.route[e].z.toString()}`});for(let e=0;e<this.newRoute.length;e++)e<this.newRoute.length-1&&t.lines.push({points:[{x:this.newRoute[e].x,y:this.newRoute[e].y},{x:this.newRoute[e+1].x,y:this.newRoute[e+1].y}],strokeWidth:.15,strokeColor:"rgba(0, 255, 0, 0.8)",strokeDash:1===this.newRoute[e].z?[.4,.4]:void 0,layer:`z${this.newRoute[e].z.toString()}`}),t.points.push({x:this.newRoute[e].x,y:this.newRoute[e].y,color:"rgba(0, 255, 0, 0.8)",label:`z: ${this.newRoute[e].z}`,layer:`z${this.newRoute[e].z.toString()}`});for(const e of this.newVias)t.circles.push({center:e,radius:this.inputRoute.viaDiameter/2,fill:"rgba(0, 0, 255, 0.5)"});for(const e of this.obstacles)t.rects.push({center:e.center,width:e.width,height:e.height,fill:e.layers?.includes("top")?"rgba(255, 0, 0, 0.3)":e.layers?.includes("bottom")?"rgba(0, 0, 255, 0.3)":"rgba(128, 128, 128, 0.3)"});for(const e of this.otherHdRoutes)for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeWidth:.15,strokeColor:0===e.route[n].z?"rgba(255, 0, 255, 0.5)":1===e.route[n].z?"rgba(128, 0, 128, 0.5)":"rgba(0, 0, 255, 0.5)",layer:`z${e.route[n].z.toString()}`});if("filteredObstaclePathSegments"in this){const e=this.filteredObstaclePathSegments;for(const[n,o]of e)t.lines.push({points:[n,o]})}return t}};function Cl(t,e,n,o){if(D(t,e,n,o))return 0;const i=Tl(t,n,o),s=Tl(e,n,o),r=Tl(n,t,e),a=Tl(o,t,e);return Math.min(i,s,r,a)}function Tl(t,e,n){const o={x:n.x-e.x,y:n.y-e.y},i=El({x:t.x-e.x,y:t.y-e.y},o);if(i<=0)return wl(t,e);const s=El(o,o);if(s<=i)return wl(t,n);const r=i/s;return wl(t,{x:e.x+r*o.x,y:e.y+r*o.y})}function El(t,e){return t.x*e.x+t.y*e.y}function wl(t,e){const n=e.x-t.x,o=e.y-t.y;return Math.sqrt(n*n+o*o)}var Rl=t=>({minX:Math.min(t[0].x,t[1].x),maxX:Math.max(t[0].x,t[1].x),minY:Math.min(t[0].y,t[1].y),maxY:Math.max(t[0].y,t[1].y)}),Ol=class{constructor(t){this.segments=t,this.buckets=new Map;const e=new Map;for(const n of t){const t=this.getSegmentKey(n);if(e.has(t))continue;e.set(t,n);const o=Rl(n),i=Math.floor(o.minX/this.CELL_SIZE),s=Math.floor(o.maxX/this.CELL_SIZE),r=Math.floor(o.minY/this.CELL_SIZE),a=Math.floor(o.maxY/this.CELL_SIZE);for(let e=i;e<=s;e++)for(let o=r;o<=a;o++){const i=`${e}x${o}`,s=this.buckets.get(i),r=[n[0],n[1],t];s?s.push(r):this.buckets.set(i,[r])}}}buckets;CELL_SIZE=.4;SEGMENT_MARGIN=.4;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getSegmentKey(t){return`${t[0].x}-${t[0].y}-${t[0].z}-${t[1].x}-${t[1].y}-${t[1].z}`}getSegmentsThatCouldIntersect(t,e){const n=[],o=new Set,i=Math.min(t.x,e.x)-this.SEGMENT_MARGIN,s=Math.min(t.y,e.y)-this.SEGMENT_MARGIN,r=Math.max(t.x,e.x)+this.SEGMENT_MARGIN,a=Math.max(t.y,e.y)+this.SEGMENT_MARGIN,c=Math.floor(i/this.CELL_SIZE),h=Math.floor(r/this.CELL_SIZE),l=Math.floor(s/this.CELL_SIZE),d=Math.floor(a/this.CELL_SIZE);for(let t=c;t<=h;t++)for(let e=l;e<=d;e++){const i=`${t}x${e}`,s=this.buckets.get(i);if(s)for(const t of s){const e=t[2];o.has(e)||(o.add(e),n.push(t))}}return n}},Al=1e-6,zl=(t,e,n)=>X(t,e,n)<=Al,Dl=(t,e)=>Math.abs(t.x-e.x)<=Al&&Math.abs(t.y-e.y)<=Al,Ll=(t,e)=>{if(!e||e.length<3)return!1;for(let n=0;n<e.length;n++){const o=e[n],i=e[(n+1)%e.length];if(zl(t,o,i))return!0}let n=!1;for(let o=0,i=e.length-1;o<e.length;i=o++){const s=e[o],r=e[i];s.y>t.y!=r.y>t.y&&t.x<(r.x-s.x)*(t.y-s.y)/(r.y-s.y)+s.x&&(n=!n)}return n},Yl=class extends Nl{pathSegments=[];totalPathLength=0;headDistanceAlongPath=0;tailDistanceAlongPath=0;minStepSize=.25;lastValidPath=null;lastValidPathHeadDistance=0;STEP_SIZE_REDUCTION_FACTOR=.25;maxStepSize=4;currentStepSize=this.maxStepSize;lastHeadMoveDistance=0;cachedValidPathSegments;filteredObstacles=[];filteredObstaclePathSegments=[];filteredVias=[];filteredJumperPads=[];jumperPadPointIndices=new Set;segmentTree;OBSTACLE_MARGIN=.1;TRACE_THICKNESS=.15;TAIL_JUMP_RATIO=.8;constructor(t){if(super(t),this.cachedValidPathSegments=new Set,this.inputRoute.route.length<=1)return this.newRoute=[...this.inputRoute.route],void(this.solved=!0);const e=this.inputRoute.route.reduce((t,e)=>(t.minX=Math.min(t.minX,e.x),t.maxX=Math.max(t.maxX,e.x),t.minY=Math.min(t.minY,e.y),t.maxY=Math.max(t.maxY,e.y),t),{minX:1/0,maxX:-1/0,minY:1/0,maxY:-1/0}),n={center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY};this.filteredObstacles=this.obstacles.filter(t=>!t.connectedTo.some(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t))).filter(t=>{if(t.connectedTo.some(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t)))return!1;return function(t,e){const n=A(t),o=A(e),i=Math.max(n.minX-o.maxX,o.minX-n.maxX,0),s=Math.max(n.minY-o.maxY,o.minY-n.maxY,0);return Math.hypot(i,s)}(n,t)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2}),this.filteredObstaclePathSegments=this.otherHdRoutes.flatMap(t=>{if(this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName))return[];const n=t.route,o=[];for(let t=0;t<n.length-1;t++){const i=n[t],s=n[t+1],r=Math.min(i.x,s.x),a=Math.max(i.x,s.x),c=Math.min(i.y,s.y),h=Math.max(i.y,s.y);r<=e.maxX&&a>=e.minX&&c<=e.maxY&&h>=e.minY&&o.push([i,s])}return o}),this.segmentTree=new Ol(this.filteredObstaclePathSegments),this.filteredVias=this.otherHdRoutes.flatMap(t=>{if(this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName))return[];const n=t.vias,o=[];for(const i of n){const n=this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2+t.viaDiameter/2,s=i.x-n,r=i.x+n,a=i.y-n,c=i.y+n;s<=e.maxX&&r>=e.minX&&a<=e.maxY&&c>=e.minY&&o.push({...i,diameter:t.viaDiameter})}return o});const o=(t,n)=>{const o=[];for(const i of t){const t=En[i.footprint]??En["0603"],s=i.end.x-i.start.x,r=i.end.y-i.start.y,a=Math.abs(s)>Math.abs(r),c=a?t.padLength:t.padWidth,h=a?t.padWidth:t.padLength,l=this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2;i.start.x-c/2-l<=e.maxX&&i.start.x+c/2+l>=e.minX&&i.start.y-h/2-l<=e.maxY&&i.start.y+h/2+l>=e.minY&&o.push({center:i.start,width:c,height:h,connectionName:n}),i.end.x-c/2-l<=e.maxX&&i.end.x+c/2+l>=e.minX&&i.end.y-h/2-l<=e.maxY&&i.end.y+h/2+l>=e.minY&&o.push({center:i.end,width:c,height:h,connectionName:n})}return o};if(this.filteredJumperPads=this.otherHdRoutes.flatMap(t=>this.connMap.areIdsConnected(this.inputRoute.connectionName,t.connectionName)?[]:o(t.jumpers??[],t.connectionName)),this.inputRoute.jumpers&&this.inputRoute.jumpers.length>0){this.filteredJumperPads.push(...o(this.inputRoute.jumpers,this.inputRoute.connectionName));for(const t of this.inputRoute.jumpers)for(let e=0;e<this.inputRoute.route.length;e++){const n=this.inputRoute.route[e];(Math.abs(n.x-t.start.x)<.01&&Math.abs(n.y-t.start.y)<.01||Math.abs(n.x-t.end.x)<.01&&Math.abs(n.y-t.end.y)<.01)&&this.jumperPadPointIndices.add(e)}}this.computePathSegments()}computePathSegments(){let t=0;for(let e=0;e<this.inputRoute.route.length-1;e++){const n=this.inputRoute.route[e],o=this.inputRoute.route[e+1],i=Math.sqrt((o.x-n.x)**2+(o.y-n.y)**2)+e/1e4;this.pathSegments.push({start:n,end:o,length:i,startDistance:t,endDistance:t+i}),t+=i}this.totalPathLength=t}arePointsEqual(t,e){return t.x===e.x&&t.y===e.y&&t.z===e.z}getPointAtDistance(t){t=Math.max(0,Math.min(t,this.totalPathLength));const e=this.pathSegments.find(e=>t>=e.startDistance&&t<=e.endDistance);if(!e)return this.inputRoute.route[this.inputRoute.route.length-1];const n=(t-e.startDistance)/e.length;return{x:e.start.x+n*(e.end.x-e.start.x),y:e.start.y+n*(e.end.y-e.start.y),z:n<.5?e.start.z:e.end.z}}getNearestIndexForDistance(t){if(t<=0)return 0;if(t>=this.totalPathLength)return this.inputRoute.route.length-1;const e=this.pathSegments.findIndex(e=>t>=e.startDistance&&t<=e.endDistance);if(-1===e)return 0;const n=this.pathSegments[e],o=(n.startDistance+n.endDistance)/2;return t>o?e+1:e}isValidPathSegment(t,e){for(const n of this.filteredObstacles){if(!n.zLayers?.includes(t.z))continue;if(K(t,e,n)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2)return!1}const n=this.segmentTree.getSegmentsThatCouldIntersect(t,e);for(const[o,i,s]of n)if(o.z===t.z&&i.z===t.z){if(Cl({x:t.x,y:t.y},{x:e.x,y:e.y},{x:o.x,y:o.y},{x:i.x,y:i.y})<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS)return!1}for(const n of this.filteredVias)if(X(n,t,e)<this.OBSTACLE_MARGIN+n.diameter/2+this.TRACE_THICKNESS/2)return!1;for(const n of this.filteredJumperPads){if(K(t,e,n)<this.OBSTACLE_MARGIN+this.TRACE_THICKNESS/2)return!1}if(this.outline&&this.outline.length>=3){const n=(({start:t,end:e,polygon:n,margin:o=.2})=>{if(!n||n.length<3)return!1;const i=Ll(t,n),s=Ll(e,n);if(!i||!s)return!0;for(let i=0;i<n.length;i++){const s=n[i],r=n[(i+1)%n.length],a=zl(t,s,r),c=zl(e,s,r);if(a&&c)continue;if(!D(t,e,s,r)){if(!a&&!c&&Cl(t,e,s,r)<o-Al)return!0;continue}const h=k(t,e,s,r);if(!(h&&(a&&Dl(h,t)||c&&Dl(h,e))||h&&(Dl(h,t)||Dl(h,e))))return!0}return!1})({start:{x:t.x,y:t.y},end:{x:e.x,y:e.y},polygon:this.outline});if(n)return!1}return!0}isValidPath(t){if(t.length<2)return!0;for(let e=0;e<t.length-1;e++)if(t[e].z!==t[e+1].z)return!1;for(let e=0;e<t.length-1;e++)if(!this.isValidPathSegment(t[e],t[e+1]))return!1;return!0}find45DegreePath(t,e){if(this.arePointsEqual(t,e))return[t];if(t.z!==e.z)return null;const n=((t,e)=>{const n=[],o=Math.abs(e.x-t.x),i=Math.abs(e.y-t.y),s=e.x>t.x?1:-1,r=e.y>t.y?1:-1,a={x:e.x-s*Math.abs(e.y-t.y),y:t.y};(a.x-t.x)*s>=0&&(a.x-e.x)*s<=0&&n.push([t,a,e]);const c={x:t.x,y:e.y-r*Math.abs(e.x-t.x)};(c.y-t.y)*r>=0&&(c.y-e.y)*r<=0&&n.push([t,c,e]);const h=Math.min(o,i),l={x:t.x+s*h,y:t.y+r*h};return(l.x-t.x)*s>=0&&(l.x-e.x)*s<=0&&(l.y-t.y)*r>=0&&(l.y-e.y)*r<=0&&n.push([t,l,e]),n})({x:t.x,y:t.y},{x:e.x,y:e.y});for(const e of n){const n=e.map(e=>({x:e.x,y:e.y,z:t.z}));if(this.isValidPath(n))return n}return null}addPathToResult(t){if(0!==t.length){for(let e=0;e<t.length;e++)0===e&&this.newRoute.length>0&&this.arePointsEqual(this.newRoute[this.newRoute.length-1],t[e])||this.newRoute.push(t[e]);this.currentStepSize=this.maxStepSize}}moveHead(t){this.lastHeadMoveDistance=t,this.headDistanceAlongPath=Math.min(this.headDistanceAlongPath+t,this.totalPathLength)}stepBackAndReduceStepSize(){this.headDistanceAlongPath=Math.max(this.tailDistanceAlongPath,this.headDistanceAlongPath-this.lastHeadMoveDistance),this.currentStepSize=Math.max(this.minStepSize,this.currentStepSize*this.STEP_SIZE_REDUCTION_FACTOR)}_step(){const t=this.tailDistanceAlongPath>=this.totalPathLength,e=this.headDistanceAlongPath>=this.totalPathLength;if(t){const t=this.inputRoute.route[this.inputRoute.route.length-1];return 0!==this.newRoute.length&&this.arePointsEqual(this.newRoute[this.newRoute.length-1],t)||this.newRoute.push(t),void(this.solved=!0)}if(e){const t=this.getPointAtDistance(this.tailDistanceAlongPath),e=this.inputRoute.route[this.inputRoute.route.length-1],n=this.find45DegreePath(t,e);if(n)return this.addPathToResult(n),void(this.solved=!0);this.lastValidPath=null,this.tailDistanceAlongPath=this.totalPathLength,this.headDistanceAlongPath=this.totalPathLength;const o=[];for(const t of this.inputRoute.route)0!==o.length&&this.arePointsEqual(o[o.length-1],t)||o.push(t);return this.newRoute=o,this.newVias=[...this.inputRoute.vias],void(this.solved=!0)}this.moveHead(this.currentStepSize);const n=this.getPointAtDistance(this.tailDistanceAlongPath),o=this.getPointAtDistance(this.headDistanceAlongPath),i=this.getNearestIndexForDistance(this.tailDistanceAlongPath),s=this.getNearestIndexForDistance(this.headDistanceAlongPath);let r=!1,a=-1;for(let t=i;t<s;t++)if(t+1<this.inputRoute.route.length&&this.inputRoute.route[t].z!==this.inputRoute.route[t+1].z){r=!0;const e=t;a=this.pathSegments[e].startDistance;break}if(r&&this.lastHeadMoveDistance>this.minStepSize)return void this.stepBackAndReduceStepSize();let c=!1,h=-1,l=-1;for(let t=i+1;t<=s;t++)if(this.jumperPadPointIndices.has(t)){c=!0,h=t,l=t>0&&t-1<this.pathSegments.length?this.pathSegments[t-1].endDistance:this.pathSegments[0]?.startDistance??0;break}if(c&&this.lastHeadMoveDistance>this.minStepSize)return void this.stepBackAndReduceStepSize();if(c&&h>=0){const t=this.inputRoute.route[h];this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null);const e=this.newRoute[this.newRoute.length-1];return e&&e.x===t.x&&e.y===t.y||this.newRoute.push({x:t.x,y:t.y,z:t.z}),this.currentStepSize=this.maxStepSize,this.tailDistanceAlongPath=l,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,void(this.lastValidPathHeadDistance=this.tailDistanceAlongPath)}if(r&&a>0){const t=this.getNearestIndexForDistance(a)+1,e=this.inputRoute.route[t],n={x:e.x,y:e.y};this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null);const o=this.newRoute[this.newRoute.length-1];o.x===n.x&&o.y===n.y||this.newRoute.push({x:n.x,y:n.y,z:o.z}),this.newVias.push(n),this.newRoute.push({x:n.x,y:n.y,z:e.z}),this.currentStepSize=this.maxStepSize;const i=this.pathSegments.findIndex(t=>t.start===e);if(-1!==i)this.tailDistanceAlongPath=this.pathSegments[i].startDistance,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,this.lastValidPathHeadDistance=this.tailDistanceAlongPath;else if(t<this.inputRoute.route.length){if(t===this.inputRoute.route.length-1)return void(this.solved=!0);console.warn("Fallback used for tailDistanceAlongPath after layer change");const e=this.pathSegments.find(e=>e.start===this.inputRoute.route[t]);e?(this.tailDistanceAlongPath=e.startDistance,this.headDistanceAlongPath=this.tailDistanceAlongPath,this.lastValidPath=null,this.lastValidPathHeadDistance=this.tailDistanceAlongPath):(console.error(`[${this.inputRoute.connectionName}] Could not find segment start after layer change. Path might be incomplete.\n Index sought: ${t}, Point: (${this.inputRoute.route[t].x.toFixed(3)}, ${this.inputRoute.route[t].y.toFixed(3)}, z=${this.inputRoute.route[t].z})\n Route Length: ${this.inputRoute.route.length}, Path Segments: ${this.pathSegments.length}`),this.solved=!0)}else console.warn("Layer change occurred at the end of the path."),this.solved=!0;return}const d=this.find45DegreePath(n,o);if(!d&&this.lastHeadMoveDistance>this.minStepSize)this.stepBackAndReduceStepSize();else{if(!d&&!this.lastValidPath){const t=this.getPointAtDistance(this.tailDistanceAlongPath);this.tailDistanceAlongPath+=this.minStepSize,this.moveHead(this.minStepSize);const e=this.getNearestIndexForDistance(this.tailDistanceAlongPath),n=this.inputRoute.route[e],o=this.inputRoute.route[this.inputRoute.route.length-1];return void(this.arePointsEqual(t,n)||this.arePointsEqual(n,o)||this.newRoute.push(n))}if(d)return this.lastValidPath=d,void(this.lastValidPathHeadDistance=this.headDistanceAlongPath);this.lastValidPath&&(this.addPathToResult(this.lastValidPath),this.lastValidPath=null,this.tailDistanceAlongPath=this.lastValidPathHeadDistance,this.moveHead(this.minStepSize))}}visualize(){const t=this.getVisualsForNewRouteAndObstacles(),e=this.getPointAtDistance(this.tailDistanceAlongPath),n=this.getPointAtDistance(this.headDistanceAlongPath);t.points.push({x:e.x,y:e.y,color:"yellow",label:["Tail",`z: ${e.z}`].join("\n")}),t.points.push({x:n.x,y:n.y,color:"orange",label:["Head",`z: ${n.z}`].join("\n")});const o=this.getPointAtDistance(this.headDistanceAlongPath+this.currentStepSize);t.points.push({x:o.x,y:o.y,color:"red",label:["Tentative Head",`z: ${o.z}`].join("\n")});let i=0;for(;i<this.totalPathLength;){const e=this.getPointAtDistance(i);t.circles.push({center:{x:e.x,y:e.y},radius:.05,fill:"rgba(100, 100, 100, 0.5)"}),i+=this.totalPathLength/20}if(this.lastValidPath&&this.lastValidPath.length>1)for(let e=0;e<this.lastValidPath.length-1;e++)t.lines.push({points:[{x:this.lastValidPath[e].x,y:this.lastValidPath[e].y},{x:this.lastValidPath[e+1].x,y:this.lastValidPath[e+1].y}],strokeColor:"rgba(0, 255, 255, 0.9)",strokeDash:"3, 3"});return t}},Xl=class extends Dn{getSolverName(){return"MultiSimplifiedPathSolver"}simplifiedHdRoutes;currentUnsimplifiedHdRouteIndex=0;activeSubSolver=null;unsimplifiedHdRoutes;obstacles;connMap;colorMap;outline;defaultViaDiameter;constructor(t){super(),this.MAX_ITERATIONS=1e8,this.unsimplifiedHdRoutes=t.unsimplifiedHdRoutes;const e=Math.max(2,...t.unsimplifiedHdRoutes.flatMap(t=>t.route.map(t=>t.z+1)))||2;this.obstacles=Ml(t.obstacles,e),this.connMap=t.connMap||new On({}),this.colorMap=t.colorMap||{},this.outline=t.outline,this.defaultViaDiameter=t.defaultViaDiameter??.3,this.simplifiedHdRoutes=[]}_step(){const t=this.unsimplifiedHdRoutes[this.currentUnsimplifiedHdRouteIndex];if(!this.activeSubSolver)return t?(this.activeSubSolver=new Yl({inputRoute:t,otherHdRoutes:this.unsimplifiedHdRoutes.slice(this.currentUnsimplifiedHdRouteIndex+1).concat(this.simplifiedHdRoutes),obstacles:this.obstacles,connMap:this.connMap,colorMap:this.colorMap,outline:this.outline}),void this.currentUnsimplifiedHdRouteIndex++):void(this.solved=!0);this.activeSubSolver.step(),this.activeSubSolver.solved&&(this.simplifiedHdRoutes.push(this.activeSubSolver.simplifiedRoute),this.activeSubSolver=null)}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:"Multi Simplified Path Solver"};for(const e of this.unsimplifiedHdRoutes)if(!this.simplifiedHdRoutes.some(t=>t.connectionName===e.connectionName)){for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeColor:1===e.route[n].z?"rgba(0, 0, 255, 0.4)":"rgba(255, 0, 0, 0.4)",strokeWidth:.15,strokeDash:1===e.route[n].z?[.5,.5]:void 0});for(const n of e.vias||[])t.circles.push({center:n,radius:(e.viaDiameter??this.defaultViaDiameter)/2,fill:"rgba(0, 0, 255, 0.4)"})}for(const e of this.simplifiedHdRoutes){const n=this.colorMap?.[e.connectionName]||"rgba(128, 128, 128, 0.8)";for(let o=0;o<e.route.length-1;o++)t.lines.push({points:[{x:e.route[o].x,y:e.route[o].y},{x:e.route[o+1].x,y:e.route[o+1].y}],strokeWidth:.15,strokeColor:n,strokeDash:1===e.route[o].z?[.5,.5]:void 0,step:1});for(const n of e.vias||[])t.circles.push({center:n,radius:e.viaDiameter/2,fill:"rgba(0, 0, 255, 0.5)",step:1})}for(const e of this.unsimplifiedHdRoutes){for(let n=0;n<e.route.length-1;n++)t.lines.push({points:[{x:e.route[n].x,y:e.route[n].y},{x:e.route[n+1].x,y:e.route[n+1].y}],strokeWidth:.15,strokeColor:"rgba(255, 0, 0, 0.2)",strokeDash:[.5,.5],step:0,layer:`z${e.route[n].z.toString()}`});for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 0, 0.2)",step:0})}for(const e of this.obstacles)t.rects.push({center:e.center,width:e.width,height:e.height,fill:e.layers?.includes("top")?"rgba(255, 0, 0, 0.3)":e.layers?.includes("bottom")?"rgba(0, 0, 255, 0.3)":"rgba(128, 128, 128, 0.3)"});if(this.currentUnsimplifiedHdRouteIndex<this.unsimplifiedHdRoutes.length){const e=this.unsimplifiedHdRoutes[this.currentUnsimplifiedHdRouteIndex];e.route.length>0&&t.circles.push({center:{x:e.route[0].x,y:e.route[0].y},radius:.2,fill:"yellow",label:"Current"})}return t}},Fl=class extends Dn{constructor(t){super(),this.input=t,this.input={...t,obstacles:Ml(t.obstacles,t.layerCount)},this.MAX_ITERATIONS=1e6,this.inputHdRoutes=this.input.inputHdRoutes,this.mergedViaHdRoutes=structuredClone(this.inputHdRoutes),this.unprocessedRoutes=[...this.input.inputHdRoutes],this.colorMap=this.input.colorMap,this.outline=this.input.outline,this.obstacles=this.input.obstacles,this.obstacleSHI=new ml("flatbush",this.input.obstacles),this.hdRouteSHI=new Sl(this.inputHdRoutes),this.vias=[],this.offendingVias=[],this.connMap=t.connMap,this.viasByNet=new Map,this.rebuildVias()}getSolverName(){return"SameNetViaMergerSolver"}inputHdRoutes;mergedViaHdRoutes;unprocessedRoutes;vias;offendingVias;currentViaRoutes=[];connMap;colorMap;outline;obstacles;viasByNet;obstacleSHI=null;hdRouteSHI=null;rebuildVias(){this.vias=[],this.viasByNet=new Map;for(let t=0;t<this.mergedViaHdRoutes.length;t++){const e=this.mergedViaHdRoutes[t];for(let n=0;n<e.vias.length;n++){const o=e.vias[n],i={x:o.x,y:o.y,diameter:e.viaDiameter,net:this.connMap?.idToNetMap[e.connectionName]??"",layers:[...new Set(e.route.map(t=>t.z))],routeIndex:t};this.vias.push(i);const s=this.viasByNet.get(i.net);s?s.push(i):this.viasByNet.set(i.net,[i])}}}findNextOffendingPair(){for(let t=0;t<this.vias.length-1;t++){const e=this.vias[t],n=this.viasByNet.get(e.net);if(!n)continue;const o=n.indexOf(e);for(let t=o>=0?o+1:0;t<n.length;t++){const o=n[t],i=e.x-o.x,s=e.y-o.y,r=i*i+s*s,a=e.diameter/2+o.diameter/2;if(r<=a*a&&0!==r)return[e,o]}}return null}handleOffendingPair(t,e){const n=t.layers.length<e.layers.length?t:e,o=n===t?e:t,i=this.mergedViaHdRoutes[n.routeIndex].route;for(let t=0;t<n.layers.length;t++)for(let t=i.length-1;t>=1;t--){const e=i[t-1],s=i[t];if(s.x===n.x&&s.y===n.y){i.splice(t,0,{x:o.x,y:o.y,z:s.z}),i.splice(t,0,{x:o.x,y:o.y,z:e.z});const r=this.mergedViaHdRoutes[n.routeIndex];return r.vias=r.vias.map(t=>t.x===n.x&&t.y===n.y?{x:o.x,y:o.y}:t),void this.rebuildVias()}}this.rebuildVias()}_step(){const t=this.findNextOffendingPair();t?this.handleOffendingPair(t[0],t[1]):this.solved=!0}getMergedViaHdRoutes(){return this.mergedViaHdRoutes}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Same Net Via Merger Solver"};for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const o=e.zLayers?.includes(0),i=e.zLayers?.includes(1);o&&i?n="rgba(128, 0, 128, 0.2)":o?n="rgba(255, 0, 0, 0.2)":i&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.mergedViaHdRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888";for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];o.z===i.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:0===o.z?"rgba(255, 0, 0, 0.5)":"rgba(0, 0, 255, 0.5)",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${o.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const o=cl(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...o.rects??[]),t.lines.push(...o.lines??[])}}return this.activeSubSolver&&t.lines.push(...this.activeSubSolver.visualize().lines??[]),t}},kl=class extends Dn{constructor(t){super(),this.simplificationConfig=t,this.simplificationConfig={...t,obstacles:Ml(t.obstacles,t.layerCount)},this.hdRoutes=[...t.hdRoutes],this.MAX_ITERATIONS=1e8}getSolverName(){return"TraceSimplificationSolver"}hdRoutes=[];simplificationPipelineLoops=0;MAX_SIMPLIFICATION_PIPELINE_LOOPS=2;PHASE_ORDER=["via_removal","via_merging","path_simplification"];currentPhase="via_removal";extractResult=null;get simplifiedHdRoutes(){return this.hdRoutes}_step(){if(this.simplificationPipelineLoops>=this.MAX_SIMPLIFICATION_PIPELINE_LOOPS)this.solved=!0;else{if(this.activeSubSolver){if(this.activeSubSolver.step(),!this.activeSubSolver.failed&&!this.activeSubSolver.solved)return;if(this.activeSubSolver.solved){if(this.extractResult&&(this.hdRoutes=this.extractResult(this.activeSubSolver)),this.activeSubSolver=null,this.extractResult=null,"via_removal"===this.currentPhase?this.currentPhase="via_merging":"via_merging"===this.currentPhase?this.currentPhase="path_simplification":(this.currentPhase="via_removal",this.simplificationPipelineLoops++),this.simplificationPipelineLoops>=this.MAX_SIMPLIFICATION_PIPELINE_LOOPS)return void(this.solved=!0)}else if(this.activeSubSolver.failed)return this.failed=!0,void(this.error=this.activeSubSolver.error??"Sub-solver failed without error message")}if(!this.activeSubSolver&&!this.solved)switch(this.currentPhase){case"via_removal":this.activeSubSolver=new _l({unsimplifiedHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],colorMap:{...this.simplificationConfig.colorMap},layerCount:this.simplificationConfig.layerCount}),this.extractResult=t=>t.getOptimizedHdRoutes()??[];break;case"via_merging":this.activeSubSolver=new Fl({inputHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],colorMap:{...this.simplificationConfig.colorMap},layerCount:this.simplificationConfig.layerCount,connMap:this.simplificationConfig.connMap,outline:this.simplificationConfig.outline?[...this.simplificationConfig.outline]:void 0}),this.extractResult=t=>t.getMergedViaHdRoutes()??[];break;case"path_simplification":this.activeSubSolver=new Xl({unsimplifiedHdRoutes:this.hdRoutes,obstacles:[...this.simplificationConfig.obstacles],connMap:this.simplificationConfig.connMap,colorMap:{...this.simplificationConfig.colorMap},outline:this.simplificationConfig.outline?[...this.simplificationConfig.outline]:void 0,defaultViaDiameter:this.simplificationConfig.defaultViaDiameter}),this.extractResult=t=>t.simplifiedHdRoutes;break;default:this.failed=!0,this.error=`Unknown phase: ${this.currentPhase}`}}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Trace Simplification Solver"};for(const e of this.simplificationConfig.obstacles){let n="rgba(128, 128, 128, 0.2)";const o=e.zLayers?.includes(0),i=e.zLayers?.includes(1);o&&i?n="rgba(128, 0, 128, 0.2)":o?n="rgba(255, 0, 0, 0.2)":i&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}for(const e of this.hdRoutes)if(0!==e.route.length){for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];o.z===i.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:0===o.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${o.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const n=cl(e.jumpers,{color:"orange",label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}return t}},$l=class extends Dn{getSolverName(){return"TraceWidthSolver"}hdRoutes;hdRoutesWithWidths=[];nominalTraceWidth;minTraceWidth;obstacleMargin;TRACE_WIDTH_SCHEDULE;connectionNominalTraceWidthMap;unprocessedRoutes=[];processedRoutes=[];currentTrace=null;cursorPosition=null;currentTraceSegmentIndex=0;currentTraceSegmentT=0;currentScheduleIndex=0;currentTargetWidth=0;hasInsufficientClearance=!1;lastCollidingObstacles=[];lastCollidingRoutes=[];lastClearance=1/0;obstacles=[];obstacleSHI;hdRouteSHI;connMap;colorMap;constructor(t){super(),this.MAX_ITERATIONS=1e6,this.hdRoutes=[...t.hdRoutes],this.minTraceWidth=t.minTraceWidth,this.obstacleMargin=t.obstacleMargin??.15,this.nominalTraceWidth=0,this.TRACE_WIDTH_SCHEDULE=[],this.unprocessedRoutes=[...this.hdRoutes],this.connMap=t.connMap,this.colorMap=t.colorMap;const e=t.layerCount;this.obstacles=Ml(t.obstacles??[],e),this.connectionNominalTraceWidthMap=new Map;for(const e of t.connection)void 0!==e.nominalTraceWidth&&this.connectionNominalTraceWidthMap.set(e.name,e.nominalTraceWidth);this.obstacles.length>0&&(this.obstacleSHI=new ml("flatbush",this.obstacles)),this.hdRouteSHI=new Sl(this.hdRoutes)}getNominalTraceWidthForRoute(t){const e=this.connectionNominalTraceWidthMap.get(t.connectionName);return void 0!==e?e:t.rootConnectionName?this.connectionNominalTraceWidthMap.get(t.rootConnectionName):void 0}_step(){if(!this.currentTrace){const t=this.unprocessedRoutes.shift();if(!t)return this.hdRoutesWithWidths=this.processedRoutes,void(this.solved=!0);const e=this.getNominalTraceWidthForRoute(t);if(void 0===e)return this.processedRoutes.push({...t}),void(this.currentTrace=null);this.currentTrace=t,this.nominalTraceWidth=e;const n=(this.nominalTraceWidth+this.minTraceWidth)/2;return this.TRACE_WIDTH_SCHEDULE=[this.nominalTraceWidth,n],this.currentTrace.route.length<2?(this.processedRoutes.push({...this.currentTrace,traceThickness:this.minTraceWidth}),void(this.currentTrace=null)):(this.currentScheduleIndex=0,this.currentTargetWidth=this.TRACE_WIDTH_SCHEDULE[0],void this.initializeCursor())}if(!this.stepCursorForward())return void this.finalizeCurrentTrace(this.currentTargetWidth);this.getClearanceAtPosition(this.cursorPosition)<this.currentTargetWidth/2+this.obstacleMargin&&(this.hasInsufficientClearance=!0,this.currentScheduleIndex++,this.currentScheduleIndex<this.TRACE_WIDTH_SCHEDULE.length?(this.currentTargetWidth=this.TRACE_WIDTH_SCHEDULE[this.currentScheduleIndex],this.initializeCursor()):this.finalizeCurrentTrace(this.minTraceWidth))}initializeCursor(){if(!this.currentTrace)return;const t=this.currentTrace.route[0];this.cursorPosition={...t},this.currentTraceSegmentIndex=0,this.currentTraceSegmentT=0,this.hasInsufficientClearance=!1}stepCursorForward(){if(!this.currentTrace||!this.cursorPosition)return!1;const t=this.currentTrace.route;let e=.1;for(;e>0;){if(this.currentTraceSegmentIndex>=t.length-1)return!1;const n=t[this.currentTraceSegmentIndex],o=t[this.currentTraceSegmentIndex+1];if(n.insideJumperPad&&o.insideJumperPad){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const i=o.x-n.x,s=o.y-n.y,r=Math.sqrt(i*i+s*s);if(0===r){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const a=this.currentTraceSegmentT*r,c=r-a;if(e<=c){const t=a+e;return this.currentTraceSegmentT=t/r,this.cursorPosition={x:n.x+i*this.currentTraceSegmentT,y:n.y+s*this.currentTraceSegmentT,z:n.z},!0}if(e-=c,this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,this.currentTraceSegmentIndex>=t.length-1){const e=t[t.length-1];return this.cursorPosition={...e},!1}}return!0}isObstacleOwnJumperPad(t){if(!this.currentTrace?.jumpers)return!1;for(const e of this.currentTrace.jumpers){const n=Math.sqrt((t.center.x-e.start.x)**2+(t.center.y-e.start.y)**2),o=Math.sqrt((t.center.x-e.end.x)**2+(t.center.y-e.end.y)**2),i=Math.max(t.width,t.height)/2+.01;if(n<i||o<i)return!0}return!1}getClearanceAtPosition(t){if(!this.currentTrace)return 1/0;const e=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,n=2*this.nominalTraceWidth;let o=1/0;if(this.lastCollidingObstacles=[],this.lastCollidingRoutes=[],this.obstacleSHI){const i=this.obstacleSHI.searchArea(t.x,t.y,n,n);for(const n of i){if(n.zLayers&&!n.zLayers.includes(t.z))continue;if(n.connectedTo.includes(e))continue;if(n.obstacleId&&this.connMap?.areIdsConnected(e,n.obstacleId))continue;let i=!1;if(this.connMap)for(const t of n.connectedTo)if(this.connMap.areIdsConnected(e,t)){i=!0;break}if(i)continue;if(this.isObstacleOwnJumperPad(n))continue;const s=n.center.x-n.width/2,r=n.center.x+n.width/2,a=n.center.y-n.height/2,c=n.center.y+n.height/2,h=Math.max(s-t.x,0,t.x-r),l=Math.max(a-t.y,0,t.y-c),d=Math.sqrt(h*h+l*l);d<this.currentTargetWidth/2+this.obstacleMargin&&this.lastCollidingObstacles.push(n),d<o&&(o=d)}}const i=this.hdRouteSHI.getConflictingRoutesNearPoint({x:t.x,y:t.y,z:t.z},n);for(const{conflictingRoute:t,distance:n}of i){const i=t.rootConnectionName??t.connectionName;if(i===e)continue;if(this.connMap?.areIdsConnected(e,i))continue;const s=n-(t.traceThickness??.15)/2;s<this.currentTargetWidth/2+this.obstacleMargin&&this.lastCollidingRoutes.push(t),s<o&&(o=s)}return this.lastClearance=o,o}finalizeCurrentTrace(t){if(!this.currentTrace)return;const e={connectionName:this.currentTrace.connectionName,rootConnectionName:this.currentTrace.rootConnectionName,traceThickness:t,viaDiameter:this.currentTrace.viaDiameter,route:[...this.currentTrace.route],vias:[...this.currentTrace.vias],jumpers:this.currentTrace.jumpers};this.processedRoutes.push(e),this.currentTrace=null,this.cursorPosition=null,this.hasInsufficientClearance=!1}visualize(){const t={lines:[],points:[],circles:[],rects:[],coordinateSystem:"cartesian",title:`Trace Width Solver (schedule: [${this.TRACE_WIDTH_SCHEDULE.map(t=>t.toFixed(2)).join(", ")}]mm, fallback: ${this.minTraceWidth.toFixed(2)}mm, margin: ${this.obstacleMargin.toFixed(2)}mm)`},e=new Set(this.lastCollidingObstacles.map(t=>t.obstacleId)),n=new Set(this.lastCollidingRoutes.map(t=>t.connectionName));for(const n of this.obstacles){const o=e.has(n.obstacleId),i=n.zLayers?.includes(0),s=n.zLayers?.includes(1);let r;r=o?"rgba(255, 0, 0, 0.6)":i&&s?"rgba(128, 0, 128, 0.15)":i?"rgba(255, 0, 0, 0.15)":s?"rgba(0, 0, 255, 0.15)":"rgba(128, 128, 128, 0.15)",t.rects.push({center:n.center,width:n.width,height:n.height,fill:r,stroke:o?"red":void 0,label:o?`COLLIDING: ${n.obstacleId??"obstacle"}`:`${n.obstacleId??"obstacle"} (Z: ${n.zLayers?.join(", ")})`})}for(const e of this.processedRoutes){if(0===e.route.length)continue;const n=e.traceThickness===this.nominalTraceWidth,o=e.traceThickness===this.TRACE_WIDTH_SCHEDULE[1],i=n?"green":o?"yellow":"orange";for(let n=0;n<e.route.length-1;n++){const o=e.route[n],s=e.route[n+1];o.insideJumperPad&&s.insideJumperPad||o.z===s.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:s.x,y:s.y}],strokeColor:i,strokeWidth:e.traceThickness,label:`${e.connectionName} (w=${e.traceThickness.toFixed(2)})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const n=cl(e.jumpers,{color:i,label:e.connectionName});t.rects.push(...n.rects??[]),t.lines.push(...n.lines??[])}}if(this.currentTrace){for(let e=0;e<this.currentTrace.route.length-1;e++){const n=this.currentTrace.route[e],o=this.currentTrace.route[e+1];n.insideJumperPad&&o.insideJumperPad||n.z===o.z&&t.lines.push({points:[{x:n.x,y:n.y},{x:o.x,y:o.y}],strokeColor:"cyan",strokeWidth:this.currentTrace.traceThickness??this.minTraceWidth,label:`Processing: ${this.currentTrace.connectionName}`})}this.cursorPosition&&(t.circles.push({center:{x:this.cursorPosition.x,y:this.cursorPosition.y},radius:this.currentTargetWidth/2,stroke:this.hasInsufficientClearance?"red":"green",fill:"none",label:`Testing width: ${this.currentTargetWidth.toFixed(2)}mm (clearance: ${this.lastClearance.toFixed(2)}mm)`}),t.points.push({x:this.cursorPosition.x,y:this.cursorPosition.y,color:"orange",label:"Cursor"}))}for(const e of this.unprocessedRoutes){if(0===e.route.length)continue;const o=n.has(e.connectionName);for(let n=0;n<e.route.length-1;n++){const i=e.route[n],s=e.route[n+1];i.z===s.z&&t.lines.push({points:[{x:i.x,y:i.y},{x:s.x,y:s.y}],strokeColor:o?"rgba(255, 0, 0, 0.8)":"rgba(128, 128, 128, 0.3)",strokeWidth:e.traceThickness??this.minTraceWidth,label:o?`COLLIDING: ${e.connectionName}`:e.connectionName})}}return t}getHdRoutesWithWidths(){return this.hdRoutesWithWidths}};function Bl(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var jl=class extends Dn{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),s=n.targetMinCapacity??.5;n.capacityDepth=zh(i,s)}this.connMap=zn(t),this.colorMap=In(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AutoroutingPipelineSolver2_PortPointPathing"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;inputNodeWithPortPoints=[];cacheProvider=null;pipelineDef=[Bl("netToPointPairsSolver",sl,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=In(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),Bl("nodeSolver",ye,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),Bl("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Bl("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),Bl("portPointPathingSolver",Gh,t=>{this.inputNodeWithPortPoints=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle}));const e=new Map(this.inputNodeWithPortPoints.map(t=>[t.capacityMeshNodeId,t])),n=t.availableSegmentPointSolver;for(const t of n.sharedEdgeSegments)for(const n of t.portPoints){const[t,o]=n.nodeIds,i={portPointId:n.segmentPortPointId,x:n.x,y:n.y,z:n.availableZ[0]??0,connectionNodeIds:[t,o],distToCentermostPortOnZ:n.distToCentermostPortOnZ},s=e.get(t);s&&s.portPoints.push(i)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:this.inputNodeWithPortPoints,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:200,hyperParameters:{NODE_PF_MAX_PENALTY:100,FORCE_OFF_BOARD_FREQUENCY:0,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:4}}]}),Bl("multiSectionPortPointOptimizer",Jh,t=>{const e=t.portPointPathingSolver;return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e.inputNodes,capacityMeshNodes:t.capacityNodes,capacityMeshEdges:t.capacityEdges,colorMap:t.colorMap,initialConnectionResults:e.connectionsWithResults,initialAssignedPortPoints:e.assignedPortPoints,initialNodeAssignedPortPoints:e.nodeAssignedPortPoints,effort:t.effort}]}),Bl("uniformPortDistributionSolver",Ae,t=>[{nodeWithPortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],inputNodesWithPortPoints:this.inputNodeWithPortPoints,minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),Bl("highDensityRouteSolver",Nh,t=>[{nodePortPoints:t.uniformPortDistributionSolver?.getOutput()??t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,effort:t.effort}]),Bl("highDensityStitchSolver",pl,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),Bl("traceSimplificationSolver",kl,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),Bl("traceWidthSolver",$l,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),s=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),l=this.uniformPortDistributionSolver?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensityStitchSolver?.visualize(),p=this.traceSimplificationSolver?.visualize(),f=this.srj.outline,g=[];if(g.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),f&&f.length>=2){const t=f.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),g.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const m={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:g},y=[m,t,e,n,o,i,s,r,a,c,h,l,d?Bn(m,d):null,u,p,this.solved?Bn(m,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...y)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const o=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const s=i[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.rootConnectionName??n.name,route:De(s,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},Wl=jl,Vl=class extends Dn{getSolverName(){return"CapacityEdgeToPortSegmentSolver"}nodes;edges;capacityPaths;nodeMap;nodeEdgeMap;unprocessedNodeIds;nodePortSegments;colorMap;constructor({nodes:t,edges:e,capacityPaths:n,colorMap:o}){super(),this.nodes=t,this.edges=e,this.nodeMap=new Map(t.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Ln(e),this.capacityPaths=n,this.colorMap=o??{},this.unprocessedNodeIds=[...new Set(n.flatMap(t=>t.nodeIds))],this.nodePortSegments=new Map}step(){const t=this.unprocessedNodeIds.pop();if(!t)return void(this.solved=!0);const e=[];for(const n of this.capacityPaths){const o=n.nodeIds.indexOf(t);-1!==o&&e.push({path:n,indexOfNodeInPath:o})}const n=this.nodeMap.get(t),o=[];for(const{path:i,indexOfNodeInPath:s}of e){const e=i.nodeIds[s-1],r=i.nodeIds[s+1];for(const s of[e,r]){const e=this.nodeMap.get(s);if(!e)continue;const r=Hl(n,e),a=e.availableZ.filter(t=>n.availableZ.includes(t));if(0===a.length)continue;const c={capacityMeshNodeId:t,start:r.start,end:r.end,connectionNames:[i.connectionName],rootConnectionNames:i.rootConnectionName?[i.rootConnectionName]:void 0,availableZ:a};o.push(c)}}const i=function(t){const e=[],n=t.map(t=>({...t,connectionNames:[...t.connectionNames],rootConnectionNames:t.rootConnectionNames?[...t.rootConnectionNames]:[],availableZ:[...t.availableZ].sort((t,e)=>t-e)}));for(;n.length>0;){const t=n.pop();let o=!1;for(let n=0;n<e.length;n++){const i=e[n],s=Gl(i.start,t.start)&&Gl(i.end,t.end)||Gl(i.start,t.end)&&Gl(i.end,t.start),r=Zl(i.availableZ,t.availableZ);if(s&&r){const e=new Set(i.connectionNames);t.connectionNames.forEach(t=>e.add(t)),i.connectionNames=Array.from(e);const n=new Set(i.rootConnectionNames||[]);t.rootConnectionNames?.forEach(t=>n.add(t)),i.rootConnectionNames=Array.from(n),o=!0;break}}o||e.push(t)}return e}(o);this.nodePortSegments.set(t,i)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};return this.nodePortSegments.forEach((e,n)=>{this.nodeMap.get(n);e.forEach(e=>{e.start.x,e.end.x;for(let o=0;o<e.connectionNames.length;o++){const i={x:.05*Math.max(...e.availableZ),y:.05*Math.max(...e.availableZ)},s={x:(e.start.x+e.end.x)/2,y:(e.start.y+e.end.y)/2},r={x:s.x+i.x,y:s.y+i.y};i.x>0&&t.lines.push({points:[s,r],strokeColor:"rgba(0, 0, 0, 0.25)",strokeDash:"5 5"}),t.points.push({x:r.x,y:r.y,label:`${n}: ${e.connectionNames.join(", ")}\navailableZ: ${e.availableZ.join(",")}\nnodePortSegmentId: ${e.nodePortSegmentId}`}),t.lines.push({points:[e.start,e.end],strokeColor:Mn(this.colorMap[e.connectionNames[o]],.6)})}})}),t}};function Hl(t,e){const n={start:Math.max(t.center.x-t.width/2,e.center.x-e.width/2),end:Math.min(t.center.x+t.width/2,e.center.x+e.width/2)},o={start:Math.max(t.center.y-t.height/2,e.center.y-e.height/2),end:Math.min(t.center.y+t.height/2,e.center.y+e.height/2)};if(n.end-n.start<o.end-o.start){const t=(n.start+n.end)/2;return{start:{x:t,y:o.start},end:{x:t,y:o.end}}}{const t=(o.start+o.end)/2;return{start:{x:n.start,y:t},end:{x:n.end,y:t}}}}var Ul=1e-9;function Gl(t,e){return Math.abs(t.x-e.x)<Ul&&Math.abs(t.y-e.y)<Ul}function Zl(t,e){if(t.length!==e.length)return!1;for(let n=0;n<t.length;n++)if(t[n]!==e[n])return!1;return!0}var ql=class{constructor(t){this.targets=t,this.buckets=new Map;for(let e=0;e<t.length;e++){const n=t[e],o=Math.floor(n.bounds.minX/this.CELL_SIZE)*this.CELL_SIZE,i=Math.floor(n.bounds.minY/this.CELL_SIZE)*this.CELL_SIZE,s=n.bounds.maxX,r=n.bounds.maxY;for(let t=o;t<=s;t+=this.CELL_SIZE)for(let o=i;o<=r;o+=this.CELL_SIZE){const i=this.getBucketKey(t,o),s=this.buckets.get(i);s?s.push([n,e]):this.buckets.set(i,[[n,e]])}}}buckets;CELL_SIZE=5;getBucketKey(t,e){return`${Math.floor(t/this.CELL_SIZE)}x${Math.floor(e/this.CELL_SIZE)}`}getTargetsInArea(t,e,n,o){const i=[],s=new Set,r=Math.floor((t-n/2)/this.CELL_SIZE)*this.CELL_SIZE,a=Math.floor((e-o/2)/this.CELL_SIZE)*this.CELL_SIZE,c=t+n/2,h=e+o/2;for(let t=r;t<=c;t+=this.CELL_SIZE)for(let e=a;e<=h;e+=this.CELL_SIZE){const n=this.getBucketKey(t,e),o=this.buckets.get(n)||[];for(const t of o)s.has(t[1])||(s.add(t[1]),i.push(t[0]))}return i}},Jl=class extends Dn{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.MAX_DEPTH=e?.capacityDepth??this.MAX_DEPTH,this.MAX_ITERATIONS=1e5,this.layerCount=t.layerCount??2,this.outlinePolygon=t.outline&&t.outline.length>=3?t.outline:void 0;const n={x:(t.bounds.minX+t.bounds.maxX)/2,y:(t.bounds.minY+t.bounds.maxY)/2},o={width:t.bounds.maxX-t.bounds.minX,height:t.bounds.maxY-t.bounds.minY},i=Math.max(o.width,o.height);this.unfinishedNodes=[{capacityMeshNodeId:this.getNextNodeId(),center:n,width:i,height:i,layer:"top",availableZ:Array.from({length:this.layerCount},(t,e)=>e),_depth:0,_containsTarget:!0,_containsObstacle:!0,_completelyInsideObstacle:!1}],this.finishedNodes=[],this.nodeToXYOverlappingObstaclesMap=new Map,this.obstacleZLayersByObstacle=new WeakMap;const s=Ml(this.srj.obstacles,this.layerCount);for(const[t,e]of this.srj.obstacles.entries())this.obstacleZLayersByObstacle.set(e,s[t].zLayers);this.obstacleTree=new ml("flatbush",this.srj.obstacles),this.targets=this.computeTargets(),this.targetTree=new ql(this.targets)}getSolverName(){return"CapacityMeshNodeSolver"}unfinishedNodes;finishedNodes;nodeToXYOverlappingObstaclesMap;layerCount;outlinePolygon;MAX_DEPTH=4;targets;targetTree;obstacleTree;obstacleZLayersByObstacle;computeTargets(){const t=[];for(const e of this.srj.connections)for(const n of e.pointsToConnect){const o=Tn(n),i=this.obstacleTree.searchArea(n.x,n.y,.01,.01).filter(t=>{const e=this.getObstacleZLayers(t);return!(!e||0===e.length)&&e.some(t=>o.some(e=>t===wn(e,this.layerCount)))});let s={minX:n.x-.005,minY:n.y-.005,maxX:n.x+.005,maxY:n.y+.005};i.length>0&&(s={minX:Math.min(...i.map(t=>t.center.x-t.width/2)),minY:Math.min(...i.map(t=>t.center.y-t.height/2)),maxX:Math.max(...i.map(t=>t.center.x+t.width/2)),maxY:Math.max(...i.map(t=>t.center.y+t.height/2))});const r={...n,connectionName:e.name,availableZ:o.map(t=>wn(t,this.layerCount)),bounds:s};t.push(r)}return t}getNodeBounds(t){const e=t.width/2,n=t.height/2;return{minX:t.center.x-e,maxX:t.center.x+e,minY:t.center.y-n,maxY:t.center.y+n}}getNodeRect(t){return{center:{x:t.center.x,y:t.center.y},width:t.width,height:t.height}}_nextNodeCounter=0;getNextNodeId(){return"cn"+this._nextNodeCounter++}getCapacityFromDepth(t){return(this.MAX_DEPTH-t+1)**2}getTargetIfNodeContainsTarget(t){const e=t.width>4*this.targetTree.CELL_SIZE?this.targets:this.targetTree.getTargetsInArea(t.center.x,t.center.y,t.width,t.height);for(const n of e)if(n.bounds.minX<=t.center.x+t.width/2&&n.bounds.maxX>=t.center.x-t.width/2&&n.bounds.minY<=t.center.y+t.height/2&&n.bounds.maxY>=t.center.y-t.height/2&&n.availableZ.some(e=>t.availableZ.includes(e)))return n;return null}getXYOverlappingObstacles(t){const e=this.nodeToXYOverlappingObstaclesMap.get(t.capacityMeshNodeId);if(e)return e;const n=[],o=this.getNodeBounds(t),i=o.minX,s=o.maxX,r=o.minY,a=o.maxY,c=t._parent?this.getXYOverlappingObstacles(t._parent):this.srj.obstacles;for(const t of c){const e=t.center.x-t.width/2,o=t.center.x+t.width/2,c=t.center.y-t.height/2,h=t.center.y+t.height/2;s>=e&&i<=o&&a>=c&&r<=h?n.push(t):(i>=e&&s<=o&&r>=c&&a<=h||e>=i&&o<=s&&c>=r&&h<=a)&&n.push(t)}return this.nodeToXYOverlappingObstaclesMap.set(t.capacityMeshNodeId,n),n}getXYZOverlappingObstacles(t){const e=this.getXYOverlappingObstacles(t),n=[];for(const o of e)t.availableZ.some(t=>this.getObstacleZLayers(o).includes(t))&&n.push(o);return n}doesNodeOverlapObstacle(t){if(this.getXYZOverlappingObstacles(t).length>0)return!0;const e=this.getNodeBounds(t);if(this.outlinePolygon){const e=this.getNodeRect(t);if(!q(e,this.outlinePolygon))return!0}return e.minX<this.srj.bounds.minX||e.maxX>this.srj.bounds.maxX||e.minY<this.srj.bounds.minY||e.maxY>this.srj.bounds.maxY}isNodeCompletelyInsideObstacle(t){const e=this.getXYZOverlappingObstacles(t),n=this.getNodeBounds(t);if(this.outlinePolygon){const e=this.getNodeRect(t);if(!Z(e,this.outlinePolygon))return!0}for(const t of e){const e=t.center.x-t.width/2,o=t.center.x+t.width/2,i=t.center.y-t.height/2,s=t.center.y+t.height/2;if(n.minX>=e&&n.maxX<=o&&n.minY>=i&&n.maxY<=s)return!0}return!1}getChildNodes(t){if(t._depth===this.MAX_DEPTH)return[];const e=[],n={width:t.width/2,height:t.height/2},o=[{x:t.center.x-n.width/2,y:t.center.y-n.height/2},{x:t.center.x+n.width/2,y:t.center.y-n.height/2},{x:t.center.x-n.width/2,y:t.center.y+n.height/2},{x:t.center.x+n.width/2,y:t.center.y+n.height/2}];for(const i of o){const o={capacityMeshNodeId:this.getNextNodeId(),center:i,width:n.width,height:n.height,layer:t.layer,availableZ:t.availableZ,_depth:(t._depth??0)+1,_parent:t};o._containsObstacle=this.doesNodeOverlapObstacle(o);const s=this.getTargetIfNodeContainsTarget(o);s&&(o._targetConnectionName=s.connectionName,o.availableZ=s.availableZ,o._containsTarget=!0),o._containsObstacle&&(o._completelyInsideObstacle=this.isNodeCompletelyInsideObstacle(o)),o._completelyInsideObstacle&&!o._containsTarget||e.push(o)}return e}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||!(!t._containsObstacle||t._completelyInsideObstacle))}_step(){const t=this.unfinishedNodes.pop();if(!t)return void(this.solved=!0);const e=this.getChildNodes(t),n=[],o=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t);e?o.push(t):e||t._containsObstacle?!e&&t._containsTarget&&n.push(t):n.push(t)}this.unfinishedNodes.push(...o),this.finishedNodes.push(...n)}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Capacity Mesh Visualization"};if(this.outlinePolygon&&this.outlinePolygon.length>=2){const e=this.outlinePolygon.map(t=>({x:t.x,y:t.y}));e.push({...e[0]}),t.lines.push({points:e,strokeColor:"rgba(0, 136, 255, 0.95)",label:"outline"});for(const e of this.outlinePolygon)t.points.push({x:e.x,y:e.y,color:"rgba(0, 136, 255, 0.95)"})}for(const e of this.srj.obstacles){const n=this.getObstacleZLayers(e);t.rects.push({center:e.center,width:e.width,height:e.height,fill:1===n.length&&n.includes(1)?"rgba(0,0,255,0.3)":"rgba(255,0,0,0.3)",stroke:"red",label:["obstacle",`z: ${n.join(",")}`].join("\n")})}const e=[...this.finishedNodes,...this.unfinishedNodes];for(const n of e){const e=Math.min(...n.availableZ),o=this.unfinishedNodes.length>0&&n===this.unfinishedNodes[this.unfinishedNodes.length-1];t.rects.push({center:{x:n.center.x+e*n.width*.05,y:n.center.y-e*n.width*.05},width:Math.max(n.width-2,.8*n.width),height:Math.max(n.height-2,.8*n.height),fill:n._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[n.availableZ.join(",")]??"rgba(0,200,200,0.1)",stroke:o?"rgba(255,165,0,0.5)":void 0,label:[n.capacityMeshNodeId,`availableZ: ${n.availableZ.join(",")}`,`target? ${n._containsTarget??!1}`,`obs? ${n._containsObstacle??!1}`,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`capacity: ${Ah(n).toFixed(2)}`].join("\n")})}return t.rects.sort((t,e)=>t.center.y-e.center.y),this.srj.connections.forEach((e,n)=>{const o=Sn[n%Sn.length];for(const i of e.pointsToConnect){const e=Tn(i);t.points.push({x:i.x,y:i.y,label:`conn-${n} (${e.join(",")})`,color:o})}}),t}getObstacleZLayers(t){return this.obstacleZLayersByObstacle.get(t)??[]}},Kl=class extends Jl{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e,this.VIA_DIAMETER=t.minViaDiameter??this.VIA_DIAMETER}getSolverName(){return"CapacityMeshNodeSolver2_NodeUnderObstacle"}VIA_DIAMETER=.6;OBSTACLE_MARGIN=.1;OVERLAP_THRESHOLD_FOR_SINGLE_LAYER_NODES=.2;isNodeCompletelyOutsideBounds(t){if(this.outlinePolygon){const e=this.getNodeRect(t);if(!Z(e,this.outlinePolygon))return!0}return t.center.x+t.width/2<this.srj.bounds.minX||t.center.x-t.width/2>this.srj.bounds.maxX||t.center.y+t.height/2<this.srj.bounds.minY||t.center.y-t.height/2>this.srj.bounds.maxY}isNodePartiallyOutsideBounds(t){if(this.outlinePolygon){const e=this.getNodeRect(t);return!!Z(e,this.outlinePolygon)&&!q(e,this.outlinePolygon)}return t.center.x-t.width/2<this.srj.bounds.minX||t.center.x+t.width/2>this.srj.bounds.maxX||t.center.y-t.height/2<this.srj.bounds.minY||t.center.y+t.height/2>this.srj.bounds.maxY}getObstacleCoveragePercentage(t){const e=this.getXYZOverlappingObstacles(t);if(0===e.length)return 0;const n=t.center.x-t.width/2,o=t.center.x+t.width/2,i=t.center.y-t.height/2,s=t.center.y+t.height/2,r=t.width*t.height;let a=0;for(const t of e){const e=Math.max(n,t.center.x-t.width/2),r=Math.min(o,t.center.x+t.width/2),c=Math.max(i,t.center.y-t.height/2),h=Math.min(s,t.center.y+t.height/2);if(e<r&&c<h){a+=(r-e)*(h-c)}}return a/r}shouldFilterSingleLayerNodeForObstacle(t){if(1!==t.availableZ.length)return!1;if(!t._containsObstacle)return!1;return this.getObstacleCoveragePercentage(t)>this.OVERLAP_THRESHOLD_FOR_SINGLE_LAYER_NODES}shouldFilterNodeForObstacle(t){return!!t._containsObstacle&&(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}createChildNodeAtPosition(t,e){const n={capacityMeshNodeId:this.getNextNodeId(),center:e.center,width:e.width,height:e.height,layer:t.layer,availableZ:e.availableZ,_depth:e._depth??(t._depth??0)+1,_parent:t},o=this.getXYZOverlappingObstacles(n);n._containsObstacle=o.length>0||this.isNodePartiallyOutsideBounds(n);const i=this.getTargetIfNodeContainsTarget(n);return i&&(n._targetConnectionName=i.connectionName,n._containsTarget=!0),n._containsObstacle&&(n._completelyInsideObstacle=this.isNodeCompletelyInsideObstacle(n)),n}getZSubdivisionChildNodes(t){if(1===t.availableZ.length)return[];const e=[],n=t.availableZ.map(t=>[t]);for(const o of n){const n=this.createChildNodeAtPosition(t,{center:{...t.center},width:t.width,height:t.height,availableZ:o,_depth:t._depth});this.isNodeCompletelyOutsideBounds(n)||e.push(n)}return e}getChildNodes(t){if(t._depth>=this.MAX_DEPTH)return[];const e=[],n={width:t.width/2,height:t.height/2},o=[{x:t.center.x-n.width/2,y:t.center.y-n.height/2},{x:t.center.x+n.width/2,y:t.center.y-n.height/2},{x:t.center.x-n.width/2,y:t.center.y+n.height/2},{x:t.center.x+n.width/2,y:t.center.y+n.height/2}];for(const i of o){const o=this.createChildNodeAtPosition(t,{center:i,width:n.width,height:n.height,availableZ:t.availableZ});this.isNodeCompletelyOutsideBounds(o)||e.push(o)}return e}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||(1===t.availableZ.length&&t._depth<=this.MAX_DEPTH||!(!t._containsObstacle||t._completelyInsideObstacle)))}_step(){const t=this.unfinishedNodes.pop();if(!t)return void(this.solved=!0);const e=this.getChildNodes(t),n=[],o=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),i=t.availableZ.length>1&&!e&&(t._containsObstacle||t.width<this.VIA_DIAMETER+this.OBSTACLE_MARGIN);if(e)o.push(t);else if(e||this.shouldFilterNodeForObstacle(t)||i)if(!e&&t._containsTarget)if(i){const e=this.getZSubdivisionChildNodes(t);n.push(...e.filter(t=>t._containsTarget||!this.shouldFilterNodeForObstacle(t)))}else n.push(t);else i&&n.push(...this.getZSubdivisionChildNodes(t).filter(t=>!this.shouldFilterNodeForObstacle(t)));else n.push(t)}this.unfinishedNodes.push(...o),this.finishedNodes.push(...n)}},Ql=class extends Dn{getSolverName(){return"CapacitySegmentToPointSolver"}unsolvedSegments;solvedSegments;nodeMap;colorMap;constructor({segments:t,colorMap:e,nodes:n}){super(),this.MAX_ITERATIONS=1e5,this.unsolvedSegments=t,this.solvedSegments=[],this.colorMap=e??{},this.nodeMap=Object.fromEntries(n.map(t=>[t.capacityMeshNodeId,t]))}_step(){let t=!1;const e=[...this.unsolvedSegments];for(const n of e){const e=n.connectionNames.length;if((!("assignedPoints"in n)||n.assignedPoints?.length!==e)&&1===e){const e={x:(n.start.x+n.end.x)/2,y:(n.start.y+n.end.y)/2,z:n.availableZ[0]};n.assignedPoints=[{connectionName:n.connectionNames[0],rootConnectionName:n.rootConnectionNames?.[0],point:e}],this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(n),1),this.solvedSegments.push(n),t=!0}}if(!t&&e.length>0){let n=e[0];for(const t of e)t.connectionNames.length<n.connectionNames.length&&(n=t);const o=[...n.connectionNames].sort(),i=n.end.x-n.start.x,s=n.end.y-n.start.y,r=o.length,a=[];for(let t=1;t<=r;t++){const e=t/(r+1);a.push({x:n.start.x+i*e,y:n.start.y+s*e,z:n.availableZ[0]})}n.assignedPoints=o.map((t,e)=>({connectionName:t,rootConnectionName:n.rootConnectionNames?.[n.connectionNames.indexOf(t)],point:a[e]})),this.unsolvedSegments.splice(this.unsolvedSegments.indexOf(n),1),this.solvedSegments.push(n),t=!0}0===this.unsolvedSegments.length&&(this.solved=!0)}getNodesWithPortPoints(){if(!this.solved)throw new Error("CapacitySegmentToPointSolver not solved, can't give port points yet");const t=new Map;for(const e of this.solvedSegments){const n=e.capacityMeshNodeId,o=this.nodeMap[n];t.has(n)||t.set(n,{capacityMeshNodeId:n,portPoints:[],center:o.center,width:o.width,height:o.height}),t.get(n).portPoints.push(...e.assignedPoints.map(t=>({...t.point,connectionName:t.connectionName})))}return Array.from(t.values())}visualize(){const t={points:[],lines:this.solvedSegments.map(t=>({points:[t.start,t.end],step:4})),rects:[],circles:[],coordinateSystem:"cartesian",title:"Capacity Segment to Point Solver"};for(let e=0;e<this.solvedSegments.length;e++){const n=this.solvedSegments[e];for(let e=0;e<n.assignedPoints.length;e++){const o=n.assignedPoints[e],i={x:o.point.x,y:o.point.y},s={x:o.point.x+.05*o.point.z,y:o.point.y+.05*o.point.z};0!==o.point.z&&t.lines.push({points:[i,s],strokeColor:"rgba(0, 0, 0, 0.25)",strokeDash:"5 5",step:4}),t.points.push({x:s.x,y:s.y,label:[`${n.capacityMeshNodeId}-${o.connectionName}`,`z: ${n.availableZ.join(",")}`,`nodePortSegmentId: ${n.nodePortSegmentId}`].join("\n"),color:this.colorMap[o.connectionName],step:4})}}const e=[],n={};for(const t of this.solvedSegments){const e=t.capacityMeshNodeId;n[e]||(n[e]={});for(const o of t.assignedPoints)n[e][o.connectionName]||(n[e][o.connectionName]=[]),n[e][o.connectionName].push({x:o.point.x,y:o.point.y})}for(const t in n)for(const o in n[t]){const i=n[t][o];i.length>1&&e.push({points:i,step:4,strokeDash:"5 5",strokeColor:this.colorMap[o]||"#000"})}return t.lines.push(...e),t}},td=(t,e={})=>{const n=Math.min(...t.availableZ);return{center:!e.rectMargin||e.zOffset?{x:t.center.x+n*t.width*(e.zOffset??.05),y:t.center.y-n*t.width*(e.zOffset??.05)}:t.center,width:e.rectMargin?t.width-2*e.rectMargin:Math.max(t.width-.5,.8*t.width),height:e.rectMargin?t.height-2*e.rectMargin:Math.max(t.height-.5,.8*t.height),fill:t._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[t.availableZ.join(",")]??"rgba(0,200,200,0.1)",layer:`z${t.availableZ.join(",")}`,label:[t.capacityMeshNodeId,`availableZ: ${t.availableZ.join(",")}`,""+(t._containsTarget?"containsTarget":""),""+(t._containsObstacle?"containsObstacle":"")].filter(Boolean).join("\n")}},ed=class extends Dn{getSolverName(){return"CapacityPathingSolver"}connectionsWithNodes;usedNodeCapacityMap;simpleRouteJson;nodes;edges;GREEDY_MULTIPLIER=1.1;MAX_CANDIDATES_IN_MEMORY=1e5;nodeMap;nodeEdgeMap;connectionNameToGoalNodeIds;colorMap;maxDepthOfNodes;activeCandidateStraightLineDistance;debug_lastNodeCostMap;hyperParameters;constructor({simpleRouteJson:t,nodes:e,edges:n,colorMap:o,MAX_ITERATIONS:i=1e6,hyperParameters:s={}}){super(),this.MAX_ITERATIONS=i,this.simpleRouteJson=t,this.nodes=e,this.edges=n,this.colorMap=o??{};const{connectionsWithNodes:r,connectionNameToGoalNodeIds:a}=this.getConnectionsWithNodes();this.connectionsWithNodes=r,this.connectionNameToGoalNodeIds=a,this.hyperParameters=s,this.usedNodeCapacityMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,0])),this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Ln(this.edges),this.maxDepthOfNodes=Math.max(...this.nodes.map(t=>t._depth??0)),this.debug_lastNodeCostMap=new Map}getTotalCapacity(t){const e=t._depth??0;return(this.maxDepthOfNodes-e+1)**2}getConnectionsWithNodes(){const t=[],e=this.nodes.filter(t=>t._containsTarget),n=new Map;for(const o of this.simpleRouteJson.connections){const i=[];for(const t of o.pointsToConnect){let n=this.nodes[0],o=Number.MAX_VALUE;for(const i of e){const e=Math.sqrt((i.center.x-t.x)**2+(i.center.y-t.y)**2);e<o&&(o=e,n=i)}i.push(n)}if(i.length<2)throw new Error(`Not enough nodes for connection "${o.name}", only ${i.length} found`);n.set(o.name,i.map(t=>t.capacityMeshNodeId)),t.push({connection:o,nodes:i,pathFound:!1,straightLineDistance:F(i[0].center,i[i.length-1].center)})}return t.sort((t,e)=>t.straightLineDistance-e.straightLineDistance),{connectionsWithNodes:t,connectionNameToGoalNodeIds:n}}currentConnectionIndex=0;candidates;visitedNodes;computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)}getBacktrackedPath(t){const e=[];let n=t;for(;n;)e.push(n.node),n=n.prevCandidate;return e}getNeighboringNodes(t){return this.nodeEdgeMap.get(t.capacityMeshNodeId).flatMap(e=>e.nodeIds.filter(e=>e!==t.capacityMeshNodeId)).map(t=>this.nodeMap.get(t))}getCapacityPaths(){const t=[];for(const e of this.connectionsWithNodes){const n=e.path;n&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,rootConnectionName:e.connection.rootConnectionName,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}doesNodeHaveCapacityForTrace(t,e){const n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,o=this.getTotalCapacity(t);if(1===t.availableZ.length&&!t._containsTarget&&n>0)return!1;let i=0;return t.availableZ.length>1&&1===e.availableZ.length&&(i+=.5),n+i<o}canTravelThroughObstacle(t,e){const n=this.connectionNameToGoalNodeIds.get(e);return n?.includes(t.capacityMeshNodeId)??!1}getDistanceBetweenNodes(t,e){return Math.sqrt((t.center.x-e.center.x)**2+(t.center.y-e.center.y)**2)}reduceCapacityAlongPath(t){for(const e of t.path??[])this.usedNodeCapacityMap.set(e.capacityMeshNodeId,this.usedNodeCapacityMap.get(e.capacityMeshNodeId)+1)}isConnectedToEndGoal(t,e){return this.nodeEdgeMap.get(t.capacityMeshNodeId).some(t=>t.nodeIds.includes(e.capacityMeshNodeId))}_step(){const t=this.connectionsWithNodes[this.currentConnectionIndex];if(!t)return void(this.solved=!0);const[e,n]=t.nodes;this.candidates||(this.candidates=[{prevCandidate:null,node:e,f:0,g:0,h:0}],this.debug_lastNodeCostMap=new Map,this.visitedNodes=new Set([e.capacityMeshNodeId]),this.activeCandidateStraightLineDistance=F(e.center,n.center)),this.candidates.sort((t,e)=>t.f-e.f);const o=this.candidates.shift();if(this.candidates.length>this.MAX_CANDIDATES_IN_MEMORY&&this.candidates.splice(this.MAX_CANDIDATES_IN_MEMORY,this.candidates.length-this.MAX_CANDIDATES_IN_MEMORY),!o)return console.error(`Ran out of candidates on connection ${t.connection.name}`),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,void(this.failed=!0);if(this.isConnectedToEndGoal(o.node,n))return t.path=this.getBacktrackedPath({prevCandidate:o,node:n,f:0,g:0,h:0}),this.reduceCapacityAlongPath(t),this.currentConnectionIndex++,this.candidates=null,void(this.visitedNodes=null);const i=this.getNeighboringNodes(o.node);for(const t of i){if(this.visitedNodes?.has(t.capacityMeshNodeId))continue;if(!this.doesNodeHaveCapacityForTrace(t,o.node))continue;const e=this.connectionsWithNodes[this.currentConnectionIndex].connection.name;if(t._containsObstacle&&!this.canTravelThroughObstacle(t,e))continue;const i=this.computeG(o,t,n),s=this.computeH(o,t,n),r=i+s*this.GREEDY_MULTIPLIER;this.debug_lastNodeCostMap.set(t.capacityMeshNodeId,{f:r,g:i,h:s});const a={prevCandidate:o,node:t,f:r,g:i,h:s};this.candidates.push(a)}this.visitedNodes.add(o.node.capacityMeshNodeId)}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(this.connectionsWithNodes)for(let e=0;e<this.connectionsWithNodes.length;e++){const n=this.connectionsWithNodes[e];if(n.path&&n.path.length>0){const o=n.path.map(({center:{x:t,y:n},width:o,availableZ:i})=>({x:t+.005*o*(e%10+e%19),y:n+.005*o*(e%10+e%19),availableZ:i}));t.lines.push({points:o,strokeColor:this.colorMap[n.connection.name]});for(let e=0;e<o.length;e++){const i=o[e];t.points.push({x:i.x,y:i.y,label:[`conn: ${n.connection.name}`,`node: ${n.path[e].capacityMeshNodeId}`,`z: ${i.availableZ.join(",")}`].join("\n")})}}}for(const e of this.nodes){const n=this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0,o=this.getTotalCapacity(e),i=this.debug_lastNodeCostMap.get(e.capacityMeshNodeId);t.rects.push({...td(e,{rectMargin:.025,zOffset:.01}),label:[`${e.capacityMeshNodeId}`,`${n}/${o}`,`${e.width.toFixed(2)}x${e.height.toFixed(2)}`,`g: ${void 0!==i?.g?i.g.toFixed(2):"?"}`,`h: ${void 0!==i?.h?i.h.toFixed(2):"?"}`,`f: ${void 0!==i?.f?i.f.toFixed(2):"?"}`,`z: ${e.availableZ.join(", ")}`].join("\n"),stroke:n>o+.5?"red":void 0})}if(this.connectionsWithNodes)for(const e of this.connectionsWithNodes)if(e.connection?.pointsToConnect)for(const n of e.connection.pointsToConnect)t.points.push({x:n.x,y:n.y,label:[`pointsToConnect ${e.connection.name}`].join("\n")});let e=this.connectionsWithNodes[this.currentConnectionIndex];if(!this.candidates&&this.currentConnectionIndex>0&&!this.connectionsWithNodes[this.currentConnectionIndex-1].path&&(e=this.connectionsWithNodes[this.currentConnectionIndex-1]),e){const[n,o]=e.connection.pointsToConnect;t.lines.push({points:[{x:n.x,y:n.y},{x:o.x,y:o.y}],strokeColor:"red",strokeDash:"10 5"})}if(this.candidates){const e=this.candidates.slice(0,5),n=this.connectionsWithNodes[this.currentConnectionIndex].connection.name;e.forEach((e,o)=>{const i=.5*(1-o/5),s=this.getBacktrackedPath(e);t.lines.push({points:s.map(({center:{x:t,y:e}})=>({x:t,y:e})),strokeColor:Mn(this.colorMap[n]??"red",1-i)})})}return t}},nd=class extends ed{getSolverName(){return"CapacityPathingSolver5"}NEGATIVE_CAPACITY_PENALTY_FACTOR=1;REDUCED_CAPACITY_PENALTY_FACTOR=1;constructor(...t){super(...t),this.GREEDY_MULTIPLIER=2.5}get maxCapacityFactor(){return this.hyperParameters.MAX_CAPACITY_FACTOR??1}getTotalCapacity(t){return Ah(t,this.maxCapacityFactor)}getNodeCapacityPenalty(t){const e=t.width+t.height,n=.05,o=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0);if(o>2)return n;return(e-n)*Math.max(1,(2-o)/(e-n))+n}getDistanceBetweenNodes(t,e){const n=t.center.x-e.center.x,o=t.center.y-e.center.y;return Math.sqrt(n**2+o**2)}computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)+this.getNodeCapacityPenalty(e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)+this.getNodeCapacityPenalty(e)}},od=class extends nd{getSolverName(){return"CapacityPathingGreedySolver"}doesNodeHaveCapacityForTrace(t,e){return!0}getNodeCapacityPenalty(t){const e=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0)-1;if(e>0)return 0;let n=1;return 1===t.availableZ.length&&(n=10),(.05+2*Math.abs(e))*n}};function id(t,e,n){const o=e.x-t.x,i=e.y-t.y;if(Math.abs(o)<1e-9&&Math.abs(i)<1e-9)return t;const s=n.width/2,r=n.height/2,a=n.center.x-s,c=n.center.x+s,h=n.center.y-r,l=n.center.y+r;let d=0,u=1/0;if(Math.abs(o)>1e-9){const e=(a-t.x)/o,n=(c-t.x)/o;d=Math.max(d,Math.min(e,n)),u=Math.min(u,Math.max(e,n))}else if(t.x<a||t.x>c)return t;if(Math.abs(i)>1e-9){const e=(h-t.y)/i,n=(l-t.y)/i;d=Math.max(d,Math.min(e,n)),u=Math.min(u,Math.max(e,n))}else if(t.y<h||t.y>l)return t;if(u<d||d===1/0||d<-1e9)return t;return{x:t.x+o*d,y:t.y+i*d}}function sd(t,e){const n=t.center,o=e.center,i=id(n,o,t),s=id(o,n,e),r=o.x-n.x,a=o.y-n.y,c=Math.sqrt(r*r+a*a);let h=i,l=s;if(c>1e-9){const n={x:r/c,y:a/c},o=.3*t.width,d=.3*e.width;o+d<Math.sqrt((s.x-i.x)**2+(s.y-i.y)**2)?(h={x:i.x+n.x*o,y:i.y+n.y*o},l={x:s.x-n.x*d,y:s.y-n.y*d}):(h=i,l=s)}return{lineStart:h,lineEnd:l}}var rd=t=>{const{usedCapacity:e,totalCapacity:n,layerCount:o}=t;if(e<n)return 0;if(n<1&&e<=1)return 0;if(1===o&&e>1)return 1-.01**e;const i=e/n-1;return 1-Math.exp(-2*i)},ad=(t,e,n)=>{if(n._containsTarget)return 0;if(t<=e)return 0;const o=1-rd({usedCapacity:t,totalCapacity:e,layerCount:n.availableZ.length});return o<=0?-1e9:Math.log(o)},cd=({totalNodeCapacityMap:t,usedNodeCapacityMap:e,nodeMap:n,sectionNodeIds:o})=>{let i=0;const s=o??new Set(e.keys());for(const o of s){if(!t.has(o))continue;const s=n.get(o);if(!s)continue;const r=t.get(o),a=e.get(o)??0;i+=ad(a,r,s)}return i};function hd({sectionNodes:t,sectionEdges:e,sectionConnectionTerminals:n,completedPaths:o,nodeMap:i,colorMap:s,centerNodeId:r,title:a,nodeOpacity:c=.1,usedNodeCapacityMap:h,totalCapacityMap:l}){const d={points:[],lines:[],rects:[],circles:[],title:a},u=new Set(t.map(t=>t.capacityMeshNodeId));for(const e of t){let t=`rgba(128, 128, 128, ${c})`,n=`rgba(128, 128, 128, ${c})`;const o=e.availableZ??[],i=o.includes(0),s=o.includes(1);i&&s?(t=`rgba(128, 0, 128, ${c})`,n=`rgba(128, 0, 128, ${c})`):i?(t=`rgba(0, 0, 255, ${c})`,n=`rgba(0, 0, 255, ${c})`):s&&(t=`rgba(255, 0, 0, ${c})`,n=`rgba(255, 0, 0, ${c})`),r&&e.capacityMeshNodeId===r&&(t=`rgba(0, 255, 0, ${c})`,n=`rgba(0, 128, 0, ${c})`),d.rects.push({...td(e),fill:t,stroke:n,label:`${e.capacityMeshNodeId}\n(Section Node)\nZ: ${o.join(",")}`});const a=d.rects.length-1;if(h&&l){const t=h.get(e.capacityMeshNodeId)??0,n=l.get(e.capacityMeshNodeId)??0,o=n>0?(t/n*100).toFixed(1):"N/A",i=rd({usedCapacity:t,totalCapacity:n,layerCount:e.availableZ.length});d.rects[a].label+=`\n${t.toFixed(1)} / ${n.toFixed(1)}\n${o}% (Pf: ${(100*i).toFixed(1)}%)`,i>.2&&(d.rects[a].stroke=Mn("red",.7*(.8+c)))}}for(const t of e){const[e,n]=t.nodeIds,o=i.get(e),s=i.get(n);if(o&&s){const{lineStart:t,lineEnd:e}=sd(o,s);d.lines.push({points:[t,e],strokeColor:`rgba(0, 0, 0, ${.2*Math.min(1,c/.1)})`})}}return n.forEach((t,e)=>{const n=i.get(t.startNodeId),o=i.get(t.endNodeId),r=s[t.connectionName]??"black",a=n&&u.has(n.capacityMeshNodeId),c=o&&u.has(o.capacityMeshNodeId),h=(e+e/50)%5;let l=0,p=0,f=0,g=0;if(a&&n){const e=.02*Math.min(n.width,n.height);l=e*h,p=e*h,d.points.push({x:n.center.x+l,y:n.center.y+p,color:r,label:`Start: ${t.connectionName}\n(${t.startNodeId})`}),d.lines.push({points:[{x:n.center.x,y:n.center.y},{x:n.center.x+l,y:n.center.y+p}],strokeColor:"gray",strokeDash:"2 2"})}if(c&&o){const e=.02*Math.min(o.width,o.height);f=e*h,g=e*h,d.points.push({x:o.center.x+f,y:o.center.y+g,color:r,label:`End: ${t.connectionName}\n(${t.endNodeId})`}),d.lines.push({points:[{x:o.center.x,y:o.center.y},{x:o.center.x+f,y:o.center.y+g}],strokeColor:"gray",strokeDash:"2 2"})}a&&c&&n&&o&&d.lines.push({points:[{x:n.center.x+l,y:n.center.y+p},{x:o.center.x+f,y:o.center.y+g}],strokeColor:r,strokeDash:"5 5"})}),o&&o.forEach((t,e)=>{if(t.path&&t.path.length>0){const n=s[t.connectionName]??"gray",o={x:(e+e/50)%5*.03,y:(e+e/50)%5*.03};d.lines.push({points:t.path.map(({center:{x:t,y:e}})=>({x:t+o.x,y:e+o.y})),strokeColor:Mn(n,.2)})}}),d}var ld=class extends Dn{getSolverName(){return"CapacityPathingSingleSectionSolver"}GREEDY_MULTIPLIER=1.5;sectionNodes;sectionEdges;sectionConnectionTerminals;nodeMap;nodeEdgeMap;colorMap;usedNodeCapacityMap;totalNodeCapacityMap;centerNodeId;currentSectionScore=0;MAX_CANDIDATES_IN_MEMORY=1e4;currentConnectionIndex=0;candidates=null;visitedNodes=null;queuedNodes=null;activeCandidateStraightLineDistance;debug_lastNodeCostMap=new Map;maxCapacityFactor=1;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.centerNodeId=t.centerNodeId,this.sectionNodes=t.sectionNodes,this.sectionEdges=t.sectionEdges,this.sectionConnectionTerminals=t.sectionConnectionTerminals.map(t=>({...t,path:void 0})),this.nodeMap=t.nodeMap??new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=t.nodeEdgeMap??Ln(this.sectionEdges),this.colorMap=t.colorMap??{},this.usedNodeCapacityMap=new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,0])),this.totalNodeCapacityMap=new Map(this.sectionNodes.map(t=>[t.capacityMeshNodeId,this.getTotalCapacity(t)]));const e=new Set(this.sectionNodes.map(t=>t.capacityMeshNodeId));this.currentSectionScore=cd({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:e}),t.hyperParameters?.SHUFFLE_SEED&&(this.sectionConnectionTerminals=Un(this.sectionConnectionTerminals,t.hyperParameters?.SHUFFLE_SEED))}getTotalCapacity(t){return Ah(t,this.maxCapacityFactor)}getNodeCapacityPenalty(t){if(!this.nodeMap.has(t.capacityMeshNodeId))return 1/0;const e=this.getTotalCapacity(t)-(this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0)-1;if(e>0)return 0;let n=1;return 1===t.availableZ.length&&(n=10),(.05+e**2*4)*n}getDistanceBetweenNodes(t,e){const n=t.center.x-e.center.x,o=t.center.y-e.center.y;return Math.sqrt(n**2+o**2)}computeG(t,e,n){return t.g+this.getDistanceBetweenNodes(t.node,e)+this.getNodeCapacityPenalty(e)}computeH(t,e,n){return this.getDistanceBetweenNodes(e,n)+this.getNodeCapacityPenalty(e)}getBacktrackedPath(t){const e=[];let n=t;for(;n;){if(e.push(n.node),!this.nodeMap.has(n.node.capacityMeshNodeId)){console.warn("Backtracked path went outside section bounds");break}n=n.prevCandidate}return e.reverse()}getNeighboringNodes(t){return this.nodeMap.has(t.capacityMeshNodeId)?this.nodeEdgeMap.get(t.capacityMeshNodeId)?.flatMap(e=>e.nodeIds.filter(e=>e!==t.capacityMeshNodeId)).map(t=>this.nodeMap.get(t)).filter(Boolean)??[]:[]}isConnectedToEndGoal(t,e){return!(!this.nodeMap.has(t.capacityMeshNodeId)||!this.nodeMap.has(e.capacityMeshNodeId))&&(this.nodeEdgeMap.get(t.capacityMeshNodeId)??[]).some(t=>t.nodeIds.includes(e.capacityMeshNodeId))}doesNodeHaveCapacityForTrace(t,e){return!0}reduceCapacityAlongPath(t){for(const e of t)if(this.usedNodeCapacityMap.has(e.capacityMeshNodeId)){const t=e.capacityMeshNodeId,n=this.nodeMap.get(t);if(!n){console.warn(`Node ${t} from path not found in section's nodeMap during score update.`);continue}const o=this.totalNodeCapacityMap.get(t),i=this.usedNodeCapacityMap.get(t)??0,s=ad(i,o,n);this.currentSectionScore-=s;const r=i+1;this.usedNodeCapacityMap.set(t,r);const a=ad(r,o,n);this.currentSectionScore+=a}}getSolvedSectionScore(){return this.currentSectionScore}_step(){const t=this.sectionConnectionTerminals[this.currentConnectionIndex];if(!t)return void(this.solved=!0);const e=this.nodeMap.get(t.startNodeId),n=this.nodeMap.get(t.endNodeId);if(!e||!n)return console.error(`Start or end node not found in section for connection ${t.connectionName}`),this.currentConnectionIndex++,this.candidates=null,void(this.visitedNodes=null);this.candidates||this._setupAStar(e,n);const o=this.candidates;if(0===o.length)return void this._handleCandidatesExhausted(t);o.sort((t,e)=>t.f-e.f);const i=o.shift();if(o.length>this.MAX_CANDIDATES_IN_MEMORY&&o.splice(this.MAX_CANDIDATES_IN_MEMORY,o.length-this.MAX_CANDIDATES_IN_MEMORY),this.visitedNodes.add(i.node.capacityMeshNodeId),i.node.capacityMeshNodeId===n.capacityMeshNodeId)return void this._handleGoalReached(i,t,n);const s=this.getNeighboringNodes(i.node);for(const e of s){if(this.queuedNodes?.has(e.capacityMeshNodeId))continue;if(!this.doesNodeHaveCapacityForTrace(e,i.node))continue;if(e._containsObstacle){const n=e.capacityMeshNodeId===t.startNodeId,o=e.capacityMeshNodeId===t.endNodeId;if(!n&&!o)continue}const s=this.computeG(i,e,n),r=this.computeH(i,e,n),a=s+r*this.GREEDY_MULTIPLIER;this.debug_lastNodeCostMap.set(e.capacityMeshNodeId,{f:a,g:s,h:r});const c={prevCandidate:i,node:e,f:a,g:s,h:r};this.queuedNodes?.add(e.capacityMeshNodeId),o.push(c)}}computeProgress(){const t=this.sectionConnectionTerminals.length;if(0===t)return 1;let e=this.currentConnectionIndex/t;if(this.currentConnectionIndex<t&&this.candidates&&this.candidates.length>0&&this.activeCandidateStraightLineDistance&&this.activeCandidateStraightLineDistance>0){const n=this.candidates.reduce((t,e)=>e.f<t.f?e:t);e+=Math.max(0,Math.min(1,1-n.h/this.activeCandidateStraightLineDistance))/t}else this.solved&&(e=1);return Math.min(1,e)}_setupAStar(t,e){this.candidates=[{prevCandidate:null,node:t,f:0,g:0,h:0}],this.visitedNodes=new Set([t.capacityMeshNodeId]),this.debug_lastNodeCostMap=new Map,this.activeCandidateStraightLineDistance=F(t.center,e.center);const n=this.computeH(null,t,e);this.candidates[0].h=n,this.candidates[0].f=n*this.GREEDY_MULTIPLIER,this.debug_lastNodeCostMap.set(t.capacityMeshNodeId,{f:this.candidates[0].f,g:0,h:n}),this.queuedNodes=new Set([t.capacityMeshNodeId])}_handleCandidatesExhausted(t){console.error(`Ran out of candidates for section connection ${t.connectionName}`),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,this.queuedNodes=null}_handleGoalReached(t,e,n){const o=this.getBacktrackedPath(t);e.path=o,this.reduceCapacityAlongPath(o),this.currentConnectionIndex++,this.candidates=null,this.visitedNodes=null,this.queuedNodes=null}visualize(){const t=this.sectionConnectionTerminals.filter(t=>t.path&&t.path.length>0).map(t=>({connectionName:t.connectionName,path:t.path})),e=hd({sectionNodes:this.sectionNodes,sectionEdges:this.sectionEdges,sectionConnectionTerminals:this.sectionConnectionTerminals,completedPaths:t,nodeMap:this.nodeMap,colorMap:this.colorMap,centerNodeId:null,title:`Section Pathing: Conn ${this.currentConnectionIndex+1}/${this.sectionConnectionTerminals.length} (${this.sectionNodes.length} nodes)`,nodeOpacity:.1});for(const t of this.sectionNodes){const n=e.rects.findIndex(e=>e.label?.includes(t.capacityMeshNodeId));if(-1!==n){const o=this.debug_lastNodeCostMap.get(t.capacityMeshNodeId),i=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,s=this.getTotalCapacity(t),r=`${i.toFixed(1)}/${s.toFixed(1)}`,a=o?`f:${o.f.toFixed(1)} g:${o.g.toFixed(1)} h:${o.h.toFixed(1)}`:"cost:?";e.rects[n].label=[t.capacityMeshNodeId,`Cap: ${r}`,a,`Z: ${t.availableZ.join(",")}`].join("\n"),i>s&&(e.rects[n].stroke=Mn("red",.7))}}if(this.candidates&&this.candidates.length>0){const t=this.candidates.slice().sort((t,e)=>t.f-e.f).slice(0,5),n=this.sectionConnectionTerminals[this.currentConnectionIndex],o=n?.connectionName??"unknown",i=this.colorMap[o]??"purple";t.forEach((t,n)=>{const o=.8*(1-n/5),s=this.getBacktrackedPath(t);s.length>0&&e.lines.push({points:s.map(({center:{x:t,y:e}})=>({x:t,y:e})),strokeColor:Mn(i,1-o),strokeWidth:.05})})}return e}},dd=t=>Array.from({length:t},(t,e)=>e),ud=class extends io{getSolverName(){return"HyperCapacityPathingSingleSectionSolver"}constructorParams;constructor(t){super(),this.MAX_ITERATIONS=1e5,this.constructorParams=t}computeG(t){return-t.getSolvedSectionScore()}computeH(t){return 0}getCombinationDefs(){const t=this.constructorParams.sectionConnectionTerminals.length;return 2===t?[["orderings2_for2"]]:3===t?[["orderings6_for3"]]:4===t?[["orderings24_for4"]]:[["orderings30"]]}getFailureMessage(){return`All CapacityPathingSingleSection solvers failed for "${this.centerNodeId}"`}getHyperParameterDefs(){return[{name:"orderings2_for2",possibleValues:dd(2).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings6_for3",possibleValues:dd(6).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings24_for4",possibleValues:dd(24).map(t=>({SHUFFLE_SEED:t}))},{name:"orderings30",possibleValues:dd(30).map(t=>({SHUFFLE_SEED:t}))}]}generateSolver(t){return new ld({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}onSolve({solver:t}){this.winningSolver=t}get centerNodeId(){return this.constructorParams.centerNodeId}get sectionNodes(){return this.constructorParams.sectionNodes}get sectionConnectionTerminals(){return this.winningSolver?.sectionConnectionTerminals}};import pd from"object-hash";var fd=t=>Math.floor(10*t)/10,gd=class extends ud{cacheHit=!1;cacheProvider;hasAttemptedToUseCache=!1;sectionNodeIdSet;cachedSectionConnectionTerminals=null;sectionScore=0;constructor(t){t.nodeMap=t.nodeMap??new Map(t.sectionNodes.map(t=>[t.capacityMeshNodeId,t])),super(t),this.sectionNodeIdSet=new Set(t.sectionNodes.map(t=>t.capacityMeshNodeId)),this.cacheProvider=void 0===t.cacheProvider?Se():t.cacheProvider}_step(){!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync()||(super._step(),(this.solved||this.failed)&&this.cacheProvider&&this.saveToCacheSync())}_computeBfsOrderingOfNodesInSection(){const t=new Set(this.constructorParams.centerNodeId),e=[],n=[{ancestorCapacitySum:0,capacity:0,g:0,capacityMeshNodeId:this.constructorParams.centerNodeId}];for(;n.length>0;){n.sort((t,e)=>e.g-t.g);const o=n.pop();if(!o)break;e.push(o.capacityMeshNodeId);const i=this.constructorParams.nodeEdgeMap.get(o.capacityMeshNodeId).flatMap(t=>t.nodeIds).filter(e=>!t.has(e)).filter(t=>this.sectionNodeIdSet.has(t));for(const e of i){t.add(e);const i=this.constructorParams.nodeMap.get(e),s=Ah(i);n.push({ancestorCapacitySum:o.g,capacity:s,g:o.g+s,capacityMeshNodeId:e})}}return e}computeCacheKeyAndTransform(){const t=this._computeBfsOrderingOfNodesInSection(),e=new Map,n=new Map;t.forEach((t,o)=>{const i=`node${o}`;e.set(t,i),n.set(i,t)});const o={};for(const n of t){const t=e.get(n),i=this.constructorParams.nodeMap.get(n),s=Ah(i);o[t]=fd(s).toFixed(1)}const i=new Set,s=[];for(const n of t){const t=e.get(n),o=this.constructorParams.nodeEdgeMap.get(n)??[];for(const r of o){const o=r.nodeIds.find(t=>t!==n);if(this.sectionNodeIdSet.has(o)){const n=[t,e.get(o)].sort(),r=`${n[0]}-${n[1]}`;i.has(r)||(s.push(n),i.add(r))}}}s.sort((t,e)=>t[0]!==e[0]?t[0].localeCompare(e[0]):t[1].localeCompare(e[1]));const r={},a=new Map,c=new Map;for(const t of this.constructorParams.sectionConnectionTerminals){const n=e.get(t.startNodeId),o=e.get(t.endNodeId),[i,s]=[n,o].sort(),h=`${i}->${s}`,l=c.get(h)??0;c.set(h,l+1);const d=`${i}->${s}::${l}`;r[d]={start:i,end:s},a.set(d,t.connectionName)}const h=`capacitypathing:${pd({node_capacity_map:o,node_edge_map:s,terminals:r})}`,l={cacheSpaceToRealConnectionId:a,cacheSpaceToRealNodeId:n};return this.cacheKey=h,this.cacheToSolveSpaceTransform=l,{cacheKey:h,cacheToSolveSpaceTransform:l}}applyCachedSolution(t){if(!this.cacheToSolveSpaceTransform)return console.error("Cache transform not available, cannot apply cached solution."),void(this.failed=!0);if(!t.success)return this.failed=!0,void(this.cacheHit=!0);this.cachedSectionConnectionTerminals=[];const{cacheSpaceToRealNodeId:e,cacheSpaceToRealConnectionId:n}=this.cacheToSolveSpaceTransform;for(const[o,i]of Object.entries(t.solutionPaths)){const t=n.get(o);if(!t){console.warn(`Could not find real connection name for ${o}`);continue}const s=this.constructorParams.sectionConnectionTerminals.find(e=>e.connectionName===t);if(!s){console.warn(`Could not find original terminal for connection name ${t}`);continue}const r=i.map(n=>{const o=e.get(n);if(!o)throw new Error(`Could not map cache node ID ${n} to real node ID for connection ${t}`);const i=this.constructorParams.nodeMap.get(o);if(!i)throw new Error(`Could not find node with ID ${o} in nodeMap for connection ${t}`);return i});this.cachedSectionConnectionTerminals.push({...s,path:r})}this.sectionScore=t.sectionScore,this.solved=!0,this.cacheHit=!0}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return console.log("Cache provider is not synchronous, skipping sync cache check."),!1;if(this.cacheKey||this.computeCacheKeyAndTransform(),!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(!this.cacheKey)return void console.error("Cannot save to cache without cache key.");if(!this.cacheToSolveSpaceTransform)return void console.error("Cache transform not available, cannot save solution to cache.");let t;if(this.failed)t={success:!1};else{if(!this.solved)return;{const e={},{cacheSpaceToRealNodeId:n,cacheSpaceToRealConnectionId:o}=this.cacheToSolveSpaceTransform,i=new Map;for(const[t,e]of n)i.set(e,t);const s=new Map;for(const[t,e]of o)s.set(e,t);const r=[];if(super.sectionConnectionTerminals)for(const t of super.sectionConnectionTerminals)if(t.path&&t.path.length>0){const e=t.path.map(t=>t.capacityMeshNodeId);r.push([t.connectionName,e])}for(const[t,n]of r){const o=s.get(t);if(!o){console.warn(`Could not find cache space connection ID for ${t} when saving to cache.`);continue}const r=n.map(e=>{const n=i.get(e);if(!n)throw new Error(`Could not map real node ID ${e} to cache node ID for connection ${t} when saving to cache.`);return n});e[o]=r}t={success:!0,sectionScore:this.sectionScore,solutionPaths:e}}}try{this.cacheProvider?.setCachedSolutionSync(this.cacheKey,t)}catch(t){console.error("Error saving solution to cache:",t)}}get sectionConnectionTerminals(){return this.cacheHit&&this.solved&&this.cachedSectionConnectionTerminals?(console.log("returning the cached section connection terminals"),this.cachedSectionConnectionTerminals):super.sectionConnectionTerminals}visualize(){if(!this.cacheHit)return super.visualize();return hd({sectionNodes:this.constructorParams.sectionNodes,sectionEdges:this.constructorParams.sectionEdges,sectionConnectionTerminals:this.cachedSectionConnectionTerminals,completedPaths:this.cachedSectionConnectionTerminals.map(t=>({connectionName:t.connectionName,path:t.path})),nodeMap:this.constructorParams.nodeMap,colorMap:this.constructorParams.colorMap,title:"CachedHyperCapacityPathingSingleSectionSolver"})}},md=class extends Dn{getSolverName(){return"CapacityPathingMultiSectionSolver"}simpleRouteJson;nodes;edges;nodeEdgeMap;connectionsWithNodes=[];colorMap;initialSolver;cacheProvider;stage="initialization";nodeMap=new Map;allNodeIdsSet;usedNodeCapacityMap=new Map;totalNodeCapacityMap=new Map;nodeCapacityPercentMap=new Map;nodeOptimizationAttemptCountMap=new Map;currentSection=null;sectionSolver=null;currentScheduleIndex=0;stats;OPTIMIZATION_SCHEDULE=[{MAX_ATTEMPTS_PER_NODE:1,MAX_EXPANSION_DEGREES:3,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.05},{MAX_ATTEMPTS_PER_NODE:2,MAX_EXPANSION_DEGREES:5,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.2},{MAX_ATTEMPTS_PER_NODE:3,MAX_EXPANSION_DEGREES:7,MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE:.9}];get currentSchedule(){return this.OPTIMIZATION_SCHEDULE[this.currentScheduleIndex]??null}constructor(t){super(),this.stats={successfulOptimizations:0,failedOptimizations:0,failedSectionSolvers:0,startingScore:0,scheduleScores:this.OPTIMIZATION_SCHEDULE.map(({MAX_EXPANSION_DEGREES:t})=>({maxExpansionDegrees:t,endingScore:0,endingHighestNodePf:0,sectionAttempts:0})),cacheHits:0,cacheMisses:0},this.MAX_ITERATIONS=t.MAX_ITERATIONS??1e7,this.cacheProvider=t.cacheProvider,this.simpleRouteJson=t.simpleRouteJson,this.nodes=t.nodes,this.edges=t.edges,this.nodeEdgeMap=Ln(this.edges),this.colorMap=t.colorMap??{},this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Ln(this.edges),this.initialSolver=t.initialPathingSolver||new od({simpleRouteJson:this.simpleRouteJson,nodes:this.nodes,edges:this.edges,colorMap:this.colorMap}),this.activeSubSolver=this.initialSolver;for(const t of this.nodes){const e=this.initialSolver.getTotalCapacity(t);this.totalNodeCapacityMap.set(t.capacityMeshNodeId,e)}this.allNodeIdsSet=new Set(this.nodes.map(t=>t.capacityMeshNodeId))}_stepInitialization(){if(this.initialSolver?.step(),this.initialSolver?.failed)return this.failed=!0,void(this.error=this.initialSolver.error);if(this.initialSolver?.solved){this.usedNodeCapacityMap=new Map(this.initialSolver.usedNodeCapacityMap);for(const t of this.nodes){const e=this.totalNodeCapacityMap.get(t.capacityMeshNodeId)??0,n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,o=e>0?n/e:0;this.nodeCapacityPercentMap.set(t.capacityMeshNodeId,o),this.nodeOptimizationAttemptCountMap.set(t.capacityMeshNodeId,0)}this.connectionsWithNodes=this.initialSolver.connectionsWithNodes,this.stats.startingScore=cd({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:this.allNodeIdsSet}),this.stage="section-optimization"}}_getNextNodeToOptimize(){let t=0,e=0,n=null;for(const o of this.nodes){if(o._containsTarget)continue;const i=this.nodeOptimizationAttemptCountMap.get(o.capacityMeshNodeId),s=this.totalNodeCapacityMap.get(o.capacityMeshNodeId),r=rd({usedCapacity:this.usedNodeCapacityMap.get(o.capacityMeshNodeId)??0,totalCapacity:s,layerCount:o.availableZ.length}),a=r/(i+1);i<this.currentSchedule.MAX_ATTEMPTS_PER_NODE&&a>t&&r>this.currentSchedule.MINIMUM_PROBABILITY_OF_FAILURE_TO_OPTIMIZE&&(t=a,e=r,n=o.capacityMeshNodeId)}return n}getOverallScore(){let t=0;for(const e of this.nodes){if(e._containsTarget)continue;const n=this.totalNodeCapacityMap.get(e.capacityMeshNodeId),o=rd({usedCapacity:this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0,totalCapacity:n,layerCount:e.availableZ.length});o>t&&(t=o)}return{highestNodePf:t,score:cd({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:this.allNodeIdsSet})}}_stepSectionOptimization(){if(!this.sectionSolver){const t=this._getNextNodeToOptimize();if(!t){const{highestNodePf:t,score:e}=this.getOverallScore();return this.stats.scheduleScores[this.currentScheduleIndex].endingHighestNodePf=t,this.stats.scheduleScores[this.currentScheduleIndex].endingScore=e,this.currentScheduleIndex++,void(this.currentSchedule||(this.solved=!0))}const e=(t=>{const{centerNodeId:e,connectionsWithNodes:n,nodeMap:o,edges:i,nodeEdgeMap:s,expansionDegrees:r}=t,a=new Set,c=[{nodeId:e,depth:0}];a.add(e);let h=0;for(;h<c.length;){const{nodeId:t,depth:e}=c[h++];if(e>=r)continue;const n=s.get(t)?.flatMap(e=>e.nodeIds.filter(e=>e!==t))??[];for(const t of n)a.has(t)||(a.add(t),c.push({nodeId:t,depth:e+1}))}const l=Array.from(a).map(t=>o.get(t)),d=i.filter(t=>{const[e,n]=t.nodeIds;return a.has(e)&&a.has(n)}),u=[];for(const t of n){if(!t.path)continue;let e=null,n=null;for(const n of t.path)if(a.has(n.capacityMeshNodeId)){e=n.capacityMeshNodeId;break}for(let e=t.path.length-1;e>=0;e--){const o=t.path[e];if(a.has(o.capacityMeshNodeId)){n=o.capacityMeshNodeId;break}}e&&n&&u.push({connectionName:t.connection.name,startNodeId:e,endNodeId:n})}return{sectionConnectionTerminals:u,sectionNodes:l,sectionEdges:d,centerNodeId:e}})({centerNodeId:t,connectionsWithNodes:this.connectionsWithNodes,nodeMap:this.nodeMap,edges:this.edges,expansionDegrees:this.currentSchedule.MAX_EXPANSION_DEGREES,nodeEdgeMap:this.nodeEdgeMap});this.stats.scheduleScores[this.currentScheduleIndex].sectionAttempts++,this.currentSection=e,this.sectionSolver=new gd({sectionNodes:this.currentSection.sectionNodes,sectionEdges:this.currentSection.sectionEdges,sectionConnectionTerminals:this.currentSection.sectionConnectionTerminals,colorMap:this.colorMap,centerNodeId:this.currentSection.centerNodeId,nodeEdgeMap:this.nodeEdgeMap,hyperParameters:{EXPANSION_DEGREES:this.currentSchedule.MAX_EXPANSION_DEGREES},cacheProvider:this.cacheProvider}),this.activeSubSolver=this.sectionSolver,this.nodeOptimizationAttemptCountMap.set(t,(this.nodeOptimizationAttemptCountMap.get(t)??0)+1)}if(this.sectionSolver.step(),(this.sectionSolver.failed||this.sectionSolver.solved)&&(this.sectionSolver.cacheHit?this.stats.cacheHits++:this.stats.cacheMisses++),this.sectionSolver.failed)return console.warn(`Section solver failed for node ${this.currentSection.centerNodeId}. Error: ${this.sectionSolver.error}`),this.stats.failedSectionSolvers++,this.stats.failedOptimizations++,this.sectionSolver=null,void(this.activeSubSolver=null);if(this.sectionSolver.solved){const t=this.sectionSolver.sectionConnectionTerminals,e=this.sectionSolver.sectionNodes,n=this.sectionSolver.centerNodeId;if(this.sectionSolver=null,this.activeSubSolver=null,!t)return void console.warn(`Pathing sub-solver for section ${this.currentSection.centerNodeId} did not complete successfully. Discarding results.`);const o=new Set(e.map(t=>t.capacityMeshNodeId)),i=cd({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeMap:this.nodeMap,sectionNodeIds:o}),s=new Map(this.usedNodeCapacityMap),r=t;for(const t of r){const e=this.connectionsWithNodes.find(e=>e.connection.name===t.connectionName);if(e?.path)for(const t of e.path)if(o.has(t.capacityMeshNodeId)){const e=s.get(t.capacityMeshNodeId)??0;s.set(t.capacityMeshNodeId,Math.max(0,e-1))}}for(const t of r)if(t.path)for(const e of t.path)o.has(e.capacityMeshNodeId)&&s.set(e.capacityMeshNodeId,(s.get(e.capacityMeshNodeId)??0)+1);cd({totalNodeCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:s,nodeMap:this.nodeMap,sectionNodeIds:o})>i?(this.stats.successfulOptimizations++,this._mergeSolvedSectionPaths({centerNodeId:n,sectionConnectionTerminals:t}),this._recalculateNodeCapacityUsage()):this.stats.failedOptimizations++}}_mergeSolvedSectionPaths({centerNodeId:t,sectionConnectionTerminals:e}){for(const n of e){if(!n.path){console.warn(`No path found for connection ${n.connectionName} in section ${t}`);continue}const e=this.connectionsWithNodes.find(t=>t.connection.name===n.connectionName);if(!e||!e.path){console.warn(`Original connection or path not found for ${n.connectionName} while merging section ${t}`);continue}const o=e.path,i=n.path,s=o.findIndex(t=>t.capacityMeshNodeId===n.startNodeId),r=o.findIndex(t=>t.capacityMeshNodeId===n.endNodeId);if(-1===s||-1===r){console.warn(`Could not find start/end nodes (${n.startNodeId}/${n.endNodeId}) in original path for ${n.connectionName}`);continue}const[a,c]=s<=r?[s,r]:[r,s],h=o.slice(0,a),l=o.slice(c+1);let d=i;if(i.length>0&&o[a]&&i[0].capacityMeshNodeId!==o[a].capacityMeshNodeId){if(i[i.length-1].capacityMeshNodeId!==o[a].capacityMeshNodeId){console.warn(`New section path for ${n.connectionName} doesn't align with original path boundaries. Skipping merge for this connection.`);continue}d=[...i].reverse()}e.path=[...h,...d,...l]}}_recalculateNodeCapacityUsage(){this.usedNodeCapacityMap.clear();for(const t of this.connectionsWithNodes)if(t.path)for(const e of t.path)this.usedNodeCapacityMap.set(e.capacityMeshNodeId,(this.usedNodeCapacityMap.get(e.capacityMeshNodeId)??0)+1);for(const t of this.nodes){const e=this.totalNodeCapacityMap.get(t.capacityMeshNodeId)??0,n=this.usedNodeCapacityMap.get(t.capacityMeshNodeId)??0,o=e>0?n/e:0;this.nodeCapacityPercentMap.set(t.capacityMeshNodeId,o)}}getCapacityPaths(){const t=[];for(const e of this.connectionsWithNodes){const n=e.path;n&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}_step(){this.iterations>=this.MAX_ITERATIONS-1?this.solved=!0:"initialization"===this.stage?this._stepInitialization():"section-optimization"===this.stage&&this._stepSectionOptimization()}visualize(){const t=this.connectionsWithNodes.filter(t=>t.path&&t.path.length>0).map(t=>({connectionName:t.connection.name,path:t.path}));return hd({nodeMap:this.nodeMap,sectionConnectionTerminals:this.connectionsWithNodes.map(t=>({connectionName:t.connection.name,startNodeId:t.path?.[0]?.capacityMeshNodeId,endNodeId:t.path?.[t.path.length-1]?.capacityMeshNodeId})),completedPaths:t,sectionNodes:this.nodes,sectionEdges:this.edges,colorMap:this.colorMap,totalCapacityMap:this.totalNodeCapacityMap,usedNodeCapacityMap:this.usedNodeCapacityMap,nodeOpacity:.05,title:"Capacity Pathing Multi-Section Solver (Solved)"})}},yd=class extends Dn{getSolverName(){return"DeadEndSolver"}removedNodeIds;targetNodeIds;leaves;leavesIndex;adjacencyList;nodeMap;nodes;edges;constructor({nodes:t,edges:e}){super(),this.MAX_ITERATIONS=t.length,this.nodes=t,this.edges=e,this.removedNodeIds=new Set,this.targetNodeIds=new Set(t.filter(t=>t._containsTarget).map(t=>t.capacityMeshNodeId)),this.adjacencyList=new Map(t.map(({capacityMeshNodeId:t})=>[t,new Set]));for(const{nodeIds:[t,n]}of e)this.adjacencyList.get(t).add(n),this.adjacencyList.get(n).add(t);this.leavesIndex=0,this.leaves=[...this.adjacencyList.entries()].filter(([t,e])=>1===e.size).filter(([t,e])=>!this.targetNodeIds.has(t)).map(([t,e])=>t)}_step(){if(this.leavesIndex===this.leaves.length)return void(this.solved=!0);const t=this.leaves[this.leavesIndex],e=this.adjacencyList.get(t);if(!e||0===e.size)return this.removedNodeIds.add(t),this.adjacencyList.delete(t),this.leavesIndex+=1,void(this.leavesIndex===this.leaves.length&&(this.solved=!0));const[n]=e,o=n?this.adjacencyList.get(n):void 0;if(!n||!o)return this.removedNodeIds.add(t),this.adjacencyList.delete(t),this.leavesIndex+=1,void(this.leavesIndex===this.leaves.length&&(this.solved=!0));o.delete(t),this.removedNodeIds.add(t),this.adjacencyList.delete(t),1!==o.size||this.targetNodeIds.has(n)||this.leaves.push(n),this.leavesIndex+=1,this.leavesIndex===this.leaves.length&&(this.solved=!0)}visualize(){if(!this.nodeMap){this.nodeMap=new Map;for(const t of this.nodes)this.nodeMap.set(t.capacityMeshNodeId,t)}const t=new Map;for(const e of this.edges)for(const n of e.nodeIds)t.set(n,1+(t.get(n)??0));const e={lines:[],points:[],rects:this.nodes.map(e=>{const n=Math.min(...e.availableZ);return{width:Math.max(e.width-2,.8*e.width),height:Math.max(e.height-2,.8*e.height),center:{x:e.center.x+n*e.width*.05,y:e.center.y-n*e.width*.05},fill:e._containsObstacle?"rgba(255,0,0,0.1)":{"0,1":"rgba(0,0,0,0.1)",0:"rgba(0,200,200, 0.1)",1:"rgba(0,0,200, 0.1)"}[e.availableZ.join(",")]??"rgba(0,200,200,0.1)",label:[e.capacityMeshNodeId,`availableZ: ${e.availableZ.join(",")}`,`target? ${e._containsTarget??!1}`,`obs? ${e._containsObstacle??!1}`,`conn: ${t.get(e.capacityMeshNodeId)??0}`].join("\n"),layer:`z${e.availableZ.join(",")}`}}),circles:[]};for(const t of this.edges){const n=this.nodeMap.get(t.nodeIds[0]),o=this.nodeMap.get(t.nodeIds[1]);if(n?.center&&o?.center){const i=Math.min(...n.availableZ),s=Math.min(...o.availableZ),r={x:n.center.x+i*n.width*.05,y:n.center.y-i*n.width*.05},a={x:o.center.x+s*o.width*.05,y:o.center.y-s*o.width*.05},c=Array.from(new Set([...n.availableZ,...o.availableZ])).sort();e.lines.push({layer:`z${c.join(",")}`,points:[r,a],strokeDash:n.availableZ.join(",")===o.availableZ.join(",")?void 0:"10 5",strokeColor:t.nodeIds.some(t=>this.removedNodeIds.has(t))?Mn("black",.9):void 0})}}return e}},xd=class extends pl{getSolverName(){return"NoOffBoardMultipleHighDensityRouteStitchSolver"}constructor(t){super(t),this.unsolvedRoutes=[];const e=new Map;for(const n of t.hdRoutes){const t=e.get(n.connectionName)||[];t.push(n),e.set(n.connectionName,t)}for(const[n,o]of e.entries()){const e=t.connections.find(t=>t.name===n);if(!e)continue;const i={...e.pointsToConnect[0],z:wn(Cn(e.pointsToConnect[0]),t.layerCount)},s={...e.pointsToConnect[1],z:wn(Cn(e.pointsToConnect[1]),t.layerCount)};this.unsolvedRoutes.push({connectionName:n,hdRoutes:o,start:i,end:s})}for(const n of t.connections)e.has(n.name)||this.unsolvedRoutes.push({connectionName:n.name,hdRoutes:[],start:{...n.pointsToConnect[0],z:wn(Cn(n.pointsToConnect[0]),t.layerCount)},end:{...n.pointsToConnect[1],z:wn(Cn(n.pointsToConnect[1]),t.layerCount)}})}},vd=.005,bd=class extends Dn{getSolverName(){return"SingleLayerNodeMergerSolver"}nodeMap;currentBatchNodeIds;absorbedNodeIds;nextBatchNodeIds;batchHadModifications;hasComputedAdjacentNodeIds=!1;newNodes;constructor(t){super(),this.nodeMap=new Map,this.MAX_ITERATIONS=1e5;for(const e of t)this.nodeMap.set(e.capacityMeshNodeId,e);this.newNodes=[],this.absorbedNodeIds=new Set;const e=[];for(const n of t)n.availableZ.length>1?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):e.push([n,n.width*n.height]);e.sort((t,e)=>t[1]-e[1]);for(const[t,n]of e){const e={...t,center:{...t.center}};this.nodeMap.set(t.capacityMeshNodeId,e)}this.currentBatchNodeIds=e.map(([t])=>t.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=>Math.max(...t.availableZ))),n=[];for(let o=0;o<=e;o++)n.push(new kn(t.filter(t=>t.availableZ[0]===o)));for(const e of t){const t=[],o=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of o)n._containsTarget&&n._targetConnectionName!==e._targetConnectionName||e._containsTarget&&(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId&&Xn(e,n)&&t.push(n);e._adjacentNodeIds=t.map(t=>t.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){return this.getAdjacentSameLayerUnprocessedNodes2(t)}getAdjacentSameLayerUnprocessedNodes2(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=>this.nodeMap.get(t)))).filter(e=>e&&e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=>t.width*t.height-e.width*e.height);for(const t of n)this.absorbedNodeIds.has(t.capacityMeshNodeId)||e.push(t);return e}_step(){this.hasComputedAdjacentNodeIds||(this.computeAdjacentNodeIdsForFirstBatch(this.currentBatchNodeIds.map(t=>this.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t&&this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=>{const n=this.nodeMap.get(t),o=this.nodeMap.get(e);return n.width*n.height-o.width*o.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=>this.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const o=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===o.length)return void this.nextBatchNodeIds.push(t);const i=t=>{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=>t._adjacentNodeIds??[])].filter(t=>t!==e.capacityMeshNodeId&&!this.absorbedNodeIds.has(t))))},s=o.filter(t=>t.center.x<e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(s.length>0){const{width:t,height:o}=s[0],r=s.every(e=>e.width===t&&e.height===o);Math.abs(s.reduce((t,e)=>t+e.height,0)-e.height)<vd&&r&&(e.width+=t,e.center.x=e.center.x-t/2,i(s),n=!0)}const r=o.filter(t=>t.center.x>e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(r.length>0&&!n){const{width:t,height:o}=r[0],s=r.every(e=>e.width===t&&e.height===o);Math.abs(r.reduce((t,e)=>t+e.height,0)-e.height)<vd&&s&&(e.width+=t,e.center.x=e.center.x+t/2,i(r),n=!0)}const a=o.filter(t=>t.center.y>e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(a.length>0&&!n){const{width:t,height:o}=a[0],s=a.every(e=>e.width===t&&e.height===o);Math.abs(a.reduce((t,e)=>t+e.width,0)-e.width)<vd&&s&&(e.height+=o,e.center.y=e.center.y+o/2,i(a),n=!0)}const c=o.filter(t=>t.center.y<e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(c.length>0&&!n){const{width:t,height:o}=c[0],s=c.every(e=>e.width===t&&e.height===o);Math.abs(c.reduce((t,e)=>t+e.width,0)-e.width)<vd&&s&&(e.height+=o,e.center.y=e.center.y-o/2,i(c),n=!0)}n?(this.batchHadModifications=!0,this.currentBatchNodeIds.push(t)):this.nextBatchNodeIds.unshift(t)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Same Layer Node Merger"};for(const e of this.newNodes)t.rects.push(td(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e&&(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const o of this.currentBatchNodeIds){const i=this.nodeMap.get(o);if(!this.absorbedNodeIds.has(o)&&i){const s=td(i,{rectMargin:.01});o===e?s.stroke="rgba(0, 255, 0, 0.8)":n?.some(t=>t.capacityMeshNodeId===o)?s.stroke="rgba(128, 0, 128, 0.8)":s.stroke="rgba(255, 165, 0, 0.8)",s.layer=`z${i.availableZ.join(",")}`,s.label=`${s.label}\n(unprocessed)`,t.rects.push(s)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)&&n){const e=td(n,{rectMargin:.01});e.layer=`z${n.availableZ.join(",")}`,e.stroke="rgba(0, 217, 255, 0.8)",e.label=`${e.label}\nx: ${n.center.x}, y: ${n.center.y}\n${n.width}x${n.height}\n(next batch)`,t.rects.push(e)}}return t}},Pd=class extends Dn{getSolverName(){return"StrawSolver"}multiLayerNodes;strawNodes;skippedNodes;unprocessedNodes;strawSize;nodeIdCounter;constructor(t){super(),this.MAX_ITERATIONS=1e5,this.strawSize=t.strawSize??.5,this.multiLayerNodes=[],this.strawNodes=[],this.skippedNodes=[],this.nodeIdCounter=0,this.unprocessedNodes=[];for(const e of t.nodes)1===e.availableZ.length?this.unprocessedNodes.push(e):this.multiLayerNodes.push(e)}getCapacityOfMultiLayerNodesWithinBounds(t){let e=0;for(const n of this.multiLayerNodes){const o=n.center.x-n.width/2,i=n.center.x+n.width/2,s=n.center.y-n.height/2,r=n.center.y+n.height/2,a=Math.max(t.minX,o),c=Math.min(t.maxX,i),h=Math.max(t.minY,s),l=Math.min(t.maxY,r);if(a<c&&h<l){const t=(c-a)*(l-h)/(n.width*n.height);e+=Ah(n)*t}}return e}getSurroundingCapacities(t){const e=Math.min(t.width,t.height);return{leftSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2-e,maxX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}),rightSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x+t.width/2,maxX:t.center.x+t.width/2+e,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}),topSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2-e,maxY:t.center.y-t.height/2}),bottomSurroundingCapacity:this.getCapacityOfMultiLayerNodesWithinBounds({minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y+t.height/2,maxY:t.center.y+t.height/2+e})}}createStrawsForNode(t){const e=[],{leftSurroundingCapacity:n,rightSurroundingCapacity:o,topSurroundingCapacity:i,bottomSurroundingCapacity:s}=this.getSurroundingCapacities(t);if(1*(n+o)>i+s){const n=Math.floor(t.height/this.strawSize),o=t.height/n;for(let i=0;i<n;i++){const n=t.center.y-t.height/2+i*o+o/2;e.push({capacityMeshNodeId:`${t.capacityMeshNodeId}_straw${i}`,center:{x:t.center.x,y:n},width:t.width,height:o,layer:t.layer,availableZ:[...t.availableZ],_depth:t._depth,_strawNode:!0,_strawParentCapacityMeshNodeId:t.capacityMeshNodeId})}}else{const n=Math.floor(t.width/this.strawSize),o=t.width/n;for(let i=0;i<n;i++){const n=t.center.x-t.width/2+i*o+o/2;e.push({capacityMeshNodeId:`${t.capacityMeshNodeId}_straw${i}`,center:{x:n,y:t.center.y},width:o,height:t.height,layer:t.layer,availableZ:[...t.availableZ],_depth:t._depth,_strawNode:!0,_strawParentCapacityMeshNodeId:t.capacityMeshNodeId})}}return e}getResultNodes(){return[...this.multiLayerNodes,...this.strawNodes,...this.skippedNodes]}_step(){const t=this.unprocessedNodes.pop();if(!t)return void(this.solved=!0);if(t.width<this.strawSize&&t.height<this.strawSize)return void this.skippedNodes.push(t);if(t._containsTarget)return void this.skippedNodes.push(t);const e=this.createStrawsForNode(t);this.strawNodes.push(...e),0===e.length&&this.strawNodes.push(t)}visualize(){const t={rects:[],lines:[],points:[],circles:[],title:"Straw Solver"};for(const e of this.unprocessedNodes)t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(200, 200, 200, 0.5)",stroke:"rgba(0, 0, 0, 0.5)",label:`${e.capacityMeshNodeId}\nUnprocessed\n${e.width}x${e.height}`});for(const e of this.strawNodes){const n=0===e.availableZ[0]?"rgba(0, 150, 255, 0.5)":"rgba(255, 100, 0, 0.5)";t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,stroke:"rgba(0, 0, 0, 0.5)",label:`${e.capacityMeshNodeId}\nLayer: ${e.availableZ[0]}\n${e.width}x${e.height}`,layer:`z${e.availableZ.join(",")}`})}for(const e of this.multiLayerNodes)t.rects.push({center:e.center,width:.9*e.width,height:.9*e.height,fill:"rgba(100, 255, 100, 0.5)",stroke:"rgba(0, 0, 0, 0.5)",layer:`z${e.availableZ.join(",")}`,label:`${e.capacityMeshNodeId}\nLayers: ${e.availableZ.join(",")}\n${e.width}x${e.height}`});return t}};function Sd(t){const{nodeId:e,nodeIdToSegmentIds:n,segmentIdToNodeIds:o,hops:i}=t;if(0===i)return[e];const s=new Set([e]),r=[{nodeId:e,remainingHops:i}];for(;r.length>0;){const{nodeId:t,remainingHops:e}=r.shift();if(0===e)continue;const i=n.get(t)||[];for(const t of i){const n=o.get(t)||[];for(const t of n)s.has(t)||(s.add(t),r.push({nodeId:t,remainingHops:e-1}))}}return Array.from(s)}var Id=t=>Array.from(t.entries()).map(([t,{x:e,y:n,z:o}])=>`${t}(${e?.toFixed(3)??""},${n?.toFixed(3)??""},${o??""})`).sort().join("&"),Md=(t,e,n,o)=>{const i=Math.min(t,e),s=Math.max(t,e),r=Math.min(n,o);return i<=Math.max(n,o)&&s>=r},_d=(t,e,n,o)=>{const i=[],s=new Map(t.originalPointMap);for(const[t,e]of n.entries()){const n=s.get(t);s.set(t,{x:e.x??n.x,y:e.y??n.y,z:e.z??n.z})}for(const n of t.allNodeIds){if(!e.get(n))continue;const r=t.segmentPairsInNode.get(n);for(const t of r){const e=s.get(t[0]),o=s.get(t[1]);e.z!==o.z&&i.push({type:"transition_via",segmentPoints:t,capacityMeshNodeId:n,probabilityOfFailure:0})}for(let t=0;t<r.length;t++)for(let e=t+1;e<r.length;e++){if(o?.areIdsConnected(r[t][0],r[t][1]))continue;const a=r[t],c=r[e],h=s.get(a[0]),l=s.get(a[1]),d=s.get(c[0]),u=s.get(c[1]);if(!Md(h.z,l.z,d.z,u.z))continue;const p=D(h,l,d,u),f=h.z===l.z&&d.z===u.z&&h.z===d.z;p&&(f?i.push({type:"same_layer_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,crossingLine1:a,crossingLine2:c,probabilityOfFailure:0}):h.z===l.z&&d.z!==u.z?i.push({type:"single_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,sameLayerCrossingLine:a,transitionCrossingLine:c,probabilityOfFailure:0}):h.z!==l.z&&d.z===u.z?i.push({type:"single_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,sameLayerCrossingLine:c,transitionCrossingLine:a,probabilityOfFailure:0}):h.z!==l.z&&d.z!==u.z&&i.push({type:"double_transition_crossing",segmentPoints:[a,c],capacityMeshNodeId:n,crossingLine1:a,crossingLine2:c,probabilityOfFailure:0}))}}return i},Nd=(t,e,n)=>{if("change_layer"===e.type)for(const n of e.segmentPointIds){const o=t.get(n)||{};t.set(n,{...o,z:e.newZ})}else if("swap_position_on_segment"===e.type){const[o,i]=e.segmentPointIds,s=n(o),r=n(i),a=t.get(o)||{},c=t.get(i)||{};t.set(o,{...a,x:r.x,y:r.y}),t.set(i,{...c,x:s.x,y:s.y})}else if("combined"===e.type)for(const o of e.operations)Nd(t,o,n)},Cd=(t,e)=>{const n=new Map,o=new Map,i=new Map,s=[];let r=0;for(const a of t)for(const t of a.assignedPoints){const c={segmentPointId:"SP"+r++,segmentId:a.nodePortSegmentId,capacityMeshNodeIds:e.get(a.nodePortSegmentId),connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,x:t.point.x,y:t.point.y,z:t.point.z,directlyConnectedSegmentPointIds:[]};n.set(c.segmentPointId,c);for(const t of c.capacityMeshNodeIds)o.set(t,[...o.get(t)??[],c.segmentPointId]);i.set(a.nodePortSegmentId,[...i.get(a.nodePortSegmentId)??[],c.segmentPointId]),s.push(c)}return{segmentPointMap:n,nodeToSegmentPointMap:o,segmentToSegmentPointMap:i}},Td=class extends Dn{getSolverName(){return"UnravelSectionSolver"}nodeMap;dedupedSegments;dedupedSegmentMap;MUTABLE_HOPS=1;unravelSection;candidates=[];lastProcessedCandidate=null;bestCandidate=null;originalCandidate;rootNodeId;nodeIdToSegmentIds;segmentIdToNodeIds;colorMap;tunedNodeCapacityMap;MAX_CANDIDATES=500;iterationsSinceImprovement=0;hyperParameters;selectedCandidateIndex=null;queuedOrExploredCandidatePointModificationHashes=new Set;constructorParams;constructor(t){if(super(),this.constructorParams=t,this.MUTABLE_HOPS=t.MUTABLE_HOPS??this.MUTABLE_HOPS,this.MAX_ITERATIONS=5e4,this.hyperParameters={...t.hyperParameters,MAX_ITERATIONS_WITHOUT_IMPROVEMENT:200},this.nodeMap=t.nodeMap,this.dedupedSegments=t.dedupedSegments,t.dedupedSegmentMap)this.dedupedSegmentMap=t.dedupedSegmentMap;else{this.dedupedSegmentMap=new Map;for(const t of this.dedupedSegments)this.dedupedSegmentMap.set(t.nodePortSegmentId,t)}this.nodeIdToSegmentIds=t.nodeIdToSegmentIds,this.segmentIdToNodeIds=t.segmentIdToNodeIds,this.rootNodeId=t.rootNodeId,this.colorMap=t.colorMap??{},this.unravelSection=this.createUnravelSection({segmentPointMap:t.segmentPointMap,nodeToSegmentPointMap:t.nodeToSegmentPointMap,segmentToSegmentPointMap:t.segmentToSegmentPointMap}),this.tunedNodeCapacityMap=new Map;for(const t of this.unravelSection.allNodeIds)this.tunedNodeCapacityMap.set(t,Ah(this.nodeMap.get(t)));this.originalCandidate=this.createInitialCandidate(),this.candidates=[this.originalCandidate]}getConstructorParams(){return{...this.constructorParams,segmentPointMap:this.unravelSection.segmentPointMap,nodeToSegmentPointMap:this.unravelSection.segmentPointsInNode,segmentToSegmentPointMap:this.unravelSection.segmentPointsInSegment}}createUnravelSection(t){const e=Sd({nodeId:this.rootNodeId,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,hops:this.MUTABLE_HOPS}),n=Sd({nodeId:this.rootNodeId,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,hops:this.MUTABLE_HOPS+1}),o=Array.from(new Set(n).difference(new Set(e)));t?.segmentPointMap||(t=Cd(this.dedupedSegments,this.segmentIdToNodeIds));const i=new Map;for(const e of n)i.set(e,t.nodeToSegmentPointMap.get(e));const s=new Map;for(const e of n)for(const n of i.get(e)){const e=t.segmentPointMap.get(n);s.set(n,e)}const r=Array.from(s.values()),a=new Map;for(const t of r)a.set(t.segmentId,[...a.get(t.segmentId)??[],t.segmentPointId]);for(const[e,n]of i.entries())for(let e=0;e<n.length;e++){const o=t.segmentPointMap.get(n[e]);for(let i=e+1;i<n.length;i++){const e=t.segmentPointMap.get(n[i]);e.segmentPointId!==o.segmentPointId&&(e.segmentId!==o.segmentId&&e.connectionName===o.connectionName&&(e.directlyConnectedSegmentPointIds.includes(o.segmentPointId)||(o.directlyConnectedSegmentPointIds.push(e.segmentPointId),e.directlyConnectedSegmentPointIds.push(o.segmentPointId))))}}const c=new Map;for(const t of n)c.set(t,[]);for(const e of r)for(const n of e.capacityMeshNodeIds){const o=c.get(n);if(o)for(const i of e.directlyConnectedSegmentPointIds){const s=t.segmentPointMap.get(i);s.segmentPointId!==e.segmentPointId&&(s.capacityMeshNodeIds.some(t=>t===n)&&(o.some(([t,n])=>t===e.segmentPointId&&n===s.segmentPointId||t===s.segmentPointId&&n===e.segmentPointId)||o.push([e.segmentPointId,s.segmentPointId])))}}const h=new Set;for(const t of e)for(const e of this.nodeIdToSegmentIds.get(t)){this.segmentIdToNodeIds.get(e).every(t=>!this.nodeMap.get(t)._containsTarget)&&h.add(e)}const l=new Set;for(const t of r){const n=t.capacityMeshNodeIds.some(t=>e.includes(t)),o=this.dedupedSegmentMap.get(t.segmentId),i=o&&o.availableZ.length>1;(n||i)&&l.add(t.segmentPointId)}const d=new Set;for(const t of r){if(t.capacityMeshNodeIds.some(t=>this.nodeMap.get(t)?._containsTarget)){const e=this.dedupedSegmentMap.get(t.segmentId);e&&1===e.availableZ.length&&d.add(t.segmentPointId)}}return{allNodeIds:n,mutableNodeIds:e,immutableNodeIds:o,mutableSegmentIds:h,segmentPairsInNode:c,segmentPointMap:s,segmentPointsInNode:i,segmentPointsInSegment:a,originalPointMap:s,mutableSegmentPointIds:l,zLockedSegmentPointIds:d}}createInitialCandidate(){const t=new Map,e=_d(this.unravelSection,this.nodeMap,t),n=this.computeG({issues:e,originalCandidate:{},operationsPerformed:0,operation:{}});return{pointModifications:t,g:n,h:0,f:n,operationsPerformed:0,candidateHash:Id(t),issues:_d(this.unravelSection,this.nodeMap,t)}}get nextCandidate(){return this.candidates[0]??null}getPointInCandidate(t,e){const n=this.unravelSection.segmentPointMap.get(e),o=t.pointModifications.get(e);return{x:o?.x??n.x,y:o?.y??n.y,z:o?.z??n.z,segmentId:n.segmentId}}getConnectionSegmentPointIds(t){const e=[];for(const[n,o]of this.unravelSection.segmentPointMap.entries())o.connectionName===t&&e.push(n);return e}canConnectionUseLayer(t,e){for(const n of t){const t=this.unravelSection.segmentPointMap.get(n),o=this.dedupedSegmentMap.get(t.segmentId);if(!o||!o.availableZ.includes(e))return!1}return!0}getOperationsForIssue(t,e){const n=[];if("transition_via"===e.type){const[o,i]=e.segmentPoints,s=this.getPointInCandidate(t,o),r=this.getPointInCandidate(t,i),a=this.unravelSection.segmentPointMap.get(o),c=(this.unravelSection.segmentPointMap.get(i),this.dedupedSegmentMap.get(s.segmentId).availableZ),h=this.dedupedSegmentMap.get(r.segmentId).availableZ,l=this.unravelSection.zLockedSegmentPointIds.has(o),d=this.unravelSection.zLockedSegmentPointIds.has(i),u=this.getConnectionSegmentPointIds(a.connectionName);if(this.canConnectionUseLayer(u,r.z)){const t=u.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));t.length>0&&n.push({type:"change_layer",newZ:r.z,segmentPointIds:t})}if(this.canConnectionUseLayer(u,s.z)){const t=u.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));t.length>0&&n.push({type:"change_layer",newZ:s.z,segmentPointIds:t})}this.unravelSection.mutableSegmentPointIds.has(o)&&!l&&c.includes(r.z)&&n.push({type:"change_layer",newZ:r.z,segmentPointIds:[o]}),this.unravelSection.mutableSegmentPointIds.has(i)&&!d&&h.includes(s.z)&&n.push({type:"change_layer",newZ:s.z,segmentPointIds:[i]})}if("same_layer_crossing"===e.type){const[t,o]=e.crossingLine1,[i,s]=e.crossingLine2,r=[],a=this.unravelSection.segmentPointMap.get(t),c=this.unravelSection.segmentPointMap.get(o),h=this.unravelSection.segmentPointMap.get(i),l=this.unravelSection.segmentPointMap.get(s),d=this.unravelSection.mutableSegmentPointIds.has(t),u=this.unravelSection.mutableSegmentPointIds.has(o),p=this.unravelSection.mutableSegmentPointIds.has(i),f=this.unravelSection.mutableSegmentPointIds.has(s),g=this.unravelSection.zLockedSegmentPointIds.has(t),m=this.unravelSection.zLockedSegmentPointIds.has(o),y=this.unravelSection.zLockedSegmentPointIds.has(i),x=this.unravelSection.zLockedSegmentPointIds.has(s);d&&p&&a.segmentId===h.segmentId&&r.push([t,i]),d&&f&&a.segmentId===l.segmentId&&r.push([t,s]),u&&p&&c.segmentId===h.segmentId&&r.push([o,i]),u&&f&&c.segmentId===l.segmentId&&r.push([o,s]);for(const[t,e]of r)n.push({type:"swap_position_on_segment",segmentPointIds:[t,e]});const v=this.getConnectionSegmentPointIds(a.connectionName),b=this.getConnectionSegmentPointIds(h.connectionName),P=new Set;for(const t of this.unravelSection.segmentPointMap.values()){const e=this.dedupedSegmentMap.get(t.segmentId);if(e)for(const t of e.availableZ)P.add(t)}for(const t of P)if(t!==a.z&&this.canConnectionUseLayer(v,t)){const e=v.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));e.length>0&&n.push({type:"change_layer",newZ:t,segmentPointIds:e})}for(const t of P)if(t!==h.z&&this.canConnectionUseLayer(b,t)){const e=b.filter(t=>this.unravelSection.mutableSegmentPointIds.has(t)&&!this.unravelSection.zLockedSegmentPointIds.has(t));e.length>0&&n.push({type:"change_layer",newZ:t,segmentPointIds:e})}const S=this.dedupedSegmentMap.get(a.segmentId),I=this.dedupedSegmentMap.get(c.segmentId),M=this.dedupedSegmentMap.get(h.segmentId),_=this.dedupedSegmentMap.get(l.segmentId),N=(t,e)=>t.every(t=>t.availableZ.includes(e));if(d&&u&&!g&&!m){const e=0===a.z?1:0;N([S,I],e)&&n.push({type:"change_layer",newZ:e,segmentPointIds:[t,o]})}if(p&&f&&!y&&!x){const t=0===h.z?1:0;N([M,_],t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[i,s]})}if(d&&!g){const e=0===a.z?1:0;S.availableZ.includes(e)&&n.push({type:"change_layer",newZ:e,segmentPointIds:[t]})}if(u&&!m){const t=0===c.z?1:0;I.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[o]})}if(p&&!y){const t=0===h.z?1:0;M.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[i]})}if(f&&!x){const t=0===l.z?1:0;_.availableZ.includes(t)&&n.push({type:"change_layer",newZ:t,segmentPointIds:[s]})}}return n}computeG(t){const{issues:e,originalCandidate:n,operationsPerformed:o,operation:i}=t,s=new Map;for(const t of e){s.has(t.capacityMeshNodeId)||s.set(t.capacityMeshNodeId,{numTransitionCrossings:0,numSameLayerCrossings:0,numEntryExitLayerChanges:0});const e=s.get(t.capacityMeshNodeId);"transition_via"===t.type?e.numTransitionCrossings++:"same_layer_crossing"===t.type?e.numSameLayerCrossings++:"double_transition_crossing"===t.type||"single_transition_crossing"===t.type?e.numEntryExitLayerChanges++:t.type}let r=0;for(const[t,{numEntryExitLayerChanges:e,numSameLayerCrossings:n,numTransitionCrossings:o}]of s){const i=this.nodeMap.get(t),s=Math.min(Dh(i,n,e,o),.999999);r+=Math.log(1-s)}var a;return(a=r)<-Math.LN2?Math.log(1-Math.exp(a)):Math.log(-Math.expm1(a))}getUnexploredNeighborByApplyingOperation(t,e){const n=new Map(t.pointModifications);Nd(n,e,e=>this.getPointInCandidate(t,e));const o=Id(n);if(this.queuedOrExploredCandidatePointModificationHashes.has(o))return null;const i=_d(this.unravelSection,this.nodeMap,n),s=t.operationsPerformed+1,r=this.computeG({issues:i,originalCandidate:t,operationsPerformed:s,operation:e});return{issues:i,g:r,h:0,f:r,pointModifications:n,candidateHash:o,operationsPerformed:s}}getNeighborOperationsForCandidate(t){return t.issues.flatMap(e=>this.getOperationsForIssue(t,e))}getNeighbors(t){const e=[],n=this.getNeighborOperationsForCandidate(t);for(const o of n){const n=this.getUnexploredNeighborByApplyingOperation(t,o);n&&e.push(n)}return e}_step(){const t=this.candidates.shift();this.iterationsSinceImprovement++,this.iterationsSinceImprovement>this.hyperParameters.MAX_ITERATIONS_WITHOUT_IMPROVEMENT?this.solved=!0:t?(this.lastProcessedCandidate=t,t.f<(this.bestCandidate?.f??1/0)&&(this.bestCandidate=t,this.iterationsSinceImprovement=0),this.getNeighbors(t).forEach(t=>{this.queuedOrExploredCandidatePointModificationHashes.has(t.candidateHash)||(this.queuedOrExploredCandidatePointModificationHashes.add(t.candidateHash),this.candidates.push(t))}),this.candidates.sort((t,e)=>t.f-e.f),this.candidates.length=Math.min(this.candidates.length,this.MAX_CANDIDATES)):this.solved=!0}visualize(){const t={points:[],lines:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Unravel Section Solver"};let e=null;if(e=null!==this.selectedCandidateIndex?"best"===this.selectedCandidateIndex?this.bestCandidate:"original"===this.selectedCandidateIndex?this.originalCandidate:this.candidates[this.selectedCandidateIndex]:this.solved?this.bestCandidate:this.lastProcessedCandidate||this.candidates[0],!e)return t;const n=new Map;for(const[t,o]of this.unravelSection.segmentPointMap){const i={...o},s=e.pointModifications.get(t);s&&(void 0!==s.x&&(i.x=s.x),void 0!==s.y&&(i.y=s.y),void 0!==s.z&&(i.z=s.z)),n.set(t,i)}for(const[e,o]of n)t.points.push({x:o.x,y:o.y,label:`${e}\nSegment: ${o.segmentId} ${this.unravelSection.mutableSegmentIds.has(o.segmentId)?"MUTABLE":"IMMUTABLE"}\nLayer: ${o.z}`,color:this.colorMap[o.connectionName]||"#000"});const o=new Map;for(const t of this.unravelSection.allNodeIds)o.set(t,{numTransitionCrossings:0,numSameLayerCrossings:0,numEntryExitLayerChanges:0,estPf:0});for(const t of e.issues){const e=o.get(t.capacityMeshNodeId);"transition_via"===t.type?e.numTransitionCrossings++:"same_layer_crossing"===t.type?e.numSameLayerCrossings++:"double_transition_crossing"!==t.type&&"single_transition_crossing"!==t.type||e.numEntryExitLayerChanges++}for(const[t,e]of o.entries()){const n=this.nodeMap.get(t);e.estPf=Dh(n,e.numSameLayerCrossings,e.numEntryExitLayerChanges,e.numTransitionCrossings)}for(const e of this.unravelSection.allNodeIds){const n=this.nodeMap.get(e),i=this.unravelSection.mutableNodeIds.includes(e),s=o.get(e),r=[`${e} (${i?"MUT":"IMM"})`,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`Pf: ${s.estPf.toFixed(3)}`,`TC: ${s.numTransitionCrossings}`,`SLC: ${s.numSameLayerCrossings}`,`EELC: ${s.numEntryExitLayerChanges}`].join("\n");t.rects.push({center:n.center,label:r,color:i?"green":"red",width:n.width/8,height:n.height/8})}for(const[e,o]of this.unravelSection.segmentPointsInSegment){if(o.length<=1)continue;const i=o.map(t=>n.get(t));for(let n=0;n<i.length-1;n++)t.lines.push({points:[{x:i[n].x,y:i[n].y},{x:i[n+1].x,y:i[n+1].y}],strokeColor:this.colorMap[e]||"#000"})}for(const[e,o]of n)for(const i of o.directlyConnectedSegmentPointIds)if(e<i){const e=n.get(i);if(!e)continue;const s=o.z===e.z,r=o.z;let a;a=s?0===r?void 0:"10 5":"3 3 10",t.lines.push({points:[{x:o.x,y:o.y},{x:e.x,y:e.y}],strokeDash:a,strokeColor:this.colorMap[o.connectionName]||"#000"})}for(const o of e.issues){const e=this.nodeMap.get(o.capacityMeshNodeId);if("transition_via"===o.type)for(const i of o.segmentPoints){const o=n.get(i);t.circles.push({center:{x:o.x,y:o.y},radius:e.width/16,stroke:"#ff0000",fill:"rgba(255, 0, 0, 0.2)",label:`Via Issue\n${i}\nLayer: ${o.z}`})}else if("same_layer_crossing"===o.type)for(const[i,s]of[o.crossingLine1,o.crossingLine2]){const o=n.get(i),r=n.get(s);t.lines.push({points:[{x:o.x,y:o.y},{x:r.x,y:r.y}],strokeColor:"rgba(255,0,0,0.2)",strokeWidth:e.width/32})}}for(const[o,i]of e.pointModifications){const e=n.get(o),i=this.unravelSection.segmentPointMap.get(o);t.circles.push({center:{x:e.x,y:e.y},radius:.05,stroke:"#0000ff",fill:"rgba(0, 0, 255, 0.2)",label:`${o}\nOriginal: (${i.x.toFixed(2)}, ${i.y.toFixed(2)}, ${i.z})\nNew: (${e.x.toFixed(2)}, ${e.y.toFixed(2)}, ${e.z})`})}return t}};import Ed from"object-hash";var wd=t=>(Math.round(20*t)/20).toFixed(2),Rd=t=>(Math.round(1e3*t)/1e3).toFixed(3);Ie();var Od=class extends Td{cacheHit=!1;cacheProvider;hasAttemptedToUseCache=!1;constructor(t){super(t),this.cacheProvider=void 0===t.cacheProvider?Pe():t.cacheProvider}_step(){!this.hasAttemptedToUseCache&&this.cacheProvider&&this.attemptToUseCacheSync()||(super._step(),(this.solved||this.failed)&&this.cacheProvider&&this.saveToCacheSync())}computeCacheKeyAndTransform(){const t=this.nodeMap.get(this.rootNodeId),e=y(-t.center.x,-t.center.y),n=new Map,o=new Map,i=new Map,s=new Map,r=new Map,a=new Map;let c=0,h=0,l=0;const d=[...this.unravelSection.allNodeIds].sort((t,e)=>{const n=this.nodeMap.get(t),o=this.nodeMap.get(e);return n.center.x!==o.center.x?n.center.x-o.center.x:n.center.y-o.center.y});for(const t of d){const e="node_"+c++;n.set(t,e),o.set(e,t)}const u=[...Array.from(this.unravelSection.segmentPointMap.entries()).sort(([,t],[,e])=>t.x!==e.x?t.x-e.x:t.y-e.y).map(([t])=>t)].sort();for(const t of u){const e="sp_"+l++;r.set(t,e),a.set(e,t);const n=this.unravelSection.segmentPointMap.get(t).segmentId;if(!i.has(n)){const t="seg_"+h++;i.set(n,t),s.set(t,n)}}const p={};for(const[t,o]of n.entries()){const n=this.nodeMap.get(t),i=m(e,n.center);p[o]={width:n.width,height:n.height,availableZ:n.availableZ,center:{x:wd(i.x),y:wd(i.y)}}}const f={};for(const[t,n]of r.entries()){const o=this.unravelSection.segmentPointMap.get(t),i=m(e,{x:o.x,y:o.y});f[n]={x:wd(i.x),y:wd(i.y),z:o.z}}const g={hyperParameters:this.hyperParameters,normalizedNodes:p,normalizedSegmentPoints:f,mutableHops:this.MUTABLE_HOPS},x=`unravelsec:${Ed(g)}`,v={realToCacheTransform:e,nodeIdMap:n,segmentIdMap:i,segmentPointIdMap:r,reverseNodeIdMap:o,reverseSegmentIdMap:s,reverseSegmentPointIdMap:a};return this.cacheKey=x,this.cacheToSolveSpaceTransform=v,{cacheKey:x,cacheToSolveSpaceTransform:v}}applyCachedSolution(t){if(!1===t.success)return void(this.failed=!0);if(!this.cacheToSolveSpaceTransform)return void console.error("Cache transform not available to apply cached solution.");const{reverseSegmentPointIdMap:e,reverseNodeIdMap:n}=this.cacheToSolveSpaceTransform,o=new Map;for(const[n,i]of t.bestCandidatePointModificationsDelta){const t=e.get(n);if(!t){console.warn(`Could not find original ID for normalized SP ID: ${n} when applying cache.`);continue}const s=this.unravelSection.segmentPointMap.get(t);if(!s){console.warn(`Could not find original segment point for ID: ${t} when applying cache.`);continue}const r={};if(void 0!==i.dx){const t=parseFloat(i.dx);Number.isNaN(t)?console.warn(`Failed to parse cached dx coordinate: ${i.dx}`):r.x=s.x+t}if(void 0!==i.dy){const t=parseFloat(i.dy);Number.isNaN(t)?console.warn(`Failed to parse cached dy coordinate: ${i.dy}`):r.y=s.y+t}void 0!==i.dz&&(r.z=s.z+i.dz),Object.keys(r).length>0&&o.set(t,r)}const i=_d(this.unravelSection,this.nodeMap,o);this.bestCandidate={pointModifications:o,issues:i,f:t.bestCandidateF,g:t.bestCandidateF,h:0,operationsPerformed:-1,candidateHash:Id(o)},this.cacheHit=!0,this.solved=!0}attemptToUseCacheSync(){if(this.hasAttemptedToUseCache=!0,!this.cacheProvider?.isSyncCache)return console.log("Cache provider is not synchronous, skipping sync cache check."),!1;if(this.cacheKey||this.computeCacheKeyAndTransform(),!this.cacheKey)return console.error("Failed to compute cache key."),!1;try{const t=this.cacheProvider.getCachedSolutionSync(this.cacheKey);if(t)return this.applyCachedSolution(t),!0}catch(t){console.error("Error attempting to use cache:",t)}return!1}saveToCacheSync(){if(this.failed)return void this.cacheProvider?.setCachedSolutionSync(this.cacheKey,{success:!1});if(!this.bestCandidate)return;const{segmentPointIdMap:t}=this.cacheToSolveSpaceTransform,e=[];for(const[n,o]of this.bestCandidate.pointModifications.entries()){const i=t.get(n);if(!i){console.warn(`Could not find normalized ID for original SP ID: ${n} when saving to cache.`);continue}const s=this.unravelSection.segmentPointMap.get(n);if(!s){console.warn(`Could not find original segment point for ID: ${n} when saving cache.`);continue}const r={};let a=!1;if(void 0!==o.x){const t=o.x-s.x,e=Rd(t);0!==parseFloat(e)&&(r.dx=e,a=!0)}if(void 0!==o.y){const t=o.y-s.y,e=Rd(t);0!==parseFloat(e)&&(r.dy=e,a=!0)}if(void 0!==o.z){const t=o.z-s.z;0!==t&&(r.dz=t,a=!0)}a&&e.push([i,r])}const n={success:!0,bestCandidatePointModificationsDelta:e,bestCandidateF:this.bestCandidate.f};this.cacheProvider?.setCachedSolutionSync(this.cacheKey,n)}},Ad=class extends Dn{getSolverName(){return"UnravelMultiSectionSolver"}nodeMap;dedupedSegmentMap;dedupedSegments;nodeIdToSegmentIds;segmentIdToNodeIds;nodeToSegmentPointMap;segmentToSegmentPointMap;colorMap;tunedNodeCapacityMap;MAX_NODE_ATTEMPTS=2;MUTABLE_HOPS=1;ACCEPTABLE_PF=.05;MAX_ITERATIONS_WITHOUT_IMPROVEMENT=200;nodePfMap;attemptsToFixNode;activeSubSolver=null;segmentPointMap;cacheProvider=null;constructor({assignedSegments:t,colorMap:e,nodes:n,cacheProvider:o}){super(),this.stats.successfulOptimizations=0,this.stats.failedOptimizations=0,this.stats.cacheHits=0,this.stats.cacheMisses=0,this.cacheProvider=o??null,this.MAX_ITERATIONS=1e6,this.dedupedSegments=(t=>{const e=[],n=new Map;let o=-1;for(const i of t){const t=`${i.start.x}-${i.start.y}-${i.end.x}-${i.end.y}-${i.availableZ.join(",")}`,s=n.get(t);s?i.nodePortSegmentId=s.nodePortSegmentId:(o++,i.nodePortSegmentId=`SEG${o}`,n.set(t,i),e.push(i))}return e})(t),this.dedupedSegmentMap=new Map;for(const t of this.dedupedSegments)this.dedupedSegmentMap.set(t.nodePortSegmentId,t);this.nodeMap=new Map;for(const t of n)this.nodeMap.set(t.capacityMeshNodeId,t);this.nodeIdToSegmentIds=new Map,this.segmentIdToNodeIds=new Map,this.attemptsToFixNode=new Map;for(const e of t)this.segmentIdToNodeIds.set(e.nodePortSegmentId,[...this.segmentIdToNodeIds.get(e.nodePortSegmentId)??[],e.capacityMeshNodeId]),this.nodeIdToSegmentIds.set(e.capacityMeshNodeId,[...this.nodeIdToSegmentIds.get(e.capacityMeshNodeId)??[],e.nodePortSegmentId]);this.colorMap=e??{},this.tunedNodeCapacityMap=new Map;for(const[t,e]of this.nodeMap)this.tunedNodeCapacityMap.set(t,Ah(e));const{segmentPointMap:i,nodeToSegmentPointMap:s,segmentToSegmentPointMap:r}=Cd(this.dedupedSegments,this.segmentIdToNodeIds);this.segmentPointMap=i,this.nodeToSegmentPointMap=s,this.segmentToSegmentPointMap=r,this.nodePfMap=this.computeInitialPfMap()}computeInitialPfMap(){const t=new Map;for(const[e,n]of this.nodeMap.entries())t.set(e,this.computeNodePf(n));return t}computeNodePf(t){const{numSameLayerCrossings:e,numEntryExitLayerChanges:n,numTransitionCrossings:o}=(t=>{let e=0,n=0,o=0;const i=new Map;for(const e of t)i.has(e.connectionName)||i.set(e.connectionName,[]),i.get(e.connectionName).push(e);const s=[],r=[];for(const[t,e]of i.entries()){if(e.length<2)continue;const o=e[0];for(let i=1;i<e.length;i++){const a=e[i],c={connectionName:t,z:o.z,points:[o,a]};o.z!==a.z?(n++,r.push({connectionName:t,points:[o,a]})):s.push(c)}}for(let t=0;t<s.length;t++)for(let n=t+1;n<s.length;n++){const o=s[t],i=s[n];o.z===i.z&&D(o.points[0],o.points[1],i.points[0],i.points[1])&&e++}for(let t=0;t<r.length;t++)for(let e=t+1;e<r.length;e++){const n=r[t],i=r[e];D(n.points[0],n.points[1],i.points[0],i.points[1])&&o++}for(let t=0;t<r.length;t++)for(let e=0;e<s.length;e++){const n=r[t],i=s[e];D(n.points[0],n.points[1],i.points[0],i.points[1])&&o++}return{numSameLayerCrossings:e,numEntryExitLayerChanges:n,numTransitionCrossings:o}})((this.nodeToSegmentPointMap.get(t.capacityMeshNodeId)??[]).map(t=>this.segmentPointMap.get(t)));return Dh(t,e,n,o)}_step(){if(this.iterations>=this.MAX_ITERATIONS-1)return void(this.solved=!0);if(!this.activeSubSolver){let t=null,e=0;for(const[n,o]of this.nodePfMap.entries()){o*(1-(this.attemptsToFixNode.get(n)??0)/this.MAX_NODE_ATTEMPTS)>e&&(e=o,t=n)}if(!t||e<this.ACCEPTABLE_PF)return void(this.solved=!0);this.attemptsToFixNode.set(t,(this.attemptsToFixNode.get(t)??0)+1),this.activeSubSolver=new Od({dedupedSegments:this.dedupedSegments,dedupedSegmentMap:this.dedupedSegmentMap,nodeMap:this.nodeMap,nodeIdToSegmentIds:this.nodeIdToSegmentIds,segmentIdToNodeIds:this.segmentIdToNodeIds,colorMap:this.colorMap,rootNodeId:t,MUTABLE_HOPS:this.MUTABLE_HOPS,segmentPointMap:this.segmentPointMap,nodeToSegmentPointMap:this.nodeToSegmentPointMap,segmentToSegmentPointMap:this.segmentToSegmentPointMap,cacheProvider:this.cacheProvider})}this.activeSubSolver.step();const{bestCandidate:t,originalCandidate:e,lastProcessedCandidate:n}=this.activeSubSolver;if(this.activeSubSolver.failed)return this.stats.failedOptimizations+=1,void(this.activeSubSolver=null);if(this.activeSubSolver.solved){this.activeSubSolver.cacheHit?this.stats.cacheHits+=1:this.stats.cacheMisses+=1;if(t&&t.g<e.g){this.stats.successfulOptimizations+=1;for(const[e,n]of t.pointModifications.entries()){const t=this.segmentPointMap.get(e);t.x=n.x??t.x,t.y=n.y??t.y,t.z=n.z??t.z}for(const t of this.activeSubSolver.unravelSection.allNodeIds)this.nodePfMap.set(t,this.computeNodePf(this.nodeMap.get(t)))}else this.stats.failedOptimizations+=1;this.activeSubSolver=null}}visualize(){if(this.activeSubSolver)return this.activeSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:"Unravel Multi Section Solver"};for(const[e,n]of this.nodeMap.entries()){const o=this.nodePfMap.get(e)||0,i=Math.min(o,1),s=`rgb(${Math.floor(255*i)}, ${Math.floor(255*(1-i))}, 0)`;0===(this.attemptsToFixNode.get(e)??0)&&0===i||t.rects.push({center:n.center,label:[e,`${n.width.toFixed(2)}x${n.height.toFixed(2)}`,`Pf: ${o.toFixed(3)}`].join("\n"),color:s,width:n.width/8,height:n.height/8})}for(const e of this.segmentPointMap.values()){const n=this.dedupedSegmentMap.get(e.segmentId);t.points.push({x:e.x,y:e.y,label:[e.segmentPointId,e.segmentId,`z: ${e.z}`,`segment.availableZ: ${n?.availableZ.join(",")}`].join("\n"),color:this.colorMap[e.connectionName]||"#000"})}const e=new Map;for(const t of this.segmentPointMap.values())e.has(t.segmentId)||e.set(t.segmentId,[]),e.get(t.segmentId).push(t);for(const[n,o]of e.entries()){if(o.length<2)continue;const e=[...o].sort((t,e)=>t.x!==e.x?t.x-e.x:t.y-e.y);for(let o=0;o<e.length-1;o++)t.lines.push({points:[{x:e[o].x,y:e[o].y},{x:e[o+1].x,y:e[o+1].y}],strokeColor:this.colorMap[n]||"#000"})}const n=new Set,o=Array.from(this.segmentPointMap.values());for(let e=0;e<o.length;e++){const i=o[e];for(let s=e+1;s<o.length;s++){const e=o[s];if(i.connectionName!==e.connectionName||i.segmentId===e.segmentId)continue;if(i.capacityMeshNodeIds.some(t=>e.capacityMeshNodeIds.includes(t))){const o=`${i.segmentPointId}-${e.segmentPointId}`;if(n.has(o))continue;n.add(o);const s=i.z===e.z,r=i.z;let a;a=s?0===r?void 0:"10 5":"3 3 10",t.lines.push({points:[{x:i.x,y:i.y},{x:e.x,y:e.y}],strokeDash:a,strokeColor:this.colorMap[i.connectionName]||"#666"})}}}return t}getNodesWithPortPoints(){if(!this.solved)throw new Error("CapacitySegmentToPointSolver not solved, can't give port points yet");const t=new Map;for(const e of this.dedupedSegments){const n=e.nodePortSegmentId;for(const e of this.segmentIdToNodeIds.get(n)){const n=this.nodeMap.get(e);t.has(e)||t.set(e,{capacityMeshNodeId:e,portPoints:[],center:n.center,width:n.width,height:n.height})}}for(const e of this.segmentPointMap.values())for(const n of e.capacityMeshNodeIds){const o=t.get(n);o&&o.portPoints.push({x:e.x,y:e.y,z:e.z,connectionName:e.connectionName,rootConnectionName:e.rootConnectionName})}return Array.from(t.values())}};function zd(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var Dd=class extends Dn{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),s=n.targetMinCapacity??.5;n.capacityDepth=zh(i,s)}this.connMap=zn(t),this.colorMap=In(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AutoroutingPipeline1_OriginalUnravel"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;initialPathingSolver;pathingOptimizer;edgeToPortSegmentSolver;colorMap;segmentToPointSolver;unravelMultiSectionSolver;segmentToPointOptimizer;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;viaDiameter;minTraceWidth;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[zd("netToPointPairsSolver",sl,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=In(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),zd("nodeSolver",Kl,t=>[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.finishedNodes}}),zd("singleLayerNodeMerger",bd,t=>[t.nodeSolver?.finishedNodes],{onSolved:t=>{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),zd("strawSolver",Pd,t=>[{nodes:t.singleLayerNodeMerger?.newNodes}],{onSolved:t=>{t.capacityNodes=t.strawSolver?.getResultNodes()}}),zd("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),zd("deadEndSolver",yd,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=>{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=>!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=>t.nodeIds.every(t=>!e.has(t)))}}),zd("initialPathingSolver",od,t=>[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}]),zd("pathingOptimizer",md,t=>[{initialPathingSolver:t.initialPathingSolver,simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,cacheProvider:t.cacheProvider,hyperParameters:{MAX_CAPACITY_FACTOR:1}}]),zd("edgeToPortSegmentSolver",Vl,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.pathingOptimizer?.getCapacityPaths()||[],colorMap:t.colorMap}]),zd("segmentToPointSolver",Ql,t=>{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments&&t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=>{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),zd("unravelMultiSectionSolver",Ad,t=>[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),zd("highDensityRouteSolver",Nh,t=>[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),zd("highDensityStitchSolver",xd,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),zd("traceSimplificationSolver",kl,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),s=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.initialPathingSolver?.visualize(),c=this.pathingOptimizer?.visualize(),h=this.edgeToPortSegmentSolver?.visualize(),l=this.segmentToPointSolver?.visualize(),d=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),u=this.highDensityRouteSolver?.visualize(),p=this.highDensityStitchSolver?.visualize(),f=this.traceSimplificationSolver?.visualize(),g=this.srj.outline,m=[];if(m.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),g&&g.length>=2){const t=g.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),m.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const y={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:m},x=[y,t,e,n,o,i,s,r,a,c,h,l,d,u?Bn(y,u):null,p,f,this.solved?Bn(y,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...x)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path&&t.push({points:e.path.map(t=>({x:t.center.x,y:t.center.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const o=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const s=i[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.rootConnectionName??n.name,route:De(s,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}};function Ld(t){const{pos:e,segments:n,dir:o,keepoutRadius:i}=t;let s=1/0;const r=i/4,a={x:e.x-o.x*r,y:e.y-o.y*r},c={x:e.x+o.x*r,y:e.y+o.y*r};for(const t of n){const e=J(a,c,t.start,t.end);s=Math.min(s,e)}return s}function Yd(t,e,n,o){const i=Xd(n,o,t),s=Xd(n,o,e),r=Xd(t,e,n),a=Xd(t,e,o);if((i>0&&s<0||i<0&&s>0)&&(r>0&&a<0||r<0&&a>0))return!0;const c=1e-4;return!!(Math.abs(i)<c&&Fd(n,o,t))||(!!(Math.abs(s)<c&&Fd(n,o,e))||(!!(Math.abs(r)<c&&Fd(t,e,n))||!!(Math.abs(a)<c&&Fd(t,e,o))))}function Xd(t,e,n){return(n.x-t.x)*(e.y-t.y)-(e.x-t.x)*(n.y-t.y)}function Fd(t,e,n){return n.x>=Math.min(t.x,e.x)-1e-4&&n.x<=Math.max(t.x,e.x)+1e-4&&n.y>=Math.min(t.y,e.y)-1e-4&&n.y<=Math.max(t.y,e.y)+1e-4}function kd(t,e,n){for(const o of n)if(Yd(t,e,o.start,o.end))return!1;return!0}var $d=1e-4;function Bd(t){const e=t.width/2,n=t.height/2,o=t.center.x,i=t.center.y,s={x:o-e,y:i+n},r={x:o+e,y:i+n},a={x:o-e,y:i-n},c={x:o+e,y:i-n};return[{start:s,end:r},{start:r,end:c},{start:c,end:a},{start:a,end:s}]}function jd(t,e,n=.1){const o=e.x-t.x,i=e.y-t.y,s=Math.sqrt(o*o+i*i);if(0===s)return[];const r=-(i/s),a=o/s,c=n/2;return[{start:{x:t.x+r*c,y:t.y+a*c},end:{x:e.x+r*c,y:e.y+a*c}},{start:{x:t.x-r*c,y:t.y-a*c},end:{x:e.x-r*c,y:e.y-a*c}}]}function Wd(t,e,n){const o=Math.hypot(t.start.x-e.x,t.start.y-e.y),i=Math.hypot(t.end.x-e.x,t.end.y-e.y);if(o<=n||i<=n)return!0;const s=t.end.x-t.start.x,r=t.end.y-t.start.y,a=s*s+r*r;if(0===a)return!1;const c=Math.max(0,Math.min(1,((e.x-t.start.x)*s+(e.y-t.start.y)*r)/a)),h=t.start.x+c*s,l=t.start.y+c*r;return Math.hypot(h-e.x,l-e.y)<=n}function Vd(t,e,n){if(!n||0===n.length)return!1;for(const o of n){const n=Math.abs(t.x-o.start.x)<$d&&Math.abs(t.y-o.start.y)<$d&&Math.abs(e.x-o.end.x)<$d&&Math.abs(e.y-o.end.y)<$d,i=Math.abs(t.x-o.end.x)<$d&&Math.abs(t.y-o.end.y)<$d&&Math.abs(e.x-o.start.x)<$d&&Math.abs(e.y-o.start.y)<$d;if(n||i)return!0}return!1}function Hd(t,e,n,o,i){const s=[];for(let r=0;r<t.length-1;r++){const a=t[r],c=t[r+1];Vd(a,c,i)||Wd({start:a,end:c},n,o+e)&&s.push(...jd(a,c,e))}return s}var Ud=1e-4;function Gd(t,e,n,o){const i=e.x-t.x,s=e.y-t.y,r=o.x-n.x,a=o.y-n.y,c=i*a-s*r;if(Math.abs(c)<1e-10)return null;const h=n.x-t.x,l=n.y-t.y,d=(h*a-l*r)/c,u=(h*s-l*i)/c,p=1e-6;return d>p&&d<.999999&&u>p&&u<.999999?{x:t.x+d*i,y:t.y+d*s}:null}function Zd(t,e){if(!e||0===e.length)return!1;for(const n of e)if(Math.abs(t.x-n.start.x)<Ud&&Math.abs(t.y-n.start.y)<Ud||Math.abs(t.x-n.end.x)<Ud&&Math.abs(t.y-n.end.y)<Ud)return!0;return!1}function qd(t,e,n,o){if(!o||0===o.length)return!1;for(let i=e;i<=n;i++)if(i>=0&&i<t.length&&Zd(t[i],o))return!0;return!1}var Jd=1e-4,Kd=class extends Dn{constructor(t){super(),this.input=t;const e=t.srj?.layerCount??2;this.input={...t,obstacles:Ml(t.obstacles,e)},this.MAX_ITERATIONS=1e6,this.originalHdRoutes=[...this.input.hdRoutes],this.hdRoutes=this.input.hdRoutes,this.KEEPOUT_RADIUS_SCHEDULE=t.keepoutRadiusSchedule??[.3,.5,.5],this.currentKeepoutRadius=this.KEEPOUT_RADIUS_SCHEDULE[0]??.15,this.unprocessedRoutes=[...this.hdRoutes],this.smoothedCursorRoutes=[...this.unprocessedRoutes];const n=[...this.input.obstacles,...this.getJumperPadObstacles()];this.obstacleSHI=new ml("flatbush",n),this.boardOutlineRoutes=this.createBoardOutlineRoutes(),this.hdRouteSHI=new Sl([...this.hdRoutes,...this.boardOutlineRoutes]);for(const[t,e,n]of this.hdRoutes.flatMap(t=>[[t.route[0],t.connectionName,t.rootConnectionName],[t.route[t.route.length-1],t.connectionName,t.rootConnectionName]])){const o=this.obstacleSHI.searchArea(t.x,t.y,.01,.01).filter(e=>e.zLayers?.includes(t.z));if(0===o.length)continue;const i=o[0];this.input.connMap.addConnections([[e,n,...i.offBoardConnectsTo??[],i.obstacleId,...i.connectedTo].filter(Boolean)])}}getSolverName(){return"TraceKeepoutSolver"}originalHdRoutes;hdRoutes;redrawnHdRoutes=[];KEEPOUT_RADIUS_SCHEDULE;currentScheduleIndex=0;currentKeepoutRadius;unprocessedRoutes=[];smoothedCursorRoutes=[];processedRoutes=[];currentTrace=null;cursorPosition=null;lastCursorPosition=null;drawPosition=null;currentTraceSegmentIndex=0;currentTraceSegmentT=0;recordedDrawPositions=[];lastCollidingSegments=[];currentTraceJumperSegments=new Map;obstacleSHI;hdRouteSHI;boardOutlineRoutes=[];getSmoothDistance(){return this.currentKeepoutRadius}getJumperPadObstacles(){const t=[];if(!this.input.jumpers)return t;for(const e of this.input.jumpers)for(const n of e.pads)t.push({...n,zLayers:[0]});return t}buildJumperSegmentMap(t){const e=new Map;if(!t.jumpers||0===t.jumpers.length)return e;const n=t.route;for(const o of t.jumpers){let t=-1,i=1/0;for(let e=0;e<n.length-1;e++){const s=n[e],r=n[e+1],a=Math.sqrt((s.x-o.start.x)**2+(s.y-o.start.y)**2),c=Math.sqrt((r.x-o.end.x)**2+(r.y-o.end.y)**2),h=a+c,l=Math.sqrt((s.x-o.end.x)**2+(s.y-o.end.y)**2),d=Math.sqrt((r.x-o.start.x)**2+(r.y-o.start.y)**2),u=l+d,p=Math.min(h,u);(h<=u?a:l)<1&&(h<=u?c:d)<1&&p<i&&(i=p,t=e)}t>=0&&e.set(t,o)}return e}_step(){if(!this.currentTrace){const t=this.unprocessedRoutes.shift();if(!t)return this.currentScheduleIndex++,this.currentScheduleIndex<this.KEEPOUT_RADIUS_SCHEDULE.length?(this.currentKeepoutRadius=this.KEEPOUT_RADIUS_SCHEDULE[this.currentScheduleIndex],this.unprocessedRoutes=Un([...this.processedRoutes],this.currentScheduleIndex),this.smoothedCursorRoutes=[...this.unprocessedRoutes],this.processedRoutes=[],void(this.hdRouteSHI=new Sl([...this.unprocessedRoutes,...this.boardOutlineRoutes]))):(this.redrawnHdRoutes=this.processedRoutes,void(this.solved=!0));if(this.currentTrace=t,this.currentTrace.route.length<2)return this.processedRoutes.push(this.currentTrace),void(this.currentTrace=null);this.currentTraceJumperSegments=this.buildJumperSegmentMap(this.currentTrace);const e=this.currentTrace.route[0];return this.cursorPosition={...e},this.lastCursorPosition={...e},this.drawPosition={x:e.x,y:e.y},this.currentTraceSegmentIndex=0,this.currentTraceSegmentT=0,void(this.recordedDrawPositions=[{...e}])}this.lastCursorPosition={...this.cursorPosition};const t=this.stepCursorForward();if("end"===t)return void this.finalizeCurrentTrace();if("jumper"===t)return void(this.drawPosition={x:this.cursorPosition.x,y:this.cursorPosition.y});const e=this.getCollidingSegments(this.cursorPosition);this.lastCollidingSegments=e;const n=function(t){const{cursorPosition:e,lastCursorPosition:n,collidingSegments:o,keepoutRadius:i}=t;if(0===o.length)return null;const s=1e-4,r=e.x-n.x,a=e.y-n.y,c=Math.sqrt(r*r+a*a),h=c>s?{x:r/c,y:a/c}:{x:1,y:0},l=-h.y,d=h.x,u=Ld({pos:e,segments:o,dir:h,keepoutRadius:i});if(u>=i)return null;for(let t=1;t<=20;t++){const n=t/20*i,s={x:e.x+l*n,y:e.y+d*n},r=Ld({pos:s,segments:o,dir:h,keepoutRadius:i}),a={x:e.x-l*n,y:e.y-d*n},c=Ld({pos:a,segments:o,dir:h,keepoutRadius:i}),u=r>=i&&kd(e,s,o),p=c>=i&&kd(e,a,o);if(u&&p)return r>=c?s:a;if(u)return s;if(p)return a}const p=i,f=[];for(let t=-60;t<=60;t++){const n=t/60*p,s={x:e.x+l*n,y:e.y+d*n},r=Ld({pos:s,segments:o,dir:h,keepoutRadius:i}),a=kd(e,s,o);f.push({pos:s,clearance:r,dist:Math.abs(n),pathClear:a,index:t})}const g=f.filter(t=>t.pathClear),m=f.findIndex(t=>0===t.index),y=m>=0?m:Math.floor(f.length/2);let x=null;for(let t=y+1;t<f.length-1;t++){const e=f[t-1],n=f[t],o=f[t+1];if(n.clearance>=e.clearance&&n.clearance>=o.clearance){x=n;break}}let v=null;for(let t=y-1;t>0;t--){const e=f[t-1],n=f[t],o=f[t+1];if(n.clearance>=e.clearance&&n.clearance>=o.clearance){v=n;break}}let b=null,P=null;if(g.length>0){const t=g.findIndex(t=>0===t.index),e=t>=0?t:Math.floor(g.length/2);for(let t=e+1;t<g.length-1;t++){const e=g[t-1],n=g[t],o=g[t+1];if(n.clearance>=e.clearance&&n.clearance>=o.clearance){b=n;break}}for(let t=e-1;t>0;t--){const e=g[t-1],n=g[t],o=g[t+1];if(n.clearance>=e.clearance&&n.clearance>=o.clearance){P=n;break}}}const S=[x,v,b,P,f.find(t=>0===t.index)].filter(t=>null!=t),I=new Set,M=S.filter(t=>{const e=`${t.pos.x.toFixed(6)},${t.pos.y.toFixed(6)}`;return!I.has(e)&&(I.add(e),!0)});if(0===M.length){let t=f[0];if(!t)return null;for(const e of f)e.clearance>t.clearance&&(t=e);return Math.sqrt((t.pos.x-e.x)**2+(t.pos.y-e.y)**2)>s?t.pos:null}let _;if(u<.15*i){_=M[0];for(const t of M)t.clearance>_.clearance&&(_=t)}else{const t=M.filter(t=>t.pathClear),e=t.length>0?t:M;_=e[0];for(const t of e)t.clearance>_.clearance&&(_=t)}return Math.sqrt((_.pos.x-e.x)**2+(_.pos.y-e.y)**2)>s?_.pos:null}({cursorPosition:this.cursorPosition,lastCursorPosition:this.lastCursorPosition,collidingSegments:e,keepoutRadius:this.currentKeepoutRadius});this.drawPosition=n??{...this.cursorPosition};const o=this.recordedDrawPositions[this.recordedDrawPositions.length-1];if(o&&this.drawPosition){const t={x:o.x,y:o.y,z:o.z},e={x:this.drawPosition.x,y:this.drawPosition.y,z:this.cursorPosition.z};this.segmentIntersectsOtherRoutes(t,e)&&(this.drawPosition={...this.cursorPosition})}this.recordedDrawPositions.push({x:this.drawPosition.x,y:this.drawPosition.y,z:this.cursorPosition.z})}getStepDistance(){return this.currentKeepoutRadius/2}getJumperAtCurrentSegmentStart(){return this.currentTraceSegmentT>Jd?null:this.currentTraceJumperSegments.get(this.currentTraceSegmentIndex)??null}stepCursorForward(){if(!this.currentTrace||!this.cursorPosition)return"end";const t=this.currentTrace.route;let e=this.getStepDistance();for(;e>0;){if(this.currentTraceSegmentIndex>=t.length-1)return"end";const n=this.getJumperAtCurrentSegmentStart();if(n){const e=t[this.currentTraceSegmentIndex],o=t[this.currentTraceSegmentIndex+1],i=Math.sqrt((e.x-n.start.x)**2+(e.y-n.start.y)**2),s=Math.sqrt((e.x-n.end.x)**2+(e.y-n.end.y)**2),r=i<=s?n.start:n.end,a=i<=s?n.end:n.start;return this.recordedDrawPositions.push({x:r.x,y:r.y,z:e.z,insideJumperPad:!0}),this.recordedDrawPositions.push({x:a.x,y:a.y,z:o.z,insideJumperPad:!0}),this.cursorPosition={x:a.x,y:a.y,z:o.z},this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,"jumper"}const o=t[this.currentTraceSegmentIndex],i=t[this.currentTraceSegmentIndex+1],s=i.x-o.x,r=i.y-o.y,a=Math.sqrt(s*s+r*r);if(0===a){this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0;continue}const c=this.currentTraceSegmentT*a,h=a-c;if(e<=h){const t=c+e;return this.currentTraceSegmentT=t/a,this.cursorPosition={x:o.x+s*this.currentTraceSegmentT,y:o.y+r*this.currentTraceSegmentT,z:o.z},"stepped"}if(e-=h,this.currentTraceSegmentIndex++,this.currentTraceSegmentT=0,this.currentTraceSegmentIndex>=t.length-1){const e=t[t.length-1];return this.cursorPosition={...e},"end"}}return"stepped"}getCollidingSegments(t){if(!this.currentTrace)return[];const e=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,n=2*this.currentKeepoutRadius,o=[],i=this.obstacleSHI.searchArea(t.x,t.y,n,n).filter(e=>e.zLayers?.includes(t.z));for(const n of i){if(n.zLayers&&!n.zLayers.includes(t.z))continue;if(n.connectedTo.includes(e))continue;if(n.obstacleId&&this.input.connMap.areIdsConnected(e,n.obstacleId))continue;let i=!1;for(const t of n.connectedTo)if(this.input.connMap.areIdsConnected(e,t)){i=!0;break}i||o.push(...Bd(n))}const s=this.hdRouteSHI.getConflictingRoutesNearPoint({x:t.x,y:t.y,z:t.z},n);for(const{conflictingRoute:i}of s){const s=i.rootConnectionName??i.connectionName;if(s===e)continue;if(this.input.connMap.areIdsConnected(e,s))continue;const r=i.traceThickness??.15;o.push(...Hd(i.route,r,{x:t.x,y:t.y},n,i.jumpers))}return o}positionHasCollision(t,e=0){const n=this.getCollidingSegments(t);for(const o of n)if(X(t,o.start,o.end)<=this.currentKeepoutRadius+e)return!0;return!1}segmentIntersectsOtherRoutes(t,e){if(!this.currentTrace)return!1;const n=this.currentTrace.rootConnectionName??this.currentTrace.connectionName,o=[...this.unprocessedRoutes,...this.smoothedCursorRoutes,...this.processedRoutes];for(const i of o){if((i.rootConnectionName??i.connectionName)!==n)for(let n=0;n<i.route.length-1;n++){const o=i.route[n],s=i.route[n+1];if((o.z===t.z||s.z===t.z)&&((!o.insideJumperPad||!s.insideJumperPad)&&D({x:t.x,y:t.y},{x:e.x,y:e.y},{x:o.x,y:o.y},{x:s.x,y:s.y})))return!0}}return!1}finalizeCurrentTrace(){if(!this.currentTrace)return;const t=this.currentTrace.route[this.currentTrace.route.length-1],e=this.recordedDrawPositions[this.recordedDrawPositions.length-1];e&&e.x===t.x&&e.y===t.y||this.recordedDrawPositions.push({...t});const n=function(t,e){if(t.length<4)return t;let n=[...t],o=!0;for(;o;){o=!1;for(let t=0;t<n.length-1&&!o;t++){const i=n[t],s=n[t+1];if(i.z===s.z)for(let r=t+2;r<n.length-1&&!o;r++){if(r===t+1)continue;const a=n[r],c=n[r+1];if(a.z!==c.z||i.z!==a.z)continue;const h=Gd(i,s,a,c);if(h){if(qd(n,t+1,r,e))continue;const s=[];for(let e=0;e<=t;e++)s.push(n[e]);s.push({x:h.x,y:h.y,z:i.z});for(let t=r+1;t<n.length;t++)s.push(n[t]);n=s,o=!0}}}}return n}(this.simplifyRoute(this.recordedDrawPositions,this.currentTrace.jumpers),this.currentTrace.jumpers),o={connectionName:this.currentTrace.connectionName,rootConnectionName:this.currentTrace.rootConnectionName,traceThickness:this.currentTrace.traceThickness,viaDiameter:this.currentTrace.viaDiameter,route:n,vias:[...this.currentTrace.vias],jumpers:this.currentTrace.jumpers};this.processedRoutes.push(o),this.hdRouteSHI.removeRoute(this.currentTrace.connectionName),this.hdRouteSHI.addRoute(o),this.currentTrace=null,this.cursorPosition=null,this.lastCursorPosition=null,this.drawPosition=null,this.recordedDrawPositions=[]}isJumperEndpoint(t,e){if(!e||0===e.length)return!1;for(const n of e)if(Math.abs(t.x-n.start.x)<Jd&&Math.abs(t.y-n.start.y)<Jd||Math.abs(t.x-n.end.x)<Jd&&Math.abs(t.y-n.end.y)<Jd)return!0;return!1}simplifyRoute(t,e){if(t.length<=2)return t;const n=[t[0]];for(let o=1;o<t.length-1;o++){const i=n[n.length-1],s=t[o],r=t[o+1];if(this.isJumperEndpoint(s,e)){n.push(s);continue}if(s.z!==i.z||s.z!==r.z){n.push(s);continue}const a=s.x-i.x,c=s.y-i.y,h=r.x-s.x,l=a*(r.y-s.y)-c*h,d=1e-6;Math.abs(l)>d&&n.push(s)}return n.push(t[t.length-1]),n}createBoardOutlineRoutes(){const t=[];if(!this.input.srj)return t;const{outline:e,bounds:n}=this.input.srj;let o;o=e&&e.length>=3?e:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}];const i=this.input.srj.layerCount??2;for(let e=0;e<o.length;e++){const n=o[e],s=o[(e+1)%o.length];for(let o=0;o<i;o++)t.push({connectionName:`__board_outline___${e}_z${o}`,traceThickness:.01,viaDiameter:0,route:[{x:n.x,y:n.y,z:o},{x:s.x,y:s.y,z:o}],vias:[]})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[],coordinateSystem:"cartesian",title:`Trace Keepout Solver (radius: ${this.currentKeepoutRadius.toFixed(2)})`};for(const e of this.originalHdRoutes)if(0!==e.route.length)for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];o.z===i.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:"rgba(0,0,0,0.25)",strokeWidth:1.5*(e.traceThickness??.15)})}if(this.input.jumpers)for(const e of this.input.jumpers){for(const n of e.pads){const e=n.connectedTo.length>0?n.connectedTo.join(", "):"unused",o=n.connectedTo.length>0?this.input.colorMap[n.connectedTo[0]]||"#888888":"rgba(128, 128, 128, 0.5)";t.rects.push({center:n.center,width:n.width,height:n.height,fill:o,stroke:"rgba(0, 0, 0, 0.5)",label:`Jumper pad (${e})`})}e.pads.length>=2&&t.lines.push({points:[e.pads[0].center,e.pads[1].center],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.2,label:"Jumper body"})}for(const e of this.input.obstacles){let n="rgba(128, 128, 128, 0.2)";const o=e.zLayers?.includes(0),i=e.zLayers?.includes(1);o&&i?n="rgba(128, 0, 128, 0.2)":o?n="rgba(255, 0, 0, 0.2)":i&&(n="rgba(0, 0, 255, 0.2)"),t.rects.push({center:e.center,width:e.width,height:e.height,fill:n,label:`Obstacle (Z: ${e.zLayers?.join(", ")})`})}if(this.input.srj){const{outline:e,bounds:n}=this.input.srj;let o;o=e&&e.length>=3?e:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY}];for(let e=0;e<o.length;e++){const n=o[e],i=o[(e+1)%o.length];t.lines.push({points:[{x:n.x,y:n.y},{x:i.x,y:i.y}],strokeColor:"rgba(0, 128, 0, 0.6)",strokeWidth:.1,label:"Board outline"})}}for(const e of this.processedRoutes){if(0===e.route.length)continue;const n=this.input.colorMap[e.connectionName]||"#888888",o=new Set;if(e.jumpers&&e.jumpers.length>0)for(const t of e.jumpers)for(let n=0;n<e.route.length-1;n++){const i=e.route[n],s=e.route[n+1],r=Math.abs(i.x-t.start.x)<Jd&&Math.abs(i.y-t.start.y)<Jd&&Math.abs(s.x-t.end.x)<Jd&&Math.abs(s.y-t.end.y)<Jd,a=Math.abs(i.x-t.end.x)<Jd&&Math.abs(i.y-t.end.y)<Jd&&Math.abs(s.x-t.start.x)<Jd&&Math.abs(s.y-t.start.y)<Jd;if(r||a){o.add(n);break}}for(let n=0;n<e.route.length-1;n++){const i=e.route[n],s=e.route[n+1];o.has(n)?t.lines.push({points:[{x:i.x,y:i.y},{x:s.x,y:s.y}],strokeColor:"rgba(128, 128, 128, 0.6)",strokeDash:"2 2",label:`${e.connectionName} (jumper segment - fixed)`}):i.z===s.z&&t.lines.push({points:[{x:i.x,y:i.y},{x:s.x,y:s.y}],strokeColor:0===i.z?"red":"blue",strokeWidth:e.traceThickness,label:`${e.connectionName} (z=${i.z})`})}for(const n of e.vias)t.circles.push({center:{x:n.x,y:n.y},radius:e.viaDiameter/2,fill:"rgba(255, 0, 255, 0.5)",label:`${e.connectionName} via`});if(e.jumpers&&e.jumpers.length>0){const o=cl(e.jumpers,{color:n,label:e.connectionName});t.rects.push(...o.rects??[]),t.lines.push(...o.lines??[])}}if(this.currentTrace&&this.recordedDrawPositions.length>0){this.input.colorMap[this.currentTrace.connectionName];for(let e=0;e<this.recordedDrawPositions.length-1;e++){const n=this.recordedDrawPositions[e],o=this.recordedDrawPositions[e+1];t.lines.push({points:[{x:n.x,y:n.y},{x:o.x,y:o.y}],strokeColor:"green",strokeWidth:this.currentTrace.traceThickness})}if(this.cursorPosition&&(t.circles.push({center:{x:this.cursorPosition.x,y:this.cursorPosition.y},radius:this.currentKeepoutRadius,stroke:"orange",fill:"none"}),t.points.push({x:this.cursorPosition.x,y:this.cursorPosition.y,color:"orange",label:"Cursor"}),this.lastCursorPosition)){const e=this.cursorPosition.x-this.lastCursorPosition.x,n=this.cursorPosition.y-this.lastCursorPosition.y,o=Math.sqrt(e*e+n*n),i=o>1e-4?{x:e/o,y:n/o}:{x:1,y:0},s=this.currentKeepoutRadius/4,r={x:this.cursorPosition.x-i.x*s,y:this.cursorPosition.y-i.y*s},a={x:this.cursorPosition.x+i.x*s,y:this.cursorPosition.y+i.y*s};t.lines.push({points:[r,a],strokeColor:"cyan",strokeWidth:.05,label:"Projected segment"})}this.drawPosition&&t.points.push({x:this.drawPosition.x,y:this.drawPosition.y,color:"lime",label:"Draw"});for(const e of this.lastCollidingSegments)t.lines.push({points:[{x:e.start.x,y:e.start.y},{x:e.end.x,y:e.end.y}],strokeColor:"rgba(255, 0, 255, 0.8)",strokeWidth:.02,label:"Colliding segment"})}if(!this.solved)for(const e of this.smoothedCursorRoutes)if(0!==e.route.length)for(let n=0;n<e.route.length-1;n++){const o=e.route[n],i=e.route[n+1];o.z===i.z&&t.lines.push({points:[{x:o.x,y:o.y},{x:i.x,y:i.y}],strokeColor:"gray"})}return t}getRedrawnHdRoutes(){return this.redrawnHdRoutes}},Qd=class extends Dn{constructor(t){super(),this.input=t,this.unprocessedObstacles=Ml(this.input.srj.obstacles,this.input.srj.layerCount).filter(t=>t.offBoardConnectsTo&&t.offBoardConnectsTo.length>0),this.unprocessedObstacles.forEach((t,e)=>{t.obstacleId=t.obstacleId??`__obs${e}`}),this.offBoardConnMap=new rl({}),this.offBoardConnMap.addConnections(this.unprocessedObstacles.filter(t=>t.offBoardConnectsTo?.length).map(t=>[t.obstacleId,...t.offBoardConnectsTo??[]])),this.nodeTree=new kn(this.input.capacityMeshNodes)}getSolverName(){return"RelateNodesToOffBoardConnectionsSolver"}unprocessedObstacles;nodeTree;offBoardConnMap;nodesInNet=new Map;lastProcessedObstacle;_step(){const t=this.unprocessedObstacles.pop();if(this.lastProcessedObstacle=t,!t)return void(this.solved=!0);const e=this.offBoardConnMap.getNetConnectedToId(t.obstacleId),n=this.nodeTree.getNodesInArea(t.center.x,t.center.y,.01,.01).filter(e=>e.availableZ.some(e=>t.zLayers?.includes(e))).filter(e=>Math.abs(e.center.x-t.center.x)<.01&&Math.abs(e.center.y-t.center.y)<.01),o=n.map(t=>t.capacityMeshNodeId),i=this.nodesInNet.get(e)??[],s=[...i.map(t=>t.capacityMeshNodeId),...o];for(const t of i)t._offBoardConnectedCapacityMeshNodeIds=s;for(const t of n)t._offBoardConnectedCapacityMeshNodeIds=s,t._offBoardConnectionId=e;this.nodesInNet.set(e,[...i,...n])}getOutput(){return{capacityNodes:this.input.capacityMeshNodes}}visualize(){const t={rects:[],lines:[],points:[],circles:[]},e=new Set;for(const[t,n]of this.nodesInNet)for(const t of n)e.add(t.capacityMeshNodeId);for(const n of this.input.capacityMeshNodes)e.has(n.capacityMeshNodeId)||t.rects.push({center:n.center,width:n.width-.1,height:n.height-.1,fill:"rgba(0, 0, 0, 0.2)"});this.lastProcessedObstacle&&t.rects.push({center:this.lastProcessedObstacle.center,width:this.lastProcessedObstacle.width,height:this.lastProcessedObstacle.height,fill:"rgba(255, 0, 0, 0.5)"});for(const[e,n]of this.nodesInNet.entries()){for(const o of n)t.rects.push({center:o.center,width:o.width,height:o.height,fill:_n(e,.2),label:`OffBoardConn: ${e}`});for(const o of n)for(const i of n)o.capacityMeshNodeId!==i.capacityMeshNodeId&&t.lines.push({points:[o.center,i.center],strokeColor:_n(e,1)})}return t}},tu=.1,eu=.1;function nu(t,e,n,o,i,s){return(i-t)*(o-e)-(s-e)*(n-t)}function ou(t,e,n,o,i,s){return Math.min(t,n)<=i&&i<=Math.max(t,n)&&Math.min(e,o)<=s&&s<=Math.max(e,o)}function iu(t,e,n,o,i,s,r,a){const c=nu(i,s,r,a,t,e),h=nu(i,s,r,a,n,o),l=nu(t,e,n,o,i,s),d=nu(t,e,n,o,r,a);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)||(!(0!==c||!ou(i,s,r,a,t,e))||(!(0!==h||!ou(i,s,r,a,n,o))||(!(0!==l||!ou(t,e,n,o,i,s))||!(0!==d||!ou(t,e,n,o,r,a)))))}function su(t,e,n,o,i,s){const r=i-n,a=s-o,c=t-n,h=e-o,l=r*r+a*a;if(0===l){return{x:n,y:o,distSq:c*c+h*h}}let d=(c*r+h*a)/l;d=Math.max(0,Math.min(1,d));const u=n+d*r,p=o+d*a,f=t-u,g=e-p;return{x:u,y:p,distSq:f*f+g*g}}var ru=class extends Dn{getSolverName(){return"SimpleHighDensitySolver"}unsolvedNodes;allNodes;routes;colorMap;traceWidth;viaDiameter;numMovablePoints;currentNode=null;lastNode=null;currentNodeStep=0;routesInProgress=[];pushMargin;currentNodeBounds=null;constructor({nodePortPoints:t,colorMap:e,traceWidth:n=.1,viaDiameter:o=.3,pushMargin:i=.3,numMovablePoints:s=2}){if(super(),s<1||s>3)throw new Error(`numMovablePoints must be 1, 2, or 3, got ${s}`);this.allNodes=[...t],this.unsolvedNodes=[...t],this.colorMap=e??{},this.routes=[],this.traceWidth=n,this.viaDiameter=o,this.numMovablePoints=s,this.pushMargin=i,this.MAX_ITERATIONS=10*t.length+1}_step(){if(null===this.currentNode){if(0===this.unsolvedNodes.length)return void(this.solved=!0);this.lastNode=this.currentNode,this.currentNode=this.unsolvedNodes.pop(),this.currentNodeStep=0,this.routesInProgress=[],this._initializeRoutesForCurrentNode()}this.currentNodeStep>0&&this._runForceDirectedStep(),this.currentNodeStep++,this.currentNodeStep>=10&&(this._finalizeRoutesForCurrentNode(),this.lastNode=this.currentNode,this.currentNode=null)}_initializeRoutesForCurrentNode(){const t=this.currentNode,e=t.center.x-t.width/2,n=t.center.x+t.width/2,o=t.center.y-t.height/2,i=t.center.y+t.height/2;this.currentNodeBounds={minX:e,maxX:n,minY:o,maxY:i};const s=new Map;for(const e of t.portPoints)s.has(e.connectionName)||s.set(e.connectionName,[]),s.get(e.connectionName).push({x:e.x,y:e.y,z:e.z,rootConnectionName:e.rootConnectionName});for(const[t,e]of s){if(e.length<2)continue;const n=e[0],o=e[e.length-1],i=n.z,s=o.x-n.x,r=o.y-n.y,a=Math.sqrt(s*s+r*r),c=a>0?s/a:0,h=a>0?r/a:0,l=[];this.numMovablePoints>=1&&l.push({x:n.x+c*eu,y:n.y+h*eu,z:i,rootConnectionName:n.rootConnectionName,connectionName:t}),this.numMovablePoints>=2&&l.push({x:o.x-c*eu,y:o.y-h*eu,z:i,rootConnectionName:n.rootConnectionName,connectionName:t}),this.numMovablePoints>=3&&l.push({x:n.x+s/2,y:n.y+r/2,z:i,rootConnectionName:n.rootConnectionName,connectionName:t}),this.routesInProgress.push({connectionName:t,rootConnectionName:n.rootConnectionName,startPoint:{x:n.x,y:n.y,z:i},endPoint:{x:o.x,y:o.y,z:i},movablePoints:l})}}_runForceDirectedStep(){const t=this.currentNodeBounds,e=[];for(const t of this.routesInProgress)e.push(...t.movablePoints);const n=new Map;for(const t of e)n.set(t,{fx:0,fy:0});const o=.3+this.pushMargin,i=new Map;for(const t of this.routesInProgress){const e=[{x:t.startPoint.x,y:t.startPoint.y,movablePoint:null}];1===t.movablePoints.length?e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}):2===t.movablePoints.length?(e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}),e.push({x:t.movablePoints[1].x,y:t.movablePoints[1].y,movablePoint:t.movablePoints[1]})):3===t.movablePoints.length&&(e.push({x:t.movablePoints[0].x,y:t.movablePoints[0].y,movablePoint:t.movablePoints[0]}),e.push({x:t.movablePoints[2].x,y:t.movablePoints[2].y,movablePoint:t.movablePoints[2]}),e.push({x:t.movablePoints[1].x,y:t.movablePoints[1].y,movablePoint:t.movablePoints[1]})),e.push({x:t.endPoint.x,y:t.endPoint.y,movablePoint:null}),i.set(t,e)}for(const s of e){const e=n.get(s),r=s.x-t.minX,a=t.maxX-s.x,c=t.maxY-s.y,h=s.y-t.minY;r<o&&(e.fx+=tu*(o-r)),a<o&&(e.fx-=tu*(o-a)),h<o&&(e.fy+=tu*(o-h)),c<o&&(e.fy-=tu*(o-c));for(const t of this.routesInProgress){if(t.rootConnectionName===s.rootConnectionName)continue;const r=i.get(t);for(let t=0;t<r.length-1;t++){const i=r[t],a=r[t+1],c=su(s.x,s.y,i.x,i.y,a.x,a.y),h=Math.sqrt(c.distSq);if(h>0&&h<2*o){const t=s.x-c.x,o=s.y-c.y,r=.002/c.distSq,h=r*t,l=r*o;e.fx+=h,e.fy+=l;const d=i.movablePoint,u=a.movablePoint;if(d&&u){const t=n.get(d),e=n.get(u);t.fx-=h/2,t.fy-=l/2,e.fx-=h/2,e.fy-=l/2}else if(d){const t=n.get(d);t.fx-=h,t.fy-=l}else if(u){const t=n.get(u);t.fx-=h,t.fy-=l}}}}}const s=t=>t.movablePoint?{x:t.movablePoint.x,y:t.movablePoint.y}:{x:t.x,y:t.y},r=t=>{let e=null;for(const n of this.routesInProgress)if(n.movablePoints.includes(t)){e=n;break}if(!e)return!1;const n=i.get(e);let o=-1;for(let e=0;e<n.length;e++)if(n[e].movablePoint===t){o=e;break}if(-1===o)return!1;const r=[];if(o>0){const e=s(n[o-1]);r.push({ax:e.x,ay:e.y,bx:t.x,by:t.y})}if(o<n.length-1){const e=s(n[o+1]);r.push({ax:t.x,ay:t.y,bx:e.x,by:e.y})}for(const t of this.routesInProgress){if(t.rootConnectionName===e.rootConnectionName)continue;const n=i.get(t);for(let t=0;t<n.length-1;t++){const e=s(n[t]),o=s(n[t+1]);for(const t of r)if(iu(t.ax,t.ay,t.bx,t.by,e.x,e.y,o.x,o.y))return!0}}return!1};for(const o of e){const e=n.get(o);o.forceX=e.fx,o.forceY=e.fy;const i=o.x,s=o.y;o.x+=e.fx,o.y+=e.fy,o.x=Math.max(t.minX,Math.min(t.maxX,o.x)),o.y=Math.max(t.minY,Math.min(t.maxY,o.y)),r(o)&&(o.x=i,o.y=s)}}_finalizeRoutesForCurrentNode(){for(const t of this.routesInProgress){const{connectionName:e,rootConnectionName:n,startPoint:o,endPoint:i,movablePoints:s}=t,r=[{x:o.x,y:o.y,z:o.z}];1===s.length?r.push({x:s[0].x,y:s[0].y,z:s[0].z}):2===s.length?(r.push({x:s[0].x,y:s[0].y,z:s[0].z}),r.push({x:s[1].x,y:s[1].y,z:s[1].z})):3===s.length&&(r.push({x:s[0].x,y:s[0].y,z:s[0].z}),r.push({x:s[2].x,y:s[2].y,z:s[2].z}),r.push({x:s[1].x,y:s[1].y,z:s[1].z})),r.push({x:i.x,y:i.y,z:i.z});const a={connectionName:e,rootConnectionName:n,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:r,vias:[]};this.routes.push(a)}this.routesInProgress=[]}_getNodeBounds(t){return{minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2}}visualize(){const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.unsolvedNodes){if(e===this.currentNode)continue;const n=this._getNodeBounds(e);t.rects.push({center:{x:(n.minX+n.maxX)/2,y:(n.minY+n.maxY)/2},width:n.maxX-n.minX,height:n.maxY-n.minY,fill:"rgba(0, 0, 0, 0.08)",stroke:"rgba(0, 0, 0, 0.2)",label:e.capacityMeshNodeId})}if(this.lastNode){const e=this._getNodeBounds(this.lastNode);t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(0, 200, 0, 0.15)",stroke:"rgba(0, 0, 255, 0.6)"})}if(this.currentNode){const e=this._getNodeBounds(this.currentNode);t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(0, 200, 0, 0.15)",stroke:"rgba(0, 200, 0, 0.6)"})}for(const e of this.unsolvedNodes){const n=new Map;for(const t of e.portPoints)n.has(t.connectionName)||n.set(t.connectionName,[]),n.get(t.connectionName).push({x:t.x,y:t.y});for(const[e,o]of n)o.length<2||t.lines.push({points:o.map(t=>({x:t.x,y:t.y})),label:e,strokeColor:"gray",strokeWidth:this.traceWidth})}for(const e of this.routes){const n=jn(e.route,e.connectionName,this.colorMap[e.connectionName]);for(const o of n)t.lines.push({points:o.points,label:o.connectionName,strokeColor:0===o.z?o.color:Mn(o.color,.75),layer:`z${o.z}`,strokeWidth:e.traceThickness,strokeDash:0!==o.z?"10, 5":void 0});const o=e.route;for(let e=0;e<o.length;e++){const n=o[e],i=0===e,s=e===o.length-1,r=!i&&!s;let a;a=i?"start":s?"end":`M${e}`,t.points.push({x:n.x,y:n.y,label:a,color:r?"orange":"blue"})}}for(const e of this.routesInProgress){const{startPoint:n,endPoint:o,movablePoints:i,connectionName:s}=e,r=this.colorMap[s]??"gray",a=[{x:n.x,y:n.y}];1===i.length?a.push({x:i[0].x,y:i[0].y}):2===i.length?(a.push({x:i[0].x,y:i[0].y}),a.push({x:i[1].x,y:i[1].y})):3===i.length&&(a.push({x:i[0].x,y:i[0].y}),a.push({x:i[2].x,y:i[2].y}),a.push({x:i[1].x,y:i[1].y})),a.push({x:o.x,y:o.y}),t.lines.push({points:a,label:s,strokeColor:r,strokeWidth:this.traceWidth}),t.points.push({x:n.x,y:n.y,label:"start",color:"blue"});for(let e=0;e<i.length;e++){const n=i[e];if(t.points.push({x:n.x,y:n.y,label:`M${e+1}`,color:"orange"}),void 0!==n.forceX&&void 0!==n.forceY){if(Math.sqrt(n.forceX*n.forceX+n.forceY*n.forceY)>.001){const o=5;t.lines.push({points:[{x:n.x,y:n.y},{x:n.x+n.forceX*o,y:n.y+n.forceY*o}],strokeColor:"red",strokeWidth:.02,label:`F${e+1}`});const i=.05,s=n.x+n.forceX*o,r=n.y+n.forceY*o,a=Math.atan2(n.forceY,n.forceX);t.lines.push({points:[{x:s,y:r},{x:s-i*Math.cos(a-Math.PI/6),y:r-i*Math.sin(a-Math.PI/6)}],strokeColor:"red",strokeWidth:.02}),t.lines.push({points:[{x:s,y:r},{x:s-i*Math.cos(a+Math.PI/6),y:r-i*Math.sin(a+Math.PI/6)}],strokeColor:"purple",strokeWidth:.02})}}}t.points.push({x:o.x,y:o.y,label:"end",color:"blue"})}return t}},au=({connMap:t,connectionsWithResults:e,inputNodes:n,obstacles:o})=>{const i=o.filter(t=>t.offBoardConnectsTo?.length);if(0===i.length)return;const s=new On({});s.addConnections(i.map((t,e)=>[t.obstacleId??`__obs${e}`,...t.offBoardConnectsTo??[]]));const r=new Map(n.map(t=>[t.capacityMeshNodeId,t]));for(const n of e){if(!n.path)continue;const e=n.connection.rootConnectionName??n.connection.name,o=new Set;for(const t of n.path){const e=r.get(t.currentNodeId);if(e?._offBoardConnectionId&&o.add(e._offBoardConnectionId),t.throughNodeId){const e=r.get(t.throughNodeId);e?._offBoardConnectionId&&o.add(e._offBoardConnectionId)}}for(const n of o){const o=s.getIdsConnectedToNet(n);o?.length&&t.addConnections([[e,...o]])}}};function cu(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var hu=class extends Dn{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),s=n.targetMinCapacity??.5;n.capacityDepth=zh(i,s)}this.connMap=zn(t),this.colorMap=In(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline2"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;relateNodesToOffBoardConnections;colorMap;highDensityRouteSolver;simpleHighDensityRouteSolver;highDensitySolver;highDensityStitchSolver;singleLayerNodeMerger;offboardPathFragmentSolver;strawSolver;deadEndSolver;traceSimplificationSolver;traceKeepoutSolver;traceWidthSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[cu("netToPointPairsSolver",il,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=In(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),cu("nodeSolver",ye,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),cu("relateNodesToOffBoardConnections",Qd,t=>[{capacityMeshNodes:t.capacityNodes,srj:t.srj}],{onSolved:t=>{t.capacityNodes=t.relateNodesToOffBoardConnections?.getOutput().capacityNodes}}),cu("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),cu("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),cu("portPointPathingSolver",Gh,t=>{const e=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle,_offBoardConnectionId:t._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t._offBoardConnectedCapacityMeshNodeIds})),n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),o=t.availableSegmentPointSolver;for(const t of o.sharedEdgeSegments)for(const e of t.portPoints){const[o,i]=e.nodeIds,s={portPointId:e.segmentPortPointId,x:e.x,y:e.y,z:e.availableZ[0]??0,connectionNodeIds:[o,i],distToCentermostPortOnZ:e.distToCentermostPortOnZ,connectsToOffBoardNode:t.nodeIds.some(t=>n.get(t)?._offBoardConnectionId)},r=n.get(o);r&&r.portPoints.push(s)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:100*t.effort,hyperParameters:{JUMPER_PF_FN_ENABLED:!1,NODE_PF_FACTOR:100,NODE_PF_MAX_PENALTY:100,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,FORCE_CENTER_FIRST:!0}}]},{onSolved:t=>{const e=t.portPointPathingSolver;e&&au({connMap:t.connMap,connectionsWithResults:e.connectionsWithResults,inputNodes:e.inputNodes,obstacles:t.srj.obstacles})}}),cu("multiSectionPortPointOptimizer",Jh,t=>{const e=t.portPointPathingSolver;return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e.inputNodes,capacityMeshNodes:t.capacityNodes,capacityMeshEdges:t.capacityEdges,colorMap:t.colorMap,initialConnectionResults:e.connectionsWithResults,initialAssignedPortPoints:e.assignedPortPoints,initialNodeAssignedPortPoints:e.nodeAssignedPortPoints}]}),cu("highDensitySolver",ru,t=>[{nodePortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,connMap:t.connMap}]),cu("highDensityStitchSolver",pl,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensitySolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),cu("traceSimplificationSolver",kl,t=>[{hdRoutes:t.highDensityStitchSolver?.mergedHdRoutes??t.highDensitySolver?.routes??t.highDensityRouteSolver?.routes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),cu("traceKeepoutSolver",Kd,t=>[{hdRoutes:t.traceSimplificationSolver?.simplifiedHdRoutes??[],obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,srj:t.srj}]),cu("traceWidthSolver",$l,t=>[{hdRoutes:t.traceKeepoutSolver?.redrawnHdRoutes??[],connection:t.srj.connections,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),s=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.offboardPathFragmentSolver?.visualize(),h=this.portPointPathingSolver?.visualize(),l=this.multiSectionPortPointOptimizer?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensitySolver?.visualize(),p=this.simpleHighDensityRouteSolver?.visualize(),f=this.highDensityStitchSolver?.visualize(),g=this.traceSimplificationSolver?.visualize(),m=this.traceKeepoutSolver?.visualize(),y=this.traceWidthSolver?.visualize(),x=this.srj.outline,v=[];if(v.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),x&&x.length>=2){const t=x.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const b={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:["obstacle",t.offBoardConnectsTo?`offboardConnections: ${t.offBoardConnectsTo?.join(", ")}`:"",t.layers?.join(", ")].filter(Boolean).join("\n")}))],lines:v},P=[b,t,e,n,o,i,s,r,a,c,h,l,d?Bn(b,d):null,u?Bn(b,u):null,p?Bn(b,p):null,f,g,m,y,this.solved?Bn(b,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...P)}preview(){const t=this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes;if(t){const e=[];for(let n=t.length-1;n>=0;n--){const o=t[n];if(e.push({points:o.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[o.connectionName]}),e.length>200)break}return{lines:e}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.hdRoutesWithWidths??this.traceKeepoutSolver?.redrawnHdRoutes??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver?.mergedHdRoutes??this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes}getConnectedOffboardObstacles(){const t={},e=new Set(this.srj.connections.map(t=>t.rootConnectionName??t.name));for(const[n,o]of this.srj.obstacles.entries()){if(!o.offBoardConnectsTo?.length)continue;const i=o.obstacleId??`__obs${n}`,s=this.connMap.getNetConnectedToId(i);if(!s)continue;const r=this.connMap.getIdsConnectedToNet(s).find(t=>e.has(t));r&&(t[i]=r)}return t}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver&&!this.simpleHighDensityRouteSolver&&!this.highDensitySolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const o=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const s=i[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.rootConnectionName??n.name,route:De(s,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},lu=class extends Dn{getSolverName(){return"MultipleHighDensityRouteStitchSolver2"}unsolvedRoutes;mergedHdRoutes=[];colorMap={};defaultTraceThickness;defaultViaDiameter;constructor(t){super(),this.colorMap=t.colorMap??{};const e=t.hdRoutes[0];this.defaultTraceThickness=e?.traceThickness??.15,this.defaultViaDiameter=e?.viaDiameter??t.defaultViaDiameter??.3;const n=new Map;for(const e of t.connectionPathResults)n.set(e.connection.name,e);const o=new Map;for(const e of t.hdRoutes){const t=o.get(e.connectionName);t?t.push(e):o.set(e.connectionName,[e])}this.unsolvedRoutes=[];for(const[e,i]of o.entries()){const o=t.connections.find(t=>t.name===e);if(!o)continue;const s=n.get(e);let r=[];s?.path&&(r=s.path.map(t=>t.currentNodeId));const a={...o.pointsToConnect[0],z:wn(Cn(o.pointsToConnect[0]),t.layerCount)},c={...o.pointsToConnect[1],z:wn(Cn(o.pointsToConnect[1]),t.layerCount)};this.unsolvedRoutes.push({connectionName:e,hdRoutes:i,nodeOrder:r,start:a,end:c})}this.MAX_ITERATIONS=1e5}_step(){const t=this.unsolvedRoutes.pop();if(!t)return void(this.solved=!0);const e=this.stitchOrderedRoutes(t);this.mergedHdRoutes.push(e)}stitchOrderedRoutes(t){const{connectionName:e,hdRoutes:n,nodeOrder:o,start:i,end:s}=t;if(0===n.length)return{connectionName:e,traceThickness:this.defaultTraceThickness,viaDiameter:this.defaultViaDiameter,route:[i,s],vias:[],jumpers:[]};let r;r=o.length>0?this.orderRoutesByNodePath(n,o,i,e):this.orderRoutesByProximity(n,i);const a=[],c=[],h=[];a.push({x:i.x,y:i.y,z:i.z});for(let t=0;t<r.length;t++){const e=r[t],n=a[a.length-1],o=e.route[0],i=e.route[e.route.length-1],s=F(n,o),l=F(n,i),d=Math.min(s,l);if(t>0&&d>1)continue;let u;u=s<=l?[...e.route]:[...e.route].reverse();const p=.001;u.length>0&&F(n,u[0])<p&&(u=u.slice(1)),a.push(...u),c.push(...e.vias),e.jumpers&&h.push(...e.jumpers)}const l=F(a[a.length-1],s);return l>.001&&l<5&&a.push({x:s.x,y:s.y,z:s.z}),{connectionName:e,rootConnectionName:n[0]?.rootConnectionName,traceThickness:n[0]?.traceThickness??this.defaultTraceThickness,viaDiameter:n[0]?.viaDiameter??this.defaultViaDiameter,route:a,vias:c,jumpers:h}}orderRoutesByNodePath(t,e,n,o){if(0===t.length)return[];const i=new Set(t);let s=null,r=1/0;for(const t of i){const e=t.route[0],o=t.route[t.route.length-1],i=Math.min(F(n,e),F(n,o));i<r&&(r=i,s=t)}if(!s)return[];i.delete(s);const a=s.route[0],c=s.route[s.route.length-1];let h,l;F(n,a)<=F(n,c)?(h=a,l=c):(h=c,l=a);const d=(t,e)=>{let n=0;for(const o of i){if(o===e)continue;const i=o.route[0],s=o.route[o.route.length-1];(F(t,i)<10||F(t,s)<10)&&n++}return n},u=[s];let p=l;for(;i.size>0;){let t=null,e=1/0,n=-1;for(const o of i){const i=o.route[0],s=o.route[o.route.length-1],r=F(p,i),a=F(p,s),c=Math.min(r,a);if(c>=10)continue;const h=d(r<=a?s:i,o),l=0===h,u=0===n,f=c-e;let g=!1;g=null===t||(!!(!l&&u&&f<5)||!(l&&!u&&f>-5)&&c<e),g&&(e=c,t=o,n=h)}if(!t)break;{u.push(t),i.delete(t);const e=t.route[0],n=t.route[t.route.length-1];p=F(p,e)<=F(p,n)?n:e}}const f=[];for(p=h;i.size>0;){let t=null,e=1/0,o=-1;const s=F(p,n);for(const r of i){const i=r.route[0],a=r.route[r.route.length-1],c=F(p,i),h=F(p,a),l=Math.min(c,h);if(l>=10)continue;const u=c<=h?a:i;if(F(u,n)>s+2)continue;const f=d(u,r),g=0===f,m=0===o,y=l-e;let x=!1;x=null===t||(!!(!g&&m&&y<5)||!(g&&!m&&y>-5)&&l<e),x&&(e=l,t=r,o=f)}if(!t)break;{f.unshift(t),i.delete(t);const e=t.route[0],n=t.route[t.route.length-1];p=F(p,e)<=F(p,n)?n:e}}const g=[...f,...u];if(i.size>0){const e=[...i].map(t=>{const e=t.route[0],n=t.route[t.route.length-1];return`start=(${e.x.toFixed(2)},${e.y.toFixed(2)}) end=(${n.x.toFixed(2)},${n.y.toFixed(2)})`});console.warn(`[StitchSolver] Skipped ${i.size} routes for connection ${t[0]?.connectionName??"?"}, skipped routes: ${e.join("; ")}`)}return g}orderRoutesByProximity(t,e){const n=new Set(t),o=[];let i=e;for(;n.size>0;){let t=null,e=1/0,s=!1;for(const o of n){const n=o.route[0],r=o.route[o.route.length-1],a=F(i,n),c=F(i,r);a<e&&(e=a,t=o,s=!1),c<e&&(e=c,t=o,s=!0)}if(!t)break;{o.push(t),n.delete(t);const e=t.route[0],r=t.route[t.route.length-1];i=s?e:r}}return o}visualize(){const t={points:[],lines:[],circles:[],rects:[],title:"Multiple High Density Route Stitch Solver 2"};for(const[e,n]of this.mergedHdRoutes.entries()){const o=this.colorMap[n.connectionName]??`hsl(120, 100%, ${40+10*e%40}%)`;for(let e=0;e<n.route.length-1;e++){const i=n.route[e],s=n.route[e+1],r=0!==i.z?Mn(o,.5):o;t.lines?.push({points:[{x:i.x,y:i.y},{x:s.x,y:s.y}],strokeColor:r,strokeWidth:n.traceThickness})}for(const e of n.route){const n=0!==e.z?Mn(o,.5):o;t.points?.push({x:e.x,y:e.y,color:n})}for(const e of n.vias)t.circles?.push({center:{x:e.x,y:e.y},radius:n.viaDiameter/2,fill:o});if(n.jumpers&&n.jumpers.length>0){const e=cl(n.jumpers,{color:o,label:n.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}for(const e of this.unsolvedRoutes){const n=this.colorMap[e.connectionName]??"gray";t.points?.push({x:e.start.x,y:e.start.y,color:n,label:`${e.connectionName} Start`},{x:e.end.x,y:e.end.y,color:n,label:`${e.connectionName} End`});for(let o=0;o<e.hdRoutes.length;o++){const i=e.hdRoutes[o];if(i.route.length>1&&t.lines?.push({points:i.route.map(t=>({x:t.x,y:t.y})),strokeColor:Mn(n,.5),strokeDash:"10 5",label:`segment ${o}`}),i.jumpers&&i.jumpers.length>0){const e=cl(i.jumpers,{color:n,label:i.connectionName});t.rects.push(...e.rects??[]),t.lines.push(...e.lines??[])}}}return t}},du=Object.create,uu=Object.defineProperty,pu=Object.getOwnPropertyDescriptor,fu=Object.getOwnPropertyNames,gu=Object.getPrototypeOf,mu=Object.prototype.hasOwnProperty,yu=(t,e)=>function(){return e||(0,t[fu(t)[0]])((e={exports:{}}).exports,e),e.exports},xu=(t,e,n)=>(n=null!=t?du(gu(t)):{},((t,e,n,o)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let i of fu(e))mu.call(t,i)||i===n||uu(t,i,{get:()=>e[i],enumerable:!(o=pu(e,i))||o.enumerable});return t})(!e&&t&&t.__esModule?n:uu(n,"default",{value:t,enumerable:!0}),t)),vu=yu({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),bu=yu({"node_modules/kind-of/index.js"(t,e){var n=vu(),o=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=o.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),Pu=yu({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(n[e(o,t[o])||o]=t[o]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),Su=yu({"node_modules/deep-rename-keys/index.js"(t,e){var n=bu(),o=Pu();e.exports=function t(e,i){var s=n(e);if("object"!==s&&"array"!==s)throw new Error("expected an object");var r=[];for(var a in"object"===s&&(e=o(e,i),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,i):r[a]=c}return r}}}),Iu=yu({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,o="~";function i(){}function s(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(o=!1)),r.prototype.eventNames=function(){var t,e,i=[];if(0===this._eventsCount)return i;for(e in t=this._events)n.call(t,e)&&i.push(o?e.slice(1):e);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},r.prototype.listeners=function(t,e){var n=o?o+t:t,i=this._events[n];if(e)return!!i;if(!i)return[];if(i.fn)return[i.fn];for(var s=0,r=i.length,a=new Array(r);s<r;s++)a[s]=i[s].fn;return a},r.prototype.emit=function(t,e,n,i,s,r){var a=o?o+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,i),!0;case 5:return l.fn.call(l.context,e,n,i,s),!0;case 6:return l.fn.call(l.context,e,n,i,s,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,i);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var i=new s(e,n||this),r=o?o+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],i]:this._events[r].push(i):(this._events[r]=i,this._eventsCount++),this},r.prototype.once=function(t,e,n){var i=new s(e,n||this,!0),r=o?o+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],i]:this._events[r].push(i):(this._events[r]=i,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,s){var r=o?o+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new i:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||s&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new i:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||s&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new i:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=o?o+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new i:delete this._events[e])):(this._events=new i,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=o,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),Mu=yu({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var o=Iu(),i=function(){},s={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:s,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,g,m,y;t=Object.assign({debug:!1},t);var x=new o,v=s.data,b="",P="",S="",I="",M="",_="",N=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var o={type:e,value:n};t.debug&&console.log("emit:",o),x.emit("data",o)}};x.stateMachine=(n(y={},s.data,(n(e={},r.lt,function(){b.trim()&&N(a.text,b),P="",M=!1,v=s.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,s.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(N(a.text,b.slice(0,-3)),b="",v=s.data)})),n(y,s.tagBegin,(n(h={},r.space,i),n(h,r.char,function(t){P=t,v=s.tagName}),n(h,r.slash,function(){P="",M=!0}),h)),n(y,s.tagName,(n(l={},r.space,function(){M?v=s.tagEnd:(v=s.attributeNameStart,N(a.openTag,P))}),n(l,r.gt,function(){N(M?a.closeTag:a.openTag,P),b="",v=s.data}),n(l,r.slash,function(){v=s.tagEnd,N(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=s.cdata,b="",P="")}),l)),n(y,s.tagEnd,(n(d={},r.gt,function(){N(a.closeTag,P),b="",v=s.data}),n(d,r.char,i),d)),n(y,s.attributeNameStart,(n(u={},r.char,function(t){S=t,v=s.attributeName}),n(u,r.gt,function(){b="",v=s.data}),n(u,r.space,i),n(u,r.slash,function(){M=!0,v=s.tagEnd}),u)),n(y,s.attributeName,(n(p={},r.space,function(){v=s.attributeNameEnd}),n(p,r.equal,function(){N(a.attributeName,S),v=s.attributeValueBegin}),n(p,r.gt,function(){I="",N(a.attributeName,S),N(a.attributeValue,I),b="",v=s.data}),n(p,r.slash,function(){M=!0,I="",N(a.attributeName,S),N(a.attributeValue,I),v=s.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,s.attributeNameEnd,(n(f={},r.space,i),n(f,r.equal,function(){N(a.attributeName,S),v=s.attributeValueBegin}),n(f,r.gt,function(){I="",N(a.attributeName,S),N(a.attributeValue,I),b="",v=s.data}),n(f,r.char,function(t){I="",N(a.attributeName,S),N(a.attributeValue,I),S=t,v=s.attributeName}),f)),n(y,s.attributeValueBegin,(n(g={},r.space,i),n(g,r.quote,function(t){_=t,I="",v=s.attributeValue}),n(g,r.gt,function(){N(a.attributeValue,I=""),b="",v=s.data}),n(g,r.char,function(t){_="",I=t,v=s.attributeValue}),g)),n(y,s.attributeValue,(n(m={},r.space,function(t){_?I+=t:(N(a.attributeValue,I),v=s.attributeNameStart)}),n(m,r.quote,function(t){_===t?(N(a.attributeValue,I),v=s.attributeNameStart):I+=t}),n(m,r.gt,function(t){_?I+=t:(N(a.attributeValue,I),b="",v=s.data)}),n(m,r.slash,function(t){_?I+=t:(N(a.attributeValue,I),M=!0,v=s.tagEnd)}),n(m,r.char,function(t){I+=t}),m)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],o=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];o(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),_u=yu({"node_modules/xml-reader/dist/reader.js"(t,e){var n=Iu(),o=Mu(),i=o.Type,s={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:s.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case i.openTag:if(null===c)(c=a).name=n.value;else{var o=r({name:n.value,parent:c});c.children.push(o),c=o}break;case i.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case i.text:c&&c.children.push(r({type:s.text,value:n.value,parent:t.parentNodes?c:null}));break;case i.attributeName:h=n.value,c.attributes[h]="";break;case i.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=o.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),o=void 0;return n.on("done",function(t){o=t}),n.parse(t),o},create:a,NodeType:s}}}),{cos:Nu,sin:Cu,PI:Tu}=Math,{tan:Eu}=Math,wu=(xu(Su()),xu(_u()),class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.constructor.name} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.constructor.name} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}}),Ru=t=>t?`hsl(${(t=>{let e=0;for(let n=0;n<t.length;n++)e=779*t.charCodeAt(n)+((e<<5)-e);return e})(t)%360}, 100%, 50%)`:"rgba(0, 0, 0, 0.5)",Ou=t=>[[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY}],[{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY}],[{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],[{x:t.minX,y:t.maxY},{x:t.minX,y:t.minY}]];function Au(t,e){const{minX:n,maxX:o,minY:i,maxY:s}=e,r=o-n,a=s-i,c=1e-6;return Math.abs(t.y-s)<c?t.x-n:Math.abs(t.x-o)<c?r+(s-t.y):Math.abs(t.y-i)<c?r+a+(o-t.x):Math.abs(t.x-n)<c?2*r+a+(t.y-i):0}function zu(t,e){const{minX:n,maxX:o,minY:i,maxY:s}=e,r=1e-6,a=Math.abs(t.y-s)<r,c=Math.abs(t.y-i)<r,h=Math.abs(t.x-o)<r,l=Math.abs(t.x-n)<r;if(a&&h)return{x:-Math.SQRT1_2,y:-Math.SQRT1_2};if(a&&l)return{x:Math.SQRT1_2,y:-Math.SQRT1_2};if(c&&h)return{x:-Math.SQRT1_2,y:Math.SQRT1_2};if(c&&l)return{x:Math.SQRT1_2,y:Math.SQRT1_2};if(a)return{x:0,y:-1};if(c)return{x:0,y:1};if(h)return{x:-1,y:0};if(l)return{x:1,y:0};const d=(i+s)/2,u=(n+o)/2-t.x,p=d-t.y,f=Math.hypot(u,p);return f>0?{x:u/f,y:p/f}:{x:0,y:-1}}function Du(t,e,n,o,i,s,r,a,c,h){for(let l=0;l<=h;l++){const d=l/h,u=1-d,p=u*u,f=p*u,g=d*d,m=g*d,y=2*l;c[y]=f*t+3*p*d*n+3*u*g*i+m*r,c[y+1]=f*e+3*p*d*o+3*u*g*s+m*a}}function Lu(t,e,n,o,i){const s=[];for(let r=0;r<=i;r++){const a=r/i,c=1-a,h=c*c,l=h*c,d=a*a,u=d*a;s.push({x:l*t.x+3*h*a*e.x+3*c*d*n.x+u*o.x,y:l*t.y+3*h*a*e.y+3*c*d*n.y+u*o.y})}return s}function Yu(t,e,n,o,i,s){const r=i-n,a=s-o,c=r*r+a*a;if(0===c){const i=t-n,s=e-o;return i*i+s*s}const h=Math.max(0,Math.min(1,((t-n)*r+(e-o)*a)/c)),l=t-(n+h*r),d=e-(o+h*a);return l*l+d*d}function Xu(t,e,n,o,i,s,r,a){const c=(r-i)*(e-s)-(a-s)*(t-i),h=(r-i)*(o-s)-(a-s)*(n-i),l=(n-t)*(s-e)-(o-e)*(i-t),d=(n-t)*(a-e)-(o-e)*(r-t);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)?0:Math.min(Yu(t,e,i,s,r,a),Yu(n,o,i,s,r,a),Yu(i,s,t,e,n,o),Yu(r,a,t,e,n,o))}function Fu(t,e,n,o,i,s,r,a){const c=(r-i)*(e-s)-(a-s)*(t-i),h=(r-i)*(o-s)-(a-s)*(n-i),l=(n-t)*(s-e)-(o-e)*(i-t),d=(n-t)*(a-e)-(o-e)*(r-t);return(c>0&&h<0||c<0&&h>0)&&(l>0&&d<0||l<0&&d>0)}function ku(t,e,n,o,i){const s=t=>(t%i+i)%i,r=s(t),a=s(e),c=s(n),h=s(o),[l,d]=r<a?[r,a]:[a,r];return c>l&&c<d&&h>l&&h<d}function $u(t,e){let n=1/0,o=-1/0,i=1/0,s=-1/0;for(let r=0;r<e;r++){const e=t[2*r],a=t[2*r+1];e<n&&(n=e),e>o&&(o=e),a<i&&(i=a),a>s&&(s=a)}return{minX:n,maxX:o,minY:i,maxY:s}}var Bu=class extends wu{constructor(t){super(),this.problem=t;for(const t of this.problem.obstacles)t.outerSegments=Ou(t);this.precomputeObstacles()}outputTraces=[];traces=[];optimizationStep=0;maxOptimizationSteps=100;sampledPoints=[];traceBounds=[];obstacleSegments=new Float64Array(0);obstacleNetworkIds=[];numObstacleSegments=0;collisionPairs=[];lastCost=1/0;stagnantSteps=0;effectiveTraceToTraceSpacing=0;getConstructorParams(){return this.problem}precomputeObstacles(){const{obstacles:t}=this.problem;let e=0;for(const n of t)n.outerSegments&&(e+=n.outerSegments.length);this.obstacleSegments=new Float64Array(4*e),this.obstacleNetworkIds=[],this.numObstacleSegments=e;let n=0;for(const e of t)if(e.outerSegments)for(const t of e.outerSegments)this.obstacleSegments[n++]=t[0].x,this.obstacleSegments[n++]=t[0].y,this.obstacleSegments[n++]=t[1].x,this.obstacleSegments[n++]=t[1].y,this.obstacleNetworkIds.push(e.networkId)}initializeTraces(){const{bounds:t,waypointPairs:e}=this.problem,{minX:n,maxX:o,minY:i,maxY:s}=t,r=o-n,a=s-i,c=2*r+2*a,h=function(t){return{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}}(t),l=e.map((e,n)=>({pair:e,t1:Au(e.start,t),t2:Au(e.end,t),idx:n})),d=l.map(()=>[]),u=l.map(()=>[]);for(const t of l)for(const e of l)if(t.idx!==e.idx){if(t.pair.networkId&&e.pair.networkId&&t.pair.networkId===e.pair.networkId)continue;ku(e.t1,e.t2,t.t1,t.t2,c)&&(d[t.idx].push(e.idx),u[e.idx].push(t.idx))}const p=d.map(t=>t.length),f=Math.max(...p,1);this.traces=l.map(({pair:e,t1:n,t2:o,idx:i})=>{const s=zu(e.start,t),c=zu(e.end,t),l=Math.hypot(e.end.x-e.start.x,e.end.y-e.start.y),g=p[i]/f,m=(e.start.x+e.end.x)/2,y=(e.start.y+e.end.y)/2,x=l*(.25+.15*(1-Math.hypot(m-h.x,y-h.y)/Math.hypot(r/2,a/2)))*(1-.3*g),v=.05*Math.min(r,a),b=Math.max(v,x),P=Math.max(v,x);return{waypointPair:e,ctrl1:{x:e.start.x+b*s.x,y:e.start.y+b*s.y},ctrl2:{x:e.end.x+P*c.x,y:e.end.y+P*c.y},networkId:e.networkId,t1:n,t2:o,perpDir1:s,perpDir2:c,d1:b,d2:P,containedBy:d[i],contains:u[i]}}),this.sampledPoints=this.traces.map(()=>new Float64Array(12)),this.traceBounds=this.traces.map(()=>({minX:0,maxX:0,minY:0,maxY:0})),this.updateSampledTraces(),this.updateCollisionPairs()}updateSampledTraces(){for(let t=0;t<this.traces.length;t++){const e=this.traces[t];Du(e.waypointPair.start.x,e.waypointPair.start.y,e.ctrl1.x,e.ctrl1.y,e.ctrl2.x,e.ctrl2.y,e.waypointPair.end.x,e.waypointPair.end.y,this.sampledPoints[t],5),this.traceBounds[t]=$u(this.sampledPoints[t],6)}}updateSingleTraceSample(t){const e=this.traces[t];Du(e.waypointPair.start.x,e.waypointPair.start.y,e.ctrl1.x,e.ctrl1.y,e.ctrl2.x,e.ctrl2.y,e.waypointPair.end.x,e.waypointPair.end.y,this.sampledPoints[t],5),this.traceBounds[t]=$u(this.sampledPoints[t],6)}updateControlPointsFromDistances(t){const e=this.traces[t],{minX:n,maxX:o,minY:i,maxY:s}=this.problem.bounds,r=1e-6;let a=e.waypointPair.start.x+e.d1*e.perpDir1.x,c=e.waypointPair.start.y+e.d1*e.perpDir1.y,h=e.waypointPair.end.x+e.d2*e.perpDir2.x,l=e.waypointPair.end.y+e.d2*e.perpDir2.y;const d=e.waypointPair.start;Math.abs(d.x-n)<r&&(a=Math.max(a,n)),Math.abs(d.x-o)<r&&(a=Math.min(a,o)),Math.abs(d.y-i)<r&&(c=Math.max(c,i)),Math.abs(d.y-s)<r&&(c=Math.min(c,s));const u=e.waypointPair.end;Math.abs(u.x-n)<r&&(h=Math.max(h,n)),Math.abs(u.x-o)<r&&(h=Math.min(h,o)),Math.abs(u.y-i)<r&&(l=Math.max(l,i)),Math.abs(u.y-s)<r&&(l=Math.min(l,s)),a=Math.max(n,Math.min(o,a)),c=Math.max(i,Math.min(s,c)),h=Math.max(n,Math.min(o,h)),l=Math.max(i,Math.min(s,l)),e.ctrl1.x=a,e.ctrl1.y=c,e.ctrl2.x=h,e.ctrl2.y=l}updateCollisionPairs(){const t=this.effectiveTraceToTraceSpacing;this.collisionPairs=[];for(let e=0;e<this.traces.length;e++)for(let n=e+1;n<this.traces.length;n++){const o=this.traces[e],i=this.traces[n];if(o.networkId&&i.networkId&&o.networkId===i.networkId)continue;const s=this.traceBounds[e],r=this.traceBounds[n];s.maxX+t>=r.minX&&r.maxX+t>=s.minX&&s.maxY+t>=r.minY&&r.maxY+t>=s.minY&&this.collisionPairs.push([e,n])}}computeTotalCost(){const{preferredObstacleToTraceSpacing:t}=this.problem,e=this.effectiveTraceToTraceSpacing,n=e**2,o=t**2;let i=0;for(const[t,o]of this.collisionPairs){const s=this.sampledPoints[t],r=this.sampledPoints[o];for(let t=0;t<5;t++){const o=s[2*t],a=s[2*t+1],c=s[2*(t+1)],h=s[2*(t+1)+1];for(let t=0;t<5;t++){const s=Xu(o,a,c,h,r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1]);if(s<n){i+=(e-Math.sqrt(s))**2,s<1e-18&&(i+=20*n)}}}}for(let e=0;e<this.traces.length;e++){const n=this.traces[e],s=this.sampledPoints[e],r=this.traceBounds[e];for(let e=0;e<this.numObstacleSegments;e++){if(n.networkId&&this.obstacleNetworkIds[e]&&n.networkId===this.obstacleNetworkIds[e])continue;const a=4*e,c=this.obstacleSegments[a],h=this.obstacleSegments[a+1],l=this.obstacleSegments[a+2],d=this.obstacleSegments[a+3],u=Math.min(c,l),p=Math.max(c,l),f=Math.min(h,d),g=Math.max(h,d);if(!(r.maxX+t<u||p+t<r.minX||r.maxY+t<f||g+t<r.minY))for(let e=0;e<5;e++){const n=Xu(s[2*e],s[2*e+1],s[2*(e+1)],s[2*(e+1)+1],c,h,l,d);if(n<o){i+=(t-Math.sqrt(n))**2,n<1e-18&&(i+=20*o)}}}}return i}computeCostForTrace(t){const{preferredObstacleToTraceSpacing:e}=this.problem,n=this.effectiveTraceToTraceSpacing,o=n**2,i=e**2,s=this.traces[t],r=this.sampledPoints[t],a=this.traceBounds[t];let c=0;for(let e=0;e<this.traces.length;e++){if(e===t)continue;const i=this.traces[e];if(s.networkId&&i.networkId&&s.networkId===i.networkId)continue;const h=this.traceBounds[e];if(a.maxX+n<h.minX||h.maxX+n<a.minX||a.maxY+n<h.minY||h.maxY+n<a.minY)continue;const l=this.sampledPoints[e];for(let t=0;t<5;t++){const e=r[2*t],i=r[2*t+1],s=r[2*(t+1)],a=r[2*(t+1)+1];for(let t=0;t<5;t++){const r=Xu(e,i,s,a,l[2*t],l[2*t+1],l[2*(t+1)],l[2*(t+1)+1]);if(r<o){c+=(n-Math.sqrt(r))**2,r<1e-18&&(c+=20*o)}}}}for(let t=0;t<this.numObstacleSegments;t++){if(s.networkId&&this.obstacleNetworkIds[t]&&s.networkId===this.obstacleNetworkIds[t])continue;const n=4*t,o=this.obstacleSegments[n],h=this.obstacleSegments[n+1],l=this.obstacleSegments[n+2],d=this.obstacleSegments[n+3],u=Math.min(o,l),p=Math.max(o,l),f=Math.min(h,d),g=Math.max(h,d);if(!(a.maxX+e<u||p+e<a.minX||a.maxY+e<f||g+e<a.minY))for(let t=0;t<5;t++){const n=Xu(r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1],o,h,l,d);if(n<i){c+=(e-Math.sqrt(n))**2,n<1e-18&&(c+=20*i)}}}return c}tracesIntersect(t,e){const n=this.traces[t],o=this.traces[e],i=15,s=new Float64Array(32),r=new Float64Array(32);Du(n.waypointPair.start.x,n.waypointPair.start.y,n.ctrl1.x,n.ctrl1.y,n.ctrl2.x,n.ctrl2.y,n.waypointPair.end.x,n.waypointPair.end.y,s,i),Du(o.waypointPair.start.x,o.waypointPair.start.y,o.ctrl1.x,o.ctrl1.y,o.ctrl2.x,o.ctrl2.y,o.waypointPair.end.x,o.waypointPair.end.y,r,i);for(let t=0;t<i;t++){const e=s[2*t],n=s[2*t+1],o=s[2*(t+1)],a=s[2*(t+1)+1];for(let t=0;t<i;t++){if(Fu(e,n,o,a,r[2*t],r[2*t+1],r[2*(t+1)],r[2*(t+1)+1]))return!0}}return!1}findIntersectingPairs(){const t=[];for(let e=0;e<this.traces.length;e++)for(let n=e+1;n<this.traces.length;n++){const o=this.traces[e],i=this.traces[n];if(o.networkId&&i.networkId&&o.networkId===i.networkId)continue;const s=this.traceBounds[e],r=this.traceBounds[n];s.maxX<r.minX||r.maxX<s.minX||s.maxY<r.minY||r.maxY<s.minY||this.tracesIntersect(e,n)&&t.push([e,n])}return t}resolveIntersections(){const{bounds:t,preferredTraceToTraceSpacing:e}=this.problem,{minX:n,maxX:o,minY:i,maxY:s}=t,r=Math.min(o-n,s-i),a=.02*r,c=1.5*r,h=this.findIntersectingPairs();if(0===h.length)return 0;let l=0;for(const[t,n]of h){const o=this.traces[t],i=this.traces[n];if(!this.tracesIntersect(t,n))continue;let s,r;if(o.containedBy.includes(n))s=n,r=t;else if(i.containedBy.includes(t))s=t,r=n;else{(o.d1+o.d2)/2<(i.d1+i.d2)/2?(s=t,r=n):(s=n,r=t)}const h=this.traces[s],d=this.traces[r],u=h.d1,p=h.d2,f=d.d1,g=d.d2,m=2*e,y=[{innerMult:1,outerMult:0},{innerMult:0,outerMult:1},{innerMult:.5,outerMult:.5},{innerMult:2,outerMult:0},{innerMult:1,outerMult:1},{innerMult:3,outerMult:0},{innerMult:2,outerMult:1},{innerMult:4,outerMult:0}];let x=this.computeTotalCost(),v=null;for(const t of y)if(h.d1=u,h.d2=p,d.d1=f,d.d2=g,d.d1=Math.min(c,f+m*t.innerMult),d.d2=Math.min(c,g+m*t.innerMult),h.d1=Math.max(a,u-m*t.outerMult),h.d2=Math.max(a,p-m*t.outerMult),this.updateControlPointsFromDistances(r),this.updateControlPointsFromDistances(s),this.updateSingleTraceSample(r),this.updateSingleTraceSample(s),!this.tracesIntersect(s,r)){const e=this.computeTotalCost();(null===v||e<x)&&(x=e,v=t)}v?(d.d1=Math.min(c,f+m*v.innerMult),d.d2=Math.min(c,g+m*v.innerMult),h.d1=Math.max(a,u-m*v.outerMult),h.d2=Math.max(a,p-m*v.outerMult),this.updateControlPointsFromDistances(r),this.updateControlPointsFromDistances(s),this.updateSingleTraceSample(r),this.updateSingleTraceSample(s),l++):(h.d1=u,h.d2=p,d.d1=f,d.d2=g,this.updateControlPointsFromDistances(s),this.updateControlPointsFromDistances(r),this.updateSingleTraceSample(s),this.updateSingleTraceSample(r))}return l}optimizeStep(){const{bounds:t}=this.problem,{minX:e,maxX:n,minY:o,maxY:i}=t,s=Math.min(n-e,i-o),r=this.effectiveTraceToTraceSpacing,a=4*(1-this.optimizationStep/this.maxOptimizationSteps)+.5,c=.02*s,h=1.5*s,l=[];for(let t=0;t<this.traces.length;t++)l.push({idx:t,cost:this.computeCostForTrace(t)});l.sort((t,e)=>e.cost-t.cost);for(const{idx:t,cost:e}of l){if(0===e)continue;const n=this.traces[t],o=e>100?2:1,i=[a*o,1.5*a*o,.5*a];for(const o of i){const i=e>100?[o,-o,2*o,2*-o,3*o,3*-o,2*r,2*-r]:[o,-o,2*o,2*-o];let s=this.computeCostForTrace(t),a=n.d1,l=n.d2;const d=n.d1,u=n.d2;for(const e of i){n.d1=Math.max(c,Math.min(h,d+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const o=this.computeCostForTrace(t);o<s&&(s=o,a=n.d1,l=u),n.d1=d,this.updateControlPointsFromDistances(t),n.d2=Math.max(c,Math.min(h,u+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const i=this.computeCostForTrace(t);i<s&&(s=i,a=d,l=n.d2),n.d2=u,this.updateControlPointsFromDistances(t),n.d1=Math.max(c,Math.min(h,d+e)),n.d2=Math.max(c,Math.min(h,u+e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const r=this.computeCostForTrace(t);r<s&&(s=r,a=n.d1,l=n.d2),n.d1=d,n.d2=u,this.updateControlPointsFromDistances(t),n.d1=Math.max(c,Math.min(h,d+e)),n.d2=Math.max(c,Math.min(h,u-e)),this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t);const p=this.computeCostForTrace(t);p<s&&(s=p,a=n.d1,l=n.d2),n.d1=d,n.d2=u,this.updateControlPointsFromDistances(t)}if(n.d1=a,n.d2=l,this.updateControlPointsFromDistances(t),this.updateSingleTraceSample(t),s<.9*e)break}}this.optimizationStep%10==0&&this.updateCollisionPairs()}buildOutputTraces(){this.outputTraces=this.traces.map(t=>({waypointPair:t.waypointPair,points:Lu(t.waypointPair.start,t.ctrl1,t.ctrl2,t.waypointPair.end,20),networkId:t.networkId}))}_step(){if(0===this.traces.length&&(this.effectiveTraceToTraceSpacing=3*this.problem.preferredTraceToTraceSpacing,this.initializeTraces(),this.lastCost=this.computeTotalCost(),this.stagnantSteps=0),this.optimizationStep<this.maxOptimizationSteps){const t=3,e=t+(1-t)*(this.optimizationStep/this.maxOptimizationSteps);if(this.effectiveTraceToTraceSpacing=this.problem.preferredTraceToTraceSpacing*e,this.optimizeStep(),this.optimizationStep++,this.optimizationStep%10==0){this.resolveIntersections()>0&&this.updateCollisionPairs()}const n=this.computeTotalCost();if(0===n)this.optimizationStep=this.maxOptimizationSteps;else if(n>=.99*this.lastCost){if(this.stagnantSteps++,this.stagnantSteps>10){this.resolveIntersections()>0?(this.updateCollisionPairs(),this.stagnantSteps=0):this.stagnantSteps>15&&(this.optimizationStep=this.maxOptimizationSteps)}}else this.stagnantSteps=0;this.lastCost=n}this.optimizationStep>=this.maxOptimizationSteps&&(this.resolveIntersections(),this.buildOutputTraces(),this.solved=!0)}visualize(){return this.traces.length>0&&this.buildOutputTraces(),((t,e=[])=>{const n={arrows:[],circles:[],lines:[],rects:[],coordinateSystem:"cartesian",points:[],texts:[],title:"Curvy Trace Problem"};n.lines.push({points:[{x:t.bounds.minX,y:t.bounds.minY},{x:t.bounds.maxX,y:t.bounds.minY},{x:t.bounds.maxX,y:t.bounds.maxY},{x:t.bounds.minX,y:t.bounds.maxY},{x:t.bounds.minX,y:t.bounds.minY}],strokeColor:"rgba(0, 0, 0, 0.1)"});for(const e of t.waypointPairs)n.points.push({...e.start,label:`start ${e.networkId??""}`,color:Ru(e.networkId)}),n.points.push({...e.end,label:`end ${e.networkId??""}`,color:Ru(e.networkId)});for(const e of t.obstacles)n.rects.push({center:e.center,width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(128, 128, 128, 0.3)",stroke:"rgba(128, 128, 128, 0.8)",label:`netId: ${e.networkId}`});for(const t of e)n.lines.push({points:t.points,strokeColor:Ru(t.networkId)});return n})(this.problem,this.outputTraces)}},ju=class extends Dn{getSolverName(){return"CurvyIntraNodeSolver"}nodeWithPortPoints;colorMap;traceWidth;viaDiameter;adjacentObstacles;routes=[];curvyTraceSolver;phase="initializing";constructor(t){super(),this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.viaDiameter=t.viaDiameter??.3,this.adjacentObstacles=t.adjacentObstacles??[],this.MAX_ITERATIONS=1e3}_step(){switch(this.phase){case"initializing":this._initializeCurvySolver();break;case"solving":this._stepCurvySolver();break;case"done":this.solved=!0}}_initializeCurvySolver(){const t=this.nodeWithPortPoints,e={minX:t.center.x-t.width/2,minY:t.center.y-t.height/2,maxX:t.center.x+t.width/2,maxY:t.center.y+t.height/2},n=new Map;for(const e of t.portPoints)n.has(e.connectionName)||n.set(e.connectionName,[]),n.get(e.connectionName).push(e);const o=[];for(const[t,e]of n){if(e.length<2)continue;const n=e[0],i=e[e.length-1];o.push({start:{x:n.x,y:n.y},end:{x:i.x,y:i.y},networkId:t})}if(0===o.length)return void(this.phase="done");const i={bounds:e,waypointPairs:o,obstacles:this.adjacentObstacles.map(t=>({minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:{x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2},networkId:t.networkId})),preferredTraceToTraceSpacing:2*this.traceWidth,preferredObstacleToTraceSpacing:2*this.traceWidth};this.curvyTraceSolver=new Bu(i),this.phase="solving"}_stepCurvySolver(){this.curvyTraceSolver?(this.activeSubSolver=this.curvyTraceSolver,this.curvyTraceSolver.step(),this.curvyTraceSolver.solved?(this._convertOutputTraces(),this.phase="done"):this.curvyTraceSolver.failed&&(this.error=this.curvyTraceSolver.error,this.failed=!0)):this.phase="done"}_convertOutputTraces(){if(!this.curvyTraceSolver)return;const t=this.nodeWithPortPoints,e=new Map;for(const n of t.portPoints){const t=n.connectionName;e.has(t)||e.set(t,{connectionName:n.connectionName,rootConnectionName:n.rootConnectionName,z:n.z})}for(const t of this.curvyTraceSolver.outputTraces){const n=t.networkId??"",o=e.get(n);if(!o)continue;const i={connectionName:o.connectionName,rootConnectionName:o.rootConnectionName,traceThickness:this.traceWidth,viaDiameter:this.viaDiameter,route:t.points.map(t=>({x:t.x,y:t.y,z:o.z})),vias:[]};this.routes.push(i)}}getConstructorParams(){return{nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:this.adjacentObstacles}}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=this.nodeWithPortPoints;t.rects.push({center:e.center,width:e.width,height:e.height,fill:"rgba(0, 200, 0, 0.1)",stroke:"rgba(0, 200, 0, 0.5)",label:e.capacityMeshNodeId});for(const e of this.adjacentObstacles)t.rects.push({center:{x:(e.minX+e.maxX)/2,y:(e.minY+e.maxY)/2},width:e.maxX-e.minX,height:e.maxY-e.minY,fill:"rgba(255, 0, 0, 0.1)",stroke:"rgba(255, 0, 0, 0.3)",label:`obstacle: ${e.networkId??""}`});if(this.curvyTraceSolver){const e=this.curvyTraceSolver.visualize();e.lines&&t.lines.push(...e.lines),e.points&&t.points.push(...e.points),e.rects&&t.rects.push(...e.rects),e.circles&&t.circles.push(...e.circles)}for(const e of this.routes){const n=this.colorMap[e.connectionName]??"gray";t.lines.push({points:e.route.map(t=>({x:t.x,y:t.y})),strokeColor:n,strokeWidth:this.traceWidth,label:e.connectionName})}for(const n of e.portPoints){const e=this.colorMap[n.connectionName]??"gray";t.points.push({x:n.x,y:n.y,color:e,label:n.connectionName})}return t}},Wu=Object.create,Vu=Object.defineProperty,Hu=Object.getOwnPropertyDescriptor,Uu=Object.getOwnPropertyNames,Gu=Object.getPrototypeOf,Zu=Object.prototype.hasOwnProperty,qu=(t,e)=>function(){return e||(0,t[Uu(t)[0]])((e={exports:{}}).exports,e),e.exports},Ju=(t,e,n)=>(n=null!=t?Wu(Gu(t)):{},((t,e,n,o)=>{if(e&&"object"==typeof e||"function"==typeof e)for(let i of Uu(e))Zu.call(t,i)||i===n||Vu(t,i,{get:()=>e[i],enumerable:!(o=Hu(e,i))||o.enumerable});return t})(!e&&t&&t.__esModule?n:Vu(n,"default",{value:t,enumerable:!0}),t)),Ku=qu({"node_modules/is-buffer/index.js"(t,e){function n(t){return!!t.constructor&&"function"==typeof t.constructor.isBuffer&&t.constructor.isBuffer(t)}e.exports=function(t){return null!=t&&(n(t)||function(t){return"function"==typeof t.readFloatLE&&"function"==typeof t.slice&&n(t.slice(0,0))}(t)||!!t._isBuffer)}}}),Qu=qu({"node_modules/kind-of/index.js"(t,e){var n=Ku(),o=Object.prototype.toString;e.exports=function(t){if(void 0===t)return"undefined";if(null===t)return"null";if(!0===t||!1===t||t instanceof Boolean)return"boolean";if("string"==typeof t||t instanceof String)return"string";if("number"==typeof t||t instanceof Number)return"number";if("function"==typeof t||t instanceof Function)return"function";if(void 0!==Array.isArray&&Array.isArray(t))return"array";if(t instanceof RegExp)return"regexp";if(t instanceof Date)return"date";var e=o.call(t);return"[object RegExp]"===e?"regexp":"[object Date]"===e?"date":"[object Arguments]"===e?"arguments":"[object Error]"===e?"error":n(t)?"buffer":"[object Set]"===e?"set":"[object WeakSet]"===e?"weakset":"[object Map]"===e?"map":"[object WeakMap]"===e?"weakmap":"[object Symbol]"===e?"symbol":"[object Int8Array]"===e?"int8array":"[object Uint8Array]"===e?"uint8array":"[object Uint8ClampedArray]"===e?"uint8clampedarray":"[object Int16Array]"===e?"int16array":"[object Uint16Array]"===e?"uint16array":"[object Int32Array]"===e?"int32array":"[object Uint32Array]"===e?"uint32array":"[object Float32Array]"===e?"float32array":"[object Float64Array]"===e?"float64array":"object"}}}),tp=qu({"node_modules/rename-keys/index.js"(t,e){!function(){function t(t,e){if("function"!=typeof e)return t;var n={};for(var o in t)Object.prototype.hasOwnProperty.call(t,o)&&(n[e(o,t[o])||o]=t[o]);return n}void 0!==e&&e.exports?e.exports=t:"function"==typeof define&&define.amd?define([],function(){return t}):window.rename=t}()}}),ep=qu({"node_modules/deep-rename-keys/index.js"(t,e){var n=Qu(),o=tp();e.exports=function t(e,i){var s=n(e);if("object"!==s&&"array"!==s)throw new Error("expected an object");var r=[];for(var a in"object"===s&&(e=o(e,i),r={}),e)if(e.hasOwnProperty(a)){var c=e[a];"object"===n(c)||"array"===n(c)?r[a]=t(c,i):r[a]=c}return r}}}),np=qu({"node_modules/eventemitter3/index.js"(t,e){var n=Object.prototype.hasOwnProperty,o="~";function i(){}function s(t,e,n){this.fn=t,this.context=e,this.once=n||!1}function r(){this._events=new i,this._eventsCount=0}Object.create&&(i.prototype=Object.create(null),(new i).__proto__||(o=!1)),r.prototype.eventNames=function(){var t,e,i=[];if(0===this._eventsCount)return i;for(e in t=this._events)n.call(t,e)&&i.push(o?e.slice(1):e);return Object.getOwnPropertySymbols?i.concat(Object.getOwnPropertySymbols(t)):i},r.prototype.listeners=function(t,e){var n=o?o+t:t,i=this._events[n];if(e)return!!i;if(!i)return[];if(i.fn)return[i.fn];for(var s=0,r=i.length,a=new Array(r);s<r;s++)a[s]=i[s].fn;return a},r.prototype.emit=function(t,e,n,i,s,r){var a=o?o+t:t;if(!this._events[a])return!1;var c,h,l=this._events[a],d=arguments.length;if(l.fn){switch(l.once&&this.removeListener(t,l.fn,void 0,!0),d){case 1:return l.fn.call(l.context),!0;case 2:return l.fn.call(l.context,e),!0;case 3:return l.fn.call(l.context,e,n),!0;case 4:return l.fn.call(l.context,e,n,i),!0;case 5:return l.fn.call(l.context,e,n,i,s),!0;case 6:return l.fn.call(l.context,e,n,i,s,r),!0}for(h=1,c=new Array(d-1);h<d;h++)c[h-1]=arguments[h];l.fn.apply(l.context,c)}else{var u,p=l.length;for(h=0;h<p;h++)switch(l[h].once&&this.removeListener(t,l[h].fn,void 0,!0),d){case 1:l[h].fn.call(l[h].context);break;case 2:l[h].fn.call(l[h].context,e);break;case 3:l[h].fn.call(l[h].context,e,n);break;case 4:l[h].fn.call(l[h].context,e,n,i);break;default:if(!c)for(u=1,c=new Array(d-1);u<d;u++)c[u-1]=arguments[u];l[h].fn.apply(l[h].context,c)}}return!0},r.prototype.on=function(t,e,n){var i=new s(e,n||this),r=o?o+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],i]:this._events[r].push(i):(this._events[r]=i,this._eventsCount++),this},r.prototype.once=function(t,e,n){var i=new s(e,n||this,!0),r=o?o+t:t;return this._events[r]?this._events[r].fn?this._events[r]=[this._events[r],i]:this._events[r].push(i):(this._events[r]=i,this._eventsCount++),this},r.prototype.removeListener=function(t,e,n,s){var r=o?o+t:t;if(!this._events[r])return this;if(!e)return 0===--this._eventsCount?this._events=new i:delete this._events[r],this;var a=this._events[r];if(a.fn)a.fn!==e||s&&!a.once||n&&a.context!==n||(0===--this._eventsCount?this._events=new i:delete this._events[r]);else{for(var c=0,h=[],l=a.length;c<l;c++)(a[c].fn!==e||s&&!a[c].once||n&&a[c].context!==n)&&h.push(a[c]);h.length?this._events[r]=1===h.length?h[0]:h:0===--this._eventsCount?this._events=new i:delete this._events[r]}return this},r.prototype.removeAllListeners=function(t){var e;return t?(e=o?o+t:t,this._events[e]&&(0===--this._eventsCount?this._events=new i:delete this._events[e])):(this._events=new i,this._eventsCount=0),this},r.prototype.off=r.prototype.removeListener,r.prototype.addListener=r.prototype.on,r.prototype.setMaxListeners=function(){return this},r.prefixed=o,r.EventEmitter=r,void 0!==e&&(e.exports=r)}}),op=qu({"node_modules/xml-lexer/dist/lexer.js"(t,e){function n(t,e,n){return e in t?Object.defineProperty(t,e,{value:n,enumerable:!0,configurable:!0,writable:!0}):t[e]=n,t}var o=np(),i=function(){},s={data:"state-data",cdata:"state-cdata",tagBegin:"state-tag-begin",tagName:"state-tag-name",tagEnd:"state-tag-end",attributeNameStart:"state-attribute-name-start",attributeName:"state-attribute-name",attributeNameEnd:"state-attribute-name-end",attributeValueBegin:"state-attribute-value-begin",attributeValue:"state-attribute-value"},r={lt:"action-lt",gt:"action-gt",space:"action-space",equal:"action-equal",quote:"action-quote",slash:"action-slash",char:"action-char",error:"action-error"},a={text:"text",openTag:"open-tag",closeTag:"close-tag",attributeName:"attribute-name",attributeValue:"attribute-value"},c={" ":r.space,"\t":r.space,"\n":r.space,"\r":r.space,"<":r.lt,">":r.gt,'"':r.quote,"'":r.quote,"=":r.equal,"/":r.slash};e.exports={State:s,Action:r,Type:a,create:function(t){var e,h,l,d,u,p,f,g,m,y;t=Object.assign({debug:!1},t);var x=new o,v=s.data,b="",P="",S="",I="",M="",_="",N=function(e,n){if("?"!==P[0]&&"!"!==P[0]){var o={type:e,value:n};t.debug&&console.log("emit:",o),x.emit("data",o)}};x.stateMachine=(n(y={},s.data,(n(e={},r.lt,function(){b.trim()&&N(a.text,b),P="",M=!1,v=s.tagBegin}),n(e,r.char,function(t){b+=t}),e)),n(y,s.cdata,n({},r.char,function(t){"]]>"===(b+=t).substr(-3)&&(N(a.text,b.slice(0,-3)),b="",v=s.data)})),n(y,s.tagBegin,(n(h={},r.space,i),n(h,r.char,function(t){P=t,v=s.tagName}),n(h,r.slash,function(){P="",M=!0}),h)),n(y,s.tagName,(n(l={},r.space,function(){M?v=s.tagEnd:(v=s.attributeNameStart,N(a.openTag,P))}),n(l,r.gt,function(){N(M?a.closeTag:a.openTag,P),b="",v=s.data}),n(l,r.slash,function(){v=s.tagEnd,N(a.openTag,P)}),n(l,r.char,function(t){"![CDATA["===(P+=t)&&(v=s.cdata,b="",P="")}),l)),n(y,s.tagEnd,(n(d={},r.gt,function(){N(a.closeTag,P),b="",v=s.data}),n(d,r.char,i),d)),n(y,s.attributeNameStart,(n(u={},r.char,function(t){S=t,v=s.attributeName}),n(u,r.gt,function(){b="",v=s.data}),n(u,r.space,i),n(u,r.slash,function(){M=!0,v=s.tagEnd}),u)),n(y,s.attributeName,(n(p={},r.space,function(){v=s.attributeNameEnd}),n(p,r.equal,function(){N(a.attributeName,S),v=s.attributeValueBegin}),n(p,r.gt,function(){I="",N(a.attributeName,S),N(a.attributeValue,I),b="",v=s.data}),n(p,r.slash,function(){M=!0,I="",N(a.attributeName,S),N(a.attributeValue,I),v=s.tagEnd}),n(p,r.char,function(t){S+=t}),p)),n(y,s.attributeNameEnd,(n(f={},r.space,i),n(f,r.equal,function(){N(a.attributeName,S),v=s.attributeValueBegin}),n(f,r.gt,function(){I="",N(a.attributeName,S),N(a.attributeValue,I),b="",v=s.data}),n(f,r.char,function(t){I="",N(a.attributeName,S),N(a.attributeValue,I),S=t,v=s.attributeName}),f)),n(y,s.attributeValueBegin,(n(g={},r.space,i),n(g,r.quote,function(t){_=t,I="",v=s.attributeValue}),n(g,r.gt,function(){N(a.attributeValue,I=""),b="",v=s.data}),n(g,r.char,function(t){_="",I=t,v=s.attributeValue}),g)),n(y,s.attributeValue,(n(m={},r.space,function(t){_?I+=t:(N(a.attributeValue,I),v=s.attributeNameStart)}),n(m,r.quote,function(t){_===t?(N(a.attributeValue,I),v=s.attributeNameStart):I+=t}),n(m,r.gt,function(t){_?I+=t:(N(a.attributeValue,I),b="",v=s.data)}),n(m,r.slash,function(t){_?I+=t:(N(a.attributeValue,I),M=!0,v=s.tagEnd)}),n(m,r.char,function(t){I+=t}),m)),y);var C=function(e){t.debug&&console.log(v,e);var n=x.stateMachine[v],o=n[function(t){return c[t]||r.char}(e)]||n[r.error]||n[r.char];o(e)};return x.write=function(t){for(var e=t.length,n=0;n<e;n++)C(t[n])},x}}}}),ip=qu({"node_modules/xml-reader/dist/reader.js"(t,e){var n=np(),o=op(),i=o.Type,s={element:"element",text:"text"},r=function(t){return Object.assign({name:"",type:s.element,value:"",parent:null,attributes:{},children:[]},t)},a=function(t){t=Object.assign({stream:!1,parentNodes:!0,doneEvent:"done",tagPrefix:"tag:",emitTopLevelOnly:!1,debug:!1},t);var e=void 0,a=void 0,c=void 0,h=void 0,l=new n,d=function(n){switch(n.type){case i.openTag:if(null===c)(c=a).name=n.value;else{var o=r({name:n.value,parent:c});c.children.push(o),c=o}break;case i.closeTag:var d=c.parent;if(t.parentNodes||(c.parent=null),c.name!==n.value)break;t.stream&&d===a&&(a.children=[],c.parent=null),t.emitTopLevelOnly&&d!==a||(l.emit(t.tagPrefix+c.name,c),l.emit("tag",c.name,c)),c===a&&(e.removeAllListeners("data"),l.emit(t.doneEvent,c),a=null),c=d;break;case i.text:c&&c.children.push(r({type:s.text,value:n.value,parent:t.parentNodes?c:null}));break;case i.attributeName:h=n.value,c.attributes[h]="";break;case i.attributeValue:c.attributes[h]=n.value}};return l.reset=function(){(e=o.create({debug:t.debug})).on("data",d),a=r(),c=null,h="",l.parse=e.write},l.reset(),l};e.exports={parseSync:function(t,e){e=Object.assign({},e,{stream:!1,tagPrefix:":"});var n=a(e),o=void 0;return n.on("done",function(t){o=t}),n.parse(t),o},create:a,NodeType:s}}}),{cos:sp,sin:rp,PI:ap}=Math,{tan:cp}=Math;Ju(ep()),Ju(ip());function hp(t,e){if(t.points)for(const n of t.points)n.step=e;if(t.lines)for(const n of t.lines)n.step=e;if(t.infiniteLines)for(const n of t.infiniteLines)n.step=e;if(t.polygons)for(const n of t.polygons)n.step=e;if(t.rects)for(const n of t.rects)n.step=e;if(t.circles)for(const n of t.circles)n.step=e;if(t.texts)for(const n of t.texts)n.step=e;return t}var lp=class{MAX_ITERATIONS=1e5;solved=!1;failed=!1;iterations=0;progress=0;error=null;activeSubSolver;failedSubSolvers;timeToSolve;stats={};_setupDone=!1;getSolverName(){return this.constructor.name}setup(){this._setupDone||(this._setup(),this._setupDone=!0)}_setup(){}step(){if(this._setupDone||this.setup(),!this.solved&&!this.failed){this.iterations++;try{this._step()}catch(t){throw this.error=`${this.getSolverName()} error: ${t}`,this.failed=!0,t}!this.solved&&this.iterations>=this.MAX_ITERATIONS&&this.tryFinalAcceptance(),!this.solved&&this.iterations>=this.MAX_ITERATIONS&&(this.error=`${this.getSolverName()} ran out of iterations`,this.failed=!0),"computeProgress"in this&&(this.progress=this.computeProgress())}}_step(){}getConstructorParams(){throw new Error("getConstructorParams not implemented")}getOutput(){return null}solve(){const t=Date.now();for(;!this.solved&&!this.failed;)this.step();const e=Date.now();this.timeToSolve=e-t}visualize(){return{lines:[],points:[],rects:[],circles:[]}}tryFinalAcceptance(){}preview(){return{lines:[],points:[],rects:[],circles:[]}}};function dp(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var up=class extends lp{startTimeOfStage={};endTimeOfStage={};timeSpentOnStage={};firstIterationOfStage={};currentPipelineStageIndex=0;inputProblem;pipelineOutputs={};constructor(t){super(),this.inputProblem=t,this.MAX_ITERATIONS=1e6}_step(){const t=this.pipelineDef[this.currentPipelineStageIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver){if(this.activeSubSolver.step(),this.activeSubSolver.solved){this.endTimeOfStage[t.solverName]=performance.now(),this.timeSpentOnStage[t.solverName]=this.endTimeOfStage[t.solverName]-this.startTimeOfStage[t.solverName];const e=this.activeSubSolver.getOutput();null!==e&&(this.pipelineOutputs[t.solverName]=e),t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStageIndex++}else this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null);return}const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnStage[t.solverName]=0,this.startTimeOfStage[t.solverName]=performance.now(),this.firstIterationOfStage[t.solverName]=this.iterations}solveUntilStage(t){for(;this.getCurrentStageName().toLowerCase()!==t.toLowerCase()&&(this.step(),!this.failed&&!this.solved););}getCurrentStageName(){return this.pipelineDef[this.currentPipelineStageIndex]?.solverName??"none"}getStageProgress(){const t=this.pipelineDef.length;if(0===t)return 1;const e=this.activeSubSolver?.progress??0;return(this.currentPipelineStageIndex+e)/t}getStageStats(){const t={};for(const e of this.pipelineDef){const n=this.timeSpentOnStage[e.solverName]||0,o=this.firstIterationOfStage[e.solverName]||0,i=this.iterations,s=e.solverName===this.getCurrentStageName()?i-o:0,r=this.currentPipelineStageIndex>this.pipelineDef.findIndex(t=>t.solverName===e.solverName);t[e.solverName]={timeSpent:n,iterations:s,completed:r}}return t}initialVisualize(){return null}finalVisualize(){return null}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();let t=0;const e=this.initialVisualize();e&&(hp(e,0),t=1);let n=null;this.solved&&(n=this.finalVisualize());const o=[e].filter(Boolean).concat(this.pipelineDef.map((e,n)=>{const o=this[e.solverName],i=o?.visualize();return i?(hp(i,n+t),i):null}).filter(Boolean));return 0===o.length?{points:[],rects:[],lines:[],circles:[],texts:[]}:(this.solved&&n&&(hp(n,o.length+t+1),o.push(n)),1===o.length?o[0]:{points:o.flatMap(t=>t.points||[]),rects:o.flatMap(t=>t.rects||[]),lines:o.flatMap(t=>t.lines||[]),circles:o.flatMap(t=>t.circles||[]),texts:o.flatMap(t=>t.texts||[])})}preview(){return this.activeSubSolver?this.activeSubSolver.preview():super.preview()}computeProgress(){return this.getStageProgress()}getStageOutput(t){return this.pipelineOutputs[t]}getAllOutputs(){return{...this.pipelineOutputs}}hasStageOutput(t){return t in this.pipelineOutputs}getSolver(t){return this[t]}},pp=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),fp=(t,e)=>{const n=[...new Set(t)].map(t=>{const n=e[t];return n?{i:t,x:n.x,y:n.y}:null}).filter(t=>null!==t);if(n.sort((t,e)=>t.x-e.x||t.y-e.y),n.length<=2)return n.map(t=>t.i);const o=[],i=[];for(const t of n){for(;o.length>=2;){const e=o[o.length-2],n=o[o.length-1];if(!e||!n||pp(e,n,t)>1e-10)break;o.pop()}o.push(t)}for(let t=n.length-1;t>=0;t--){const e=n[t];if(e){for(;i.length>=2;){const t=i[i.length-2],n=i[i.length-1];if(!t||!n||pp(t,n,e)>1e-10)break;i.pop()}i.push(e)}}return o.pop(),i.pop(),o.concat(i).map(t=>t.i)},gp=t=>void 0!==t,mp=class extends lp{input;output=null;constructor(t){super(),this.input=t}_step(){const{regions:t,hulls:e}={regions:(n=this.input).cells.map(t=>t.map(t=>n.pts[t]).filter(gp)),hulls:n.cells.map(t=>fp(t,n.pts).map(t=>n.pts[t]).filter(gp))};var n;this.output={pts:this.input.pts,validTris:this.input.validTris,regions:t,hulls:e,depths:this.input.depths},this.stats={regions:t.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output;return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.regions.flatMap(t=>t.flatMap((e,n)=>{const o=t[(n+1)%t.length];return o?[{points:[e,o],strokeColor:"#0f766e"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`regions: ${t.regions.length}`,color:"#1f2937"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},yp=(t,e,n)=>{const o=Math.cos(n.ccwRotation),i=Math.sin(n.ccwRotation);return{x:n.center.x+t*o-e*i,y:n.center.y+t*i+e*o}},xp=(t,e=[],n,o=[])=>{const i=[],{minX:s,maxX:r,minY:a,maxY:c}=t;i.push({x:s,y:a},{x:r,y:a},{x:r,y:c},{x:s,y:c});for(let t=1;t<10;t++){const e=t/10;i.push({x:s+e*(r-s),y:a}),i.push({x:r,y:a+e*(c-a)}),i.push({x:r-e*(r-s),y:c}),i.push({x:s,y:c-e*(c-a)})}for(const t of e){const e=t.diameter/2+n;for(let n=0;n<24;n++){const o=2*Math.PI*n/24;i.push({x:t.center.x+e*Math.cos(o),y:t.center.y+e*Math.sin(o)})}}for(const t of o){const e=t.width/2+n,o=t.height/2+n,s=Math.max(2,Math.ceil(Math.max(2*e,2*o)/20));for(let n=0;n<s;n++){const r=n/s;i.push(yp(2*r*e-e,-o,t)),i.push(yp(e,2*r*o-o,t)),i.push(yp(e-2*r*e,o,t)),i.push(yp(-e,o-2*r*o,t))}}return i.map((t,e)=>({x:t.x+1e-6*(e%7-3),y:t.y+1e-6*(e%5-2)}))},vp=class extends lp{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[];this.output={pts:xp(this.input.bounds,t,this.input.clearance,e)},this.stats={points:this.output.pts.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=(this.output?.pts??[]).map(t=>({x:t.x,y:t.y,color:"#2563eb"}));return{points:t,lines:[],rects:[],circles:(this.input.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2+this.input.clearance,stroke:"#ef4444"})),texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`sample points: ${t.length}`,color:"#1f2937"}]}}},bp=(t,e,n)=>{const o=n.x-e.x,i=n.y-e.y,s=o*o+i*i;if(s<1e-10)return Math.hypot(t.x-e.x,t.y-e.y);let r=((t.x-e.x)*o+(t.y-e.y)*i)/s;return r=Math.max(0,Math.min(1,r)),Math.hypot(t.x-e.x-r*o,t.y-e.y-r*i)},Pp=(t,e)=>{if(t.length<=3)return 0;const n=fp(t,e),o=new Set(n),i=n.map(t=>e[t]).filter(t=>Boolean(t));let s=0;for(const n of t){if(o.has(n))continue;const t=e[n];if(!t)continue;let r=Number.POSITIVE_INFINITY;for(let e=0;e<i.length;e++){const n=i[e],o=i[(e+1)%i.length];n&&o&&(r=Math.min(r,bp(t,n,o)))}s=Math.max(s,r)}return s},Sp=(t,e)=>t<e?1e5*t+e:1e5*e+t,Ip=(t,e)=>{const n=t.map((e,n)=>[e,t[(n+1)%t.length]]),o=e.map((t,n)=>[t,e[(n+1)%e.length]]),i=new Set;for(const[t,e]of n)if(void 0!==e)for(const[n,s]of o)void 0!==s&&t===s&&e===n&&i.add(Sp(t,e));if(0===i.size)return null;const s=[];for(const[t,e]of n)void 0!==e&&(i.has(Sp(t,e))||s.push([t,e]));for(const[t,e]of o)void 0!==e&&(i.has(Sp(t,e))||s.push([t,e]));if(0===s.length)return null;const r=new Map;for(const[t,e]of s)r.set(t,e);const a=s[0]?.[0];if(void 0===a)return null;const c=[a];let h=r.get(a),l=0;for(;void 0!==h&&h!==a&&l++<s.length+5;)c.push(h),h=r.get(h);return h!==a||c.length!==s.length?null:c},Mp=(t,e)=>t<e?1e5*t+e:1e5*e+t,_p=class extends lp{input;output=null;constructor(t){super(),this.input=t}_step(){const t=((t,e,n)=>{if(!t.length)return{cells:[],depths:[]};const o=t.map(([t,n,o])=>{const i=e[t],s=e[n],r=e[o];return i&&s&&r&&pp(i,s,r)<0?[t,o,n]:[t,n,o]});let i=!0,s=0;for(;i&&s++<800;){i=!1;const t=new Map,s=o.map(()=>new Set);for(let e=0;e<o.length;e++){const n=o[e];if(n)for(let o=0;o<n.length;o++){const i=n[o],r=n[(o+1)%n.length];if(void 0===i||void 0===r)continue;const a=Mp(i,r);if(t.has(a)){const n=t.get(a);void 0!==n&&(s[e]?.add(n),s[n]?.add(e))}else t.set(a,e)}}let r=-1,a=-1,c=null,h=Number.POSITIVE_INFINITY;for(let t=0;t<o.length;t++){const i=s[t];if(i)for(const s of i){if(s<=t)continue;const i=Ip(o[t]??[],o[s]??[]);if(!i)continue;const l=Pp(i,e);l<=n+1e-6&&l<h&&(h=l,r=t,a=s,c=i)}}if(r<0||a<0||!c)break;o[r]=c,o.splice(a,1),i=!0}const r=o.map(t=>Pp(t,e));return{cells:o,depths:r}})(this.input.validTris,this.input.pts,this.input.concavityTolerance);this.output={pts:this.input.pts,validTris:this.input.validTris,cells:t.cells,depths:t.depths},this.stats={mergedCells:t.cells.length,maxDepth:t.depths.length?Math.max(...t.depths):0},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.cells??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#3b82f6"})),lines:t.flatMap(t=>t.flatMap((e,n)=>{const o=this.input.pts[e],i=t[(n+1)%t.length],s=void 0===i?void 0:this.input.pts[i];return o&&s?[{points:[o,s],strokeColor:"#10b981"}]:[]})),rects:[],circles:[],texts:[{x:4,y:12,text:`merged cells: ${t.length}`,color:"#1f2937"}]}}},Np=(t,e,n)=>{const o=2*(t.x*(e.y-n.y)+e.x*(n.y-t.y)+n.x*(t.y-e.y));if(Math.abs(o)<1e-10)return{x:0,y:0,r2:1e18};const i=t.x*t.x+t.y*t.y,s=e.x*e.x+e.y*e.y,r=n.x*n.x+n.y*n.y,a=(i*(e.y-n.y)+s*(n.y-t.y)+r*(t.y-e.y))/o,c=(i*(n.x-e.x)+s*(t.x-n.x)+r*(e.x-t.x))/o;return{x:a,y:c,r2:(t.x-a)**2+(t.y-c)**2}},Cp=(t,e,n)=>[t.a,t.b,t.c].includes(e)&&[t.a,t.b,t.c].includes(n),Tp=(t,e,n,o=[],i,s=[])=>t.filter(([t,r,a])=>{const c=e[t],h=e[r],l=e[a];if(!c||!h||!l)return!1;return((t,e,n,o=[],i,s=[])=>{const{minX:r,maxX:a,minY:c,maxY:h}=n;if(t<r-.1||t>a+.1||e<c-.1||e>h+.1)return!1;for(const n of o){const o=n.diameter/2+i;if((t-n.center.x)**2+(e-n.center.y)**2<o*o-.1)return!1}for(const n of s){const o=n.width/2+i,s=n.height/2+i,r=t-n.center.x,a=e-n.center.y,c=Math.cos(n.ccwRotation),h=Math.sin(n.ccwRotation),l=r*c+a*h,d=-r*h+a*c;if(Math.abs(l)<o-.1&&Math.abs(d)<s-.1)return!1}return!0})((c.x+h.x+l.x)/3,(c.y+h.y+l.y)/3,n,o,i,s)}),Ep=class extends lp{input;output=null;constructor(t){super(),this.input=t}_step(){const t=this.input.vias??[],e=this.input.rects??[],n=(t=>{const e=t.map((t,e)=>({...t,i:e}));if(e.length<3)return[];let n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,s=Number.NEGATIVE_INFINITY;for(const t of e)n=Math.min(n,t.x),o=Math.min(o,t.y),i=Math.max(i,t.x),s=Math.max(s,t.y);const r=Math.max(i-n,s-o)||1,a=(n+i)/2,c=(o+s)/2,h={x:a-30*r,y:c-r,i:-1},l={x:a,y:c+30*r,i:-2},d={x:a+30*r,y:c-r,i:-3};let u=[{a:h,b:l,c:d,cc:Np(h,l,d)}];for(const t of e){const e=u.filter(e=>{const n=t.x-e.cc.x,o=t.y-e.cc.y;return n*n+o*o<e.cc.r2+1e-6}),n=new Set(e),o=[];for(const t of e){const n=[[t.a,t.b],[t.b,t.c],[t.c,t.a]];for(const[i,s]of n){let n=!1;for(const o of e)if(o!==t&&Cp(o,i,s)){n=!0;break}n||o.push([i,s])}}u=u.filter(t=>!n.has(t));for(const[e,n]of o)u.push({a:e,b:n,c:t,cc:Np(e,n,t)})}return u.filter(t=>t.a.i>=0&&t.b.i>=0&&t.c.i>=0).map(t=>[t.a.i,t.b.i,t.c.i])})(this.input.pts),o=Tp(n,this.input.pts,this.input.bounds,t,this.input.clearance,e);this.output={pts:this.input.pts,validTris:o},this.stats={candidateTriangles:n.length,validTriangles:o.length},this.solved=!0}getConstructorParams(){return[this.input]}getOutput(){return this.output}visualize(){const t=this.output?.validTris??[];return{points:this.input.pts.map(t=>({x:t.x,y:t.y,color:"#2563eb"})),lines:t.flatMap(([t,e,n])=>{const o=this.input.pts[t],i=this.input.pts[e],s=this.input.pts[n];return o&&i&&s?[{points:[o,i],strokeColor:"#64748b"},{points:[i,s],strokeColor:"#64748b"},{points:[s,o],strokeColor:"#64748b"}]:[]}),rects:[],circles:[],texts:[{x:this.input.bounds.minX+6,y:this.input.bounds.minY+12,text:`valid triangles: ${t.length}`,color:"#1f2937"}]}}},wp=class extends up{pipelineDef=[dp("generatePoints",vp,t=>[t.inputProblem]),dp("triangulate",Ep,t=>{const e=t.getStageOutput("generatePoints");if(!e)throw new Error("generatePoints output missing");return[{pts:e.pts,bounds:t.inputProblem.bounds,vias:t.inputProblem.vias,rects:t.inputProblem.rects,clearance:t.inputProblem.clearance}]}),dp("mergeCells",_p,t=>{const e=t.getStageOutput("triangulate");if(!e)throw new Error("triangulate output missing");return[{pts:e.pts,validTris:e.validTris,concavityTolerance:t.inputProblem.concavityTolerance}]}),dp("buildRegions",mp,t=>{const e=t.getStageOutput("mergeCells");if(!e)throw new Error("mergeCells output missing");return[e]})];getConstructorParams(){return[this.inputProblem]}getOutput(){return this.getStageOutput("buildRegions")??null}visualize(){const t=this.getOutput();return t?{points:t.pts.map(t=>({x:t.x,y:t.y,color:"#38b6ff"})),lines:t.regions.flatMap(t=>t.map((e,n)=>{const o=t[(n+1)%t.length]??e;return{points:[{x:e.x,y:e.y},{x:o.x,y:o.y}],strokeColor:"#4ecb82"}})),rects:[],circles:(this.inputProblem.vias??[]).map(t=>({center:{x:t.center.x,y:t.center.y},radius:t.diameter/2,stroke:"#ff6b6b"})),texts:[{x:this.inputProblem.bounds.minX+8,y:this.inputProblem.bounds.minY+16,text:`regions=${t.regions.length}`,color:"#ffffff"}]}:{points:[],lines:[],rects:[],circles:[],texts:[]}}},Rp=1e-9,Op=(t,e)=>{const n=[Up(t)],o=[];let i=e.maxSplitsPerRegion??32;for(;n.length>0;){const t=n.pop();if(!t)continue;if(t.length<4){o.push(t);continue}const s=Ap(t,e);if(!s||i<=0){o.push(t);continue}const[r,a]=Dp(t,s.i,s.j);i-=1,n.push(r,a)}return o},Ap=(t,e)=>{const n=Yp(t);if(!n)return null;const{triangles:o}=n,i=jp(t);if(i<=Rp)return null;const s=Math.sqrt(i),r=o.map(e=>Wp(t[e[0]],t[e[1]],t[e[2]]));let a=null;for(const c of n.internalEdges){const{i:h,j:l,triA:d,triB:u}=c,p=Vp(t[h],t[l])/s;if(p>e.maxNeckRatio)continue;const f=zp(d,u,o.length,n.triangleAdjacency,r),g=i-f,m=Math.min(f,g)/i;if(m<e.minSplitBalanceRatio)continue;const y=p/Math.max(m,Rp);(!a||y<a.score)&&(a={i:h,j:l,score:y})}return a?{i:a.i,j:a.j}:null},zp=(t,e,n,o,i)=>{const s=new Array(n).fill(!1),r=[t];s[e]=!0;let a=0;for(;r.length>0;){const t=r.pop();if(void 0===t||s[t])continue;s[t]=!0,a+=i[t]??0;const e=o[t]??[];for(const t of e)s[t]||r.push(t)}return a},Dp=(t,e,n)=>[Lp(t,e,n),Lp(t,n,e)],Lp=(t,e,n)=>{const o=[],i=t.length;let s=e;for(o.push(t[s]);s!==n;)s=(s+1)%i,o.push(t[s]);return Up(o)},Yp=t=>{const e=t.length;if(e<3)return null;const n=new Set;for(let t=0;t<e;t++){const o=(t+1)%e;n.add(Hp(t,o))}const o=Xp(t);if(!o||0===o.length)return null;const i=new Map;o.forEach((t,e)=>{for(let n=0;n<3;n++){const o=t[n],s=t[(n+1)%3],r=Hp(o,s),a=i.get(r);a?a.push(e):i.set(r,[e])}});const s=Array.from({length:o.length},()=>[]),r=[];for(const[t,e]of i.entries()){if(n.has(t))continue;if(2!==e.length)continue;const[o,i]=t.split("_"),a=Number(o),c=Number(i),h=e[0],l=e[1];r.push({i:a,j:c,triA:h,triB:l});const d=s[h],u=s[l];d&&d.push(l),u&&u.push(h)}return{triangles:o,internalEdges:r,triangleAdjacency:s}},Xp=t=>{const e=t.length;if(e<3)return null;const n=Math.sign(Bp(t));if(0===n)return null;const o=[...Array(e).keys()];n<0&&o.reverse();const i=[];let s=0;for(;o.length>3&&s<e*e;){let e=!1;for(let n=0;n<o.length;n++){const s=o[(n-1+o.length)%o.length],r=o[n],a=o[(n+1)%o.length];if(void 0===s||void 0===r||void 0===a)continue;const c=t[s],h=t[r],l=t[a];if(!c||!h||!l)continue;if(!Fp(c,h,l))continue;let d=!1;for(const e of o){if(e===s||e===r||e===a)continue;const n=t[e];if(n&&kp(n,c,h,l)){d=!0;break}}if(!d){i.push([s,r,a]),o.splice(n,1),e=!0;break}}if(!e)return null;s+=1}if(3===o.length){const[t,e,n]=o;void 0!==t&&void 0!==e&&void 0!==n&&i.push([t,e,n])}return i},Fp=(t,e,n)=>$p(t,e,n)>Rp,kp=(t,e,n,o)=>{const i=$p(e,n,t),s=$p(n,o,t),r=$p(o,e,t);return i>=-1e-9&&s>=-1e-9&&r>=-1e-9},$p=(t,e,n)=>(e.x-t.x)*(n.y-t.y)-(e.y-t.y)*(n.x-t.x),Bp=t=>{let e=0;for(let n=0;n<t.length;n++){const o=t[n],i=t[(n+1)%t.length];o&&i&&(e+=o.x*i.y-i.x*o.y)}return e/2},jp=t=>Math.abs(Bp(t)),Wp=(t,e,n)=>Math.abs($p(t,e,n))/2,Vp=(t,e)=>Math.hypot(t.x-e.x,t.y-e.y),Hp=(t,e)=>t<e?`${t}_${e}`:`${e}_${t}`,Up=t=>{if(t.length<2)return t;const e=t[0],n=t[t.length-1];return e&&n&&e.x===n.x&&e.y===n.y?t.slice(0,-1):t},Gp={pattern:"grid",pitchX:2.2,pitchY:1.8,staggerAxis:"x",staggerOffset:1.1,staggerOffsetX:1.1,padWidth:.9,padHeight:1,padGap:.35,viaDiameter:.3,clearance:.2,concavityTolerance:.3,boundsPadding:1.2,orientation:"horizontal",portSpacing:.25,maxNeckRatio:0,minSplitBalanceRatio:.2},Zp=(t,e)=>{let n=Number.POSITIVE_INFINITY,o=Number.POSITIVE_INFINITY,i=Number.NEGATIVE_INFINITY,s=Number.NEGATIVE_INFINITY;for(const r of t)for(const t of r.padCenters){const r="horizontal"===e.orientation?e.padWidth/2:e.padHeight/2,a="horizontal"===e.orientation?e.padHeight/2:e.padWidth/2;t.x-r<n&&(n=t.x-r),t.y-a<o&&(o=t.y-a),t.x+r>i&&(i=t.x+r),t.y+a>s&&(s=t.y+a)}return{minX:n-e.boundsPadding,minY:o-e.boundsPadding,maxX:i+e.boundsPadding,maxY:s+e.boundsPadding}},qp=t=>"staggered"===t.pattern?(t=>{const e=[],n=[],o=t.padGap/2+t.padWidth/2,i=-(t.cols-1)*t.pitchX/2,s=-(t.rows-1)*t.pitchY/2;for(let r=0;r<t.rows;r++){const a="x"===t.staggerAxis&&r%2==1?t.staggerOffset:0;for(let c=0;c<t.cols;c++){const h="y"===t.staggerAxis&&c%2==1?t.staggerOffset:0,l={x:i+c*t.pitchX+a,y:s+r*t.pitchY+h},d="horizontal"===t.orientation?{x:l.x-o,y:l.y}:{x:l.x,y:l.y-o},u="horizontal"===t.orientation?{x:l.x+o,y:l.y}:{x:l.x,y:l.y+o};e.push({jumperId:`jumper_r${r}_c${c}`,center:l,orientation:t.orientation,padCenters:[d,u]}),n.push({center:d,diameter:t.viaDiameter},{center:u,diameter:t.viaDiameter})}}return{jumpers:e,vias:n,bounds:Zp(e,t)}})(t):(t=>{const e=[],n=[],o=t.padGap/2+t.padWidth/2,i=-(t.cols-1)*t.pitchX/2,s=-(t.rows-1)*t.pitchY/2;for(let r=0;r<t.rows;r++)for(let a=0;a<t.cols;a++){const c={x:i+a*t.pitchX,y:s+r*t.pitchY},h="horizontal"===t.orientation?{x:c.x-o,y:c.y}:{x:c.x,y:c.y-o},l="horizontal"===t.orientation?{x:c.x+o,y:c.y}:{x:c.x,y:c.y+o},d=`jumper_r${r}_c${a}`;e.push({jumperId:d,center:c,orientation:t.orientation,padCenters:[h,l]}),n.push({center:h,diameter:t.viaDiameter},{center:l,diameter:t.viaDiameter})}return{jumpers:e,vias:n,bounds:{minX:i-o-t.padWidth/2-t.boundsPadding,maxX:i+(t.cols-1)*t.pitchX+o+t.padWidth/2+t.boundsPadding,minY:s-o-t.padHeight/2-t.boundsPadding,maxY:s+(t.rows-1)*t.pitchY+o+t.padHeight/2+t.boundsPadding}}})(t),Jp=t=>({x:(t.minX+t.maxX)/2,y:(t.minY+t.maxY)/2}),Kp=t=>[{x:t.minX,y:t.minY},{x:t.maxX,y:t.minY},{x:t.maxX,y:t.maxY},{x:t.minX,y:t.maxY}],Qp=(t,e,n)=>Math.abs(t-e)<=n,tf=(t,e,n)=>Qp(t.x,e.x,n)&&Qp(t.y,e.y,n),ef=t=>t.map((t,e)=>{const n=(t=>{let e=Number.POSITIVE_INFINITY,n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.NEGATIVE_INFINITY;for(const s of t)s.x<e&&(e=s.x),s.y<n&&(n=s.y),s.x>o&&(o=s.x),s.y>i&&(i=s.y);return{minX:e,minY:n,maxX:o,maxY:i}})(t);return{regionId:`top_${e}`,ports:[],d:{bounds:n,center:Jp(n),polygon:t,isPad:!1}}}),nf=t=>{const e=t.end.x-t.start.x,n=t.end.y-t.start.y;return Math.hypot(e,n)},of=(t,e)=>({x:t.start.x+(t.end.x-t.start.x)*e,y:t.start.y+(t.end.y-t.start.y)*e}),sf=(t,e,n)=>{const o=[];if(!t.d.polygon||!e.d.polygon)return o;for(let i=0;i<t.d.polygon.length;i++){const s=t.d.polygon[i],r=t.d.polygon[(i+1)%t.d.polygon.length];if(s&&r)for(let t=0;t<e.d.polygon.length;t++){const i=e.d.polygon[t],a=e.d.polygon[(t+1)%e.d.polygon.length];if(!i||!a)continue;const c=hf({start:s,end:r},{start:i,end:a},n);if(!c)continue;o.some(t=>cf(t,c,n))||o.push(c)}}return o},rf=(t,e)=>{const n=[];for(const o of t){let t=o,i=!0;for(;i;){i=!1;for(let o=0;o<n.length;o++){const s=n[o];if(!s)continue;const r=af(t,s,e);if(r){t=r,n.splice(o,1),i=!0;break}}}n.push(t)}return n},af=(t,e,n)=>{const o=t.end.x-t.start.x,i=t.end.y-t.start.y,s=e.end.x-e.start.x,r=e.end.y-e.start.y,a=o**2+i**2;if(a<=n**2)return null;if(!Qp(o*r-i*s,0,n))return null;const c=e.start.x-t.start.x,h=e.start.y-t.start.y,l=e.end.x-t.start.x,d=e.end.y-t.start.y,u=o*d-i*l;if(!Qp(o*h-i*c,0,n)||!Qp(u,0,n))return null;const p=(c*o+h*i)/a,f=(l*o+d*i)/a,g=Math.min(p,f),m=Math.max(p,f),y=n/Math.sqrt(a);if(g>1+y||m<0-y)return null;const x=Math.min(0,g),v=Math.max(1,m);return{start:of(t,x),end:of(t,v)}},cf=(t,e,n)=>tf(t.start,e.start,n)&&tf(t.end,e.end,n)||tf(t.start,e.end,n)&&tf(t.end,e.start,n),hf=(t,e,n)=>{const o=t.end.x-t.start.x,i=t.end.y-t.start.y,s=e.end.x-e.start.x,r=e.end.y-e.start.y,a=o**2+i**2;if(a<=n**2)return null;if(!Qp(o*r-i*s,0,n))return null;const c=e.start.x-t.start.x,h=e.start.y-t.start.y,l=e.end.x-t.start.x,d=e.end.y-t.start.y,u=o*d-i*l;if(!Qp(o*h-i*c,0,n)||!Qp(u,0,n))return null;const p=(c*o+h*i)/a,f=(l*o+d*i)/a,g=Math.max(0,Math.min(p,f)),m=Math.min(1,Math.max(p,f));return m-g<=n/Math.sqrt(a)?null:{start:of(t,g),end:of(t,m)}},lf=(t,e,n)=>{const o=Math.max(t.minX,e.minX),i=Math.min(t.maxX,e.maxX),s=Math.max(t.minY,e.minY),r=Math.min(t.maxY,e.maxY);return i<o-n||r<s-n?null:{minX:o,maxX:i,minY:s,maxY:r}},df=t=>{const e=(t=>{const e=t.orientation??Gp.orientation,n=t.staggerAxis??Gp.staggerAxis,o=t.padWidth??Gp.padWidth,i=t.padHeight??Gp.padHeight,s=t.padGap??Gp.padGap,r=t.clearance??Gp.clearance,a=t.colSpacing??t.pitchX??Gp.pitchX,c=t.rowSpacing??t.pitchY??Gp.pitchY,h=(l=o,d=i,u=s,"horizontal"===e?{x:u+2*l,y:d}:{x:d,y:u+2*l});var l,d,u;const p=r,f=((t,e,n,o,i)=>"horizontal"===t?"x"===e?i+2*n:o:"x"===e?o:i+2*n)(e,n,o,i,s)/2,g=t.staggerOffset??t.staggerOffsetX??f,m={...Gp,...t,orientation:e,staggerAxis:n,pitchX:Math.max(a,h.x+p),pitchY:Math.max(c,h.y+p),padWidth:o,padHeight:i,padGap:s,staggerOffset:g,staggerOffsetX:g,concavityTolerance:t.concavityTolerance??Gp.concavityTolerance,clearance:r,portSpacing:t.portSpacing??Gp.portSpacing,maxNeckRatio:t.maxNeckRatio??Gp.maxNeckRatio,minSplitBalanceRatio:t.minSplitBalanceRatio??Gp.minSplitBalanceRatio};if(m.cols<=0||m.rows<=0)throw new Error("rows and cols must be > 0");if(!Number.isFinite(m.portSpacing)||m.portSpacing<=0)throw new Error("portSpacing must be > 0");if(!Number.isFinite(m.maxNeckRatio)||m.maxNeckRatio<0)throw new Error("maxNeckRatio must be >= 0");if(!Number.isFinite(m.minSplitBalanceRatio)||m.minSplitBalanceRatio<0||m.minSplitBalanceRatio>.5)throw new Error("minSplitBalanceRatio must be between 0 and 0.5");return m})(t),n=qp(e),o="horizontal"===e.orientation?e.padWidth:e.padHeight,i="horizontal"===e.orientation?e.padHeight:e.padWidth,s=n.jumpers.flatMap(t=>t.padCenters.map(t=>({center:t,width:o,height:i,ccwRotation:0}))),r=new wp({bounds:n.bounds,rects:s,clearance:0,concavityTolerance:e.concavityTolerance});r.solve();const a=r.getOutput();if(!a)throw new Error(r.error??"ConvexRegionsSolver failed");const c=((t,e)=>{if(e.maxNeckRatio<=0)return t;const n=[];for(const o of t)n.push(...Op(o,e));return n})(a.regions,{maxNeckRatio:e.maxNeckRatio,minSplitBalanceRatio:e.minSplitBalanceRatio}),h=ef(c),l=((t,e)=>t.flatMap(t=>{const[n,o]=t.padCenters,i="horizontal"===e.orientation?e.padWidth/2:e.padHeight/2,s="horizontal"===e.orientation?e.padHeight/2:e.padWidth/2,r={minX:n.x-i,maxX:n.x+i,minY:n.y-s,maxY:n.y+s},a={minX:o.x-i,maxX:o.x+i,minY:o.y-s,maxY:o.y+s},c=i/2,h=s/2,l="horizontal"===e.orientation?{minX:Math.min(n.x,o.x),maxX:Math.max(n.x,o.x),minY:t.center.y-h,maxY:t.center.y+h}:{minX:t.center.x-c,maxX:t.center.x+c,minY:Math.min(n.y,o.y),maxY:Math.max(n.y,o.y)};return[{regionId:`${t.jumperId}_pad1`,ports:[],d:{bounds:r,center:n,polygon:Kp(r),isPad:!0,isThroughJumper:!1}},{regionId:`${t.jumperId}_bridge`,ports:[],d:{bounds:l,center:t.center,polygon:Kp(l),isPad:!1,isThroughJumper:!0}},{regionId:`${t.jumperId}_pad2`,ports:[],d:{bounds:a,center:o,polygon:Kp(a),isPad:!0,isThroughJumper:!1}}]}))(n.jumpers,{orientation:e.orientation,padWidth:e.padWidth,padHeight:e.padHeight}),d=((t,e,n=1e-5)=>{const o=[];let i=0;for(let s=0;s<t.length;s++){const r=t[s];if(r?.d.polygon)for(let a=s+1;a<t.length;a++){const s=t[a];if(!s?.d.polygon)continue;const c=sf(r,s,n);for(const t of c){const n=nf(t),a=Math.floor(n/e),c=Math.max(1,a-1);for(let e=0;e<c;e++){const n=of(t,(e+1)/(c+1));o.push({portId:"tp_"+i++,region1:r,region2:s,d:{x:n.x,y:n.y}})}}}}return o})(h,e.portSpacing),u=((t,e,n=1e-5)=>{const o=[];let i=0,s=0;const r=t.filter(t=>t.d.isPad),a=t.filter(t=>t.d.isThroughJumper&&!t.d.isPad);for(const t of r)for(const s of e){const e=sf(t,s,n),r=rf(e,n);for(const e of r){const n=of(e,.5);o.push({portId:"jp_"+i++,region1:t,region2:s,d:{x:n.x,y:n.y}})}}for(const t of a)for(const e of r){const i=lf(t.d.bounds,e.d.bounds,n);if(!i)continue;const r=Jp(i);o.push({portId:"jip_"+s++,region1:e,region2:t,d:{x:r.x,y:r.y}})}return o})(l,h),p=[...d,...u];return(t=>{for(const e of t)e.region1.ports.push(e),e.region2.ports.push(e)})(p),{regions:[...h,...l],ports:p,jumperLocations:n.jumpers.map((t,e)=>({center:t.center,orientation:t.orientation,padRegions:[l[3*e],l[3*e+2]].filter(t=>Boolean(t))})),topLayerRegions:h,jumperRegions:l,jumpers:n.jumpers,vias:n.vias,bounds:n.bounds}},uf=class extends Dn{getSolverName(){return"JumperPrepatternSolver2_HyperGraph"}constructorParams;nodeWithPortPoints;colorMap;traceWidth;obstacleMargin;hyperParameters;jumperGraphSolver=null;xyConnections=[];graphBounds=null;jumperLocations=[];solvedRoutes=[];jumpers=[];phase="jumperGraph";curvySolvers=[];currentCurvySolverIndex=0;routeInfos=[];regionCurvedPaths=new Map;constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.obstacleMargin=t.obstacleMargin??.15,this.hyperParameters=t.hyperParameters??{},this.MAX_ITERATIONS=1e6,0===Object.keys(this.colorMap).length&&(this.colorMap=this._buildColorMap())}getConstructorParams(){return this.constructorParams}_buildColorMap(){const t=["#e6194b","#3cb44b","#ffe119","#4363d8","#f58231","#911eb4","#46f0f0","#f032e6","#bcf60c","#fabebe"],e={},n=new Set;for(const t of this.nodeWithPortPoints.portPoints)n.add(t.connectionName);let o=0;for(const i of Array.from(n))e[i]=t[o%t.length],o++;return e}_normalizeRegionPolygonsToBounds(t){for(const e of t.regions){const t=e.d,n=t?.polygon,o=t?.bounds;if(!n||0===n.length||!o)continue;let i=1/0,s=1/0;for(const t of n)i=Math.min(i,t.x),s=Math.min(s,t.y);const r=o.minX-i,a=o.minY-s;(Math.abs(r)>1e-12||Math.abs(a)>1e-12)&&(t.polygon=n.map(t=>({x:t.x+r,y:t.y+a}))),t.polygonPerimeterCache&&(t.polygonPerimeterCache=void 0)}return t}_getPatternConfig(){return{cols:this.hyperParameters.COLS??1,rows:this.hyperParameters.ROWS??1}}_generate0603Grid(t,e,n,o){const i="horizontal"===e?t.rows:t.cols,s="horizontal"===e?t.cols:t.rows,r=o.maxX-o.minX,a=o.maxY-o.minY,c=.35,h=this.hyperParameters.TRACE_CHANNELS_BETWEEN_JUMPERS??1,l=this.traceWidth*h+2*this.obstacleMargin,d="horizontal"===e?2.15:1,u="horizontal"===e?1:2.15,p="horizontal"===e?"x":"y",f="staggered"===n,g=f&&"x"===p?d/2:f?u/2:0,m=Math.max(0,r-1),x=Math.max(0,a-1),v=Math.max(0,m-(f&&"x"===p?g:0)),b=Math.max(0,x-(f&&"y"===p?g:0)),P=i>1?Math.max(d+l,(v-d)/(i-1)):d,S=s>1?Math.max(u+l,(b-u)/(s-1)):u,I=df({cols:i,rows:s,orientation:e,pattern:n,staggerAxis:p,colSpacing:P,rowSpacing:S,padWidth:.9,padHeight:1,padGap:c,clearance:l,boundsPadding:0,maxNeckRatio:.4,minSplitBalanceRatio:.2}),M=I.bounds,_=(M.minX+M.maxX)/2,N=(M.minY+M.maxY)/2,C=y((o.minX+o.maxX)/2-_,(o.minY+o.maxY)/2-N);return this._normalizeRegionPolygonsToBounds(Ti(I,C))}_initializeGraph(){const t=this.nodeWithPortPoints,e=this._getPatternConfig(),n=this.hyperParameters.ORIENTATION??"vertical",o=this.hyperParameters.JUMPER_TYPE??"1206x4",i=this.hyperParameters.PATTERN??"grid",s={minX:t.center.x-t.width/2,maxX:t.center.x+t.width/2,minY:t.center.y-t.height/2,maxY:t.center.y+t.height/2};let r;if(this.graphBounds=s,"0603"===o){const t=this._generate0603Grid(e,n,i,s);if(!t)return this.error=`0603 grid (${e.cols}x${e.rows}) is too large to fit in node bounds`,this.failed=!0,!1;r=t}else r=rs({cols:e.cols,rows:e.rows,marginX:Math.max(1.2,.3*e.cols),marginY:Math.max(1.2,.3*e.rows),outerPaddingX:.4,outerPaddingY:.4,parallelTracesUnderJumperCount:2,innerColChannelPointCount:3,innerRowChannelPointCount:3,outerChannelXPointCount:3,outerChannelYPointCount:3,regionsBetweenPads:!0,orientation:n,bounds:s});if(r.regions.length>0){let t=1/0,e=-1/0,n=1/0,i=-1/0;for(const o of r.regions){if(!o.d?.isPad)continue;const s=o.d?.bounds;s&&(t=Math.min(t,s.minX),e=Math.max(e,s.maxX),n=Math.min(n,s.minY),i=Math.max(i,s.maxY))}const a="0603"===o?.5:1;if(t-a<s.minX||e+a>s.maxX||n-a<s.minY||i+a>s.maxY)return this.error=`baseGraph bounds (${t.toFixed(2)}, ${n.toFixed(2)}, ${e.toFixed(2)}, ${i.toFixed(2)}) exceed node bounds (${s.minX.toFixed(2)}, ${s.minY.toFixed(2)}, ${s.maxX.toFixed(2)}, ${s.maxY.toFixed(2)})`,this.failed=!0,!1}this.jumperLocations=r.jumperLocations?.map(t=>({center:t.center,orientation:t.orientation,padRegions:t.padRegions}))??[];const a=new Map;for(const e of t.portPoints){const t=a.get(e.connectionName);t?t.points.push(e):a.set(e.connectionName,{points:[e],rootConnectionName:e.rootConnectionName})}this.xyConnections=[];for(const[t,e]of Array.from(a.entries()))e.points.length<2||this.xyConnections.push({start:{x:e.points[0].x,y:e.points[0].y},end:{x:e.points[1].x,y:e.points[1].y},connectionId:t});if(0===this.xyConnections.length)return this.solved=!0,!0;const c=((t,e)=>{const n=[...t.regions],o=[...t.ports],i=[],s=Ni(t.regions);for(const r of e){const{start:e,end:a,connectionId:c}=r,h=Ki(`conn:${c}:start`,e.x,e.y);n.push(h);const l=Ki(`conn:${c}:end`,a.x,a.y);n.push(l);const d=is(e.x,e.y,t.regions,s);if(d){const t=Ji(`conn:${c}:start-port`,h,d.region,d.portPosition);o.push(t)}const u=is(a.x,a.y,t.regions,s);if(u){const t=Ji(`conn:${c}:end-port`,l,u.region,u.portPosition);o.push(t)}const p={connectionId:c,mutuallyConnectedNetworkId:c,startRegion:h,endRegion:l};i.push(p)}return{regions:n,ports:o,connections:i}})(r,this.xyConnections);return this.jumperGraphSolver=new qi({inputGraph:{regions:c.regions,ports:c.ports},inputConnections:c.connections}),this.jumperGraphSolver.MAX_ITERATIONS*=3,!0}_step(){switch(this.phase){case"jumperGraph":this._stepJumperGraph();break;case"curvyTrace":this._stepCurvyTrace();break;case"done":this.solved=!0}}_stepJumperGraph(){if(!this.jumperGraphSolver){if(this._initializeGraph(),this.solved)return;if(!this.jumperGraphSolver)return void(this.failed=!0)}this.activeSubSolver=this.jumperGraphSolver,this.jumperGraphSolver.step(),this.jumperGraphSolver.solved?(this._initializeCurvyTraceSolvers(),this.curvySolvers.length>0?this.phase="curvyTrace":(this._finalizeCurvyTraceResults(),this.phase="done",this.solved=!0)):this.jumperGraphSolver.failed&&(this.error=this.jumperGraphSolver.error,this.failed=!0)}_stepCurvyTrace(){if(this.currentCurvySolverIndex>=this.curvySolvers.length)return this._finalizeCurvyTraceResults(),this.phase="done",void(this.solved=!0);const t=this.curvySolvers[this.currentCurvySolverIndex],e=t.solver;if(this.activeSubSolver=e,e.step(),e.solved){const n=t.regionId;this.regionCurvedPaths.has(n)||this.regionCurvedPaths.set(n,new Map);for(const t of e.outputTraces){const e=t.networkId??"",o=t.points.map(t=>({x:t.x,y:t.y})),i={path:o,start:o[0]??{x:0,y:0},end:o[o.length-1]??{x:0,y:0}};this.regionCurvedPaths.get(n).has(e)||this.regionCurvedPaths.get(n).set(e,[]),this.regionCurvedPaths.get(n).get(e).push(i)}this.currentCurvySolverIndex++}else e.failed&&this.currentCurvySolverIndex++}_initializeCurvyTraceSolvers(){if(!this.jumperGraphSolver)return;const t=new Set,e=[];for(const t of this.jumperLocations)for(const n of t.padRegions){const t=n.d.bounds,o=n.d.center;e.push({minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:{x:o.x,y:o.y},networkIds:[]})}const n=new Map;for(let e=0;e<this.jumperGraphSolver.solvedRoutes.length;e++){const o=this.jumperGraphSolver.solvedRoutes[e],i=o.connection.connectionId,s=this.nodeWithPortPoints.portPoints.find(t=>t.connectionName===i)?.rootConnectionName,r=[],a=[];let c=null,h=null;for(let l=0;l<o.path.length;l++){const d=o.path[l],u=d.port,p=d.lastRegion,f=u.region1,g=u.region2;let m;if(p)f&&f.regionId!==p.regionId?m=f:g&&g.regionId!==p.regionId&&(m=g);else{const t=o.path[l+1],e=t?.lastRegion;if(e&&(f&&f.regionId===e.regionId?m=f:g&&g.regionId===e.regionId&&(m=g)),!m){const t=t=>t?.regionId?.startsWith("conn:");m=!f||t(f)||f.d?.isPad||f.d?.isThroughJumper?!g||t(g)||g.d?.isPad||g.d?.isThroughJumper?!f||f.d?.isPad||f.d?.isThroughJumper?(!g||g.d?.isPad||g.d?.isThroughJumper)&&f||g:f:g:f}}if(m&&(!c||m.regionId!==c.regionId)){if(c&&h){a.push({regionId:c.regionId,region:c,entryPort:h,exitPort:u});const t=c.regionId;n.has(t)||n.set(t,[]),n.get(t).push({regionId:c.regionId,region:c,routeIndex:e,connectionName:i,rootConnectionName:s,entryPort:h,exitPort:u})}c=m,h=u}if(p?.d?.isThroughJumper&&!t.has(p.regionId)){t.add(p.regionId);const e=p.d.bounds,n=p.d.center,o=e.maxX-e.minX>e.maxY-e.minY,i="0603"===(this.hyperParameters.JUMPER_TYPE??"1206x4")?"0603":"1206x4_pair";o?r.push({route_type:"jumper",start:{x:e.minX,y:n.y},end:{x:e.maxX,y:n.y},footprint:i}):r.push({route_type:"jumper",start:{x:n.x,y:e.minY},end:{x:n.x,y:e.maxY},footprint:i})}}if(c&&h){const t=o.path[o.path.length-1];a.push({regionId:c.regionId,region:c,entryPort:h,exitPort:t?.port||null})}this.routeInfos.push({connectionId:i,rootConnectionName:s,jumpers:r,traversals:a})}for(let t=0;t<this.routeInfos.length;t++){const n=this.routeInfos[t],o=n.rootConnectionName??n.connectionId;for(const t of n.jumpers){const n=[t.start,t.end];for(const t of n)for(const n of e){const e=Math.abs(n.center.x-t.x),i=Math.abs(n.center.y-t.y);e<.1&&i<.1&&(n.networkIds.includes(o)||n.networkIds.push(o))}}}for(const[t,o]of n){if(0===o.length)continue;const n=o[0].region;if(n.d.isPad||n.d.isThroughJumper)continue;const i=n.d.bounds,s=[];for(const t of o)s.push({start:{x:t.entryPort.d.x,y:t.entryPort.d.y},end:{x:t.exitPort.d.x,y:t.exitPort.d.y},networkId:t.rootConnectionName??t.connectionName});const r=.01,a=e.filter(t=>t.minX<=i.maxX+r&&t.maxX>=i.minX-r&&t.minY<=i.maxY+r&&t.maxY>=i.minY-r).map(t=>{const e=o.map(t=>t.rootConnectionName??t.connectionName),n=t.networkIds.find(t=>e.includes(t));return{minX:t.minX,minY:t.minY,maxX:t.maxX,maxY:t.maxY,center:t.center,networkId:n}}),c={bounds:i,waypointPairs:s,obstacles:a,preferredTraceToTraceSpacing:2*this.traceWidth,preferredObstacleToTraceSpacing:2*this.traceWidth},h=new Bu(c);this.curvySolvers.push({solver:h,regionId:t,traversals:o.map(t=>({routeIndex:t.routeIndex,connectionName:t.connectionName,rootConnectionName:t.rootConnectionName}))})}}_finalizeCurvyTraceResults(){const t=(t,e)=>Math.sqrt((t.x-e.x)**2+(t.y-e.y)**2);for(let e=0;e<this.routeInfos.length;e++){const n=this.routeInfos[e],o=[];for(const e of n.traversals){const i=e.regionId,s=n.rootConnectionName??n.connectionId,r=this.regionCurvedPaths.get(i)?.get(s);let a=null;if(r&&r.length>0){const n={x:e.entryPort.d.x,y:e.entryPort.d.y},o=e.exitPort?{x:e.exitPort.d.x,y:e.exitPort.d.y}:null;let i=null,s=1/0;for(const e of r){const r=t(e.start,n)+(o?t(e.end,o):0);r<s&&(s=r,i=e)}i&&s<.5&&(a=i.path)}if(a&&a.length>0){for(let t=o.length>0?1:0;t<a.length;t++)o.push({x:a[t].x,y:a[t].y,z:0})}else 0===o.length&&o.push({x:e.entryPort.d.x,y:e.entryPort.d.y,z:0}),e.exitPort&&o.push({x:e.exitPort.d.x,y:e.exitPort.d.y,z:0})}this.solvedRoutes.push({connectionName:n.connectionId,rootConnectionName:n.rootConnectionName,traceThickness:this.traceWidth,route:o,jumpers:n.jumpers})}}getOutput(){return this.solvedRoutes}getOutputJumpers(){if(this.jumpers.length>0)return this.jumpers;const t=new Map;for(const e of this.solvedRoutes)for(const n of e.jumpers){const o=[n.start,n.end];for(const n of o){const o=`${n.x.toFixed(3)},${n.y.toFixed(3)}`,i=t.get(o)??[];e.rootConnectionName&&!i.includes(e.rootConnectionName)&&i.push(e.rootConnectionName),i.includes(e.connectionName)||i.push(e.connectionName),t.set(o,i)}}const e=this.hyperParameters.JUMPER_TYPE??"1206x4",n=En["0603"===e?"0603":"1206x4_pair"];for(const o of this.jumperLocations){const i="horizontal"===o.orientation,s=o.padRegions.map(e=>{const n=e.d.bounds,o=e.d.center,i=n.maxX-n.minX,s=n.maxY-n.minY,r=`${o.x.toFixed(3)},${o.y.toFixed(3)}`;return{type:"rect",center:o,width:i,height:s,layers:["top"],connectedTo:[...t.get(r)??[]]}}),r={jumper_footprint:e,center:o.center,orientation:o.orientation,width:i?n.length:n.width,height:i?n.width:n.length,pads:s};this.jumpers.push(r)}return this.jumpers=this.jumpers.filter(t=>t.pads.some(t=>t.connectedTo.length>0)),this.jumpers}visualize(){if(this.jumperGraphSolver&&!this.solved)return this.jumperGraphSolver.visualize();const t={lines:[],points:[],rects:[],circles:[]},e=this.nodeWithPortPoints,n={minX:e.center.x-e.width/2,maxX:e.center.x+e.width/2,minY:e.center.y-e.height/2,maxY:e.center.y+e.height/2};t.lines.push({points:[{x:n.minX,y:n.minY},{x:n.maxX,y:n.minY},{x:n.maxX,y:n.maxY},{x:n.minX,y:n.maxY},{x:n.minX,y:n.minY}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"});for(const n of e.portPoints)t.points.push({x:n.x,y:n.y,label:n.connectionName,color:this.colorMap[n.connectionName]??"blue"});for(const e of this.solvedRoutes){const n=this.colorMap[e.connectionName]??"blue";for(let o=0;o<e.route.length-1;o++){const i=e.route[o],s=e.route[o+1];t.lines.push({points:[i,s],strokeColor:Mn(n,.2),strokeWidth:e.traceThickness,layer:"route-layer-0"})}for(const o of e.jumpers)this._drawJumperPads(t,o,Mn(n,.5))}return t}_drawJumperPads(t,e,n){const o=En[e.footprint],i=e.end.x-e.start.x,s=e.end.y-e.start.y,r=Math.abs(i)>Math.abs(s),a=r?o.padLength:o.padWidth,c=r?o.padWidth:o.padLength;t.rects.push({center:{x:e.start.x,y:e.start.y},width:a,height:c,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:a,height:c,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*o.padWidth,layer:"jumper-body"})}},pf=class extends io{constructorParams;nodeWithPortPoints;colorMap;traceWidth;obstacleMargin;connMap;baseHyperParameters;availableJumperTypes;solvedRoutes=[];jumpers=[];constructor(t){super(),this.constructorParams=t,this.nodeWithPortPoints=t.nodeWithPortPoints,this.colorMap=t.colorMap??{},this.traceWidth=t.traceWidth??.15,this.obstacleMargin=t.obstacleMargin??.15,this.connMap=t.connMap,this.baseHyperParameters=t.hyperParameters??{},this.availableJumperTypes=t.availableJumperTypes??["0603"],this.MAX_ITERATIONS=1e6,this.GREEDY_MULTIPLIER=1,this.MIN_SUBSTEPS=1e3}getConstructorParams(){return this.constructorParams}getHyperParameterDefs(){const t=[],e=this.nodeWithPortPoints,n=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",1);t.push({name:"0603_max_rows_and_cols_vert_1trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:n.cols,ROWS:n.rows,ORIENTATION:"vertical",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const o=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",1,"staggered");t.push({name:"0603_max_rows_and_cols_vert_1trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:o.cols,ROWS:o.rows,ORIENTATION:"vertical",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const i=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",2);t.push({name:"0603_max_rows_and_cols_vert_2trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:i.cols,ROWS:i.rows,ORIENTATION:"vertical",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const s=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"vertical",2,"staggered");t.push({name:"0603_max_rows_and_cols_vert_2trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:s.cols,ROWS:s.rows,ORIENTATION:"vertical",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const r=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",1);t.push({name:"0603_max_rows_and_cols_horz_1trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:r.cols,ROWS:r.rows,ORIENTATION:"horizontal",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const a=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",1,"staggered");t.push({name:"0603_max_rows_and_cols_horz_1trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:a.cols,ROWS:a.rows,ORIENTATION:"horizontal",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:1}]});const c=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",2);t.push({name:"0603_max_rows_and_cols_horz_2trace_grid",possibleValues:[{JUMPER_TYPE:"0603",COLS:c.cols,ROWS:c.rows,ORIENTATION:"horizontal",PATTERN:"grid",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]});const h=this.calculateMax0603ConfigWithTraceChannels(e.width,e.height,"horizontal",2,"staggered");t.push({name:"0603_max_rows_and_cols_horz_2trace_staggered",possibleValues:[{JUMPER_TYPE:"0603",COLS:h.cols,ROWS:h.rows,ORIENTATION:"horizontal",PATTERN:"staggered",TRACE_CHANNELS_BETWEEN_JUMPERS:2}]}),t.push({name:"1206x4",possibleValues:[{JUMPER_TYPE:"1206x4"}]});return t.push({name:"1206x4_cols",possibleValues:[1,2,3,4,6,8,10].map(t=>({COLS:t}))}),t.push({name:"1206x4_rows",possibleValues:[1,2,3,4,8].map(t=>({ROWS:t}))}),t.push({name:"orientation",possibleValues:[{ORIENTATION:"vertical"},{ORIENTATION:"horizontal"}]}),t}isValidCombination(t){const{JUMPER_TYPE:e,COLS:n,ROWS:o}=t,i=[1,2,4,6,8],s=[1,2,3,4,6,8,10],r=[1,2,3,4,8];return"0603"===e?i.includes(n)&&i.includes(o):"1206x4"===e&&(s.includes(n)&&r.includes(o))}getCombinationDefs(){return[["0603_max_rows_and_cols_vert_1trace_grid"],["0603_max_rows_and_cols_vert_1trace_staggered"],["0603_max_rows_and_cols_horz_1trace_grid"],["0603_max_rows_and_cols_horz_1trace_staggered"],["0603_max_rows_and_cols_vert_2trace_grid"],["0603_max_rows_and_cols_vert_2trace_staggered"],["0603_max_rows_and_cols_horz_2trace_grid"],["0603_max_rows_and_cols_horz_2trace_staggered"],["1206x4","1206x4_cols","1206x4_rows","orientation"]]}calculateMax0603ConfigWithTraceChannels(t,e,n,o,i="grid"){const s=this.traceWidth*o+2*this.obstacleMargin,r="horizontal"===n?2.15:1,a="horizontal"===n?1:2.15,c="horizontal"===n?"x":"y",h="staggered"===i&&"x"===c?r/2:"staggered"===i?a/2:0,l=Math.max(0,t-1),d=Math.max(0,e-1),u=Math.max(0,l-("staggered"===i&&"x"===c?h:0)),p=Math.max(0,d-("staggered"===i&&"y"===c?h:0)),f=r+s,g=a+s,m=Math.max(1,Math.floor(1+(u-r)/f)),y=Math.max(1,Math.floor(1+(p-a)/g));return"vertical"===n?{cols:m,rows:y}:{cols:y,rows:m}}initializeSolvers(){const t=this.getHyperParameterDefs(),e=this.getCombinationDefs();this.supervisedSolvers=[];for(const n of e){const e=n.some(t=>t.startsWith("0603_max_rows_and_cols_")),o=n.includes("1206x4");if(e&&!this.availableJumperTypes.includes("0603"))continue;if(o&&!this.availableJumperTypes.includes("1206x4"))continue;const i=this.getHyperParameterCombinations(t.filter(t=>n.includes(t.name)));for(const t of i){const e=this.generateSolver(t),n=this.computeG(e);this.supervisedSolvers.push({hyperParameters:t,solver:e,h:0,g:n,f:n})}}}generateSolver(t){return new uf({nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,traceWidth:this.traceWidth,hyperParameters:{COLS:t.COLS,ROWS:t.ROWS,ORIENTATION:t.ORIENTATION,JUMPER_TYPE:t.JUMPER_TYPE,PATTERN:t.PATTERN,TRACE_CHANNELS_BETWEEN_JUMPERS:t.TRACE_CHANNELS_BETWEEN_JUMPERS},obstacleMargin:this.obstacleMargin})}computeG(t){const e=t.hyperParameters.COLS*t.hyperParameters.ROWS;return t.iterations/1e4+.25*e}computeH(t){return 1-(t.progress||0)}onSolve(t){this.solvedRoutes=t.solver.solvedRoutes,this.jumpers=t.solver.getOutputJumpers()}getOutput(){return this.solvedRoutes}getOutputJumpers(){return this.jumpers}visualize(){return this.winningSolver?this.winningSolver.visualize():super.visualize()}};function ff(t){return{connectionName:t.connectionName,rootConnectionName:t.rootConnectionName,traceThickness:t.traceThickness,viaDiameter:0,route:t.route,vias:[],jumpers:t.jumpers}}var gf=class extends Dn{getSolverName(){return"JumperHighDensitySolver"}allNodes;nodeAnalyses;routes;colorMap;traceWidth;obstacleMargin;viaDiameter;connMap;hyperParameters;availableJumperTypes;capacityMeshNodes;capacityMeshEdges;capacityMeshNodeMap;nodeAdjacencyMap;nodesWithoutCrossings;nodesWithCrossings;curvyIntraNodeSolvers;currentCurvySolverIndex;jumperSolvers;currentJumperSolverIndex;phase;jumpers=[];constructor({nodePortPoints:t,colorMap:e,traceWidth:n=.15,obstacleMargin:o=.15,viaDiameter:i=.3,connMap:s,hyperParameters:r,capacityMeshNodes:a=[],capacityMeshEdges:c=[],availableJumperTypes:h}){super(),this.allNodes=[...t],this.colorMap=e??{},this.routes=[],this.traceWidth=n,this.obstacleMargin=o,this.viaDiameter=i,this.connMap=s,this.hyperParameters=r,this.capacityMeshNodes=a,this.capacityMeshEdges=c,this.availableJumperTypes=h??["0603"],this.capacityMeshNodeMap=new Map(a.map(t=>[t.capacityMeshNodeId,t])),this.nodeAdjacencyMap=this._buildNodeAdjacencyMap(),this.nodesWithoutCrossings=[],this.nodesWithCrossings=[],this.nodeAnalyses=[],this.curvyIntraNodeSolvers=[],this.currentCurvySolverIndex=0,this.jumperSolvers=[],this.currentJumperSolverIndex=0,this.phase="analyzing",this._analyzeNodes();const l=1e3*this.nodesWithoutCrossings.length,d=1e5*this.nodesWithCrossings.length;this.MAX_ITERATIONS=l+d+100}_buildNodeAdjacencyMap(){const t=new Map;for(const e of this.capacityMeshEdges){const[n,o]=e.nodeIds;t.has(n)||t.set(n,new Set),t.has(o)||t.set(o,new Set),t.get(n).add(o),t.get(o).add(n)}return t}_analyzeNodes(){for(const t of this.allNodes){const e=Oh(t),n={node:t,hasCrossings:e.numSameLayerCrossings>0,numSameLayerCrossings:e.numSameLayerCrossings};this.nodeAnalyses.push(n),e.numSameLayerCrossings>0?this.nodesWithCrossings.push(t):this.nodesWithoutCrossings.push(t)}this.nodesWithoutCrossings.length>0?(this.phase="curvy",this._initializeCurvySolvers()):this.nodesWithCrossings.length>0?(this.phase="jumpers",this._initializeJumperSolvers()):this.phase="done"}_step(){switch(this.phase){case"analyzing":this.nodesWithoutCrossings.length>0?(this.phase="curvy",this._initializeCurvySolvers()):this.nodesWithCrossings.length>0?(this.phase="jumpers",this._initializeJumperSolvers()):this.phase="done";break;case"curvy":this._stepCurvySolvers();break;case"jumpers":this._stepJumperSolvers();break;case"done":this.solved=!0}}_getAdjacentObstacles(t){const e=[],n=this.nodeAdjacencyMap.get(t.capacityMeshNodeId);if(!n||0===n.size)return e;const o=new Map(this.allNodes.map(t=>[t.capacityMeshNodeId,t]));for(const t of n){const n=this.capacityMeshNodeMap.get(t);if(!n)continue;if(!n._containsObstacle&&!n._containsTarget)continue;const i=n.center.x-n.width/2,s=n.center.y-n.height/2,r=n.center.x+n.width/2,a=n.center.y+n.height/2;let c;if(n._containsTarget)if(n._targetConnectionName)c=n._targetConnectionName;else{const e=o.get(t);e&&e.portPoints.length>0&&(c=e.portPoints[0].rootConnectionName??e.portPoints[0].connectionName)}e.push({minX:i,minY:s,maxX:r,maxY:a,networkId:c})}return e}_initializeCurvySolvers(){for(const t of this.nodesWithoutCrossings){const e=this._getAdjacentObstacles(t),n=new ju({nodeWithPortPoints:t,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:e});this.curvyIntraNodeSolvers.push(n)}}_stepCurvySolvers(){if(0===this.curvyIntraNodeSolvers.length)return this.phase=this.nodesWithCrossings.length>0?"jumpers":"done",void("jumpers"===this.phase&&this._initializeJumperSolvers());const t=this.curvyIntraNodeSolvers[this.currentCurvySolverIndex];if(this.activeSubSolver=t,!t)return this.phase=this.nodesWithCrossings.length>0?"jumpers":"done",void("jumpers"===this.phase&&this._initializeJumperSolvers());if(t.step(),t.solved){this.routes.push(...t.routes),this.currentCurvySolverIndex++;for(let t=this.currentCurvySolverIndex;t<this.curvyIntraNodeSolvers.length;t++){this.curvyIntraNodeSolvers[t];const e=this.nodesWithoutCrossings[t],n=this._getAdjacentObstacles(e),o=new ju({nodeWithPortPoints:e,colorMap:this.colorMap,traceWidth:this.traceWidth,viaDiameter:this.viaDiameter,adjacentObstacles:n});this.curvyIntraNodeSolvers[t]=o}this.currentCurvySolverIndex>=this.curvyIntraNodeSolvers.length&&(this.phase=this.nodesWithCrossings.length>0?"jumpers":"done","jumpers"===this.phase&&this._initializeJumperSolvers())}else t.failed&&(this.error=`CurvyIntraNodeSolver failed for node: ${t.nodeWithPortPoints.capacityMeshNodeId}: ${t.error}`,this.failed=!0)}_initializeJumperSolvers(){for(const t of this.nodesWithCrossings){const e=new pf({nodeWithPortPoints:t,colorMap:this.colorMap,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,connMap:this.connMap,availableJumperTypes:this.availableJumperTypes});this.jumperSolvers.push(e)}}_stepJumperSolvers(){if(0===this.jumperSolvers.length)return this.phase="done",void(this.solved=!0);const t=this.jumperSolvers[this.currentJumperSolverIndex];if(this.activeSubSolver=t,!t)return this.phase="done",void(this.solved=!0);if(t.step(),t.solved){for(const e of t.solvedRoutes)this.routes.push(ff(e));this.jumpers.push(...t.getOutputJumpers()),this.currentJumperSolverIndex++,this.currentJumperSolverIndex>=this.jumperSolvers.length&&(this.phase="done",this.solved=!0)}else t.failed&&(this.error=`HyperJumperPrepatternSolver2 failed for node: ${t.nodeWithPortPoints.capacityMeshNodeId}: ${t.error}`,this.failed=!0)}computeProgress(){const t=this.allNodes.length;if(0===t)return 1;let e=0;e+=this.currentCurvySolverIndex;const n=this.curvyIntraNodeSolvers[this.currentCurvySolverIndex];n&&(e+=n.progress),e+=this.currentJumperSolverIndex;const o=this.jumperSolvers[this.currentJumperSolverIndex];return o&&(e+=o.progress),e/t}getConstructorParams(){return{nodePortPoints:this.allNodes,colorMap:this.colorMap,traceWidth:this.traceWidth,obstacleMargin:this.obstacleMargin,viaDiameter:this.viaDiameter,connMap:this.connMap,hyperParameters:this.hyperParameters,capacityMeshNodes:this.capacityMeshNodes,capacityMeshEdges:this.capacityMeshEdges,availableJumperTypes:this.availableJumperTypes}}getOutputJumpers(){return this.jumpers}visualize(){const t={lines:[],points:[],rects:[],circles:[]};if(this.failed&&this.activeSubSolver)return this.activeSubSolver.visualize();if("curvy"===this.phase&&this.curvyIntraNodeSolvers[this.currentCurvySolverIndex])return this.curvyIntraNodeSolvers[this.currentCurvySolverIndex].visualize();if("jumpers"===this.phase&&this.jumperSolvers[this.currentJumperSolverIndex])return this.jumperSolvers[this.currentJumperSolverIndex].visualize();for(const e of this.routes){const n=e.rootConnectionName??e.connectionName,o=jn(e.route,e.connectionName,this.colorMap[n]);for(const n of o)t.lines.push({points:n.points,label:n.connectionName,strokeColor:0===n.z?n.color:Mn(n.color??"gray",.75),layer:`z${n.z}`,strokeWidth:e.traceThickness,strokeDash:0!==n.z?"10, 5":void 0});for(const o of e.vias)t.circles.push({center:o,radius:e.viaDiameter/2,fill:Mn(this.colorMap[n]??"gray",.5),layer:"via"});if("jumpers"in e&&e.jumpers)for(const o of e.jumpers){const e=this.colorMap[n]??"gray",i=o.footprint??"1206",s=En[i],r=o.end.x-o.start.x,a=o.end.y-o.start.y,c=Math.abs(r)>Math.abs(a),h=c?s.padLength:s.padWidth,l=c?s.padWidth:s.padLength;t.rects.push({center:o.start,width:h,height:l,fill:Mn(e,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:o.end,width:h,height:l,fill:Mn(e,.5),stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[o.start,o.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*s.padWidth,layer:"jumper-body"})}}for(const e of this.nodeAnalyses){const n=e.node;n.center.x,n.width,n.center.x,n.width,n.center.y,n.height,n.center.y,n.height;t.rects.push({center:n.center,width:n.width,height:n.height,fill:e.hasCrossings?"rgba(255, 200, 0, 0.1)":"rgba(0, 200, 0, 0.1)",stroke:e.hasCrossings?"rgba(255, 150, 0, 0.5)":"rgba(0, 150, 0, 0.5)",label:[n.capacityMeshNodeId,e.hasCrossings?`crossings: ${e.numSameLayerCrossings}`:"no crossings"].join("\n")})}return t}};function mf(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var yf=class extends Dn{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),s=n.targetMinCapacity??.5;n.capacityDepth=zh(i,s)}this.connMap=zn(t),this.colorMap=In(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline3"}netToPointPairsSolver;traceKeepoutSolver;nodeSolver;nodeTargetMerger;edgeSolver;relateNodesToOffBoardConnections;colorMap;highDensityRouteSolver;simpleHighDensityRouteSolver;highDensitySolver;highDensityStitchSolver;singleLayerNodeMerger;offboardPathFragmentSolver;strawSolver;deadEndSolver;traceSimplificationSolver;traceWidthSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[mf("netToPointPairsSolver",il,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=In(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),mf("nodeSolver",ye,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),mf("relateNodesToOffBoardConnections",Qd,t=>[{capacityMeshNodes:t.capacityNodes,srj:t.srj}],{onSolved:t=>{t.capacityNodes=t.relateNodesToOffBoardConnections?.getOutput().capacityNodes}}),mf("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),mf("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!1}]),mf("portPointPathingSolver",Gh,t=>{const e=t.capacityNodes.map(t=>({capacityMeshNodeId:t.capacityMeshNodeId,center:t.center,width:t.width,height:t.height,portPoints:[],availableZ:t.availableZ,_containsTarget:t._containsTarget,_containsObstacle:t._containsObstacle,_offBoardConnectionId:t._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:t._offBoardConnectedCapacityMeshNodeIds})),n=new Map(e.map(t=>[t.capacityMeshNodeId,t])),o=t.availableSegmentPointSolver;for(const t of o.sharedEdgeSegments)for(const e of t.portPoints){const[o,i]=e.nodeIds,s={portPointId:e.segmentPortPointId,x:e.x,y:e.y,z:e.availableZ[0]??0,connectionNodeIds:[o,i],distToCentermostPortOnZ:e.distToCentermostPortOnZ,connectsToOffBoardNode:t.nodeIds.some(t=>n.get(t)?._offBoardConnectionId)},r=n.get(o);r&&r.portPoints.push(s)}return[{simpleRouteJson:t.srjWithPointPairs,inputNodes:e,capacityMeshNodes:t.capacityNodes,colorMap:t.colorMap,numShuffleSeeds:10*t.effort,hyperParameters:{JUMPER_PF_FN_ENABLED:!0,NODE_PF_FACTOR:100,MAX_RIPS:100*t.effort,RIPPING_ENABLED:!0,MAX_RIPPING_PF_THRESHOLD:.9,MIN_RIPPING_PF_THRESHOLD:.1,RANDOM_RIP_FRACTION:.05,NODE_PF_MAX_PENALTY:1e3,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:0,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,FORCE_CENTER_FIRST:!0}}]},{onSolved:t=>{const e=t.portPointPathingSolver;e&&au({connMap:t.connMap,connectionsWithResults:e.connectionsWithResults,inputNodes:e.inputNodes,obstacles:t.srj.obstacles})}}),mf("highDensitySolver",gf,t=>[{nodePortPoints:t.multiSectionPortPointOptimizer?.getNodesWithPortPoints()??t.portPointPathingSolver?.getNodesWithPortPoints()??[],colorMap:t.colorMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth,obstacleMargin:t.srj.defaultObstacleMargin??.15,connMap:t.connMap,capacityMeshNodes:t.capacityNodes??[],capacityMeshEdges:t.capacityEdges??[],availableJumperTypes:t.srj.availableJumperTypes}]),mf("highDensityStitchSolver",lu,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensitySolver.routes,connectionPathResults:t.multiSectionPortPointOptimizer?.connectionResults??t.portPointPathingSolver?.connectionsWithResults??[],colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),mf("traceKeepoutSolver",Kd,t=>[{hdRoutes:t.traceSimplificationSolver?.simplifiedHdRoutes??t.highDensityStitchSolver?.mergedHdRoutes??[],obstacles:t.srj.obstacles,jumpers:t.highDensitySolver?.getOutputJumpers()??[],connMap:t.connMap,colorMap:t.colorMap,srj:t.srj}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),s=this.edgeSolver?.visualize(),r=this.traceKeepoutSolver?.visualize(),a=this.deadEndSolver?.visualize(),c=this.availableSegmentPointSolver?.visualize(),h=this.offboardPathFragmentSolver?.visualize(),l=this.portPointPathingSolver?.visualize(),d=this.multiSectionPortPointOptimizer?.visualize(),u=this.highDensityRouteSolver?.visualize(),p=this.highDensitySolver?.visualize(),f=this.simpleHighDensityRouteSolver?.visualize(),g=this.highDensityStitchSolver?.visualize(),m=this.traceSimplificationSolver?.visualize(),y=this.traceWidthSolver?.visualize(),x=this.srj.outline,v=[];if(v.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),x&&x.length>=2){const t=x.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),v.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const b={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:["obstacle",t.offBoardConnectsTo?`offboardConnections: ${t.offBoardConnectsTo?.join(", ")}`:"",t.layers?.join(", ")].filter(Boolean).join("\n")}))],lines:v},P=[b,t,e,n,o,i,s,a,c,h,l,d,u?Bn(b,u):null,p?Bn(b,p):null,f?Bn(b,f):null,g,m,r,y,this.solved?Bn(b,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...P)}preview(){const t=this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes;if(t){const e=[];for(let n=t.length-1;n>=0;n--){const o=t[n];if(e.push({points:o.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[o.connectionName]}),e.length>200)break}return{lines:e}}if(this.portPointPathingSolver){const t=[];for(const e of this.portPointPathingSolver.connectionsWithResults)e.path&&t.push({points:e.path.map(t=>({x:t.point.x,y:t.point.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.hdRoutesWithWidths??this.traceKeepoutSolver?.redrawnHdRoutes??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver?.mergedHdRoutes??this.highDensitySolver?.routes??this.simpleHighDensityRouteSolver?.routes??this.highDensityRouteSolver?.routes}getConnectedOffboardObstacles(){const t={},e=new Set(this.srj.connections.map(t=>t.rootConnectionName??t.name));for(const[n,o]of this.srj.obstacles.entries()){if(!o.offBoardConnectsTo?.length)continue;const i=o.obstacleId??`__obs${n}`;o.obstacleId=i;const s=this.connMap.getNetConnectedToId(i);if(!s)continue;const r=this.connMap.getIdsConnectedToNet(s).find(t=>e.has(t));r&&(t[i]=r)}return t}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver&&!this.simpleHighDensityRouteSolver&&!this.highDensitySolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const o=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const s=i[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.rootConnectionName??n.name,route:De(s,this.srj.layerCount)};t.push(r)}}return t}getOutputJumpers(){return this.highDensitySolver?this.highDensitySolver.getOutputJumpers():[]}getOutputSimpleRouteJson(){const t=this.getOutputJumpers();return{...this.srj,traces:this.getOutputSimplifiedPcbTraces(),jumpers:t.length>0?t:void 0}}},xf=t=>{const{candidates:e,mapOfCapacityMeshNodeIdToRef:n}=t;let o=!0;for(const t of e){let e=!1;t.port.nodeIds.forEach(t=>{const o=n.get(t);if(!o)throw new Error(`Could not find capacity mesh node for id ${t}`);o._containsObstacle&&(e=!0)}),e||(o=!1)}return o},vf=t=>t.depth+1e3*t.countOfCrampedPortPointsInPath,bf=class extends M{constructor(t){if(super(),this.input=t,this.input.depthLimit<1)throw new Error("Depth limit must be at least 1");this._setup()}queue=[];resultExploredPortPoints=[];currentExploredPortPoints=null;visitedExploredPortPoints=new Map;getSolverName(){return"singleTargetNecessaryCrampedPortPointSolver"}_setup(){const t=this.input.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(this.input.target.capacityMeshNodeId)??[];for(const e of t){if(this.input.shouldIgnoreCrampedPortPoints&&e.cramped)continue;const t={port:e,depth:1,parent:null,countOfCrampedPortPointsInPath:e.cramped?1:0},n=this.visitedExploredPortPoints.get(e);(!n||this.getCandidateCost(t)<this.getCandidateCost(n))&&(this.visitedExploredPortPoints.set(e,t),this.queue.push(t))}}_step(){if(0===this.queue.length)return this.currentExploredPortPoints=null,void(this.solved=!0);for(;this.queue.length>0;){this.currentExploredPortPoints=this.queue.shift();if(this.visitedExploredPortPoints.get(this.currentExploredPortPoints.port)!==this.currentExploredPortPoints)continue;if(this.currentExploredPortPoints.depth===this.input.depthLimit){this.resultExploredPortPoints.push(this.currentExploredPortPoints);continue}const t=this.currentExploredPortPoints.port.nodeIds.map(t=>{const e=this.input.mapOfCapacityMeshNodeIdToRef.get(t);if(!e)throw new Error(`Could not find capacity mesh node for id ${t}`);return e}).flatMap(t=>this.input.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(t.capacityMeshNodeId)??[]);for(const e of t){if(this.input.shouldIgnoreCrampedPortPoints&&e.cramped)continue;const t={port:e,depth:this.currentExploredPortPoints.depth+1,parent:this.currentExploredPortPoints,countOfCrampedPortPointsInPath:this.currentExploredPortPoints.countOfCrampedPortPointsInPath+(e.cramped?1:0)},n=this.visitedExploredPortPoints.get(e);n&&this.getCandidateCost(n)<=this.getCandidateCost(t)||(this.visitedExploredPortPoints.set(e,t),this.queue.push(t))}}this.solved=!0}getCandidateCost(t){return t.depth+1e3*t.countOfCrampedPortPointsInPath}getOutput(){return this.resultExploredPortPoints}visualize(){const t={points:[],rects:[]};for(const e of this.visitedExploredPortPoints.keys())t.points.push({...e,color:e.cramped?"blue":"green"});return t}},Pf=class extends M{constructor(t){super(),this.input=t,this._setup()}unprocessedTargets=[];targetNode=[];currentTarget;crampedPortPointsToKeep=new Set;candidatesAtDepth=[];isRunningCrampedPass=!1;activeSubSolver=null;nodeMap=new Map;mapOfCapacityMeshNodeIdToSegmentPortPoints=new Map;getSolverName(){return"multiTargetNecessaryCrampedPortPointSolver"}_setup(){this.targetNode=this.input.capacityMeshNodes.filter(t=>t._containsObstacle);const t=this.input.simpleRouteJson.connections.flatMap(t=>t.pointsToConnect);this.targetNode=this.targetNode.filter(e=>{let n=!1;return t.forEach(t=>{$(t,e)<=0&&(n=!0)}),n}),this.unprocessedTargets=[...this.targetNode],this.unprocessedTargets.sort((t,e)=>t.center.x-e.center.x);for(const t of this.input.capacityMeshNodes)this.nodeMap.set(t.capacityMeshNodeId,t);for(const t of this.input.sharedEdgeSegments)for(const e of t.portPoints){const t=e.nodeIds;for(const n of t){if(!this.nodeMap.get(n))throw new Error(`Could not find capacity mesh node for id ${n}`);const t=this.mapOfCapacityMeshNodeIdToSegmentPortPoints.get(n)||[];this.mapOfCapacityMeshNodeIdToSegmentPortPoints.set(n,[...t,e])}}}_step(){if(this.activeSubSolver){if(this.activeSubSolver._step(),!this.activeSubSolver.solved)return;if(this.activeSubSolver.failed)return this.failed=!0,void(this.error=this.activeSubSolver.error);if(this.candidatesAtDepth=this.activeSubSolver.getOutput(),this.activeSubSolver=null,!this.currentTarget)return this.failed=!0,void(this.error="Missing current capacity mesh node while finishing BFS");if(!this.isRunningCrampedPass){return xf({candidates:this.candidatesAtDepth,mapOfCapacityMeshNodeIdToRef:this.nodeMap})||0===this.candidatesAtDepth.length?(this.isRunningCrampedPass=!0,void(this.activeSubSolver=new bf({target:this.currentTarget,depthLimit:2,shouldIgnoreCrampedPortPoints:!1,mapOfCapacityMeshNodeIdToSegmentPortPoints:this.mapOfCapacityMeshNodeIdToSegmentPortPoints,mapOfCapacityMeshNodeIdToRef:this.nodeMap}))):void(this.currentTarget=void 0)}let t=this.candidatesAtDepth.filter(t=>{const e=t.port;return e.nodeIds.map(t=>{const e=this.nodeMap.get(t);if(!e)throw this.failed=!0,this.error=`Could not find capacity mesh node for id ${t}`,new Error(`Could not find capacity mesh node for id ${t}`);return e}).every(t=>!t._containsObstacle)&&e.cramped});xf({candidates:t,mapOfCapacityMeshNodeIdToRef:this.nodeMap})&&(this.error=`All candidates are blocked by obstacles even after including cramped port points for capacity mesh node ${this.currentTarget.capacityMeshNodeId}`),this.candidatesAtDepth=[...t].sort((t,e)=>vf(t)-vf(e));const e=this.candidatesAtDepth[0];return e&&0!==t.length?this.crampedPortPointsToKeep.add(e.port):this.error=`No candidates found for capacity mesh node ${this.currentTarget.capacityMeshNodeId} even after including cramped port points`,this.isRunningCrampedPass=!1,void(this.currentTarget=void 0)}if(!this.currentTarget)return this.currentTarget=this.unprocessedTargets.shift(),this.currentTarget?(this.isRunningCrampedPass=!1,this.candidatesAtDepth=[],void(this.activeSubSolver=new bf({target:this.currentTarget,depthLimit:2,shouldIgnoreCrampedPortPoints:!0,mapOfCapacityMeshNodeIdToSegmentPortPoints:this.mapOfCapacityMeshNodeIdToSegmentPortPoints,mapOfCapacityMeshNodeIdToRef:this.nodeMap}))):void(this.solved=!0)}getOutput(){return this.input.sharedEdgeSegments.map(t=>({...t,portPoints:t.portPoints.filter(t=>!t.cramped||this.crampedPortPointsToKeep.has(t))}))}visualize(){const t={rects:[],points:[]};for(const e of this.targetNode)t.rects.push({...e,fill:this.currentTarget?.capacityMeshNodeId===e.capacityMeshNodeId?"rgba(255, 0, 0, 0.5)":"rgba(255, 0, 0, 0.2)"});for(const e of this.candidatesAtDepth)t.points.push({...e.port,color:e.port.cramped?"blue":"green"});for(const e of this.crampedPortPointsToKeep)t.points.push({...e,color:"blue"});return this.activeSubSolver?I(t,this.activeSubSolver.visualize()):t}};function Sf(t,e){if(null==t)throw new Error(e)}function If(t){if(0===$(t.point,t.region.d)){if(function(t,e){const n=[];for(const o of t)e.includes(o)&&n.push(o);return n}(("layers"in t.point?t.point.layers:[t.point.layer]).map(e=>wn(e,t.layerCount)),t.region.d.availableZ).length>0)return!0}return!1}function Mf(t,e){const n={lines:[],points:[]};if(!t)return n;let o=t.shift();if(!o)return n;const i=[];n.points.push({...o.port.d,color:"rgb(255, 50, 50)",label:`g: ${o.g}\nh: ${o.h}\nf: ${o.f}\nripRequired: ${o.ripRequired}`});do{i.push({x:o.port.d.x,y:o.port.d.y,z:o.port.d.z}),o=o.parent}while(o);i.reverse();const s=i[0]?.z??0;i.unshift({x:e.x,y:e.y,z:s});for(let t=0;t<i.length-1;t++){const e=i[t],o=i[t+1];let s;s=e.z===o.z?0===e.z?void 0:"10 5":"3 3 10",n.lines.push({points:[{x:e.x,y:e.y},{x:o.x,y:o.y}],strokeColor:"rgba(255, 250, 50, 1)",strokeWidth:.1,strokeDash:s})}for(const e of t)n.points.push({...e.port.d,color:"rgb(0, 64, 255)",label:`${e.port.portId}\ng: ${e.g}\nh: ${e.h}\nf: ${e.f}\nripRequired: ${e.ripRequired}`});return n}function _f(t,e){const n={lines:[],points:[]};for(const o of t){const t=e[o.connection.connectionId]??"rgba(255, 50, 50, 1)",i=[{x:o.connection.startRegion.d.center.x,y:o.connection.startRegion.d.center.y,z:o.connection.startRegion.d.availableZ[0]??0}];for(const t of o.path)i.push({x:t.port.d.x,y:t.port.d.y,z:t.port.d.z});i.push({x:o.connection.endRegion.d.center.x,y:o.connection.endRegion.d.center.y,z:o.connection.endRegion.d.availableZ[0]??0});for(let e=0;e<i.length-1;e++){const o=i[e],s=i[e+1];let r;r=o.z===s.z?0===o.z?void 0:"10 5":"3 3 10";const a={points:[{x:o.x,y:o.y},{x:s.x,y:s.y}],strokeColor:t,strokeWidth:.1,strokeDash:r};n.lines.push(a)}}return n}function Nf(t,e){const n={lines:[],points:[]};for(const o of t){const t=o.startRegion.d.center,i=o.endRegion.d.center,s=(t.x+i.x)/2,r=(t.y+i.y)/2,a=e[o.connectionId]??"rgba(255, 50, 150, 0.8)";n.points.push({x:s,y:r,color:a,label:o.connectionId}),n.lines.push({points:[t,i],strokeColor:a,strokeWidth:.05,strokeDash:0===(o.startRegion.d.availableZ[0]??0)?void 0:"10 5"})}return n}function Cf(t){const e={rects:[],points:[]};for(const n of t.regions)e.rects.push({center:n.d.center,width:n.d.width,height:n.d.height,fill:"rgba(200, 200, 200, 0.5)",label:n.regionId});for(const n of t.ports)e.points.push({x:n.d.x,y:n.d.y,color:"rgba(4, 90, 20, 0.3)",label:n.portId});return e}var Tf=class extends yi{constructor(t){super({inputConnections:t.connections,inputGraph:t.graph,greedyMultiplier:t.weights.GREEDY_MULTIPLIER,ripCost:t.weights.RIPPING_PF_COST,rippingEnabled:t.flags.RIPPING_ENABLED}),this.params=t,this.regionMemoryPfMap=t.opts?.regionMemoryPfMap??new Map,this.baseRegionFailureCostMap=new Map,this.regionRipCountMap=new Map,this.totalRipCount=0,t.weights.MAX_ITERATIONS_PER_PATH>0&&(this.MAX_ITERATIONS=t.weights.MAX_ITERATIONS_PER_PATH*t.effort)}regionMemoryPfMap;baseRegionFailureCostMap;regionRipCountMap;totalRipCount;estimateCostToEnd(t){const e=this.currentEndRegion;return Sf(e,"Current end region is undefined"),F(t.d,e.d.center)}computeH(t){const e=t,n=this.computeDistanceTraveled(e);if(this.params.weights.RANDOM_WALK_DISTANCE>0&&n<this.params.weights.RANDOM_WALK_DISTANCE)return 0;const o=this.estimateCostToEnd(t.port),i=(t.port.d.distToCentermostPortOnZ-this.params.weights.CENTER_OFFSET_FOCUS_SHIFT)*this.params.weights.CENTER_OFFSET_DIST_PENALTY_FACTOR,s=t.nextRegion?.regionId??t.lastRegion?.regionId,r=s?this.regionMemoryPfMap.get(s)??0:0;return o+i+this.computeMemoryPfPenalty(r)+this.computeDeviation(t)*this.params.weights.STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR}computeIncreasedRegionCostIfPortsAreUsed(t,e,n){const o=this.currentConnection;Sf(o,"Current connection is undefined");const i=this.getBaseRegionFailureCost(t),s=this.computeRegionPfWithAdditionalSegment(t,e,n,o.connectionId,o.mutuallyConnectedNetworkId);if(s>=this.NODE_MAX_PF)return this.params.weights.NODE_PF_MAX_PENALTY;const r=this.pfToFailureCost(s),a=Math.max(0,r-i);return Math.min(this.params.weights.NODE_PF_MAX_PENALTY,a*this.params.weights.NODE_PF_FACTOR)}computeG(t){const e=t;let n=super.computeG(t);return e.lastPort&&e.lastPort.d.z!==e.port.d.z&&(n+=this.params.weights.LAYER_CHANGE_COST),e.nextRegion!==this.currentEndRegion?n:n+this.computeEndRegionCloseCost(e)}getPortUsagePenalty(t){const e=t.assignment;if(!e)return 0;const n=this.currentConnection?.mutuallyConnectedNetworkId;return e.connection.mutuallyConnectedNetworkId===n?0:.5*Math.max(1,this.params.weights.NODE_PF_FACTOR)+this.params.weights.BASE_CANDIDATE_COST}getRipsRequiredForPortUsage(t,e,n){const o=t.assignments??[];if(0===o.length)return[];return o.filter(t=>t.connection.mutuallyConnectedNetworkId!==this.currentConnection?.mutuallyConnectedNetworkId&&(t.regionPort1!==e&&t.regionPort2!==e&&(t.regionPort1!==n&&t.regionPort2!==n&&D(t.regionPort1.d,t.regionPort2.d,e.d,n.d))))}selectCandidatesForEnteringRegion(t){const e=this.currentConnection?.startRegion,n=this.currentConnection?.endRegion;Sf(e,"Current connection or start region is undefined"),Sf(n,"Current connection or end region is undefined");const o=t.filter(t=>{const o=t.nextRegion;return!o?.d._containsObstacle||(o===e||o===n)});let i=this.params.flags.FORCE_CENTER_FIRST?this.getCenterFirstEnteringRegionCandidates(o):o;const s=-this.params.weights.MIN_ALLOWED_BOARD_SCORE;if(s>0){const t=i.filter(t=>t.g+t.h<=s);t.length>0&&(i=t)}return i}routeSolvedHook(t){this.baseRegionFailureCostMap.clear();const e=new Set;for(const n of t.path){const t=n.lastRegion;t&&e.add(t)}for(const t of e){const e=this.computeRegionPfFromAssignments(t);this.regionMemoryPfMap.set(t.regionId,e)}if(!t.requiredRip)return;if(this.unprocessedConnections.length<2)return;const[n,...o]=this.unprocessedConnections;this.unprocessedConnections=[...o,n]}computeRoutesToRip(t){const e=super.computePortOverlapRoutes(t),n=new Set(e),o=new Map;t.path.map(t=>{if(!t.lastPort||!t.lastRegion)return;const e=this.getRipsRequiredForPortUsage(t.lastRegion,t.lastPort,t.port);if(0===e.length)return null;const n=o.get(t.lastRegion)??new Set;for(const t of e)n.add(t.solvedRoute);o.set(t.lastRegion,n)});const i=t.path.flatMap(t=>t.lastRegion?[t.lastRegion]:[]),s=Array.from(new Set([...o.keys(),...i])),r=this.params.weights.SHUFFLE_SEED+this.iterations+this.solvedRoutes.length+this.totalRipCount,a=Un(s,r);for(const e of a){if(this.totalRipCount>=this.params.weights.MAX_RIPS)break;const o=this.getRegionRippingPfThreshold(e.regionId);let i=this.computeRegionPf({region:e,newlySolvedRoute:t,routesToRip:n});if(this.regionMemoryPfMap.set(e.regionId,i),i<=o)continue;const s=new Set;let a=0;for(;i>o&&!(this.totalRipCount>=this.params.weights.MAX_RIPS);){if(!e.assignments||0===e.assignments.length)throw new Error("We are trying to rip a region with no assignments, this should not happen");const o=e.assignments.map(e=>{const o=e.solvedRoute;return e.connection.connectionId===t.connection.connectionId?null:n.has(o)?void 0:o}).filter(t=>!!t);if(0===o.length)break;const c=Un(o,r+a+s.size)[0];if(!c)break;s.add(c.connection),n.add(c),this.totalRipCount++,a++,this.regionRipCountMap.set(e.regionId,(this.regionRipCountMap.get(e.regionId)??0)+1),i=this.computeRegionPf({region:e,newlySolvedRoute:t,routesToRip:n}),this.regionMemoryPfMap.set(e.regionId,i)}}if(n.size>e.size){if(this.totalRipCount>=this.params.weights.MAX_RIPS)return n;const e=this.solvedRoutes.filter(e=>!n.has(e)&&e.connection.connectionId!==t.connection.connectionId);if(0===e.length)return n;const o=Math.max(1,Math.floor(this.params.weights.RANDOM_RIP_FRACTION*e.length)),i=Un(e,r);let s=0;for(const t of i){if(s>=o)break;if(this.totalRipCount>=this.params.weights.MAX_RIPS)break;n.has(t)||(n.add(t),s++,this.totalRipCount++)}}return n}computeDeviation(t){const e=this.currentConnection?.startRegion.d.center,n=this.currentConnection?.endRegion.d.center;Sf(e,"Current connection or start region is undefined"),Sf(n,"Current connection or end region is undefined");return X(t.port.d,e,n)}computeDistanceTraveled(t){let e=0,n=t;for(;n?.parent;)e+=F(n.parent.port.d,n.port.d),n=n.parent;return e}computeMemoryPfPenalty(t){const e=Math.min(Math.max(t,0),.999999),n=Math.min(this.params.weights.NODE_PF_MAX_PENALTY,-Math.log(1-e));return n*this.params.weights.MEMORY_PF_FACTOR+n*this.params.weights.NODE_PF_FACTOR*.01}computeEndRegionCloseCost(t){const e=this.currentConnection,n=this.currentEndRegion;Sf(e,"Current connection is undefined"),Sf(n,"Current end region is undefined");const o=e.endRegion.d.center,i={portId:`end-target:${e.connectionId}`,region1:n,region2:n,d:{portId:`end-target:${e.connectionId}`,x:o.x,y:o.y,z:t.port.d.z,distToCentermostPortOnZ:0,regions:[n,n]}};return this.computeIncreasedRegionCostIfPortsAreUsed(n,t.port,i)}getCenterFirstEnteringRegionCandidates(t){const e=new Map;for(const n of t){const t=n.port.d.z,o=e.get(t)??[];o.push(n),e.set(t,o)}const n=[];for(const t of e.values()){const e=t.sort((t,e)=>t.port.d.distToCentermostPortOnZ-e.port.d.distToCentermostPortOnZ)[0];if(!e)continue;if(this.isPortAvailableForCurrentNet(e.port)){n.push(e);continue}const o=t.sort((t,e)=>t.port.d.x!==e.port.d.x?t.port.d.x-e.port.d.x:t.port.d.y-e.port.d.y),i=[];let s=[];for(const t of o)this.isPortAvailableForCurrentNet(t.port)?s.push(t):s.length>0&&(i.push(s),s=[]);s.length>0&&i.push(s);for(const t of i)n.push(t[Math.floor(t.length/2)])}return n}isPortAvailableForCurrentNet(t){const e=t.assignment;if(!e)return!0;const n=this.currentConnection?.mutuallyConnectedNetworkId;return e.connection.mutuallyConnectedNetworkId===n}computeRegionPfFromAssignments(t){const e=this.getRegionAssignedPortPoints(t),n={...t.d,portPoints:e},o=Oh(n),i=t.d;return Dh(i,o.numSameLayerCrossings,o.numEntryExitLayerChanges,o.numTransitionPairCrossings)}clampPf(t){return Math.min(Math.max(t,0),.999999)}get NODE_MAX_PF(){return Math.min(.99999,1-Math.exp(-this.params.weights.NODE_PF_MAX_PENALTY))}pfToFailureCost(t){const e=this.clampPf(t);return e>=this.NODE_MAX_PF?this.params.weights.NODE_PF_MAX_PENALTY:-Math.log(1-e)}getBaseRegionFailureCost(t){const e=this.baseRegionFailureCostMap.get(t.regionId);if(null!=e)return e;const n=this.computeRegionPfFromAssignments(t),o=this.pfToFailureCost(n);return this.baseRegionFailureCostMap.set(t.regionId,o),o}getRegionAssignedPortPoints(t){return(t.assignments??[]).flatMap(t=>{const e=t.regionPort1.d,n=t.regionPort2.d,o=t.connection.connectionId,i=t.connection.mutuallyConnectedNetworkId;return[{x:e.x,y:e.y,z:e.z,connectionName:o,rootConnectionName:i},{x:n.x,y:n.y,z:n.z,connectionName:o,rootConnectionName:i}]})}computeRegionPfWithAdditionalSegment(t,e,n,o,i){const s=this.getRegionAssignedPortPoints(t),r=[{x:e.d.x,y:e.d.y,z:e.d.z,connectionName:o,rootConnectionName:i},{x:n.d.x,y:n.d.y,z:n.d.z,connectionName:o,rootConnectionName:i}],a={...t.d,portPoints:[...s,...r]},c=Oh(a);return Dh(t.d,c.numSameLayerCrossings,c.numEntryExitLayerChanges,c.numTransitionPairCrossings)}getRegionRippingPfThreshold(t){const e=this.regionRipCountMap.get(t)??0,n=Math.max(1,Math.floor(this.params.weights.MAX_RIPS/10)),o=Math.min(1,e/n);return(this.params.weights.START_RIPPING_PF_THRESHOLD||.3)*(1-o)+(this.params.weights.END_RIPPING_PF_THRESHOLD||1)*o}computeRegionPf({region:t,newlySolvedRoute:e,routesToRip:n}){const o=[...(t.assignments??[]).filter(t=>!n.has(t.solvedRoute)).flatMap(t=>{const e=t.regionPort1,n=t.regionPort2,o=t.connection.connectionId,i=t.connection.mutuallyConnectedNetworkId;return[{x:e.d.x,y:e.d.y,z:e.d.z,connectionName:o,rootConnectionName:i},{x:n.d.x,y:n.d.y,z:n.d.z,connectionName:o,rootConnectionName:i}]}),...e.path.flatMap(n=>{if(!n.lastPort||n.lastRegion!==t)return[];const o=n.lastPort,i=n.port;return[{x:o.d.x,y:o.d.y,z:o.d.z,connectionName:e.connection.connectionId,rootConnectionName:e.connection.mutuallyConnectedNetworkId},{x:i.d.x,y:i.d.y,z:i.d.z,connectionName:e.connection.connectionId,rootConnectionName:e.connection.mutuallyConnectedNetworkId}]})],i={capacityMeshNodeId:t.d.capacityMeshNodeId,center:t.d.center,width:t.d.width,height:t.d.height,portPoints:o,availableZ:t.d.availableZ},s=Oh(i),r=t.d;return Dh(r,s.numSameLayerCrossings,s.numEntryExitLayerChanges,s.numTransitionPairCrossings)}getOutput(){new Map(this.params.graph.regions.map(t=>[t.regionId,t]));const t=new Set;for(const e of this.params.connections)t.add(e.startRegion.regionId),t.add(e.endRegion.regionId);const e=new Map;for(const t of this.solvedRoutes){const n=t.path;if(0===n.length)continue;const o=n[0]?.port,i=n[n.length-1]?.port;if(!o||!i)continue;const s=t.connection.connectionId,r=t.connection.mutuallyConnectedNetworkId,a=t.connection.startRegion.regionId,c=t.connection.endRegion.regionId,h=e.get(a)??[];h.push({portPointId:o.d.portId,x:o.d.x,y:o.d.y,z:o.d.z,connectionName:s,rootConnectionName:r}),e.set(a,h);const l=e.get(c)??[];l.push({portPointId:i.d.portId,x:i.d.x,y:i.d.y,z:i.d.z,connectionName:s,rootConnectionName:r}),e.set(c,l)}const n=[],o=[];for(const i of this.params.graph.regions){const s=(i.assignments??[]).flatMap(t=>{const e=t.connection.connectionId,n=t.connection.mutuallyConnectedNetworkId;return[{portPointId:t.regionPort1.d.portId,x:t.regionPort1.d.x,y:t.regionPort1.d.y,z:t.regionPort1.d.z,connectionName:e,rootConnectionName:n},{portPointId:t.regionPort2.d.portId,x:t.regionPort2.d.x,y:t.regionPort2.d.y,z:t.regionPort2.d.z,connectionName:e,rootConnectionName:n}]}),r=[];if(i.d._containsObstacle&&t.has(i.regionId)){const t=e.get(i.regionId)??[],n=[];for(const e of t){s.some(t=>t.connectionName===e.connectionName&&t.rootConnectionName===e.rootConnectionName&&t.portPointId===e.portPointId)||n.push(e)}s.push(...n);const o=new Map;for(const t of s){const e=`${t.connectionName}::${t.rootConnectionName??""}`,n=o.get(e)??[];n.push(t),o.set(e,n)}for(const[t,e]of o.entries()){const[n,o=""]=t.split("::"),s=e[0];s&&r.push({portPointId:`center:${i.regionId}:${n}:${o}`,x:i.d.center.x,y:i.d.center.y,z:s.z,connectionName:n,rootConnectionName:o||void 0})}}const a=[...s,...r];a.length>0&&n.push({capacityMeshNodeId:i.d.capacityMeshNodeId,center:i.d.center,width:i.d.width,height:i.d.height,portPoints:a,availableZ:i.d.availableZ});const c=i.ports.map(t=>{const e=t.d.regions.some(t=>Boolean(t.d._offBoardConnectionId));return{portPointId:t.d.portId,x:t.d.x,y:t.d.y,z:t.d.z,connectionNodeIds:t.d.regions.map(t=>t.regionId),distToCentermostPortOnZ:t.d.distToCentermostPortOnZ,connectsToOffBoardNode:e}});o.push({capacityMeshNodeId:i.d.capacityMeshNodeId,center:i.d.center,width:i.d.width,height:i.d.height,portPoints:c,availableZ:i.d.availableZ,_containsObstacle:i.d._containsObstacle,_containsTarget:i.d._containsTarget,_offBoardConnectionId:i.d._offBoardConnectionId,_offBoardConnectedCapacityMeshNodeIds:i.d._offBoardConnectedCapacityMeshNodeIds})}return{nodesWithPortPoints:n,inputNodeWithPortPoints:o}}visualize(){return function(t){let e={};return e=t.reduce((t,e)=>t&&e?I(t,e):{},e),e||{}}([Cf(this.params.graph),Nf(this.params.connections,this.params.colorMap??{}),Mf(this.candidateQueue.peekMany(100),this.currentConnection?.startRegion.d.center),_f(this.solvedRoutes,this.params.colorMap??{})])}};function Ef(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var wf=class extends Dn{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8,this.viaDiameter=t.minViaDiameter??.3,this.minTraceWidth=t.minTraceWidth;const n=this.opts;if(this.effort=n.effort??1,void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),s=n.targetMinCapacity??.5;n.capacityDepth=zh(i,s)}this.connMap=zn(t),this.colorMap=In(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;colorMap;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;strawSolver;deadEndSolver;traceSimplificationSolver;availableSegmentPointSolver;portPointPathingSolver;multiSectionPortPointOptimizer;uniformPortDistributionSolver;traceWidthSolver;necessaryCrampedPortPointSolver;viaDiameter;minTraceWidth;effort;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[Ef("netToPointPairsSolver",sl,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=In(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),Ef("nodeSolver",ye,t=>[{simpleRouteJson:t.srjWithPointPairs}],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.getOutput().meshNodes??[]}}),Ef("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Ef("availableSegmentPointSolver",Yn,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],traceWidth:t.minTraceWidth,colorMap:t.colorMap,shouldReturnCrampedPortPoints:!0}]),Ef("necessaryCrampedPortPointSolver",Pf,t=>[{capacityMeshNodes:t.capacityNodes,sharedEdgeSegments:t.availableSegmentPointSolver.getOutput(),simpleRouteJson:t.srjWithPointPairs}]),Ef("portPointPathingSolver",Tf,t=>{const{graph:e,connections:n}=function(t){const e={ports:[],regions:[]},n=[];for(const n of t.capacityMeshNodes)e.regions.push({regionId:n.capacityMeshNodeId,d:n,ports:[]});for(const n of t.segmentPortPoints){const[t,o]=n.nodeIds,i=e.regions.find(e=>e.regionId===t),s=e.regions.find(t=>t.regionId===o);Sf(i,`Could not find region with id ${t} for segment port point ${n.segmentPortPointId}`),Sf(s,`Could not find region with id ${o} for segment port point ${n.segmentPortPointId}`);for(const t of n.availableZ){const o={portId:`${n.segmentPortPointId}::${t}`,x:n.x,y:n.y,z:t,distToCentermostPortOnZ:n.distToCentermostPortOnZ,regions:[i,s]},r={portId:n.segmentPortPointId,d:o,region1:i,region2:s};e.ports.push(r),i.ports.push(r),s.ports.push(r)}}for(const o of t.simpleRouteJsonConnections){const[i,s]=o.pointsToConnect,r=e.regions.find(e=>If({point:i,region:e,layerCount:t.layerCount})),a=e.regions.find(e=>If({point:s,region:e,layerCount:t.layerCount}));Sf(r,`Could not find start region for connection "${o.name}"`),Sf(a,`Could not find end region for connection "${o.name}"`),n.push({connectionId:o.name,mutuallyConnectedNetworkId:o.rootConnectionName??o.name,startRegion:r,endRegion:a,simpleRouteConnection:o})}return{graph:e,connections:n}}({capacityMeshNodes:t.capacityNodes,layerCount:t.srj.layerCount,segmentPortPoints:t.availableSegmentPointSolver.getOutput().flatMap(t=>t.portPoints),simpleRouteJsonConnections:t.srjWithPointPairs.connections});return[{graph:e,connections:n,layerCount:t.srj.layerCount,effort:t.effort,flags:{FORCE_CENTER_FIRST:!0,RIPPING_ENABLED:!0},weights:{SHUFFLE_SEED:0,MEMORY_PF_FACTOR:4,CENTER_OFFSET_DIST_PENALTY_FACTOR:0,CENTER_OFFSET_FOCUS_SHIFT:0,NODE_PF_FACTOR:0,LAYER_CHANGE_COST:0,RIPPING_PF_COST:0,NODE_PF_MAX_PENALTY:100,BASE_CANDIDATE_COST:.6,MAX_ITERATIONS_PER_PATH:0,RANDOM_WALK_DISTANCE:0,START_RIPPING_PF_THRESHOLD:.3,END_RIPPING_PF_THRESHOLD:1,MAX_RIPS:1e3,RANDOM_RIP_FRACTION:.3,STRAIGHT_LINE_DEVIATION_PENALTY_FACTOR:4,GREEDY_MULTIPLIER:.7,MIN_ALLOWED_BOARD_SCORE:-1e4}}]}),Ef("uniformPortDistributionSolver",Ae,t=>[{nodeWithPortPoints:t.portPointPathingSolver?.getOutput().nodesWithPortPoints??[],inputNodesWithPortPoints:t.portPointPathingSolver?.getOutput().inputNodeWithPortPoints??[],minTraceWidth:t.minTraceWidth,obstacles:t.srj.obstacles,layerCount:t.srj.layerCount}]),Ef("highDensityRouteSolver",Nh,t=>[{nodePortPoints:t.uniformPortDistributionSolver?.getOutput()??[],colorMap:t.colorMap,connMap:t.connMap,viaDiameter:t.viaDiameter,traceWidth:t.minTraceWidth}]),Ef("highDensityStitchSolver",pl,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount,defaultViaDiameter:t.viaDiameter}]),Ef("traceSimplificationSolver",kl,t=>[{hdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline,defaultViaDiameter:t.viaDiameter,layerCount:t.srj.layerCount,iterations:2}]),Ef("traceWidthSolver",$l,t=>[{hdRoutes:t.traceSimplificationSolver.simplifiedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,minTraceWidth:t.minTraceWidth,connection:t.srj.connections,layerCount:t.srj.layerCount}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),o=this.singleLayerNodeMerger?.visualize(),i=this.strawSolver?.visualize(),s=this.edgeSolver?.visualize(),r=this.deadEndSolver?.visualize(),a=this.availableSegmentPointSolver?.visualize(),c=this.portPointPathingSolver?.visualize(),h=this.multiSectionPortPointOptimizer?.visualize(),l=this.uniformPortDistributionSolver?.visualize(),d=this.highDensityRouteSolver?.visualize(),u=this.highDensityStitchSolver?.visualize(),p=this.traceSimplificationSolver?.visualize(),f=this.necessaryCrampedPortPointSolver?.visualize(),g=this.srj.outline,m=[];if(m.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),g&&g.length>=2){const t=g.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),m.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const y={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:m},x=[y,t,e,n,o,i,s,r,a,f,c,h,l,d?Bn(y,d):null,u,p,this.solved?Bn(y,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...x)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.traceWidthSolver?.getHdRoutesWithWidths()??this.traceSimplificationSolver?.simplifiedHdRoutes??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes();for(const n of this.netToPointPairsSolver?.newConnections??[]){const o=n.netConnectionName??this.srj.connections.find(t=>t.name===n.name)?.netConnectionName,i=e.filter(t=>t.connectionName===n.name);for(let e=0;e<i.length;e++){const s=i[e],r={type:"pcb_trace",pcb_trace_id:`${n.name}_${e}`,connection_name:o??n.rootConnectionName??n.name,route:De(s,this.srj.layerCount)};t.push(r)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},Rf=class extends Kl{constructor(t,e={}){super(t,e),this.srj=t,this.opts=e}MAX_SIZE_FOR_SINGLE_LAYER_NODES=2;isObstacleAssignable(t){return Boolean(t?.netIsAssignable)}getOverlappingAssignableObstacles(t){return this.getXYZOverlappingObstacles(t).filter(t=>this.isObstacleAssignable(t))}shouldNodeBeXYSubdivided(t){return!(t._depth>=this.MAX_DEPTH)&&(!!t._containsTarget||(!(!t._containsObstacle||t._completelyInsideObstacle)||1===t.availableZ.length&&(t.width>this.MAX_SIZE_FOR_SINGLE_LAYER_NODES||t.height>this.MAX_SIZE_FOR_SINGLE_LAYER_NODES)))}shouldFilterNodeForObstacle(t){if(!t._containsObstacle)return!1;return!(this.getOverlappingAssignableObstacles(t).length>0)&&(1!==t.availableZ.length||this.shouldFilterSingleLayerNodeForObstacle(t))}insertAssignableObstaclesAsNodes(){const t=this.srj.obstacles.filter(t=>this.isObstacleAssignable(t)),e=new Map;for(const n of t){const t=[];for(const e of this.finishedNodes){this.getXYZOverlappingObstacles(e).some(t=>t===n)&&t.push(e)}e.set(n,t)}const n=new Set;for(const t of e.values())for(const e of t)n.add(e);this.finishedNodes=this.finishedNodes.filter(t=>!n.has(t));for(const n of t){const t=e.get(n)||[],o=n.layers&&n.layers.length>0?Array.from(new Set(n.layers.map(t=>wn(t,this.srj.layerCount)))).sort((t,e)=>t-e):Array.from({length:this.srj.layerCount},(t,e)=>this.srj.layerCount-e-1);let i=n.center.x-n.width/2,s=n.center.x+n.width/2,r=n.center.y-n.height/2,a=n.center.y+n.height/2;for(const e of t){const t=e.center.x-e.width/2,n=e.center.x+e.width/2,o=e.center.y-e.height/2,c=e.center.y+e.height/2;i=Math.min(i,t),s=Math.max(s,n),r=Math.min(r,o),a=Math.max(a,c)}const c=s-i,h=a-r,l=(i+s)/2,d=(r+a)/2;let u=!1;for(const t of this.srj.connections){for(const e of t.pointsToConnect)if(e.x>=i&&e.x<=s&&e.y>=r&&e.y<=a){u=!0;break}if(u)break}const p={capacityMeshNodeId:`assignable_via_${n.center.x}_${n.center.y}`,center:{x:l,y:d},width:c,height:h,layer:1===o.length?`z${o[0]}`:`z${o.join(",")}`,availableZ:o,_depth:0,_containsTarget:u,_containsObstacle:!1,_completelyInsideObstacle:!1};p._assignedViaObstacle=n,this.finishedNodes.push(p)}}_step(){const t=this.unfinishedNodes.pop();if(!t)return this.insertAssignableObstaclesAsNodes(),void(this.solved=!0);const e=this.getChildNodes(t),n=[],o=[];for(const t of e){const e=this.shouldNodeBeXYSubdivided(t),i=t.availableZ.length>1&&!e;if(e)o.push(t);else{if(i){const e=this.getZSubdivisionChildNodes(t);for(const t of e)!t._containsTarget&&this.shouldFilterNodeForObstacle(t)||(this.shouldNodeBeXYSubdivided(t)?o.push(t):(t._containsObstacle=!1,n.push(t)));continue}this.shouldFilterNodeForObstacle(t)&&!t._containsTarget||n.push(t)}}this.unfinishedNodes.push(...o),this.finishedNodes.push(...n)}},Of=.005,Af=class extends Dn{getSolverName(){return"SingleLayerNodeMergerSolver_OnlyMergeTargets"}nodeMap;currentBatchNodeIds;absorbedNodeIds;nextBatchNodeIds;batchHadModifications;hasComputedAdjacentNodeIds=!1;newNodes;constructor(t){super(),this.nodeMap=new Map,this.MAX_ITERATIONS=1e5;for(const e of t)this.nodeMap.set(e.capacityMeshNodeId,e);this.newNodes=[],this.absorbedNodeIds=new Set;const e=[];for(const n of t)n._assignedViaObstacle?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):n._containsTarget?n.availableZ.length>1?(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId)):e.push([n,n.width*n.height]):(this.newNodes.push(n),this.absorbedNodeIds.add(n.capacityMeshNodeId));e.sort((t,e)=>t[1]-e[1]);for(const[t,n]of e){const e={...t,center:{...t.center}};this.nodeMap.set(t.capacityMeshNodeId,e)}this.currentBatchNodeIds=e.map(([t])=>t.capacityMeshNodeId),this.nextBatchNodeIds=[],this.batchHadModifications=!1}computeAdjacentNodeIdsForFirstBatch(t){const e=Math.max(...t.map(t=>Math.max(...t.availableZ))),n=[];for(let o=0;o<=e;o++)n.push(new kn(t.filter(t=>t.availableZ[0]===o)));for(const e of t){const t=[],o=n[e.availableZ[0]].getNodesInArea(e.center.x,e.center.y,4*e.width,4*e.height);for(const n of o)n._containsTarget&&n._targetConnectionName!==e._targetConnectionName||e._containsTarget&&(!n._containsTarget||n._targetConnectionName!==e._targetConnectionName)||n.capacityMeshNodeId!==e.capacityMeshNodeId&&Xn(e,n)&&t.push(n);e._adjacentNodeIds=t.map(t=>t.capacityMeshNodeId)}}getAdjacentSameLayerUnprocessedNodes(t){const e=[],n=Array.from(new Set((t._adjacentNodeIds??[]).map(t=>this.nodeMap.get(t)))).filter(e=>e&&e.capacityMeshNodeId!==t.capacityMeshNodeId);n.sort((t,e)=>t.width*t.height-e.width*e.height);for(const t of n)this.absorbedNodeIds.has(t.capacityMeshNodeId)||e.push(t);return e}_step(){this.hasComputedAdjacentNodeIds||(this.computeAdjacentNodeIdsForFirstBatch(this.currentBatchNodeIds.map(t=>this.nodeMap.get(t))),this.hasComputedAdjacentNodeIds=!0);let t=this.currentBatchNodeIds.pop();for(;t&&this.absorbedNodeIds.has(t);)t=this.currentBatchNodeIds.pop();if(!t)return this.batchHadModifications?(this.currentBatchNodeIds=this.nextBatchNodeIds.sort((t,e)=>{const n=this.nodeMap.get(t),o=this.nodeMap.get(e);return n.width*n.height-o.width*o.height}),this.nextBatchNodeIds=[],void(this.batchHadModifications=!1)):(this.solved=!0,void this.newNodes.push(...this.nextBatchNodeIds.map(t=>this.nodeMap.get(t))));const e=this.nodeMap.get(t);let n=!1;const o=this.getAdjacentSameLayerUnprocessedNodes(e);if(0===o.length)return void this.nextBatchNodeIds.push(t);const i=t=>{for(const e of t)this.absorbedNodeIds.add(e.capacityMeshNodeId);e._adjacentNodeIds=Array.from(new Set([...e._adjacentNodeIds??[],...t.flatMap(t=>t._adjacentNodeIds??[])].filter(t=>t!==e.capacityMeshNodeId&&!this.absorbedNodeIds.has(t))))},s=o.filter(t=>t.center.x<e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(s.length>0){const{width:t,height:o}=s[0],r=s.every(e=>e.width===t&&e.height===o);Math.abs(s.reduce((t,e)=>t+e.height,0)-e.height)<Of&&r&&(e.width+=t,e.center.x=e.center.x-t/2,i(s),n=!0)}const r=o.filter(t=>t.center.x>e.center.x&&Math.abs(t.center.y-e.center.y)<e.height/2);if(r.length>0&&!n){const{width:t,height:o}=r[0],s=r.every(e=>e.width===t&&e.height===o);Math.abs(r.reduce((t,e)=>t+e.height,0)-e.height)<Of&&s&&(e.width+=t,e.center.x=e.center.x+t/2,i(r),n=!0)}const a=o.filter(t=>t.center.y>e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(a.length>0&&!n){const{width:t,height:o}=a[0],s=a.every(e=>e.width===t&&e.height===o);Math.abs(a.reduce((t,e)=>t+e.width,0)-e.width)<Of&&s&&(e.height+=o,e.center.y=e.center.y+o/2,i(a),n=!0)}const c=o.filter(t=>t.center.y<e.center.y&&Math.abs(t.center.x-e.center.x)<e.width/2);if(c.length>0&&!n){const{width:t,height:o}=c[0],s=c.every(e=>e.width===t&&e.height===o);Math.abs(c.reduce((t,e)=>t+e.width,0)-e.width)<Of&&s&&(e.height+=o,e.center.y=e.center.y-o/2,i(c),n=!0)}n?(this.batchHadModifications=!0,this.currentBatchNodeIds.push(t)):this.nextBatchNodeIds.unshift(t)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Single Layer Node Merger (Only Merge Targets)"};for(const e of this.newNodes)t.rects.push(td(e));const e=this.currentBatchNodeIds[this.currentBatchNodeIds.length-1];let n;e&&(n=this.getAdjacentSameLayerUnprocessedNodes(this.nodeMap.get(e)));for(const o of this.currentBatchNodeIds){const i=this.nodeMap.get(o);if(!this.absorbedNodeIds.has(o)&&i){const s=td(i,{rectMargin:.01});o===e?s.stroke="rgba(0, 255, 0, 0.8)":n?.some(t=>t.capacityMeshNodeId===o)?s.stroke="rgba(128, 0, 128, 0.8)":s.stroke="rgba(255, 165, 0, 0.8)",s.layer=`z${i.availableZ.join(",")}`,s.label=`${s.label}\n(unprocessed)`,t.rects.push(s)}}for(const e of this.nextBatchNodeIds){const n=this.nodeMap.get(e);if(!this.absorbedNodeIds.has(e)&&n){const e=td(n,{rectMargin:.01});e.layer=`z${n.availableZ.join(",")}`,e.stroke="rgba(0, 217, 255, 0.8)",e.label=`${e.label}\nx: ${n.center.x}, y: ${n.center.y}\n${n.width}x${n.height}\n(next batch)`,t.rects.push(e)}}return t}},zf=class extends Dn{getSolverName(){return"AssignableViaNodeMergerSolver"}newNodes;obstacleToNodesMap;obstaclesToProcess;mergedNodeIds;constructor(t){super(),this.MAX_ITERATIONS=1e4,this.newNodes=[],this.obstacleToNodesMap=new Map,this.mergedNodeIds=new Set;for(const e of t){const t=e._assignedViaObstacle;if(t){const n=this.obstacleToNodesMap.get(t)||[];n.push(e),this.obstacleToNodesMap.set(t,n)}else this.newNodes.push(e)}this.obstaclesToProcess=Array.from(this.obstacleToNodesMap.keys())}_step(){const t=this.obstaclesToProcess.pop();if(!t)return void(this.solved=!0);const e=this.obstacleToNodesMap.get(t);if(!e||0===e.length)return;let n=Number.POSITIVE_INFINITY,o=Number.NEGATIVE_INFINITY,i=Number.POSITIVE_INFINITY,s=Number.NEGATIVE_INFINITY;const r=new Set;let a=!1;for(const t of e){const e=t.center.x-t.width/2,c=t.center.x+t.width/2,h=t.center.y-t.height/2,l=t.center.y+t.height/2;n=Math.min(n,e),o=Math.max(o,c),i=Math.min(i,h),s=Math.max(s,l);for(const e of t.availableZ)r.add(e);t._containsTarget&&(a=!0)}const c=o-n,h=s-i,l=(n+o)/2,d=(i+s)/2,u=Array.from(r).sort((t,e)=>t-e),p={capacityMeshNodeId:`merged_via_${t.center.x}_${t.center.y}`,center:{x:l,y:d},width:c,height:h,layer:1===u.length?`z${u[0]}`:`z${u.join(",")}`,availableZ:u,_containsTarget:a,_containsObstacle:!1,_completelyInsideObstacle:!1};p._assignedViaObstacle=t;for(const t of e)this.mergedNodeIds.add(t.capacityMeshNodeId);this.newNodes.push(p)}visualize(){const t={circles:[],lines:[],points:[],rects:[],coordinateSystem:"cartesian",title:"Assignable Via Node Merger"};for(const e of this.newNodes){const n=td(e);e._assignedViaObstacle&&(n.stroke="rgba(255, 0, 255, 0.8)",n.label=`${n.label||""}\n(merged via)`),t.rects.push(n)}const e=this.obstaclesToProcess[this.obstaclesToProcess.length-1];if(e){const n=this.obstacleToNodesMap.get(e)||[];for(const e of n){const n=td(e,{rectMargin:.01});n.stroke="rgba(0, 255, 0, 0.8)",n.label=`${n.label||""}\n(to be merged)`,t.rects.push(n)}}return t}},Df=class extends Dn{constructor(t){const{simpleRouteJson:e,nodes:n,edges:o,colorMap:i,MAX_ITERATIONS:s=1e6,hyperParameters:r={}}=t;super(),this.inputParams=t,this.hyperParameters=r,this.MAX_ITERATIONS=s,this.simpleRouteJson=e,this.nodes=n,this.edges=o,this.colorMap=i??{},this.nodeMap=new Map(this.nodes.map(t=>[t.capacityMeshNodeId,t])),this.nodeEdgeMap=Ln(this.edges);const a=this.nodes.filter(t=>t._containsTarget);this.unprocessedConnectionPairs=Un(this.simpleRouteJson.connections.map(t=>{const[e,n]=t.pointsToConnect;return{start:a.find(t=>F(t.center,e)<t.width/2),end:a.find(t=>F(t.center,n)<t.width/2),connection:t}}),this.hyperParameters.SHUFFLE_SEED??0),this.viaNodes=this.nodes.filter(t=>t.availableZ.length>1)}getSolverName(){return"AssignableViaCapacityPathingSolver_DirectiveSubOptimal"}GREEDY_MULTIPLIER=1.5;simpleRouteJson;nodes;edges;colorMap;MAX_ITERATIONS;hyperParameters;usedNodeMap=new Map;nodeMap;nodeEdgeMap;unprocessedConnectionPairs;solvedRoutes=[];activeConnectionPair=null;ogUnprocessedSubpaths=null;unprocessedSubpaths=null;solvedSubpaths=null;activeSubpath=null;viaNodes=[];closestViaForConnectionStartMap=new Map;closestViaForConnectionEndMap=new Map;getConstructorParams(){return this.inputParams}lastStepOperation="none";computeClosestViaForAllConnections(){this.closestViaForConnectionStartMap.clear(),this.closestViaForConnectionEndMap.clear();for(const t of this.unprocessedConnectionPairs){const e=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId));if(e.length>0){const n=e.reduce((e,n)=>{const o=this._dist(e,t.start);return this._dist(n,t.start)<o?n:e});this.closestViaForConnectionStartMap.set(t,n);const o=e.reduce((e,n)=>{const o=this._dist(e,t.end);return this._dist(n,t.end)<o?n:e});this.closestViaForConnectionEndMap.set(t,o)}}}_step(){if(!this.activeConnectionPair)return this.activeConnectionPair=this.unprocessedConnectionPairs.shift(),this.activeConnectionPair?(this.computeClosestViaForAllConnections(),void(this.lastStepOperation="dequeueConnectionPair")):void(this.solved=!0);if(this.activeConnectionPair&&!this.unprocessedSubpaths)return this.unprocessedSubpaths=this.breakConnectionPairIntoSubpaths(this.activeConnectionPair),this.ogUnprocessedSubpaths=this.unprocessedSubpaths.slice(),this.solvedSubpaths=[],void(this.lastStepOperation="breakConnectionPairIntoSubpaths");if(this.activeSubpath){if(this.activeSubpath&&(this.stepSolveSubpath(this.activeSubpath),this.activeSubpath.solved))return this.solvedSubpaths.push(this.activeSubpath),this.activeSubpath=null,this.clearCandidateNodes(),void(this.lastStepOperation="finishedSolvingSubpath");this.lastStepOperation="stepSolveSubpath"}else{if(this.activeSubpath=this.unprocessedSubpaths.shift(),!this.activeSubpath){const t=this.activeConnectionPair;return this.activeConnectionPair=null,this.unprocessedSubpaths=null,this.ogUnprocessedSubpaths=null,this.activeSubpath=null,this.solvedRoutes.push(this.createSolvedRoute(this.solvedSubpaths,t)),void(this.lastStepOperation="finishedSolvingConnectionPair")}this.lastStepOperation="dequeueSubpath"}}queuedCandidateNodes=[];visitedNodes=new Set;_dist(t,e){return Math.hypot(t.center.x-e.center.x,t.center.y-e.center.y)}stepSolveSubpath(t){const{start:e,end:n}=t;if(e.capacityMeshNodeId===n.capacityMeshNodeId)return t.path=[e],t.solved=!0,void this.usedNodeMap.set(e.capacityMeshNodeId,!0);if(0===this.queuedCandidateNodes.length&&0===this.visitedNodes.size){const t=this._dist(e,n),o={prevCandidate:null,node:e,g:0,h:t,f:this.GREEDY_MULTIPLIER*t};this.queuedCandidateNodes.push(o)}let o;for(this.queuedCandidateNodes.sort((t,e)=>t.f-e.f);this.queuedCandidateNodes.length&&!o;){const t=this.queuedCandidateNodes.shift();this.visitedNodes.has(t.node.capacityMeshNodeId)||(o=t)}if(!o)return this.failed=!0,void(this.error="No viable candidates left");if(this.visitedNodes.add(o.node.capacityMeshNodeId),o.node.capacityMeshNodeId===n.capacityMeshNodeId){const e=[];let n=o;for(;n;)e.unshift(n.node),this.usedNodeMap.set(n.node.capacityMeshNodeId,!0),n=n.prevCandidate;return t.path=e,void(t.solved=!0)}const i=this.getNeighbors(o.node);for(const t of i){const e=t.capacityMeshNodeId;if(this.visitedNodes.has(e))continue;const i=this.computeG(o,t,n),s=this.computeH(o,t,n),r=i+this.GREEDY_MULTIPLIER*s,a=this.queuedCandidateNodes.findIndex(t=>t.node.capacityMeshNodeId===e);if(a>=0){if(this.queuedCandidateNodes[a].g<=i)continue;this.queuedCandidateNodes.splice(a,1)}this.queuedCandidateNodes.push({prevCandidate:o,node:t,g:i,h:s,f:r})}}getNeighbors(t){const e=new Set,n=this.nodeEdgeMap.get(t.capacityMeshNodeId)??[];for(const o of n){const[n,i]=o.nodeIds,s=n===t.capacityMeshNodeId?i:n,r=this.nodeMap.get(s);r&&e.add(r)}const o=this.activeSubpath?.layer;return Array.from(e).filter(t=>!(t.capacityMeshNodeId!==this.activeSubpath?.end.capacityMeshNodeId)||!t._containsObstacle&&(!t._containsTarget&&(!this.usedNodeMap.has(t.capacityMeshNodeId)&&!(void 0!==o&&!t.availableZ.includes(o)))))}clearCandidateNodes(){this.queuedCandidateNodes=[],this.visitedNodes=new Set}computeG(t,e,n){const o=this._dist(t.node,e);return t.g+o}computeH(t,e,n){return this._dist(e,n)}createSolvedRoute(t,e){const n=[];for(let e=0;e<t.length;e++){const o=t[e];o.path?0===e?n.push(...o.path):n.push(...o.path.slice(1)):(0===e&&n.push(o.start),e===t.length-1&&n.push(o.end))}return{connection:e.connection,path:n}}breakConnectionPairIntoSubpaths(t){var e,n;if(!(e=[this.hyperParameters.DIRECTIVE_SEED??0,this.solvedRoutes.length],n=this.hyperParameters.FORCE_VIA_TRAVEL_CHANCE??0,Vn(e.reduce((t,e)=>t+16807*e%2147483647,0))()<n))return[{start:t.start,end:t.end,solved:!1,layer:t.start.availableZ[0]??0}];const o=this.getClosestVia(t.start),i=this.getFarVia(o,t.end),s=t.start.availableZ[0]??0,r=t.end.availableZ[0]??0,a=[];return a.push({start:t.start,end:o,solved:!1,layer:s}),s===r?(a.push({start:o,end:i,solved:!1,layer:0===s?1:0}),a.push({start:i,end:t.end,solved:!1,layer:r})):a.push({start:o,end:t.end,solved:!1,layer:r}),a}getClosestVia(t){if(0===this.viaNodes.length)return t;const e=new Set;for(const[t,n]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair&&e.add(n.capacityMeshNodeId);for(const[t,n]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair&&e.add(n.capacityMeshNodeId);const n=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId)).filter(t=>!e.has(t.capacityMeshNodeId));if(0===n.length){const e=this.viaNodes.filter(t=>!t._completelyInsideObstacle&&!t._containsObstacle).filter(t=>!this.usedNodeMap.has(t.capacityMeshNodeId));return 0===e.length?t:(e.sort((e,n)=>this._dist(e,t)-this._dist(n,t)),e[0])}n.sort((e,n)=>this._dist(e,t)-this._dist(n,t));const o=this.hyperParameters.MAX_CLOSEST_VIA_SKIP??0;if(o>0&&n.length>1){const t=Vn((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length),e=Math.floor(t()*(o+1));return n[Math.min(e,n.length-1)]}return n[0]}getFarVia(t,e){if(0===this.viaNodes.length)return t;const n=null!=this.hyperParameters.FAR_VIA_MIN_DISTANCE?this.hyperParameters.FAR_VIA_MIN_DISTANCE:50,o=new Set;for(const[t,e]of this.closestViaForConnectionStartMap)t!==this.activeConnectionPair&&o.add(e.capacityMeshNodeId);for(const[t,e]of this.closestViaForConnectionEndMap)t!==this.activeConnectionPair&&o.add(e.capacityMeshNodeId);const i=this.viaNodes.filter(e=>!this.usedNodeMap.has(e.capacityMeshNodeId)&&e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!o.has(e.capacityMeshNodeId)&&this._dist(e,t)>=n);if(0===i.length){const o=this.viaNodes.filter(e=>e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!this.usedNodeMap.has(e.capacityMeshNodeId)&&this._dist(e,t)>=n).sort((t,n)=>this._dist(t,e)-this._dist(n,e));if(o.length>0)return o[0];return this.viaNodes.filter(e=>e.capacityMeshNodeId!==t.capacityMeshNodeId&&!e._completelyInsideObstacle&&!e._containsObstacle&&!this.usedNodeMap.has(e.capacityMeshNodeId)).sort((t,n)=>this._dist(t,e)-this._dist(n,e))[0]??t}i.sort((t,n)=>this._dist(t,e)-this._dist(n,e));const s=this.hyperParameters.MAX_FURTHEST_VIA_SKIP??0;if(s>0&&i.length>1){const t=Vn((this.hyperParameters.DIRECTIVE_SEED??0)+this.solvedRoutes.length+1e3),e=Math.floor(t()*(s+1));return i[Math.min(e,i.length-1)]}return i[0]}getCapacityPaths(){const t=[];for(const e of this.solvedRoutes){const n=e.path;n&&n.length>0&&t.push({capacityPathId:e.connection.name,connectionName:e.connection.name,nodeIds:n.map(t=>t.capacityMeshNodeId)})}return t}visualize(){const t={lines:[],points:[],rects:[],circles:[]},e=t=>!!t&&"number"==typeof t.x&&"number"==typeof t.y&&!Number.isNaN(t.x)&&!Number.isNaN(t.y)&&Number.isFinite(t.x)&&Number.isFinite(t.y),n=t=>"number"==typeof t&&!Number.isNaN(t)&&Number.isFinite(t);for(const o of this.nodes){const i=this.queuedCandidateNodes.some(t=>t.node.capacityMeshNodeId===o.capacityMeshNodeId),s=this.queuedCandidateNodes.find(t=>t.node.capacityMeshNodeId===o.capacityMeshNodeId);if(e(o.center)&&n(o.width)&&n(o.height)){const e=td(o,{rectMargin:.025,zOffset:.01});t.rects.push({...e,fill:i?"rgba(255, 128, 255, 0.5)":o._containsTarget?"rgba(0, 150, 255, 0.15)":o._containsObstacle?"rgba(255, 0, 0, 0.1)":"rgba(200, 200, 200, 0.05)",label:[`ID: ${o.capacityMeshNodeId}`,`Size: ${o.width.toFixed(2)}x${o.height.toFixed(2)}`,`Z: ${o.availableZ.join(", ")}`,s?`g: ${s.g.toFixed(2)}`:"",s?`h: ${s.h.toFixed(2)}`:"",s?`f: ${s.f.toFixed(2)}`:"",o._containsTarget?"TARGET":"",o._containsObstacle?"OBSTACLE":""].filter(t=>t).join("\n")})}}for(const n of this.edges){const[o,i]=n.nodeIds,s=this.nodeMap.get(o),r=this.nodeMap.get(i);s?.center&&r?.center&&e(s.center)&&e(r.center)&&t.lines.push({points:[s.center,r.center],strokeColor:"rgba(150, 150, 150, 0.2)"})}for(let n=0;n<this.solvedRoutes.length;n++){const o=this.solvedRoutes[n],i=o.path,s="blue";for(let o=0;o<i.length-1;o++){const r=i[o],a=i[o+1];if(r?.center&&a?.center&&e(r.center)&&e(a.center)){const e=r.availableZ.includes(1)&&a.availableZ.includes(1),o=n%5*.02;t.lines.push({points:[{x:r.center.x+o,y:r.center.y+o},{x:a.center.x+o,y:a.center.y+o}],strokeColor:s,strokeDash:e?"5 5":void 0})}}if(i.length>0){const n=i[0],s=i[i.length-1];n?.center&&e(n.center)&&t.points.push({x:n.center.x,y:n.center.y,label:`START: ${o.connection.name}`}),s?.center&&e(s.center)&&t.points.push({x:s.center.x,y:s.center.y,label:`END: ${o.connection.name}`})}}if(this.solvedSubpaths)for(let n=0;n<this.solvedSubpaths.length;n++){const o=this.solvedSubpaths[n];if(o.path&&o.path.length>1)for(let n=0;n<o.path.length-1;n++){const i=o.path[n],s=o.path[n+1];i?.center&&s?.center&&e(i.center)&&e(s.center)&&t.lines.push({points:[i.center,s.center],strokeColor:"green",strokeDash:1===o.layer?"3 3":void 0})}}if(this.activeSubpath){const n=this.activeSubpath.start?.center,o=this.activeSubpath.end?.center;n&&o&&e(n)&&e(o)&&(t.lines.push({points:[n,o],strokeColor:"orange",strokeDash:"5 5"}),t.points.push({x:n.x,y:n.y,label:"ACTIVE START"}),t.points.push({x:o.x,y:o.y,label:"ACTIVE END"}))}const o=this.queuedCandidateNodes.slice(0,10).sort((t,e)=>t.f-e.f);for(let n=0;n<o.length;n++){const i=.6*(1-n/10),s=[];let r=o[n];for(;r;)s.push(r.node),r=r.prevCandidate;if(s.reverse(),s.length>1){const n=s.map(t=>t.center).filter(t=>e(t));n.length>1&&t.lines.push({points:n,strokeColor:Mn("purple",1-i),strokeDash:1===this.activeSubpath?.layer?"4 2":void 0})}}if(this.activeConnectionPair){const n=this.activeConnectionPair.start?.center,o=this.activeConnectionPair.end?.center;n&&o&&e(n)&&e(o)&&t.lines.push({points:[n,o],strokeColor:"cyan",strokeDash:"20 5"})}if(this.ogUnprocessedSubpaths&&3===this.ogUnprocessedSubpaths.length){const[,o]=this.ogUnprocessedSubpaths;if(o.start?.center&&e(o.start.center)){const e=Math.max(o.start.width||0,o.start.height||0);n(e)&&e>0&&(t.circles.push({center:o.start.center,radius:e,stroke:"blue"}),t.points.push({x:o.start.center.x,y:o.start.center.y,label:"DIRECTIVE VIA 1"}))}if(o.end?.center&&e(o.end.center)){const e=Math.max(o.end.width||0,o.end.height||0);n(e)&&e>0&&(t.circles.push({center:o.end.center,radius:e,stroke:"purple"}),t.points.push({x:o.end.center.x,y:o.end.center.y,label:"DIRECTIVE VIA 2"}))}}if(this.queuedCandidateNodes.length>0)for(const n of this.queuedCandidateNodes){const o=n.node;o?.center&&e(o.center)&&t.circles.push({center:o.center,radius:.05,fill:"rgba(255, 255, 0, 0.6)",stroke:"yellow"})}if(this.visitedNodes.size>0)for(const n of this.visitedNodes){const o=this.nodeMap.get(n);o?.center&&e(o.center)&&t.circles.push({center:o.center,radius:.08,fill:"rgba(128, 128, 128, 0.5)",stroke:"gray"})}return t}},Lf=class extends io{getSolverName(){return"HyperAssignableViaCapacityPathingSolver"}constructorParams;constructor(t){super(),this.constructorParams=t,this.MAX_ITERATIONS=t.MAX_ITERATIONS??12e4,this.MIN_SUBSTEPS=5,this.GREEDY_MULTIPLIER=1.35}getHyperParameterDefs(){return[{name:"traceOrderingSeed",possibleValues:[{SHUFFLE_SEED:0},{SHUFFLE_SEED:1},{SHUFFLE_SEED:2},{SHUFFLE_SEED:3},{SHUFFLE_SEED:4},{SHUFFLE_SEED:5},{SHUFFLE_SEED:6},{SHUFFLE_SEED:7},{SHUFFLE_SEED:8},{SHUFFLE_SEED:9}]},{name:"forceViaTravelChance",possibleValues:[{FORCE_VIA_TRAVEL_CHANCE:.6},{FORCE_VIA_TRAVEL_CHANCE:.8},{FORCE_VIA_TRAVEL_CHANCE:.9}]}]}computeG(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length,o=e>0?n/e:0;return t.iterations/t.MAX_ITERATIONS+(1-o)}computeH(t){const e=t.unprocessedConnectionPairs.length+t.solvedRoutes.length+(t.activeConnectionPair?1:0),n=t.solvedRoutes.length;return e>0?1-n/e:0}generateSolver(t){return new Df({...this.constructorParams,hyperParameters:{...this.constructorParams.hyperParameters,...t}})}};function Yf(t){const e=new Map;for(const n of t)e.set(n.capacityMeshNodeId,n);return e}function Xf(t,e){return{x:(t.x+e.x)/2,y:(t.y+e.y)/2}}var Ff=class extends Dn{getSolverName(){return"OffboardCapacityNodeSolver"}capacityNodes;capacityEdges;enhancedEdges=[];animationState="showing_nodes";assignableNodes=[];shownNodes=[];pendingEdges=[];createdEdges=[];nextEdgeId=0;nodeMap=new Map;constructor(t){super(),this.capacityNodes=t.capacityNodes,this.capacityEdges=t.capacityEdges,this.nodeMap=Yf(this.capacityNodes),this.enhancedEdges=[...this.capacityEdges],this.initializeAssignableNodes(),this.initializePendingEdges(),this.MAX_ITERATIONS=this.assignableNodes.length+this.pendingEdges.length+10}initializeAssignableNodes(){for(const t of this.capacityNodes){const e=t._assignedViaObstacle;e?.offBoardConnectsTo&&e.offBoardConnectsTo.length>0&&this.assignableNodes.push(t)}}initializePendingEdges(){const t=new Map;for(const e of this.assignableNodes){const n=e._assignedViaObstacle;if(n?.offBoardConnectsTo)for(const o of n.offBoardConnectsTo)t.has(o)||t.set(o,[]),t.get(o).push(e)}this.pendingEdges=[];for(const[e,n]of t)if(n.length>1)for(let t=0;t<n.length;t++)for(let o=t+1;o<n.length;o++)this.pendingEdges.push({node1:n[t],node2:n[o],netName:e})}_step(){switch(this.animationState){case"showing_nodes":if(this.assignableNodes.length>0){const t=this.assignableNodes.shift();this.shownNodes.push(t)}else this.animationState="showing_edges";break;case"showing_edges":if(this.pendingEdges.length>0){const{node1:t,node2:e,netName:n}=this.pendingEdges.shift(),o=this.createOffboardEdge(t,e,n);this.enhancedEdges.push(o),this.createdEdges.push(o)}else this.animationState="done",this.solved=!0;break;case"done":this.solved=!0}}createOffboardEdge(t,e,n){return{capacityMeshEdgeId:"offboard_"+this.nextEdgeId++,nodeIds:[t.capacityMeshNodeId,e.capacityMeshNodeId],isOffboardEdge:!0,offboardNetName:n}}visualize(){const t=[],e=[],n=[],o=new Set(this.shownNodes.map(t=>t.capacityMeshNodeId));for(const e of this.capacityEdges){if(e.isOffboardEdge)continue;if(o.has(e.nodeIds[0])||o.has(e.nodeIds[1])){const n=this.nodeMap.get(e.nodeIds[0]),o=this.nodeMap.get(e.nodeIds[1]);n&&o&&t.push({points:[n.center,o.center],strokeColor:"rgba(0, 200, 0, 0.5)",strokeWidth:.05})}}for(let t=0;t<this.shownNodes.length;t++){const o=this.shownNodes[t],i=o._assignedViaObstacle,s=t===this.shownNodes.length-1&&"showing_nodes"===this.animationState;n.push({center:o.center,width:o.width,height:o.height,fill:s?"rgba(255, 165, 0, 0.5)":"rgba(173, 216, 230, 0.5)",stroke:s?"orange":"blue",strokeWidth:s?.15:.1}),e.push({x:o.center.x,y:o.center.y,color:s?"orange":"blue",label:`${s?"NEW: ":""}${o.capacityMeshNodeId}\n${i?.offBoardConnectsTo?.join(", ")||""}`})}for(let n=0;n<this.createdEdges.length;n++){const o=this.createdEdges[n],i=n===this.createdEdges.length-1&&"showing_edges"===this.animationState,s=this.nodeMap.get(o.nodeIds[0]),r=this.nodeMap.get(o.nodeIds[1]);if(s&&r){t.push({points:[s.center,r.center],strokeColor:i?"red":"orange",strokeWidth:i?.2:.1,strokeDasharray:"0.3,0.15"});const n=Xf(s.center,r.center);e.push({x:n.x,y:n.y,color:i?"red":"orange",label:`${i?"NEW: ":""}⚡ ${o.offboardNetName}`})}}let i="Offboard Capacity Node Solver";switch(this.animationState){case"showing_nodes":i+=` - Showing nodes (${this.shownNodes.length}/${this.shownNodes.length+this.assignableNodes.length})`;break;case"showing_edges":i+=` - Creating edges (${this.createdEdges.length}/${this.createdEdges.length+this.pendingEdges.length})`;break;case"done":i+=` - Done (${this.shownNodes.length} nodes, ${this.createdEdges.length} edges)`}return{lines:t,points:e,rects:n,title:i}}getVirtualOffboardNodes(){return[]}getOffboardEdges(){return this.enhancedEdges.filter(t=>t.isOffboardEdge)}};function kf(t,e){return t.x>=e.center.x-e.width/2&&t.x<=e.center.x+e.width/2&&t.y>=e.center.y-e.height/2&&t.y<=e.center.y+e.height/2}var $f=class extends Dn{getSolverName(){return"OffboardPathFragmentSolver"}inputPaths;capacityEdges;originalConnections;fragmentedPaths=[];fragmentedConnections=[];fragmentedOriginalConnectionNames=new Set;nextFragmentId=0;animationState="showing_original_path";currentPath=null;currentFragments=[];currentFragmentIndex=0;nodeMap=new Map;constructor({capacityPaths:t,capacityEdges:e,capacityNodes:n,connections:o}){super(),this.inputPaths=[...t],this.capacityEdges=e,this.originalConnections=o,this.nodeMap=Yf(n)}_step(){switch(this.animationState){case"showing_original_path":if(0===this.inputPaths.length)return this.animationState="done",void(this.solved=!0);this.currentPath=this.inputPaths.shift(),this.currentFragments=this.splitPath(this.currentPath),this.currentFragmentIndex=0;this.currentFragments.some(t=>t.isFragmentedPath)?this.animationState="showing_fragment":this.fragmentedPaths.push(...this.currentFragments);break;case"showing_fragment":if(this.currentFragmentIndex<this.currentFragments.length){const t=this.currentFragments[this.currentFragmentIndex];this.fragmentedPaths.push(t),this.currentFragmentIndex++}else this.currentPath&&(this.fragmentedOriginalConnectionNames.add(this.currentPath.connectionName),this.createFragmentConnections(this.currentPath,this.currentFragments)),this.currentPath=null,this.currentFragments=[],this.currentFragmentIndex=0,this.animationState="showing_original_path";break;case"done":this.solved=!0}}createFragmentConnections(t,e){const n=this.originalConnections.find(e=>e.name===t.connectionName);if(n)for(let t=0;t<e.length;t++){const o=e[t];if(!o.isFragmentedPath)continue;const i=n.pointsToConnect.filter(t=>{for(const e of o.nodeIds){const n=this.nodeMap.get(e);if(n&&kf(t,n))return!0}return!1}),s=0===t,r=s?o.nodeIds[o.nodeIds.length-1]:o.nodeIds[0],a=this.nodeMap.get(r);if(i.length>0&&a){const t=i[0],e={x:a.center.x,y:a.center.y,layer:Cn(t)},r=s?[...i,e]:[e,...i];this.fragmentedConnections.push({name:o.connectionName,pointsToConnect:r,netConnectionName:n.netConnectionName,rootConnectionName:n.rootConnectionName})}}}splitPath(t){const{nodeIds:e}=t;if(e.length<2)return[t];const n=[];for(let t=0;t<e.length-1;t++){const o=this.capacityEdges.find(n=>n.nodeIds[0]===e[t]&&n.nodeIds[1]===e[t+1]||n.nodeIds[0]===e[t+1]&&n.nodeIds[1]===e[t]);o&&o.isOffboardEdge&&n.push(t)}if(0===n.length)return[t];const o=[];let i=0,s=0;for(const r of n){const n=e.slice(i,r+1);if(n.length>=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${s++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}i=r+1}if(i<e.length){const n=e.slice(i);if(n.length>=1){const e=this.nextFragmentId++;o.push({capacityPathId:`${t.capacityPathId}_frag_${e}`,connectionName:`${t.connectionName}_frag_${s++}`,rootConnectionName:t.rootConnectionName,nodeIds:n,isFragmentedPath:!0,mstPairConnectionName:t.connectionName})}}return o.length>0?o:[t]}getFragmentedPaths(){return this.fragmentedPaths}getFragmentedConnections(){return this.fragmentedConnections}getFragmentedOriginalConnectionNames(){return this.fragmentedOriginalConnectionNames}visualize(){const t=[],e=[],n=[];if("showing_original_path"===this.animationState&&this.currentPath&&this.drawPath({path:this.currentPath,color:"gray",lines:t,points:e,rects:n,labelPrefix:"Original: "}),this.fragmentedPaths.forEach((o,i)=>{if(o.isFragmentedPath){const s=i%2==0?"blue":"red";this.drawPath({path:o,color:s,lines:t,points:e,rects:n,labelPrefix:`Frag ${i}: `})}else this.drawPath({path:o,color:"green",lines:t,points:e,rects:n,labelPrefix:""})}),"showing_fragment"===this.animationState&&this.currentFragmentIndex>0){const o=this.fragmentedPaths.length-1;if(o>=0){const i=this.fragmentedPaths[o];i.isFragmentedPath&&this.drawPath({path:i,color:"orange",lines:t,points:e,rects:n,labelPrefix:"NEW: "})}}for(const e of this.capacityEdges)if(e.isOffboardEdge){const n=this.nodeMap.get(e.nodeIds[0]),o=this.nodeMap.get(e.nodeIds[1]);n&&o&&t.push({points:[n.center,o.center],strokeColor:"orange",strokeWidth:.15,strokeDasharray:"0.3,0.15"})}let o="Offboard Path Fragment Solver";return"showing_original_path"===this.animationState?o+=" - Analyzing path...":"showing_fragment"===this.animationState?o+=` - Fragment ${this.currentFragmentIndex}/${this.currentFragments.length}`:o+=` - Done (${this.fragmentedPaths.filter(t=>t.isFragmentedPath).length} fragments)`,{lines:t,points:e,rects:n,title:o}}drawPath(t){const{path:e,color:n,lines:o,points:i,rects:s,labelPrefix:r}=t,a=[];for(let t=0;t<e.nodeIds.length;t++){const o=e.nodeIds[t],c=this.nodeMap.get(o);c&&(a.push(c.center),s.push({center:c.center,width:.8*c.width,height:.8*c.height,stroke:n,strokeWidth:.05,fill:`${n}33`}),0!==t&&t!==e.nodeIds.length-1||i.push({x:c.center.x,y:c.center.y,color:n,label:`${r}${e.connectionName}\n${o}`}))}a.length>1&&o.push({points:a,strokeColor:n,strokeWidth:.1})}};function Bf(t,e,n,o={}){return{solverName:t,solverClass:e,getConstructorParams:n,onSolved:o.onSolved}}var jf=class extends Dn{constructor(t,e={}){super(),this.srj=t,this.opts=e,this.srj=t,this.opts={...e},this.MAX_ITERATIONS=1e8;const n=this.opts;if(void 0===n.capacityDepth){const e=t.bounds.maxX-t.bounds.minX,o=t.bounds.maxY-t.bounds.minY,i=Math.max(e,o),s=n.targetMinCapacity??.5;n.capacityDepth=zh(i,s)}this.connMap=zn(t),this.colorMap=In(t,this.connMap),this.cacheProvider=void 0===n.cacheProvider?Se():null===n.cacheProvider?null:n.cacheProvider,this.startTimeOfPhase={},this.endTimeOfPhase={},this.timeSpentOnPhase={}}getSolverName(){return"AssignableAutoroutingPipeline1Solver"}netToPointPairsSolver;nodeSolver;nodeTargetMerger;edgeSolver;initialPathingSolver;initialPathingHyperSolver;pathingOptimizer;edgeToPortSegmentSolver;colorMap;segmentToPointSolver;unravelMultiSectionSolver;segmentToPointOptimizer;highDensityRouteSolver;highDensityStitchSolver;singleLayerNodeMerger;mergeAssignableViaNodes;offboardCapacityNodeSolver;offboardPathFragmentSolver;strawSolver;deadEndSolver;uselessViaRemovalSolver1;uselessViaRemovalSolver2;multiSimplifiedPathSolver1;multiSimplifiedPathSolver2;startTimeOfPhase;endTimeOfPhase;timeSpentOnPhase;activeSubSolver=null;connMap;srjWithPointPairs;capacityNodes=null;capacityEdges=null;cacheProvider=null;pipelineDef=[Bf("netToPointPairsSolver",il,t=>[t.srj,t.colorMap],{onSolved:t=>{t.srjWithPointPairs=t.netToPointPairsSolver?.getNewSimpleRouteJson(),t.colorMap=In(t.srjWithPointPairs,this.connMap),t.connMap=zn(t.srjWithPointPairs)}}),Bf("nodeSolver",Rf,t=>[t.netToPointPairsSolver?.getNewSimpleRouteJson()||t.srj,t.opts],{onSolved:t=>{t.capacityNodes=t.nodeSolver?.finishedNodes}}),Bf("mergeAssignableViaNodes",zf,t=>[t.nodeSolver?.finishedNodes],{onSolved:t=>{t.capacityNodes=t.mergeAssignableViaNodes?.newNodes}}),Bf("singleLayerNodeMerger",Af,t=>[t.capacityNodes],{onSolved:t=>{t.capacityNodes=t.singleLayerNodeMerger?.newNodes}}),Bf("edgeSolver",$n,t=>[t.capacityNodes],{onSolved:t=>{t.capacityEdges=t.edgeSolver?.edges}}),Bf("offboardCapacityNodeSolver",Ff,t=>[{capacityNodes:t.capacityNodes,capacityEdges:t.capacityEdges||[]}],{onSolved:t=>{t.capacityEdges=t.offboardCapacityNodeSolver?.enhancedEdges||t.capacityEdges}}),Bf("deadEndSolver",yd,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges}],{onSolved:t=>{const e=t.deadEndSolver?.removedNodeIds;t.capacityNodes=t.capacityNodes.filter(t=>!e.has(t.capacityMeshNodeId)),t.capacityEdges=t.capacityEdges.filter(t=>t.nodeIds.every(t=>!e.has(t)))}}),Bf("initialPathingHyperSolver",Lf,t=>[{simpleRouteJson:t.srjWithPointPairs,nodes:t.capacityNodes,edges:t.capacityEdges||[],colorMap:t.colorMap,hyperParameters:{MAX_CAPACITY_FACTOR:1}}],{onSolved:t=>{const e=t.initialPathingHyperSolver?.winningSolver;e&&(t.initialPathingSolver=e)}}),Bf("offboardPathFragmentSolver",$f,t=>[{capacityPaths:t.initialPathingSolver?.getCapacityPaths()||[],capacityEdges:t.capacityEdges||[],capacityNodes:t.capacityNodes||[],connections:t.srjWithPointPairs?.connections||[]}],{onSolved:t=>{const e=t.offboardPathFragmentSolver;if(!e)return;const n=e.getFragmentedPaths();for(const e of n)if(e.isFragmentedPath&&e.mstPairConnectionName){const n=t.colorMap[e.mstPairConnectionName];n&&!t.colorMap[e.connectionName]&&(t.colorMap[e.connectionName]=n)}const o=e.getFragmentedOriginalConnectionNames(),i=e.getFragmentedConnections();o.size>0&&t.srjWithPointPairs&&(t.srjWithPointPairs={...t.srjWithPointPairs,connections:[...t.srjWithPointPairs.connections.filter(t=>!o.has(t.name)),...i]},t.connMap=zn(t.srjWithPointPairs))}}),Bf("edgeToPortSegmentSolver",Vl,t=>[{nodes:t.capacityNodes,edges:t.capacityEdges||[],capacityPaths:t.offboardPathFragmentSolver?.getFragmentedPaths()||t.initialPathingSolver?.getCapacityPaths()||[],colorMap:t.colorMap}]),Bf("segmentToPointSolver",Ql,t=>{const e=[];return t.edgeToPortSegmentSolver?.nodePortSegments&&t.edgeToPortSegmentSolver.nodePortSegments.forEach(t=>{e.push(...t)}),[{segments:e,colorMap:t.colorMap,nodes:t.capacityNodes}]}),Bf("unravelMultiSectionSolver",Ad,t=>[{assignedSegments:t.segmentToPointSolver?.solvedSegments||[],colorMap:t.colorMap,nodes:t.capacityNodes,cacheProvider:this.cacheProvider}]),Bf("highDensityRouteSolver",Nh,t=>[{nodePortPoints:t.unravelMultiSectionSolver?.getNodesWithPortPoints()??t.segmentToPointOptimizer?.getNodesWithPortPoints()??[],colorMap:t.colorMap,connMap:t.connMap}]),Bf("highDensityStitchSolver",pl,t=>[{connections:t.srjWithPointPairs.connections,hdRoutes:t.highDensityRouteSolver.routes,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Bf("uselessViaRemovalSolver1",_l,t=>[{unsimplifiedHdRoutes:t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Bf("multiSimplifiedPathSolver1",Xl,t=>[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver1?.getOptimizedHdRoutes()||t.highDensityStitchSolver.mergedHdRoutes,obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}]),Bf("uselessViaRemovalSolver2",_l,t=>[{unsimplifiedHdRoutes:t.multiSimplifiedPathSolver1.simplifiedHdRoutes,obstacles:t.srj.obstacles,colorMap:t.colorMap,layerCount:t.srj.layerCount}]),Bf("multiSimplifiedPathSolver2",Xl,t=>[{unsimplifiedHdRoutes:t.uselessViaRemovalSolver2?.getOptimizedHdRoutes(),obstacles:t.srj.obstacles,connMap:t.connMap,colorMap:t.colorMap,outline:t.srj.outline}])];getConstructorParams(){return[this.srj,this.opts]}currentPipelineStepIndex=0;_step(){const t=this.pipelineDef[this.currentPipelineStepIndex];if(!t)return void(this.solved=!0);if(this.activeSubSolver)return this.activeSubSolver.step(),void(this.activeSubSolver.solved?(this.endTimeOfPhase[t.solverName]=performance.now(),this.timeSpentOnPhase[t.solverName]=this.endTimeOfPhase[t.solverName]-this.startTimeOfPhase[t.solverName],t.onSolved?.(this),this.activeSubSolver=null,this.currentPipelineStepIndex++):this.activeSubSolver.failed&&(this.error=this.activeSubSolver?.error,this.failed=!0,this.activeSubSolver=null));const e=t.getConstructorParams(this);this.activeSubSolver=new t.solverClass(...e),this[t.solverName]=this.activeSubSolver,this.timeSpentOnPhase[t.solverName]=0,this.startTimeOfPhase[t.solverName]=performance.now()}solveUntilPhase(t){for(;this.getCurrentPhase()!==t;)this.step()}getCurrentPhase(){return this.pipelineDef[this.currentPipelineStepIndex]?.solverName??"none"}visualize(){if(!this.solved&&this.activeSubSolver)return this.activeSubSolver.visualize();const t=this.netToPointPairsSolver?.visualize(),e=this.nodeSolver?.visualize(),n=this.nodeTargetMerger?.visualize(),o=this.mergeAssignableViaNodes?.visualize(),i=this.singleLayerNodeMerger?.visualize(),s=this.strawSolver?.visualize(),r=this.edgeSolver?.visualize(),a=(this.offboardCapacityNodeSolver?.visualize(),this.deadEndSolver?.visualize()),c=this.initialPathingSolver?.visualize(),h=this.offboardPathFragmentSolver?.visualize(),l=this.pathingOptimizer?.visualize(),d=this.edgeToPortSegmentSolver?.visualize(),u=this.segmentToPointSolver?.visualize(),p=this.unravelMultiSectionSolver?.visualize()??this.segmentToPointOptimizer?.visualize(),f=this.highDensityRouteSolver?.visualize(),g=this.highDensityStitchSolver?.visualize(),m=this.uselessViaRemovalSolver1?.visualize(),y=this.uselessViaRemovalSolver2?.visualize(),x=this.multiSimplifiedPathSolver1?.visualize(),v=this.multiSimplifiedPathSolver2?.visualize(),b=this.srj.outline,P=[];if(P.push({points:[{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.minY??-50},{x:this.srj.bounds?.maxX??50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.maxY??50},{x:this.srj.bounds?.minX??-50,y:this.srj.bounds?.minY??-50}],strokeColor:"rgba(255,0,0,0.25)"}),b&&b.length>=2){const t=b.map(t=>({x:t.x,y:t.y}));t.push({...t[0]}),P.push({points:t,strokeColor:"rgba(0, 136, 255, 0.95)"})}const S={points:[...this.srj.connections.flatMap(t=>t.pointsToConnect.map(e=>({...e,label:`${t.name} ${e.pcb_port_id??""}`})))],rects:[...(this.srj.obstacles??[]).map(t=>({...t,fill:t.layers?.includes("top")?"rgba(255,0,0,0.25)":t.layers?.includes("bottom")?"rgba(0,0,255,0.25)":"rgba(255,0,0,0.25)",label:t.layers?.join(", ")}))],lines:P},I=[S,t,e,n,o,i,s,r,a,c,h,l,d,u,p,f?Bn(S,f):null,g,m,x,y,v,this.solved?Bn(S,Rn(this.getOutputSimpleRouteJson())):null].filter(Boolean);return Bn(...I)}preview(){if(this.highDensityRouteSolver){const t=[];for(let e=this.highDensityRouteSolver.routes.length-1;e>=0;e--){const n=this.highDensityRouteSolver.routes[e];if(t.push({points:n.route.map(t=>({x:t.x,y:t.y})),strokeColor:this.colorMap[n.connectionName]}),t.length>200)break}return{lines:t}}if(this.pathingOptimizer){const t=[];for(const e of this.pathingOptimizer.connectionsWithNodes)e.path&&t.push({points:e.path.map(t=>({x:t.center.x,y:t.center.y})),strokeColor:this.colorMap[e.connection.name]});return{lines:t}}return this.netToPointPairsSolver?this.netToPointPairsSolver?.visualize():{}}_getOutputHdRoutes(){return this.multiSimplifiedPathSolver2?.simplifiedHdRoutes??this.uselessViaRemovalSolver2?.getOptimizedHdRoutes()??this.multiSimplifiedPathSolver1?.simplifiedHdRoutes??this.uselessViaRemovalSolver1?.getOptimizedHdRoutes()??this.highDensityStitchSolver.mergedHdRoutes}getOutputSimplifiedPcbTraces(){if(!this.solved||!this.highDensityRouteSolver)throw new Error("Cannot get output before solving is complete");const t=[],e=this._getOutputHdRoutes(),n=this.srjWithPointPairs?.connections??[];for(const o of n){const n=o.netConnectionName,i=o.rootConnectionName,s=e.filter(t=>t.connectionName===o.name);for(let e=0;e<s.length;e++){const r=s[e],a={type:"pcb_trace",pcb_trace_id:`${o.name}_${e}`,connection_name:n??i??o.name,route:De(r,this.srj.layerCount)};t.push(a)}}return t}getOutputSimpleRouteJson(){return{...this.srj,traces:this.getOutputSimplifiedPcbTraces()}}},Wf=1.8,Vf=.95,Hf=.8,Uf=.95,Gf=class extends Dn{getSolverName(){return"SingleHighDensityRouteWithJumpersSolver"}obstacleRoutes;bounds;boundsSize;boundsCenter;A;B;roundedGoalPosition;straightLineDistance;traceThickness;obstacleMargin;minCellSize=.05;cellStep=.05;GREEDY_MULTIPLER=1.1;numRoutes;JUMPER_PENALTY_FACTOR;FUTURE_CONNECTION_START_END_PENALTY;FUTURE_CONNECTION_START_END_PROXIMITY;FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY;FUTURE_CONNECTION_JUMPER_PAD_PENALTY;JUMPER_JUMPER_PAD_PROXIMITY;JUMPER_JUMPER_PAD_PENALTY;FUTURE_CONNECTION_LINE_PROXIMITY;FUTURE_CONNECTION_LINE_PENALTY;OBSTACLE_PROX_PENALTY_FACTOR;OBSTACLE_PROX_SIGMA;EDGE_PROX_PENALTY_FACTOR;EDGE_PROX_SIGMA;ALLOW_DIAGONAL;MIN_TRAVEL_BEFORE_JUMPER;CELL_SIZE_FACTOR;exploredNodes;candidates;connectionName;rootConnectionName;solvedPath=null;futureConnections;hyperParameters;connMap;debug_exploredNodesOrdered;debug_exploredNodeValues;debug_nodesTooCloseToObstacle;debug_nodePathToParentIntersectsObstacle;debugEnabled=!0;initialNodeGridOffset;existingJumpers;constructor(t){super(),this.bounds=t.bounds,this.connMap=t.connMap,this.hyperParameters=t.hyperParameters??{};const e=Math.sqrt((t.bounds.maxX-t.bounds.minX)**2+(t.bounds.maxY-t.bounds.minY)**2);this.CELL_SIZE_FACTOR=this.hyperParameters.CELL_SIZE_FACTOR??1,this.JUMPER_PENALTY_FACTOR=.2,this.FUTURE_CONNECTION_START_END_PROXIMITY??=8,this.FUTURE_CONNECTION_START_END_PENALTY??=3,this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY=this.hyperParameters.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY??e/4,this.FUTURE_CONNECTION_JUMPER_PAD_PENALTY=this.hyperParameters.FUTURE_CONNECTION_JUMPER_PAD_PENALTY??1e3,this.JUMPER_JUMPER_PAD_PROXIMITY=this.hyperParameters.JUMPER_JUMPER_PAD_PROXIMITY??5,this.JUMPER_JUMPER_PAD_PENALTY=this.hyperParameters.JUMPER_JUMPER_PAD_PENALTY??0,this.FUTURE_CONNECTION_LINE_PROXIMITY=this.hyperParameters.FUTURE_CONNECTION_LINE_PROXIMITY??10,this.FUTURE_CONNECTION_LINE_PENALTY=this.hyperParameters.FUTURE_CONNECTION_LINE_PENALTY??5,this.OBSTACLE_PROX_PENALTY_FACTOR=this.hyperParameters.OBSTACLE_PROX_PENALTY_FACTOR??2,this.OBSTACLE_PROX_SIGMA=this.hyperParameters.OBSTACLE_PROX_SIGMA??2,this.EDGE_PROX_PENALTY_FACTOR=this.hyperParameters.EDGE_PROX_PENALTY_FACTOR??1,this.EDGE_PROX_SIGMA=this.hyperParameters.EDGE_PROX_SIGMA??1,this.ALLOW_DIAGONAL=this.hyperParameters.ALLOW_DIAGONAL??!0,this.MIN_TRAVEL_BEFORE_JUMPER??=3,this.boundsSize={width:this.bounds.maxX-this.bounds.minX,height:this.bounds.maxY-this.bounds.minY},this.boundsCenter={x:(this.bounds.minX+this.bounds.maxX)/2,y:(this.bounds.minY+this.bounds.maxY)/2},this.connectionName=t.connectionName,this.rootConnectionName=t.rootConnectionName,this.obstacleRoutes=t.obstacleRoutes,this.A={...t.A,z:0},this.B={...t.B,z:0},this.traceThickness=t.traceThickness??.15,this.obstacleMargin=t.obstacleMargin??.2,this.exploredNodes=new Set,this.straightLineDistance=F(this.A,this.B),this.futureConnections=t.futureConnections??[],this.MAX_ITERATIONS=1e4,this.debug_exploredNodesOrdered=[],this.debug_exploredNodeValues=new Map,this.debug_nodesTooCloseToObstacle=new Set,this.debug_nodePathToParentIntersectsObstacle=new Set,this.numRoutes=this.obstacleRoutes.length+this.futureConnections.length,this.existingJumpers=[];for(const t of this.obstacleRoutes)t.jumpers&&this.existingJumpers.push(...t.jumpers);const n=Math.ceil(5*(this.numRoutes+1));let o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;for(;o*i>n**2&&!(this.cellStep>t.minDistBetweenEnteringPoints);)this.cellStep*=2,o=this.boundsSize.width/this.cellStep,i=this.boundsSize.height/this.cellStep;this.cellStep*=this.CELL_SIZE_FACTOR;const s=Math.abs(this.A.x-this.bounds.minX)<.001&&Math.abs(this.B.x-this.bounds.minX)<.001||Math.abs(this.A.x-this.bounds.maxX)<.001&&Math.abs(this.B.x-this.bounds.maxX)<.001||Math.abs(this.A.y-this.bounds.minY)<.001&&Math.abs(this.B.y-this.bounds.minY)<.001||Math.abs(this.A.y-this.bounds.maxY)<.001&&Math.abs(this.B.y-this.bounds.maxY)<.001;this.futureConnections&&0===this.futureConnections.length&&0===this.obstacleRoutes.length&&!s&&this.handleSimpleCases();const r={x:t.A.x,y:t.A.y};this.initialNodeGridOffset={x:r.x-Math.round(t.A.x/this.cellStep)*this.cellStep,y:r.y-Math.round(t.A.y/this.cellStep)*this.cellStep},this.roundedGoalPosition={x:Math.round(t.B.x/this.cellStep)*this.cellStep,y:Math.round(t.B.y/this.cellStep)*this.cellStep,z:0};const a={distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},c={distanceToGoal:0,obstacleProximity:0,edgeProximity:0,futureConnectionStartEndProximityPenalty:0,futureConnectionLine:0,total:0,obstacleProximityRate:0,edgeProximityRate:0,futureConnectionStartEndProximityRate:0,futureConnectionLineRate:0};this.candidates=new Zn([{...t.A,...r,z:0,g:0,h:0,f:0,jumperCount:0,gComponents:a,hComponents:c,parent:{...t.A,z:0,g:0,h:0,f:0,gComponents:a,hComponents:c,parent:null}}])}handleSimpleCases(){this.solved=!0;const{A:t,B:e}=this;this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,route:[{x:t.x,y:t.y,z:0},{x:e.x,y:e.y,z:0}],traceThickness:this.traceThickness,jumpers:[]}}get jumperPenaltyDistance(){return Wf+this.straightLineDistance*this.JUMPER_PENALTY_FACTOR}isNodeTooCloseToObstacle(t,e){e??=this.obstacleMargin;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){const o=Zf(n);for(const n of o)if(X(t,n.A,n.B)<this.traceThickness+e)return!0}for(const o of n.jumpers||[])if(this.isNodeTooCloseToJumper(t,o,e))return!0}return!1}isNodeTooCloseToJumper(t,e,n){const o=e.end.x-e.start.x,i=e.end.y-e.start.y,s=Math.abs(o)>Math.abs(i),r=(s?Hf:Uf)/2+n,a=(s?Uf:Hf)/2+n;return Math.abs(t.x-e.start.x)<r&&Math.abs(t.y-e.start.y)<a||Math.abs(t.x-e.end.x)<r&&Math.abs(t.y-e.end.y)<a}isNodeTooCloseToEdge(t){const e=t.gComponents?.distFromStart??0<this.obstacleMargin/2?-this.obstacleMargin/2:this.obstacleMargin/2,n=t.x<this.bounds.minX+e||t.x>this.bounds.maxX-e||t.y<this.bounds.minY+e||t.y>this.bounds.maxY-e;return(!n||!(F(t,this.B)<2*e||F(t,this.A)<2*e))&&n}doesPathToParentIntersectObstacle(t){const e=t.parent;if(!e)return!1;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Zf(n))if(D(t,e,o.A,o.B))return!0;for(const o of n.jumpers||[])if(this.doesSegmentIntersectJumperPads(t,e,o))return!0}}return!1}doesSegmentIntersectJumperPads(t,e,n){const o=this.obstacleMargin,i=n.end.x-n.start.x,s=n.end.y-n.start.y,r=Math.abs(i)>Math.abs(s),a=(r?Hf:Uf)/2+o,c=(r?Uf:Hf)/2+o;return!!this.doesSegmentIntersectRect(t,e,n.start,a,c)||!!this.doesSegmentIntersectRect(t,e,n.end,a,c)}doesSegmentIntersectRect(t,e,n,o,i){const s=n.x-o,r=n.x+o,a=n.y-i,c=n.y+i;if(t.x>=s&&t.x<=r&&t.y>=a&&t.y<=c)return!0;if(e.x>=s&&e.x<=r&&e.y>=a&&e.y<=c)return!0;const h=[{A:{x:s,y:a},B:{x:r,y:a}},{A:{x:r,y:a},B:{x:r,y:c}},{A:{x:r,y:c},B:{x:s,y:c}},{A:{x:s,y:c},B:{x:s,y:a}}];for(const n of h)if(D(t,e,n.A,n.B))return!0;return!1}findObstaclesBetween(t,e){const n=[];for(const o of this.obstacleRoutes){const i=this.connMap?.areIdsConnected?.(this.connectionName,o.connectionName);if(!i)for(const i of Zf(o))D(t,e,i.A,i.B)&&n.push({A:i.A,B:i.B})}return n}computeHComponents(t){const e=F(t,this.roundedGoalPosition),n=this.getObstacleProximityPenalty(t),o=this.getEdgeProximityPenalty(t),i=this.getFutureConnectionStartEndPenalty(t),s=this.getFutureConnectionLinePenalty(t),r=t.parent,a=r?.hComponents,c=r?F(t,r):0,h=(t,n)=>{if(void 0===n||c<1e-9||e<1e-9)return t;const o=(t-n)/c;return(t+Math.max(0,t+o*e))/2},l=h(n,a?.obstacleProximityRate),d=h(o,a?.edgeProximityRate),u=h(i,a?.futureConnectionStartEndProximityRate),p=h(s,a?.futureConnectionLineRate),f=l*e,g=d*e,m=u*e,y=p*e;return{distanceToGoal:e,obstacleProximity:f,edgeProximity:g,futureConnectionStartEndProximityPenalty:m,futureConnectionLine:y,total:e+f+g+m+y,obstacleProximityRate:n,edgeProximityRate:o,futureConnectionStartEndProximityRate:i,futureConnectionLineRate:s}}computeH(t){return this.computeHComponents(t).total}computeGComponents(t){const e=t.parent,n=e?F(t,e):0,o=e?.gComponents??{distFromStart:0,weightedMmNearObstacle:0,weightedMmNearEdge:0,weightedMmNearFutureConnectionStartEnd:0,weightedMmNearFutureConnectionLine:0,jumperPenalty:0,jumperPadFutureConnectionPenalty:0,total:0},i=o.distFromStart+n,s=o.weightedMmNearObstacle+this.getObstacleProximityPenalty(t)*n,r=o.weightedMmNearEdge+this.getEdgeProximityPenalty(t)*n,a=o.weightedMmNearFutureConnectionStartEnd+this.getFutureConnectionStartEndPenalty(t)*n,c=o.weightedMmNearFutureConnectionLine+this.getFutureConnectionLinePenalty(t)*n;let h=o.jumperPenalty,l=o.jumperPadFutureConnectionPenalty;t.isJumperExit&&(h+=this.jumperPenaltyDistance,l+=this.getJumperPadFutureConnectionPenalty(t));return{distFromStart:i,weightedMmNearObstacle:s,weightedMmNearEdge:r,weightedMmNearFutureConnectionStartEnd:a,weightedMmNearFutureConnectionLine:c,jumperPenalty:h,jumperPadFutureConnectionPenalty:l,total:i+s+r+a+c+h+l}}computeG(t){return this.computeGComponents(t).total}computeF(t,e){return t+e*this.GREEDY_MULTIPLER}getClosestFutureConnectionPoint(t){let e=1/0,n=null;for(const o of this.futureConnections)for(const i of o.points){const o=F(t,i);o<e&&(e=o,n=i)}return n}getFutureConnectionStartEndPenalty(t){let e=0;const n=this.getClosestFutureConnectionPoint(t);if(n){const o=F(t,n);if(o>this.FUTURE_CONNECTION_START_END_PROXIMITY)return 0;const i=o/this.FUTURE_CONNECTION_START_END_PROXIMITY;e=this.FUTURE_CONNECTION_START_END_PENALTY*(1-i)**2}return e}getFutureConnectionLinePenalty(t){if(0===this.futureConnections.length)return 0;let e=1/0;const n=Math.min(1,(t.hComponents?.distanceToGoal??0)/this.FUTURE_CONNECTION_LINE_PROXIMITY)**2;for(const n of this.futureConnections){if(n.points.length<2)continue;const o=X(t,n.points[0],n.points[n.points.length-1]);e=Math.min(e,o)}if(e*=n,e<this.FUTURE_CONNECTION_LINE_PROXIMITY){const t=Math.max(.1,e/this.FUTURE_CONNECTION_LINE_PROXIMITY);return this.FUTURE_CONNECTION_LINE_PENALTY*(1-t)**2}return 0}getJumperPadFutureConnectionPenalty(t){if(!t.isJumperExit||!t.jumperEntry)return 0;const e=t.jumperEntry,n={x:t.x,y:t.y};let o=1/0;for(const t of this.futureConnections)for(const i of t.points){const t=F(e,i),s=F(n,i),r=Math.min(t,s);o=Math.min(o,r)}if(o<this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY){const t=o/this.FUTURE_CONNECTION_JUMPER_PAD_PROXIMITY;return this.FUTURE_CONNECTION_JUMPER_PAD_PENALTY*(1-t)}return 0}getClearanceToObstacles(t){let e=1/0;for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(!o){for(const o of Zf(n))e=Math.min(e,X(t,o.A,o.B));for(const o of n.jumpers||[])e=Math.min(e,this.distanceToJumperPads(t,o))}}return e}distanceToJumperPads(t,e){const n=e.end.x-e.start.x,o=e.end.y-e.start.y,i=Math.abs(n)>Math.abs(o),s=(i?Hf:Uf)/2,r=(i?Uf:Hf)/2;return Math.min(this.pointToRectDistance(t,e.start,s,r),this.pointToRectDistance(t,e.end,s,r))}pointToRectDistance(t,e,n,o){const i=Math.max(Math.abs(t.x-e.x)-n,0),s=Math.max(Math.abs(t.y-e.y)-o,0);return Math.hypot(i,s)}getClearanceToEdge(t){return Math.min(t.x-this.bounds.minX,this.bounds.maxX-t.x,t.y-this.bounds.minY,this.bounds.maxY-t.y)}getObstacleProximityPenalty(t){const e=this.getClearanceToObstacles(t),n=Math.max(0,e-(this.traceThickness+this.obstacleMargin)),o=this.OBSTACLE_PROX_SIGMA;return this.OBSTACLE_PROX_PENALTY_FACTOR*Math.exp(-n/o)}getEdgeProximityPenalty(t){const e=this.getClearanceToEdge(t),n=this.EDGE_PROX_SIGMA;if(e>2*this.EDGE_PROX_SIGMA)return 0;const o=F(t,this.B),i=Math.min(1,o/(2*this.EDGE_PROX_SIGMA));return this.EDGE_PROX_PENALTY_FACTOR*Math.exp(-e/n)*i}getNodeKey(t){const e=t.isJumperExit?"_j":"";return`${Math.round(t.x/this.cellStep)*this.cellStep},${Math.round(t.y/this.cellStep)*this.cellStep},${t.z}${e}`}getJumperNeighbors(t){const e=[];if((t.gComponents?.distFromStart??0)<this.MIN_TRAVEL_BEFORE_JUMPER)return e;const n=[{dx:1,dy:0},{dx:-1,dy:0},{dx:0,dy:1},{dx:0,dy:-1}];for(const o of n){const n=2*Wf,i=t.x+o.dx*n,s=t.y+o.dy*n,r=this.findObstaclesBetween(t,{x:i,y:s});if(r.length>0)for(const n of r){const i=this.calculateJumperExit(t,n,o);i&&!this.exploredNodes.has(this.getNodeKey(i))&&(this.isNodeTooCloseToObstacle(i)||this.isNodeTooCloseToEdge(i)||!this.isJumperPlacementValid(t,i)||(i.gComponents=this.computeGComponents(i),i.hComponents=this.computeHComponents(i),i.g=i.gComponents.total,i.h=i.hComponents.total,i.f=this.computeF(i.g,i.h),e.push(i)))}}return e}calculateJumperExit(t,e,n){const o=Wf,i=Math.sqrt(n.dx*n.dx+n.dy*n.dy),s=n.dx/i,r=n.dy/i,a=t.x+s*o,c=t.y+r*o;return a<this.bounds.minX||a>this.bounds.maxX||c<this.bounds.minY||c>this.bounds.maxY?null:{x:a,y:c,z:0,parent:t,g:0,h:0,f:0,jumperEntry:{x:t.x,y:t.y},isJumperExit:!0,jumperCount:(t.jumperCount??0)+1}}isJumperTooCloseToTraces(t,e){const n=e.x-t.x,o=e.y-t.y,i=Math.abs(n)>Math.abs(o),s=(i?Hf:Uf)/2,r=(i?Uf:Hf)/2,a=this.obstacleMargin,c=[t,e];for(const t of c){const e=[t,{x:t.x-s,y:t.y-r},{x:t.x+s,y:t.y-r},{x:t.x-s,y:t.y+r},{x:t.x+s,y:t.y+r},{x:t.x-s,y:t.y},{x:t.x+s,y:t.y},{x:t.x,y:t.y-r},{x:t.x,y:t.y+r}];for(const n of this.obstacleRoutes){const o=this.connMap?.areIdsConnected?.(this.connectionName,n.connectionName);if(o)continue;const i=Zf(n);for(const n of i){for(const t of e)if(X(t,n.A,n.B)<this.traceThickness+a)return!0;if(this.doesSegmentIntersectRect(n.A,n.B,t,s+a,r+a))return!0}}}return!1}isJumperPlacementValid(t,e){if(this.isJumperTooCloseToTraces(t,e))return!1;const n={route_type:"jumper",start:{x:t.x,y:t.y},end:{x:e.x,y:e.y},footprint:"0603"};for(const t of this.existingJumpers)if(this.doJumpersOverlap(n,t))return!1;const o=this.getJumpersInPath(t);for(const t of o)if(this.doJumpersOverlap(n,t))return!1;return!0}doJumpersOverlap(t,e){const n=this.obstacleMargin,o=Math.min(t.start.x,t.end.x)-Vf/2-n,i=Math.max(t.start.x,t.end.x)+Vf/2+n,s=Math.min(t.start.y,t.end.y)-Vf/2-n,r=Math.max(t.start.y,t.end.y)+Vf/2+n,a=Math.min(e.start.x,e.end.x)-Vf/2-n,c=Math.max(e.start.x,e.end.x)+Vf/2+n,h=Math.min(e.start.y,e.end.y)-Vf/2-n,l=Math.max(e.start.y,e.end.y)+Vf/2+n;return!(i<a||o>c||r<h||s>l)}getJumpersInPath(t){const e=[];let n=t;for(;n&&n.parent;)n.isJumperExit&&n.jumperEntry&&e.push({route_type:"jumper",start:n.jumperEntry,end:{x:n.x,y:n.y},footprint:"0603"}),n=n.parent;return e}getNeighbors(t){const e=[],{maxX:n,minX:o,maxY:i,minY:s}=this.bounds;for(let r=-1;r<=1;r++)for(let a=-1;a<=1;a++){if(0===r&&0===a)continue;if(!this.ALLOW_DIAGONAL&&0!==r&&0!==a)continue;const c=t.x+r*this.cellStep,h=t.y+a*this.cellStep,l=qf(c,o,n),d=qf(h,s,i),u={...t,parent:t,x:l,y:d,isJumperExit:!1,jumperEntry:void 0,jumperCount:t.jumperCount??0},p=this.getNodeKey(u);this.exploredNodes.has(p)||(this.isNodeTooCloseToObstacle(u)?(this.debug_nodesTooCloseToObstacle.add(p),this.exploredNodes.add(p)):this.isNodeTooCloseToEdge(u)?this.debug_nodesTooCloseToObstacle.add(p):this.doesPathToParentIntersectObstacle(u)?(this.debug_nodePathToParentIntersectsObstacle.add(p),this.exploredNodes.add(p)):(u.gComponents=this.computeGComponents(u),u.hComponents=this.computeHComponents(u),u.g=u.gComponents.total,u.h=u.hComponents.total,u.f=this.computeF(u.g,u.h),e.push(u)))}const r=this.getJumperNeighbors(t);return e.push(...r),e}getNodePath(t){const e=[];let n=t;for(;n;)e.push(n),n=n.parent;return e}setSolvedPath(t){const e=this.getNodePath(t);e.reverse();const n=[];for(let t=0;t<e.length;t++){const o=e[t];o.isJumperExit&&o.jumperEntry&&n.push({route_type:"jumper",start:o.jumperEntry,end:{x:o.x,y:o.y},footprint:"0603"})}this.solvedPath={connectionName:this.connectionName,rootConnectionName:this.rootConnectionName,traceThickness:this.traceThickness,route:e.map(t=>({x:t.x,y:t.y,z:0})).concat([{x:this.B.x,y:this.B.y,z:0}]),jumpers:n}}computeProgress(t,e){const n=1-e/this.straightLineDistance;return Math.max(this.progress||0,2/Math.PI*Math.atan(.112*n/(1-n)))}_step(){let t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;for(;t&&e&&this.exploredNodes.has(e);)t=this.candidates.dequeue(),e=t?this.getNodeKey(t):void 0;if(!t||!e)return this.failed=!0,void(this.error="Ran out of candidate nodes to explore");this.exploredNodes.add(e),this.debug_exploredNodesOrdered.push(e),this.debug_exploredNodeValues.set(e,{g:t.g,h:t.h,f:t.f,gComponents:t.gComponents,hComponents:t.hComponents});const n=F(t,this.roundedGoalPosition);this.progress=this.computeProgress(t,n),n<=this.cellStep*Math.SQRT2&&!this.doesPathToParentIntersectObstacle({...t,parent:t,x:this.B.x,y:this.B.y})&&(this.solved=!0,this.setSolvedPath(t));const o=this.getNeighbors(t);for(const t of o)this.candidates.enqueue(t)}drawJumperPads(t,e,n,o,i){const s=e.end.x-e.start.x,r=e.end.y-e.start.y,a=Hf,c=Uf,h=Math.abs(s)>Math.abs(r),l=h?a:c,d=h?c:a;t.rects.push({center:{x:e.start.x,y:e.start.y},width:l,height:d,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:o??"jumper",step:i}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:l,height:d,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:o??"jumper",step:i}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*c,layer:o??"jumper-body",step:i})}visualize(){const t={lines:[],points:[],rects:[],circles:[]};t.points.push({x:this.A.x,y:this.A.y,label:`Input A\nz: ${this.A.z}`,color:"orange"}),t.points.push({x:this.B.x,y:this.B.y,label:`Input B\nz: ${this.B.z}`,color:"orange"}),t.lines.push({points:[this.A,this.B],strokeColor:"rgba(255, 0, 0, 0.5)",label:"Direct Input Connection"});for(let e=0;e<this.obstacleRoutes.length;e++){const n=this.obstacleRoutes[e];for(let o=0;o<n.route.length-1;o++)t.lines.push({points:[n.route[o],n.route[o+1]],strokeColor:"rgba(255, 0, 0, 0.75)",strokeWidth:n.traceThickness,label:"Obstacle Route",layer:`obstacle${e.toString()}`});for(const o of n.jumpers||[])this.drawJumperPads(t,o,"rgba(255, 0, 0, 0.5)",`obstacle-jumper-${e}`)}for(let e=0;e<this.futureConnections.length;e++){const n=this.futureConnections[e];if(n.points.length<2)continue;const o=n.points[0],i=n.points[n.points.length-1];t.lines.push({points:[o,i],strokeColor:"rgba(0, 100, 255, 0.6)",strokeWidth:this.traceThickness,label:`Future: ${n.connectionName}`,layer:`future-connection-${e}`})}for(let e=0;e<this.debug_exploredNodesOrdered.length;e++){const n=this.debug_exploredNodesOrdered[e];if(this.debug_nodesTooCloseToObstacle.has(n))continue;if(this.debug_nodePathToParentIntersectsObstacle.has(n))continue;const[o,i]=n.split(",").map(Number),s=n.endsWith("_j"),r=this.debug_exploredNodeValues.get(n),a=r?.gComponents,c=r?.hComponents,h=c?.distanceToGoal??0,l=[s?"Explored (jumper)":"Explored"];l.push(`g.distFromStart: ${a?.distFromStart.toFixed(2)??"?"}`),l.push(`g.nearObstacle: ${a?.weightedMmNearObstacle.toFixed(2)??"?"}`),l.push(`g.nearEdge: ${a?.weightedMmNearEdge.toFixed(2)??"?"}`),l.push(`g.nearFutStrtEnd: ${a?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??"?"}`),l.push(`g.nearFutLine: ${a?.weightedMmNearFutureConnectionLine.toFixed(2)??"?"}`),l.push(`g.jumper: ${a?.jumperPenalty.toFixed(2)??"?"}`),l.push(`g.jumperPadFutPenalty: ${a?.jumperPadFutureConnectionPenalty.toFixed(2)??"?"}`),l.push(`h.goalDist: ${h.toFixed(2)}`),l.push(`h.obstacleProx: ${c?.obstacleProximity.toFixed(2)??"?"} (${h>0?((c?.obstacleProximity??0)/h).toFixed(3):0}/mm)`),l.push(`h.edgeProx: ${c?.edgeProximity.toFixed(2)??"?"} (${h>0?((c?.edgeProximity??0)/h).toFixed(3):0}/mm)`),l.push(`h.futureConnPt: ${c?.futureConnectionStartEndProximityPenalty.toFixed(2)??"?"} (${h>0?((c?.futureConnectionStartEndProximityPenalty??0)/h).toFixed(3):0}/mm)`),l.push(`h.futureConnLine: ${c?.futureConnectionLine.toFixed(2)??"?"} (${h>0?((c?.futureConnectionLine??0)/h).toFixed(3):0}/mm)`),l.push(`g: ${r?.g.toFixed(2)??"?"}`),l.push(`h: ${r?.h.toFixed(2)??"?"}`),l.push(`f: ${r?.f.toFixed(2)??"?"}`);const d=l.join("\n");t.rects.push({center:{x:o+this.initialNodeGridOffset.x,y:i+this.initialNodeGridOffset.y},fill:s?`rgba(0,255,255,${.4-e/this.debug_exploredNodesOrdered.length*.3})`:`rgba(255,0,255,${.3-e/this.debug_exploredNodesOrdered.length*.2})`,width:.9*this.cellStep,height:.9*this.cellStep,label:d})}if(this.candidates.peek()){const e=this.candidates.peek();t.rects.push({center:{x:e.x,y:e.y},fill:"rgba(0, 255, 0, 0.8)",width:.9*this.cellStep,height:.9*this.cellStep,label:"Next"})}const e=this.candidates.getTopN(5);for(let n=0;n<e.length;n++){const o=e[n],i=o.isJumperExit??!1,s=o.gComponents,r=o.hComponents,a=r?.distanceToGoal??0,c=[`Candidate #${n+1}${i?" (jumper)":""}`];c.push(`g.distFromStart: ${s?.distFromStart.toFixed(2)??"?"}`),c.push(`g.nearObstacle: ${s?.weightedMmNearObstacle.toFixed(2)??"?"}`),c.push(`g.nearEdge: ${s?.weightedMmNearEdge.toFixed(2)??"?"}`),c.push(`g.nearFutureConnPt: ${s?.weightedMmNearFutureConnectionStartEnd.toFixed(2)??"?"}`),c.push(`g.nearFutureConnLine: ${s?.weightedMmNearFutureConnectionLine.toFixed(2)??"?"}`),c.push(`g.jumper: ${s?.jumperPenalty.toFixed(2)??"?"}`),c.push(`g.jumperPadFutureConn: ${s?.jumperPadFutureConnectionPenalty.toFixed(2)??"?"}`),c.push(`g: ${o.g.toFixed(2)}`),c.push(`h.goalDist: ${a.toFixed(2)}`),c.push(`h.obstacleProx: ${r?.obstacleProximity.toFixed(2)??"?"} (${a>0?((r?.obstacleProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.edgeProx: ${r?.edgeProximity.toFixed(2)??"?"} (${a>0?((r?.edgeProximity??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnPt: ${r?.futureConnectionStartEndProximityPenalty.toFixed(2)??"?"} (${a>0?((r?.futureConnectionStartEndProximityPenalty??0)/a).toFixed(3):0}/mm)`),c.push(`h.futureConnLine: ${r?.futureConnectionLine.toFixed(2)??"?"} (${a>0?((r?.futureConnectionLine??0)/a).toFixed(3):0}/mm)`),c.push(`h: ${o.h.toFixed(2)}`),c.push(`f: ${o.f.toFixed(2)}`);const h=c.join("\n");t.points.push({x:o.x,y:o.y,color:"gray",label:h})}if(this.solvedPath){t.lines.push({points:this.solvedPath.route,strokeColor:"green",label:"Solved Route",strokeWidth:this.traceThickness});for(const e of this.solvedPath.jumpers)this.drawJumperPads(t,e,"rgba(0, 200, 0, 0.8)","solved-jumper")}const{minX:n,minY:o,maxX:i,maxY:s}=this.bounds;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:s},{x:n,y:s},{x:n,y:o}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}};function Zf(t){const e=[];for(let n=0;n<t.route.length-1;n++)if(t.route[n].z===t.route[n+1].z){const o=t.route[n],i=t.route[n+1],s=t.jumpers?.some(t=>{const e=Math.abs(t.start.x-o.x)<.001&&Math.abs(t.start.y-o.y)<.001&&Math.abs(t.end.x-i.x)<.001&&Math.abs(t.end.y-i.y)<.001,n=Math.abs(t.start.x-i.x)<.001&&Math.abs(t.start.y-i.y)<.001&&Math.abs(t.end.x-o.x)<.001&&Math.abs(t.end.y-o.y)<.001;return e||n});s||e.push({z:o.z,A:o,B:i})}return e}function qf(t,e,n){return Math.max(e,Math.min(t,n))}var Jf=.8,Kf=.95,Qf=class extends Dn{getSolverName(){return"IntraNodeSolverWithJumpers"}nodeWithPortPoints;colorMap;unsolvedConnections;totalConnections;solvedRoutes;failedSubSolvers;hyperParameters;minDistBetweenEnteringPoints;traceWidth;activeSubSolver=null;lastActiveSubSolver=null;connMap;get failedSolvers(){return this.failedSubSolvers}get activeSolver(){return this.activeSubSolver}constructor(t){const{nodeWithPortPoints:e,colorMap:n}=t;super(),this.nodeWithPortPoints=e,this.colorMap=n??{},this.solvedRoutes=[],this.hyperParameters=t.hyperParameters??{},this.failedSubSolvers=[],this.connMap=t.connMap,this.traceWidth=t.traceWidth??.15;const o=new Map;for(const{connectionName:t,rootConnectionName:n,x:i,y:s}of e.portPoints){const e=o.get(t);o.set(t,{rootConnectionName:e?.rootConnectionName??n,points:[...e?.points??[],{x:i,y:s,z:0}]})}this.unsolvedConnections=Array.from(o.entries().map(([t,{rootConnectionName:e,points:n}])=>({connectionName:t,rootConnectionName:e,points:n}))),this.hyperParameters.SHUFFLE_SEED&&(this.unsolvedConnections=Un(this.unsolvedConnections,this.hyperParameters.SHUFFLE_SEED??0),this.unsolvedConnections=this.unsolvedConnections.map(({points:t,...e},n)=>({...e,points:Un(t,7117*n+(this.hyperParameters.SHUFFLE_SEED??0))}))),this.totalConnections=this.unsolvedConnections.length,this.MAX_ITERATIONS=1e3*this.totalConnections**1.5,this.minDistBetweenEnteringPoints=Gn(this.nodeWithPortPoints)}getConstructorParams(){return{nodeWithPortPoints:this.nodeWithPortPoints,colorMap:this.colorMap,hyperParameters:this.hyperParameters,connMap:this.connMap,traceWidth:this.traceWidth}}computeProgress(){return(this.solvedRoutes.length+(this.activeSubSolver?.progress||0))/this.totalConnections}_step(){if(this.activeSubSolver)return this.activeSubSolver.step(),this.progress=this.computeProgress(),void(this.activeSubSolver.solved?(this.solvedRoutes.push(this.activeSubSolver.solvedPath),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null):this.activeSubSolver.failed&&(this.failedSubSolvers.push(this.activeSubSolver),this.lastActiveSubSolver=this.activeSubSolver,this.activeSubSolver=null,this.error=this.failedSubSolvers.map(t=>t.error).join("\n"),this.failed=!0));const t=this.unsolvedConnections.pop();if(this.progress=this.computeProgress(),!t)return void(this.solved=0===this.failedSubSolvers.length);if(1===t.points.length)return;if(2===t.points.length){const[e,n]=t.points,o=Math.abs(e.x-n.x)<1e-6,i=Math.abs(e.y-n.y)<1e-6;if(o&&i)return}const{connectionName:e,rootConnectionName:n,points:o}=t;this.activeSubSolver=new Gf({connectionName:e,rootConnectionName:n,minDistBetweenEnteringPoints:this.minDistBetweenEnteringPoints,bounds:Me(this.nodeWithPortPoints),A:{x:o[0].x,y:o[0].y,z:0},B:{x:o[o.length-1].x,y:o[o.length-1].y,z:0},obstacleRoutes:this.solvedRoutes.filter(t=>(!n||t.rootConnectionName!==n)&&!this.connMap?.areIdsConnected(t.connectionName,e)),futureConnections:this.unsolvedConnections,hyperParameters:this.hyperParameters,connMap:this.connMap,traceThickness:this.traceWidth})}drawJumperPads(t,e,n,o){const i=e.end.x-e.start.x,s=e.end.y-e.start.y,r=Jf,a=Kf,c=Math.abs(i)>Math.abs(s),h=c?r:a,l=c?a:r;t.rects.push({center:{x:e.start.x,y:e.start.y},width:h,height:l,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.rects.push({center:{x:e.end.x,y:e.end.y},width:h,height:l,fill:n,stroke:"rgba(0, 0, 0, 0.5)",layer:"jumper"}),t.lines.push({points:[e.start,e.end],strokeColor:"rgba(100, 100, 100, 0.8)",strokeWidth:.3*a,layer:"jumper-body"})}visualize(){if(this.activeSubSolver&&!this.solved)return this.activeSubSolver.visualize();if(this.failed&&this.lastActiveSubSolver)return this.lastActiveSubSolver.visualize();const t={lines:[],points:[],rects:[],circles:[]};for(const e of this.nodeWithPortPoints.portPoints)t.points.push({x:e.x,y:e.y,label:[e.connectionName,"layer: 0 (single-layer)"].join("\n"),color:this.colorMap[e.connectionName]??"blue"});for(let e=0;e<this.solvedRoutes.length;e++){const n=this.solvedRoutes[e];if(n.route.length>0){const o=this.colorMap[n.connectionName]??"blue";for(let e=0;e<n.route.length-1;e++){const i=n.route[e],s=n.route[e+1];t.lines.push({points:[i,s],strokeColor:Mn(o,.2),layer:"route-layer-0",strokeWidth:n.traceThickness})}for(const i of n.jumpers)this.drawJumperPads(t,i,Mn(o,.5),e)}}const e=Me(this.nodeWithPortPoints),{minX:n,minY:o,maxX:i,maxY:s}=e;return t.lines.push({points:[{x:n,y:o},{x:i,y:o},{x:i,y:s},{x:n,y:s},{x:n,y:o}],strokeColor:"rgba(255, 0, 0, 0.25)",strokeDash:"4 4",layer:"border"}),t}};export{jf as AssignableAutoroutingPipeline1Solver,hu as AssignableAutoroutingPipeline2,yf as AssignableAutoroutingPipeline3,Dd as AutoroutingPipeline1_OriginalUnravel,jl as AutoroutingPipelineSolver,wf as AutoroutingPipelineSolver3_HgPortPointPathing,Wl as CapacityMeshSolver,ju as CurvyIntraNodeSolver,gf as HighDensitySolver,xe as InMemoryCache,Qf as IntraNodeSolverWithJumpers,be as LocalStorageCache,Gf as SingleHighDensityRouteWithJumpersSolver,zh as calculateOptimalCapacityDepth,Rn as convertSrjToGraphicsObject,Se as getGlobalInMemoryCache,Pe as getGlobalLocalStorageCache,Ah as getTunedTotalCapacity1,Ie as setupGlobalCaches};
2
2
  /*! Bundled license information:
3
3
 
4
4
  is-buffer/index.js: