biscuitboard 1.0.1

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.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../node_modules/is-buffer/index.js","../node_modules/kind-of/index.js","../node_modules/rename-keys/index.js","../node_modules/deep-rename-keys/index.js","../node_modules/eventemitter3/index.js","../node_modules/xml-lexer/dist/lexer.js","../node_modules/xml-reader/dist/reader.js","../lib/ArduinoShieldClad.tsx","../lib/BiscuitBoard.tsx","../node_modules/@tscircuit/alphabet/dist/index.js","../node_modules/iobuffer/src/text.ts","../node_modules/iobuffer/src/iobuffer.ts","../node_modules/fast-png/src/helpers/crc.ts","../node_modules/fast-png/src/helpers/decode_interlace_adam7.ts","../node_modules/fast-png/src/helpers/decode_interlace_null.ts","../node_modules/fast-png/src/helpers/signature.ts","../node_modules/fast-png/src/helpers/text.ts","../node_modules/graphics-debug/node_modules/transformation-matrix/src/rotate.js","../node_modules/graphics-debug/node_modules/transformation-matrix/src/skew.js","../node_modules/svgson/dist/svgson.esm.js","../node_modules/graphics-debug/lib/setStepOfAllObjects.ts","../node_modules/@tscircuit/solver-utils/dist/index.js","../node_modules/@tscircuit/biscuit-board-autorouter/lib/geometry.ts","../node_modules/@tscircuit/power-trace-expander/node_modules/graphics-debug/node_modules/transformation-matrix/src/rotate.js","../node_modules/@tscircuit/power-trace-expander/node_modules/graphics-debug/node_modules/transformation-matrix/src/skew.js","../node_modules/@tscircuit/power-trace-expander/node_modules/@tscircuit/solver-utils/dist/index.js","../node_modules/@tscircuit/power-trace-expander/src/ConnectionNameResolver.ts","../node_modules/@tscircuit/power-trace-expander/src/geometry.ts","../node_modules/@tscircuit/power-trace-expander/src/LayerAwareGridRouteSolver.ts","../node_modules/@tscircuit/power-trace-expander/src/ElasticTracePushSolver.ts","../node_modules/@tscircuit/power-trace-expander/src/octilinear.ts","../node_modules/@tscircuit/power-trace-expander/src/ObstacleAwareGridRouteSolver.ts","../node_modules/@tscircuit/power-trace-expander/node_modules/flatbush/node_modules/flatqueue/index.js","../node_modules/@tscircuit/power-trace-expander/node_modules/flatbush/index.js","../node_modules/@tscircuit/power-trace-expander/src/SpatialObstacleIndex.ts","../node_modules/@tscircuit/power-trace-expander/src/LocalTraceInflationSolver.ts","../node_modules/@tscircuit/power-trace-expander/src/PowerTraceCleanupSolver.ts","../node_modules/@tscircuit/power-trace-expander/src/PowerTraceClearanceRepairSolver.ts","../node_modules/@tscircuit/power-trace-expander/src/PowerTraceExpanderSolver.ts","../node_modules/@tscircuit/biscuit-board-autorouter/lib/build-biscuit-board-traces-solver.ts","../node_modules/@tscircuit/biscuit-board-autorouter/lib/min-heap.ts","../node_modules/@tscircuit/biscuit-board-autorouter/lib/rip-up-rubber-band-solver.ts","../node_modules/@tscircuit/biscuit-board-autorouter/lib/post-process-biscuit-board-traces-solver.ts","../node_modules/@tscircuit/biscuit-board-autorouter/lib/beautify-biscuit-board-traces-solver.ts","../node_modules/@tscircuit/biscuit-board-autorouter/lib/expand-biscuit-board-traces-solver.ts","../node_modules/@tscircuit/biscuit-board-autorouter/lib/generate-biscuit-board-hypergraph-solver.ts","../node_modules/@tscircuit/biscuit-board-autorouter/lib/prune-redundant-same-net-copper-solver.ts","../node_modules/@tscircuit/biscuit-board-autorouter/lib/biscuit-board-routing-pipeline-solver.ts","../node_modules/@tscircuit/biscuit-board-autorouter/lib/biscuit-board-autorouter.ts","../lib/biscuit-board-autorouter.ts","../lib/create-prefabricated-via-autorouter.ts","../lib/BoosterPackClad.tsx","../lib/breadboard-clad.tsx","../lib/Clad40x40.tsx","../lib/feather-clad.tsx","../lib/xiao-clad.tsx","../lib/xiao-clad-with-perforated-pin-headers.tsx"],"sourcesContent":["/*!\n * Determine if an object is a Buffer\n *\n * @author Feross Aboukhadijeh <https://feross.org>\n * @license MIT\n */\n\n// The _isBuffer check is for Safari 5-7 support, because it's missing\n// Object.prototype.constructor. Remove this eventually\nmodule.exports = function (obj) {\n return obj != null && (isBuffer(obj) || isSlowBuffer(obj) || !!obj._isBuffer)\n}\n\nfunction isBuffer (obj) {\n return !!obj.constructor && typeof obj.constructor.isBuffer === 'function' && obj.constructor.isBuffer(obj)\n}\n\n// For Node v0.10 support. Remove this eventually.\nfunction isSlowBuffer (obj) {\n return typeof obj.readFloatLE === 'function' && typeof obj.slice === 'function' && isBuffer(obj.slice(0, 0))\n}\n","var isBuffer = require('is-buffer');\nvar toString = Object.prototype.toString;\n\n/**\n * Get the native `typeof` a value.\n *\n * @param {*} `val`\n * @return {*} Native javascript type\n */\n\nmodule.exports = function kindOf(val) {\n // primitivies\n if (typeof val === 'undefined') {\n return 'undefined';\n }\n if (val === null) {\n return 'null';\n }\n if (val === true || val === false || val instanceof Boolean) {\n return 'boolean';\n }\n if (typeof val === 'string' || val instanceof String) {\n return 'string';\n }\n if (typeof val === 'number' || val instanceof Number) {\n return 'number';\n }\n\n // functions\n if (typeof val === 'function' || val instanceof Function) {\n return 'function';\n }\n\n // array\n if (typeof Array.isArray !== 'undefined' && Array.isArray(val)) {\n return 'array';\n }\n\n // check for instances of RegExp and Date before calling `toString`\n if (val instanceof RegExp) {\n return 'regexp';\n }\n if (val instanceof Date) {\n return 'date';\n }\n\n // other objects\n var type = toString.call(val);\n\n if (type === '[object RegExp]') {\n return 'regexp';\n }\n if (type === '[object Date]') {\n return 'date';\n }\n if (type === '[object Arguments]') {\n return 'arguments';\n }\n if (type === '[object Error]') {\n return 'error';\n }\n\n // buffer\n if (isBuffer(val)) {\n return 'buffer';\n }\n\n // es6: Map, WeakMap, Set, WeakSet\n if (type === '[object Set]') {\n return 'set';\n }\n if (type === '[object WeakSet]') {\n return 'weakset';\n }\n if (type === '[object Map]') {\n return 'map';\n }\n if (type === '[object WeakMap]') {\n return 'weakmap';\n }\n if (type === '[object Symbol]') {\n return 'symbol';\n }\n\n // typed arrays\n if (type === '[object Int8Array]') {\n return 'int8array';\n }\n if (type === '[object Uint8Array]') {\n return 'uint8array';\n }\n if (type === '[object Uint8ClampedArray]') {\n return 'uint8clampedarray';\n }\n if (type === '[object Int16Array]') {\n return 'int16array';\n }\n if (type === '[object Uint16Array]') {\n return 'uint16array';\n }\n if (type === '[object Int32Array]') {\n return 'int32array';\n }\n if (type === '[object Uint32Array]') {\n return 'uint32array';\n }\n if (type === '[object Float32Array]') {\n return 'float32array';\n }\n if (type === '[object Float64Array]') {\n return 'float64array';\n }\n\n // must be a plain object\n return 'object';\n};\n","(function() {\n 'use strict';\n\n function rename(obj, fn) {\n if (typeof fn !== 'function') {\n return obj;\n }\n\n var res = {};\n for (var key in obj) {\n if (Object.prototype.hasOwnProperty.call(obj, key)) {\n res[fn(key, obj[key]) || key] = obj[key];\n }\n }\n return res;\n }\n\n if (typeof module !== 'undefined' && module.exports) {\n module.exports = rename;\n } else {\n if (typeof define === 'function' && define.amd) {\n define([], function() {\n return rename;\n });\n } else {\n window.rename = rename;\n }\n }\n})();\n","/*!\n * deep-rename-keys <https://github.com/jonschlinkert/deep-rename-keys>\n *\n * Copyright (c) 2015 Jon Schlinkert, contributors.\n * Licensed under the MIT license.\n */\n\n'use strict';\n\nvar typeOf = require('kind-of');\nvar rename = require('rename-keys');\n\n/**\n * Expose `renameDeep`\n */\n\nmodule.exports = function renameDeep(obj, cb) {\n var type = typeOf(obj);\n\n if (type !== 'object' && type !== 'array') {\n throw new Error('expected an object');\n }\n\n var res = [];\n if (type === 'object') {\n obj = rename(obj, cb);\n res = {};\n }\n\n for (var key in obj) {\n if (obj.hasOwnProperty(key)) {\n var val = obj[key];\n if (typeOf(val) === 'object' || typeOf(val) === 'array') {\n res[key] = renameDeep(val, cb);\n } else {\n res[key] = val;\n }\n }\n }\n return res;\n};\n","'use strict';\n\nvar has = Object.prototype.hasOwnProperty\n , prefix = '~';\n\n/**\n * Constructor to create a storage for our `EE` objects.\n * An `Events` instance is a plain object whose properties are event names.\n *\n * @constructor\n * @api private\n */\nfunction Events() {}\n\n//\n// We try to not inherit from `Object.prototype`. In some engines creating an\n// instance in this way is faster than calling `Object.create(null)` directly.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// character to make sure that the built-in object properties are not\n// overridden or used as an attack vector.\n//\nif (Object.create) {\n Events.prototype = Object.create(null);\n\n //\n // This hack is needed because the `__proto__` property is still inherited in\n // some old browsers like Android 4, iPhone 5.1, Opera 11 and Safari 5.\n //\n if (!new Events().__proto__) prefix = false;\n}\n\n/**\n * Representation of a single event listener.\n *\n * @param {Function} fn The listener function.\n * @param {Mixed} context The context to invoke the listener with.\n * @param {Boolean} [once=false] Specify if the listener is a one-time listener.\n * @constructor\n * @api private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Minimal `EventEmitter` interface that is molded against the Node.js\n * `EventEmitter` interface.\n *\n * @constructor\n * @api public\n */\nfunction EventEmitter() {\n this._events = new Events();\n this._eventsCount = 0;\n}\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @api public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var names = []\n , events\n , name;\n\n if (this._eventsCount === 0) return names;\n\n for (name in (events = this._events)) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return the listeners registered for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Boolean} exists Only check if there are listeners.\n * @returns {Array|Boolean}\n * @api public\n */\nEventEmitter.prototype.listeners = function listeners(event, exists) {\n var evt = prefix ? prefix + event : event\n , available = this._events[evt];\n\n if (exists) return !!available;\n if (!available) return [];\n if (available.fn) return [available.fn];\n\n for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {\n ee[i] = available[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Calls each of the listeners registered for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @returns {Boolean} `true` if the event had listeners, else `false`.\n * @api public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if (listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n case 4: listeners[i].fn.call(listeners[i].context, a1, a2, a3); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Add a listener for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn The listener function.\n * @param {Mixed} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n var listener = new EE(fn, context || this)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;\n else if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [this._events[evt], listener];\n\n return this;\n};\n\n/**\n * Add a one-time listener for a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn The listener function.\n * @param {Mixed} [context=this] The context to invoke the listener with.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n var listener = new EE(fn, context || this, true)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) this._events[evt] = listener, this._eventsCount++;\n else if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [this._events[evt], listener];\n\n return this;\n};\n\n/**\n * Remove the listeners of a given event.\n *\n * @param {String|Symbol} event The event name.\n * @param {Function} fn Only remove the listeners that match this function.\n * @param {Mixed} context Only remove the listeners that have this context.\n * @param {Boolean} once Only remove one-time listeners.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events[evt]) return this;\n if (!fn) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n return this;\n }\n\n var listeners = this._events[evt];\n\n if (listeners.fn) {\n if (\n listeners.fn === fn\n && (!once || listeners.once)\n && (!context || listeners.context === context)\n ) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n } else {\n for (var i = 0, events = [], length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn\n || (once && !listeners[i].once)\n || (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) this._events[evt] = events.length === 1 ? events[0] : events;\n else if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n\n return this;\n};\n\n/**\n * Remove all listeners, or those of the specified event.\n *\n * @param {String|Symbol} [event] The event name.\n * @returns {EventEmitter} `this`.\n * @api public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n var evt;\n\n if (event) {\n evt = prefix ? prefix + event : event;\n if (this._events[evt]) {\n if (--this._eventsCount === 0) this._events = new Events();\n else delete this._events[evt];\n }\n } else {\n this._events = new Events();\n this._eventsCount = 0;\n }\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// This function doesn't apply anymore.\n//\nEventEmitter.prototype.setMaxListeners = function setMaxListeners() {\n return this;\n};\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Allow `EventEmitter` to be imported as module namespace.\n//\nEventEmitter.EventEmitter = EventEmitter;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n","'use strict';\n\nfunction _defineProperty(obj, key, value) { if (key in obj) { Object.defineProperty(obj, key, { value: value, enumerable: true, configurable: true, writable: true }); } else { obj[key] = value; } return obj; }\n\nvar EventEmitter = require('eventemitter3');\nvar noop = function noop() {};\n\nvar State = {\n data: 'state-data',\n cdata: 'state-cdata',\n tagBegin: 'state-tag-begin',\n tagName: 'state-tag-name',\n tagEnd: 'state-tag-end',\n attributeNameStart: 'state-attribute-name-start',\n attributeName: 'state-attribute-name',\n attributeNameEnd: 'state-attribute-name-end',\n attributeValueBegin: 'state-attribute-value-begin',\n attributeValue: 'state-attribute-value'\n};\n\nvar Action = {\n lt: 'action-lt',\n gt: 'action-gt',\n space: 'action-space',\n equal: 'action-equal',\n quote: 'action-quote',\n slash: 'action-slash',\n char: 'action-char',\n error: 'action-error'\n};\n\nvar Type = {\n text: 'text',\n openTag: 'open-tag',\n closeTag: 'close-tag',\n attributeName: 'attribute-name',\n attributeValue: 'attribute-value'\n};\n\nvar charToAction = {\n ' ': Action.space,\n '\\t': Action.space,\n '\\n': Action.space,\n '\\r': Action.space,\n '<': Action.lt,\n '>': Action.gt,\n '\"': Action.quote,\n \"'\": Action.quote,\n '=': Action.equal,\n '/': Action.slash\n};\n\nvar getAction = function getAction(char) {\n return charToAction[char] || Action.char;\n};\n\n/**\n * @param {Object} options\n * @param {Boolean} options.debug\n * @return {Object}\n */\nvar create = function create(options) {\n var _State$data, _State$tagBegin, _State$tagName, _State$tagEnd, _State$attributeNameS, _State$attributeName, _State$attributeNameE, _State$attributeValue, _State$attributeValue2, _lexer$stateMachine;\n\n options = Object.assign({ debug: false }, options);\n var lexer = new EventEmitter();\n var state = State.data;\n var data = '';\n var tagName = '';\n var attrName = '';\n var attrValue = '';\n var isClosing = '';\n var openingQuote = '';\n\n var emit = function emit(type, value) {\n // for now, ignore tags like: '?xml', '!DOCTYPE' or comments\n if (tagName[0] === '?' || tagName[0] === '!') {\n return;\n }\n var event = { type: type, value: value };\n if (options.debug) {\n console.log('emit:', event);\n }\n lexer.emit('data', event);\n };\n\n lexer.stateMachine = (_lexer$stateMachine = {}, _defineProperty(_lexer$stateMachine, State.data, (_State$data = {}, _defineProperty(_State$data, Action.lt, function () {\n if (data.trim()) {\n emit(Type.text, data);\n }\n tagName = '';\n isClosing = false;\n state = State.tagBegin;\n }), _defineProperty(_State$data, Action.char, function (char) {\n data += char;\n }), _State$data)), _defineProperty(_lexer$stateMachine, State.cdata, _defineProperty({}, Action.char, function (char) {\n data += char;\n if (data.substr(-3) === ']]>') {\n emit(Type.text, data.slice(0, -3));\n data = '';\n state = State.data;\n }\n })), _defineProperty(_lexer$stateMachine, State.tagBegin, (_State$tagBegin = {}, _defineProperty(_State$tagBegin, Action.space, noop), _defineProperty(_State$tagBegin, Action.char, function (char) {\n tagName = char;\n state = State.tagName;\n }), _defineProperty(_State$tagBegin, Action.slash, function () {\n tagName = '';\n isClosing = true;\n }), _State$tagBegin)), _defineProperty(_lexer$stateMachine, State.tagName, (_State$tagName = {}, _defineProperty(_State$tagName, Action.space, function () {\n if (isClosing) {\n state = State.tagEnd;\n } else {\n state = State.attributeNameStart;\n emit(Type.openTag, tagName);\n }\n }), _defineProperty(_State$tagName, Action.gt, function () {\n if (isClosing) {\n emit(Type.closeTag, tagName);\n } else {\n emit(Type.openTag, tagName);\n }\n data = '';\n state = State.data;\n }), _defineProperty(_State$tagName, Action.slash, function () {\n state = State.tagEnd;\n emit(Type.openTag, tagName);\n }), _defineProperty(_State$tagName, Action.char, function (char) {\n tagName += char;\n if (tagName === '![CDATA[') {\n state = State.cdata;\n data = '';\n tagName = '';\n }\n }), _State$tagName)), _defineProperty(_lexer$stateMachine, State.tagEnd, (_State$tagEnd = {}, _defineProperty(_State$tagEnd, Action.gt, function () {\n emit(Type.closeTag, tagName);\n data = '';\n state = State.data;\n }), _defineProperty(_State$tagEnd, Action.char, noop), _State$tagEnd)), _defineProperty(_lexer$stateMachine, State.attributeNameStart, (_State$attributeNameS = {}, _defineProperty(_State$attributeNameS, Action.char, function (char) {\n attrName = char;\n state = State.attributeName;\n }), _defineProperty(_State$attributeNameS, Action.gt, function () {\n data = '';\n state = State.data;\n }), _defineProperty(_State$attributeNameS, Action.space, noop), _defineProperty(_State$attributeNameS, Action.slash, function () {\n isClosing = true;\n state = State.tagEnd;\n }), _State$attributeNameS)), _defineProperty(_lexer$stateMachine, State.attributeName, (_State$attributeName = {}, _defineProperty(_State$attributeName, Action.space, function () {\n state = State.attributeNameEnd;\n }), _defineProperty(_State$attributeName, Action.equal, function () {\n emit(Type.attributeName, attrName);\n state = State.attributeValueBegin;\n }), _defineProperty(_State$attributeName, Action.gt, function () {\n attrValue = '';\n emit(Type.attributeName, attrName);\n emit(Type.attributeValue, attrValue);\n data = '';\n state = State.data;\n }), _defineProperty(_State$attributeName, Action.slash, function () {\n isClosing = true;\n attrValue = '';\n emit(Type.attributeName, attrName);\n emit(Type.attributeValue, attrValue);\n state = State.tagEnd;\n }), _defineProperty(_State$attributeName, Action.char, function (char) {\n attrName += char;\n }), _State$attributeName)), _defineProperty(_lexer$stateMachine, State.attributeNameEnd, (_State$attributeNameE = {}, _defineProperty(_State$attributeNameE, Action.space, noop), _defineProperty(_State$attributeNameE, Action.equal, function () {\n emit(Type.attributeName, attrName);\n state = State.attributeValueBegin;\n }), _defineProperty(_State$attributeNameE, Action.gt, function () {\n attrValue = '';\n emit(Type.attributeName, attrName);\n emit(Type.attributeValue, attrValue);\n data = '';\n state = State.data;\n }), _defineProperty(_State$attributeNameE, Action.char, function (char) {\n attrValue = '';\n emit(Type.attributeName, attrName);\n emit(Type.attributeValue, attrValue);\n attrName = char;\n state = State.attributeName;\n }), _State$attributeNameE)), _defineProperty(_lexer$stateMachine, State.attributeValueBegin, (_State$attributeValue = {}, _defineProperty(_State$attributeValue, Action.space, noop), _defineProperty(_State$attributeValue, Action.quote, function (char) {\n openingQuote = char;\n attrValue = '';\n state = State.attributeValue;\n }), _defineProperty(_State$attributeValue, Action.gt, function () {\n attrValue = '';\n emit(Type.attributeValue, attrValue);\n data = '';\n state = State.data;\n }), _defineProperty(_State$attributeValue, Action.char, function (char) {\n openingQuote = '';\n attrValue = char;\n state = State.attributeValue;\n }), _State$attributeValue)), _defineProperty(_lexer$stateMachine, State.attributeValue, (_State$attributeValue2 = {}, _defineProperty(_State$attributeValue2, Action.space, function (char) {\n if (openingQuote) {\n attrValue += char;\n } else {\n emit(Type.attributeValue, attrValue);\n state = State.attributeNameStart;\n }\n }), _defineProperty(_State$attributeValue2, Action.quote, function (char) {\n if (openingQuote === char) {\n emit(Type.attributeValue, attrValue);\n state = State.attributeNameStart;\n } else {\n attrValue += char;\n }\n }), _defineProperty(_State$attributeValue2, Action.gt, function (char) {\n if (openingQuote) {\n attrValue += char;\n } else {\n emit(Type.attributeValue, attrValue);\n data = '';\n state = State.data;\n }\n }), _defineProperty(_State$attributeValue2, Action.slash, function (char) {\n if (openingQuote) {\n attrValue += char;\n } else {\n emit(Type.attributeValue, attrValue);\n isClosing = true;\n state = State.tagEnd;\n }\n }), _defineProperty(_State$attributeValue2, Action.char, function (char) {\n attrValue += char;\n }), _State$attributeValue2)), _lexer$stateMachine);\n\n var step = function step(char) {\n if (options.debug) {\n console.log(state, char);\n }\n var actions = lexer.stateMachine[state];\n var action = actions[getAction(char)] || actions[Action.error] || actions[Action.char];\n action(char);\n };\n\n lexer.write = function (str) {\n var len = str.length;\n for (var i = 0; i < len; i++) {\n step(str[i]);\n }\n };\n\n return lexer;\n};\n\nmodule.exports = {\n State: State,\n Action: Action,\n Type: Type,\n create: create\n};","'use strict';\n\nvar EventEmitter = require('eventemitter3');\nvar Lexer = require('xml-lexer');\nvar Type = Lexer.Type;\n\nvar NodeType = {\n element: 'element',\n text: 'text'\n};\n\nvar createNode = function createNode(params) {\n return Object.assign({\n name: '',\n type: NodeType.element,\n value: '',\n parent: null,\n attributes: {},\n children: []\n }, params);\n};\n\nvar create = function create(options) {\n options = Object.assign({\n stream: false,\n parentNodes: true,\n doneEvent: 'done',\n tagPrefix: 'tag:',\n emitTopLevelOnly: false,\n debug: false\n }, options);\n\n var lexer = void 0,\n rootNode = void 0,\n current = void 0,\n attrName = void 0;\n\n var reader = new EventEmitter();\n\n var handleLexerData = function handleLexerData(data) {\n switch (data.type) {\n\n case Type.openTag:\n if (current === null) {\n current = rootNode;\n current.name = data.value;\n } else {\n var node = createNode({\n name: data.value,\n parent: current\n });\n current.children.push(node);\n current = node;\n }\n break;\n\n case Type.closeTag:\n var parent = current.parent;\n if (!options.parentNodes) {\n current.parent = null;\n }\n if (current.name !== data.value) {\n // ignore unexpected closing tag\n break;\n }\n if (options.stream && parent === rootNode) {\n rootNode.children = [];\n // do not expose parent node in top level nodes\n current.parent = null;\n }\n if (!options.emitTopLevelOnly || parent === rootNode) {\n reader.emit(options.tagPrefix + current.name, current);\n reader.emit('tag', current.name, current);\n }\n if (current === rootNode) {\n // end of document, stop listening\n lexer.removeAllListeners('data');\n reader.emit(options.doneEvent, current);\n rootNode = null;\n }\n current = parent;\n break;\n\n case Type.text:\n if (current) {\n current.children.push(createNode({\n type: NodeType.text,\n value: data.value,\n parent: options.parentNodes ? current : null\n }));\n }\n break;\n\n case Type.attributeName:\n attrName = data.value;\n current.attributes[attrName] = '';\n break;\n\n case Type.attributeValue:\n current.attributes[attrName] = data.value;\n break;\n }\n };\n\n reader.reset = function () {\n lexer = Lexer.create({ debug: options.debug });\n lexer.on('data', handleLexerData);\n rootNode = createNode();\n current = null;\n attrName = '';\n reader.parse = lexer.write;\n };\n\n reader.reset();\n return reader;\n};\n\nvar parseSync = function parseSync(xml, options) {\n options = Object.assign({}, options, { stream: false, tagPrefix: ':' });\n var reader = create(options);\n var res = void 0;\n reader.on('done', function (ast) {\n res = ast;\n });\n reader.parse(xml);\n return res;\n};\n\nmodule.exports = {\n parseSync: parseSync,\n create: create,\n NodeType: NodeType\n};","import type { AutorouterProp, ConnectorProps } from \"@tscircuit/props\"\nimport { Fragment, type ReactNode } from \"react\"\nimport {\n BISCUIT_BOARD_HEIGHT,\n BISCUIT_BOARD_MOUNTING_HOLE_POSITIONS,\n BISCUIT_BOARD_WIDTH,\n} from \"./BiscuitBoard\"\nimport type { BiscuitBoardAutorouterOptions } from \"./biscuit-board-autorouter\"\nimport { createPrefabricatedViaAutorouter } from \"./create-prefabricated-via-autorouter\"\n\nexport const ARDUINO_SHIELD_CLAD_WIDTH = BISCUIT_BOARD_WIDTH\nexport const ARDUINO_SHIELD_CLAD_HEIGHT = BISCUIT_BOARD_HEIGHT\nexport const ARDUINO_SHIELD_HEADER_PITCH = 2.54\nexport const ARDUINO_SHIELD_HEADER_ROW_Y = 24.13\nexport const ARDUINO_SHIELD_CONNECTOR_OFFSET_X = -ARDUINO_SHIELD_HEADER_PITCH\n\nexport const ARDUINO_SHIELD_HEADER_PLACEMENTS = {\n power: {\n x: 2.54 + ARDUINO_SHIELD_CONNECTOR_OFFSET_X,\n y: -24.13,\n rotation: 0,\n },\n analog: {\n x: 22.86 + ARDUINO_SHIELD_CONNECTOR_OFFSET_X,\n y: -24.13,\n rotation: 0,\n },\n digital0To7: {\n x: 20.32 + ARDUINO_SHIELD_CONNECTOR_OFFSET_X,\n y: 24.13,\n rotation: 180,\n },\n digital8To13: {\n x: -4.064 + ARDUINO_SHIELD_CONNECTOR_OFFSET_X,\n y: 24.13,\n rotation: 180,\n },\n icsp: {\n x: 30.607 + ARDUINO_SHIELD_CONNECTOR_OFFSET_X,\n y: 1.27,\n rotation: 270,\n },\n} as const\n\n/** The original five BiscuitBoard mounting-hole centers. */\nexport const ARDUINO_SHIELD_MOUNTING_HOLE_POSITIONS =\n BISCUIT_BOARD_MOUNTING_HOLE_POSITIONS\nexport const ARDUINO_SHIELD_MOUNTING_HOLE_DIAMETER = 2.2\nexport const ARDUINO_SHIELD_CLAD_VIA_HOLE_DIAMETER = 0.3\nexport const ARDUINO_SHIELD_CLAD_VIA_OUTER_DIAMETER = 0.6\nexport const ARDUINO_SHIELD_CLAD_VIA_SPACING = 1.3\n\nconst ARDUINO_SHIELD_EDGE_CLEARANCE = 0.2\nconst ARDUINO_SHIELD_EDGE_CLEARANCE_VALIDATION_TOLERANCE = 0.001\n\nexport interface ArduinoShieldCladViaPosition {\n x: number\n y: number\n}\n\ninterface ViaCandidateZone {\n minX: number\n maxX: number\n minY: number\n maxY: number\n spacing: number\n}\n\nconst rangeInclusive = (start: number, end: number, increment: number) =>\n Array.from(\n { length: Math.max(0, Math.floor((end - start) / increment) + 1) },\n (_, index) => Math.round((start + index * increment) * 1e6) / 1e6,\n )\n\nconst createViaZone = (\n zone: ViaCandidateZone,\n): ArduinoShieldCladViaPosition[] =>\n rangeInclusive(zone.minX, zone.maxX, zone.spacing).flatMap((x) =>\n rangeInclusive(zone.minY, zone.maxY, zone.spacing).map((y) => ({ x, y })),\n )\n\n/**\n * Clustered fixed-via field arranged around the UNO shield connectors. The\n * main header rows remain clear and the right side is split around the two UNO\n * mounting/ICSP regions.\n */\nexport const ARDUINO_SHIELD_CLAD_VIA_CANDIDATE_ZONES = [\n {\n minX: -33.5,\n maxX: -25.5,\n minY: 17.5,\n maxY: 21.5,\n spacing: ARDUINO_SHIELD_CLAD_VIA_SPACING,\n },\n {\n minX: -33.5,\n maxX: -25.5,\n minY: -21.5,\n maxY: -17.5,\n spacing: ARDUINO_SHIELD_CLAD_VIA_SPACING,\n },\n {\n minX: -21.5,\n maxX: -13.5,\n minY: 13.5,\n maxY: 17.5,\n spacing: ARDUINO_SHIELD_CLAD_VIA_SPACING,\n },\n {\n minX: -21.5,\n maxX: -13.5,\n minY: -17.5,\n maxY: -13.5,\n spacing: ARDUINO_SHIELD_CLAD_VIA_SPACING,\n },\n {\n minX: -19,\n maxX: -3,\n minY: -6,\n maxY: 6,\n spacing: ARDUINO_SHIELD_CLAD_VIA_SPACING,\n },\n {\n minX: 34.5,\n maxX: 34.5,\n minY: -19.5,\n maxY: -7.5,\n spacing: ARDUINO_SHIELD_CLAD_VIA_SPACING,\n },\n {\n minX: 34.5,\n maxX: 34.5,\n minY: 7.5,\n maxY: 19.5,\n spacing: ARDUINO_SHIELD_CLAD_VIA_SPACING,\n },\n] as const satisfies readonly ViaCandidateZone[]\n\nconst pointKey = (point: ArduinoShieldCladViaPosition) =>\n `${point.x.toFixed(3)},${point.y.toFixed(3)}`\n\nexport const ARDUINO_SHIELD_CLAD_VIA_POSITIONS = Array.from(\n new Map(\n ARDUINO_SHIELD_CLAD_VIA_CANDIDATE_ZONES.flatMap(createViaZone).map(\n (point) => [pointKey(point), point],\n ),\n ).values(),\n)\n\nconst powerPins = {\n pin1: [\"NC\"],\n pin2: [\"IOREF\"],\n pin3: [\"RESET\"],\n pin4: [\"V3V3\", \"3V3\"],\n pin5: [\"V5\", \"5V\"],\n pin6: [\"GND1\", \"GND\"],\n pin7: [\"GND2\", \"GND\"],\n pin8: [\"VIN\"],\n} as const\n\nconst analogPins = {\n pin1: [\"A0\", \"D14\"],\n pin2: [\"A1\", \"D15\"],\n pin3: [\"A2\", \"D16\"],\n pin4: [\"A3\", \"D17\"],\n pin5: [\"A4\", \"D18\", \"SDA\"],\n pin6: [\"A5\", \"D19\", \"SCL\"],\n} as const\n\nconst digital0To7Pins = {\n pin1: [\"D0\", \"RX\"],\n pin2: [\"D1\", \"TX\"],\n pin3: [\"D2\"],\n pin4: [\"D3\"],\n pin5: [\"D4\"],\n pin6: [\"D5\"],\n pin7: [\"D6\"],\n pin8: [\"D7\"],\n} as const\n\nconst digital8To13Pins = {\n pin1: [\"D8\"],\n pin2: [\"D9\"],\n pin3: [\"D10\", \"SS\"],\n pin4: [\"D11\", \"COPI\", \"MOSI\"],\n pin5: [\"D12\", \"CIPO\", \"MISO\"],\n pin6: [\"D13\", \"SCK\"],\n pin7: [\"GND\"],\n pin8: [\"AREF\"],\n pin9: [\"SDA_R3\", \"SDA\"],\n pin10: [\"SCL_R3\", \"SCL\"],\n} as const\n\nconst icspPins = {\n pin1: [\"CIPO\", \"MISO\"],\n pin2: [\"V5\", \"5V\"],\n pin3: [\"SCK\"],\n pin4: [\"COPI\", \"MOSI\"],\n pin5: [\"RESET\"],\n pin6: [\"GND\"],\n} as const\n\nconst pinNames = (count: number) =>\n Array.from({ length: count }, (_, index) => `pin${index + 1}`)\n\nconst SingleRowShieldHeaderFootprint = ({ pinCount }: { pinCount: number }) => (\n <footprint insertionDirection=\"from_below\">\n {Array.from({ length: pinCount }, (_, index) => {\n const pin = index + 1\n const x = (index - (pinCount - 1) / 2) * ARDUINO_SHIELD_HEADER_PITCH\n return (\n <Fragment key={`pin-${pin}`}>\n {pin === 1 ? (\n <platedhole\n portHints={[`pin${pin}`]}\n shape=\"circular_hole_with_rect_pad\"\n holeDiameter=\"1mm\"\n rectPadWidth=\"1.7mm\"\n rectPadHeight=\"1.7mm\"\n pcbX={x}\n />\n ) : (\n <platedhole\n portHints={[`pin${pin}`]}\n shape=\"circle\"\n holeDiameter=\"1mm\"\n outerDiameter=\"1.7mm\"\n pcbX={x}\n />\n )}\n </Fragment>\n )\n })}\n <silkscreenrect\n width={`${pinCount * ARDUINO_SHIELD_HEADER_PITCH}mm`}\n height=\"2.54mm\"\n />\n </footprint>\n)\n\nconst IcspShieldSocketFootprint = () => (\n <footprint insertionDirection=\"from_below\">\n {[-1, 0, 1].flatMap((column) =>\n [-1, 1].map((row, rowIndex) => {\n const pin = (column + 1) * 2 + rowIndex + 1\n return (\n <Fragment key={`icsp-pin-${pin}`}>\n {pin === 1 ? (\n <platedhole\n portHints={[`pin${pin}`]}\n shape=\"circular_hole_with_rect_pad\"\n holeDiameter=\"1mm\"\n rectPadWidth=\"1.7mm\"\n rectPadHeight=\"1.7mm\"\n pcbX={column * ARDUINO_SHIELD_HEADER_PITCH}\n pcbY={(row * ARDUINO_SHIELD_HEADER_PITCH) / 2}\n />\n ) : (\n <platedhole\n portHints={[`pin${pin}`]}\n shape=\"circle\"\n holeDiameter=\"1mm\"\n outerDiameter=\"1.7mm\"\n pcbX={column * ARDUINO_SHIELD_HEADER_PITCH}\n pcbY={(row * ARDUINO_SHIELD_HEADER_PITCH) / 2}\n />\n )}\n </Fragment>\n )\n }),\n )}\n <silkscreenrect width=\"7.62mm\" height=\"5.08mm\" />\n </footprint>\n)\n\nexport const ArduinoShieldPowerHeader = (props: ConnectorProps) => (\n <connector\n pinLabels={powerPins}\n manufacturerPartNumber=\"GENERIC-1X8-ARDUINO-STACKING-HEADER\"\n footprint={<SingleRowShieldHeaderFootprint pinCount={8} />}\n noSchematicRepresentation\n {...props}\n />\n)\n\nexport const ArduinoShieldAnalogHeader = (props: ConnectorProps) => (\n <connector\n pinLabels={analogPins}\n manufacturerPartNumber=\"GENERIC-1X6-ARDUINO-STACKING-HEADER\"\n footprint={<SingleRowShieldHeaderFootprint pinCount={6} />}\n noSchematicRepresentation\n {...props}\n />\n)\n\nexport const ArduinoShieldDigital0To7Header = (props: ConnectorProps) => (\n <connector\n pinLabels={digital0To7Pins}\n manufacturerPartNumber=\"GENERIC-1X8-ARDUINO-STACKING-HEADER\"\n footprint={<SingleRowShieldHeaderFootprint pinCount={8} />}\n noSchematicRepresentation\n {...props}\n />\n)\n\nexport const ArduinoShieldDigital8To13Header = (props: ConnectorProps) => (\n <connector\n pinLabels={digital8To13Pins}\n manufacturerPartNumber=\"GENERIC-1X10-ARDUINO-R3-STACKING-HEADER\"\n footprint={<SingleRowShieldHeaderFootprint pinCount={10} />}\n noSchematicRepresentation\n {...props}\n />\n)\n\nexport const ArduinoShieldIcspSocket = (props: ConnectorProps) => (\n <connector\n pinLabels={icspPins}\n manufacturerPartNumber=\"GENERIC-2X3-ARDUINO-ICSP-FEMALE-DOWN\"\n footprint={<IcspShieldSocketFootprint />}\n noSchematicRepresentation\n {...props}\n />\n)\n\nexport interface ArduinoShieldCladProps {\n children?: ReactNode\n autorouter?: AutorouterProp\n autorouterOptions?: BiscuitBoardAutorouterOptions\n minTraceWidth?: number\n nominalTraceWidth?: number\n routingDisabled?: boolean\n /** Marks every shield header pin NC for bare-template previews only. */\n markHeadersNoConnect?: boolean\n /** Overrides the no-connect pins for routed shield applications. */\n headerNoConnects?: {\n power?: string[]\n analog?: string[]\n digital0To7?: string[]\n digital8To13?: string[]\n icsp?: string[]\n }\n}\n\n/** A BiscuitBoard-sized clad with the official Arduino UNO R3 connector grid. */\nexport const ArduinoShieldClad = ({\n children,\n autorouter,\n autorouterOptions,\n minTraceWidth,\n nominalTraceWidth = 0.3,\n routingDisabled = false,\n markHeadersNoConnect = false,\n headerNoConnects,\n}: ArduinoShieldCladProps) => (\n <board\n name=\"ArduinoShieldClad\"\n title=\"BiscuitBoard clad with Arduino UNO R3 shield headers\"\n width={`${ARDUINO_SHIELD_CLAD_WIDTH}mm`}\n height={`${ARDUINO_SHIELD_CLAD_HEIGHT}mm`}\n borderRadius=\"1.5mm\"\n layers={2}\n minTraceWidth={`${minTraceWidth ?? 0.15}mm`}\n minBoardEdgeClearance={`${ARDUINO_SHIELD_EDGE_CLEARANCE - ARDUINO_SHIELD_EDGE_CLEARANCE_VALIDATION_TOLERANCE}mm`}\n minViaHoleDiameter=\"0.2mm\"\n minViaPadDiameter=\"0.4mm\"\n autorouter={\n autorouter ??\n createPrefabricatedViaAutorouter({\n width: ARDUINO_SHIELD_CLAD_WIDTH,\n height: ARDUINO_SHIELD_CLAD_HEIGHT,\n edgeClearance: ARDUINO_SHIELD_EDGE_CLEARANCE,\n options: autorouterOptions,\n minimumTraceWidth: minTraceWidth,\n nominalTraceWidth,\n })\n }\n routingDisabled={routingDisabled}\n >\n <net name=\"GND\" isGroundNet />\n\n {ARDUINO_SHIELD_MOUNTING_HOLE_POSITIONS.map((hole) => (\n <Fragment key={`arduino-mounting-hole-${hole.x}-${hole.y}`}>\n <hole\n pcbX={hole.x}\n pcbY={hole.y}\n diameter={`${ARDUINO_SHIELD_MOUNTING_HOLE_DIAMETER}mm`}\n />\n </Fragment>\n ))}\n\n <ArduinoShieldPowerHeader\n name=\"J_POWER\"\n noConnect={\n headerNoConnects?.power ??\n (markHeadersNoConnect ? pinNames(8) : [\"pin1\"])\n }\n pcbX={ARDUINO_SHIELD_HEADER_PLACEMENTS.power.x}\n pcbY={ARDUINO_SHIELD_HEADER_PLACEMENTS.power.y}\n />\n <ArduinoShieldAnalogHeader\n name=\"J_ANALOG\"\n noConnect={\n headerNoConnects?.analog ??\n (markHeadersNoConnect ? pinNames(6) : undefined)\n }\n pcbX={ARDUINO_SHIELD_HEADER_PLACEMENTS.analog.x}\n pcbY={ARDUINO_SHIELD_HEADER_PLACEMENTS.analog.y}\n />\n <ArduinoShieldDigital0To7Header\n name=\"J_DIGITAL_0_7\"\n noConnect={\n headerNoConnects?.digital0To7 ??\n (markHeadersNoConnect ? pinNames(8) : undefined)\n }\n pcbX={ARDUINO_SHIELD_HEADER_PLACEMENTS.digital0To7.x}\n pcbY={ARDUINO_SHIELD_HEADER_PLACEMENTS.digital0To7.y}\n pcbRotation={ARDUINO_SHIELD_HEADER_PLACEMENTS.digital0To7.rotation}\n />\n <ArduinoShieldDigital8To13Header\n name=\"J_DIGITAL_8_13\"\n noConnect={\n headerNoConnects?.digital8To13 ??\n (markHeadersNoConnect ? pinNames(10) : undefined)\n }\n pcbX={ARDUINO_SHIELD_HEADER_PLACEMENTS.digital8To13.x}\n pcbY={ARDUINO_SHIELD_HEADER_PLACEMENTS.digital8To13.y}\n pcbRotation={ARDUINO_SHIELD_HEADER_PLACEMENTS.digital8To13.rotation}\n />\n <ArduinoShieldIcspSocket\n name=\"J_ICSP\"\n noConnect={\n headerNoConnects?.icsp ??\n (markHeadersNoConnect ? pinNames(6) : undefined)\n }\n pcbX={ARDUINO_SHIELD_HEADER_PLACEMENTS.icsp.x}\n pcbY={ARDUINO_SHIELD_HEADER_PLACEMENTS.icsp.y}\n pcbRotation={ARDUINO_SHIELD_HEADER_PLACEMENTS.icsp.rotation}\n />\n\n <silkscreentext\n text=\"ARDUINO UNO R3 SHIELD\"\n pcbX={0}\n pcbY={-10.5}\n fontSize=\"0.8mm\"\n />\n <silkscreentext\n text=\"POWER\"\n pcbX={ARDUINO_SHIELD_HEADER_PLACEMENTS.power.x}\n pcbY={-21.5}\n fontSize=\"0.65mm\"\n />\n <silkscreentext\n text=\"ANALOG\"\n pcbX={ARDUINO_SHIELD_HEADER_PLACEMENTS.analog.x}\n pcbY={-21.5}\n fontSize=\"0.65mm\"\n />\n <silkscreentext\n text=\"D8-13\"\n pcbX={ARDUINO_SHIELD_HEADER_PLACEMENTS.digital8To13.x}\n pcbY={21.5}\n fontSize=\"0.65mm\"\n />\n <silkscreentext\n text=\"D0-7\"\n pcbX={ARDUINO_SHIELD_HEADER_PLACEMENTS.digital0To7.x}\n pcbY={21.5}\n fontSize=\"0.65mm\"\n />\n <silkscreentext\n text=\"ICSP\"\n pcbX={ARDUINO_SHIELD_HEADER_PLACEMENTS.icsp.x - 3.307}\n pcbY={ARDUINO_SHIELD_HEADER_PLACEMENTS.icsp.y}\n fontSize=\"0.6mm\"\n />\n\n {ARDUINO_SHIELD_CLAD_VIA_CANDIDATE_ZONES.map((zone) => (\n <Fragment key={`arduino-via-zone-${zone.minX}-${zone.minY}`}>\n <pcbnoterect\n color=\"blue\"\n width={Math.max(0.2, zone.maxX - zone.minX)}\n height={Math.max(0.2, zone.maxY - zone.minY)}\n pcbPositionAnchor=\"center\"\n pcbX={zone.minX + (zone.maxX - zone.minX) / 2}\n pcbY={zone.minY + (zone.maxY - zone.minY) / 2}\n />\n </Fragment>\n ))}\n\n {ARDUINO_SHIELD_CLAD_VIA_POSITIONS.map((via) => (\n <Fragment key={`arduino-prefab-via-${via.x}-${via.y}`}>\n <via\n netIsAssignable\n pcbX={via.x}\n pcbY={via.y}\n fromLayer=\"top\"\n toLayer=\"bottom\"\n holeDiameter={`${ARDUINO_SHIELD_CLAD_VIA_HOLE_DIAMETER}mm`}\n outerDiameter={`${ARDUINO_SHIELD_CLAD_VIA_OUTER_DIAMETER}mm`}\n />\n </Fragment>\n ))}\n\n <pcbnotedimension\n from={{\n x: -ARDUINO_SHIELD_CLAD_WIDTH / 2,\n y: ARDUINO_SHIELD_CLAD_HEIGHT / 2 + 2.5,\n }}\n to={{\n x: ARDUINO_SHIELD_CLAD_WIDTH / 2,\n y: ARDUINO_SHIELD_CLAD_HEIGHT / 2 + 2.5,\n }}\n text={`${ARDUINO_SHIELD_CLAD_WIDTH}mm`}\n />\n <pcbnotedimension\n from={{\n x: ARDUINO_SHIELD_CLAD_WIDTH / 2 + 2.5,\n y: -ARDUINO_SHIELD_CLAD_HEIGHT / 2,\n }}\n to={{\n x: ARDUINO_SHIELD_CLAD_WIDTH / 2 + 2.5,\n y: ARDUINO_SHIELD_CLAD_HEIGHT / 2,\n }}\n text={`${ARDUINO_SHIELD_CLAD_HEIGHT}mm`}\n />\n\n {children}\n </board>\n)\n","import type { AutorouterProp } from \"@tscircuit/props\"\nimport { Fragment, type ReactNode } from \"react\"\nimport type { BiscuitBoardAutorouterOptions } from \"./biscuit-board-autorouter\"\nimport { createPrefabricatedViaAutorouter } from \"./create-prefabricated-via-autorouter\"\n\nexport const BISCUIT_BOARD_WIDTH = 75\nexport const BISCUIT_BOARD_HEIGHT = 55\nconst BISCUIT_BOARD_EDGE_CLEARANCE = 0.5\n// Core's DRC currently treats an exactly-equal floating-point distance as a\n// violation. Route at the full clearance, but leave a 1 µm comparison epsilon.\nconst BISCUIT_BOARD_EDGE_CLEARANCE_VALIDATION_TOLERANCE = 0.001\n\nexport interface BiscuitBoardViaPosition {\n x: number\n y: number\n}\n\nconst range = (start: number, end: number, increment: number): number[] =>\n Array.from(\n { length: Math.max(0, Math.floor((end - start) / increment)) },\n (_, index) => start + index * increment,\n )\n\nconst createViaZone = (zone: {\n minX: number\n maxX: number\n minY: number\n maxY: number\n spacing: number\n}): BiscuitBoardViaPosition[] => {\n const xRange = range(zone.minX, zone.maxX, zone.spacing)\n const yRange = range(zone.minY, zone.maxY, zone.spacing)\n const centeringOffsetX =\n (zone.maxX - zone.minX - (xRange.length - 1) * zone.spacing) / 2\n const centeringOffsetY =\n (zone.maxY - zone.minY - (yRange.length - 1) * zone.spacing) / 2\n\n return xRange.flatMap((x) =>\n yRange.map((y) => ({\n x: x + centeringOffsetX,\n y: y + centeringOffsetY,\n })),\n )\n}\n\nexport const BISCUIT_BOARD_VIA_ZONES = [\n { minX: -33.5, maxX: -21.5, minY: -23.5, maxY: -15.5, spacing: 4 },\n { minX: -33.5, maxX: -21.5, minY: 15.5, maxY: 23.5, spacing: 4 },\n { minX: 10, maxX: 27.5, minY: 17.5, maxY: 25.5, spacing: 4 },\n { minX: 30.5, maxX: 34.5, minY: -22.5, maxY: 22.5, spacing: 4 },\n { minX: -20, maxX: 0, minY: -8, maxY: 8, spacing: 4 },\n] as const\n\nexport const BISCUIT_BOARD_VIA_POSITIONS =\n BISCUIT_BOARD_VIA_ZONES.flatMap(createViaZone)\n\nexport const BISCUIT_BOARD_MOUNTING_HOLE_POSITIONS = [\n { x: BISCUIT_BOARD_WIDTH / 2 - 2.5, y: BISCUIT_BOARD_HEIGHT / 2 - 2.5 },\n { x: BISCUIT_BOARD_WIDTH / 2 - 6.5, y: BISCUIT_BOARD_HEIGHT / 2 - 2.5 },\n { x: BISCUIT_BOARD_WIDTH / 2 - 2.5, y: -BISCUIT_BOARD_HEIGHT / 2 + 2.5 },\n { x: -BISCUIT_BOARD_WIDTH / 2 + 2.5, y: -BISCUIT_BOARD_HEIGHT / 2 + 2.5 },\n { x: -BISCUIT_BOARD_WIDTH / 2 + 2.5, y: BISCUIT_BOARD_HEIGHT / 2 - 2.5 },\n] as const\n\nexport interface BiscuitBoardProps {\n children?: ReactNode\n autorouter?: AutorouterProp\n autorouterOptions?: BiscuitBoardAutorouterOptions\n /** Enforced minimum trace width in millimeters. */\n minTraceWidth?: number\n /** Preferred post-route trace width in millimeters. Defaults to 0.3 mm. */\n nominalTraceWidth?: number\n routingDisabled?: boolean\n}\n\n/**\n * A prefabricated 75 mm x 55 mm copper-clad board with fixed through vias.\n * Child components use ordinary tscircuit TSX; the default local autorouter\n * can change layers only at the checked-in prefabricated via positions.\n */\nexport const BiscuitBoard = ({\n children,\n autorouter,\n autorouterOptions,\n minTraceWidth,\n nominalTraceWidth = 0.3,\n routingDisabled = false,\n}: BiscuitBoardProps) => (\n <board\n name=\"BiscuitBoard\"\n title=\"BiscuitBoard prefabricated copper clad\"\n width={`${BISCUIT_BOARD_WIDTH}mm`}\n height={`${BISCUIT_BOARD_HEIGHT}mm`}\n borderRadius=\"2mm\"\n layers={2}\n minTraceWidth={`${minTraceWidth ?? 0.15}mm`}\n minBoardEdgeClearance={`${BISCUIT_BOARD_EDGE_CLEARANCE - BISCUIT_BOARD_EDGE_CLEARANCE_VALIDATION_TOLERANCE}mm`}\n minViaHoleDiameter=\"0.2mm\"\n minViaPadDiameter=\"0.4mm\"\n autorouter={\n autorouter ??\n createPrefabricatedViaAutorouter({\n width: BISCUIT_BOARD_WIDTH,\n height: BISCUIT_BOARD_HEIGHT,\n edgeClearance: BISCUIT_BOARD_EDGE_CLEARANCE,\n options: autorouterOptions,\n minimumTraceWidth: minTraceWidth,\n nominalTraceWidth,\n })\n }\n routingDisabled={routingDisabled}\n >\n <net name=\"GND\" isGroundNet />\n\n <silkscreentext\n text=\"UP\"\n pcbX={BISCUIT_BOARD_WIDTH / 2 - 10}\n pcbY={25.5}\n layer=\"top\"\n fontSize=\"2mm\"\n />\n\n {BISCUIT_BOARD_MOUNTING_HOLE_POSITIONS.map((hole) => (\n <Fragment key={`mounting-hole-${hole.x}-${hole.y}`}>\n <hole pcbX={hole.x} pcbY={hole.y} diameter=\"2.2mm\" />\n </Fragment>\n ))}\n\n {BISCUIT_BOARD_VIA_ZONES.map((zone) => (\n <Fragment key={`via-zone-${zone.minX}-${zone.minY}`}>\n <pcbnoterect\n color=\"blue\"\n width={zone.maxX - zone.minX}\n height={zone.maxY - zone.minY}\n pcbPositionAnchor=\"center\"\n pcbX={zone.minX + (zone.maxX - zone.minX) / 2}\n pcbY={zone.minY + (zone.maxY - zone.minY) / 2}\n />\n </Fragment>\n ))}\n\n {BISCUIT_BOARD_VIA_POSITIONS.map((via) => (\n <Fragment key={`prefab-via-${via.x}-${via.y}`}>\n <via\n netIsAssignable\n pcbX={via.x}\n pcbY={via.y}\n fromLayer=\"top\"\n toLayer=\"bottom\"\n holeDiameter=\"2.1mm\"\n outerDiameter=\"2.3mm\"\n />\n </Fragment>\n ))}\n\n <pcbnotedimension\n from={{\n x: -BISCUIT_BOARD_WIDTH / 2,\n y: BISCUIT_BOARD_HEIGHT / 2 + 2.5,\n }}\n to={{\n x: BISCUIT_BOARD_WIDTH / 2,\n y: BISCUIT_BOARD_HEIGHT / 2 + 2.5,\n }}\n text={`${BISCUIT_BOARD_WIDTH}mm`}\n />\n <pcbnotedimension\n from={{\n x: BISCUIT_BOARD_WIDTH / 2 + 2.5,\n y: -BISCUIT_BOARD_HEIGHT / 2,\n }}\n to={{\n x: BISCUIT_BOARD_WIDTH / 2 + 2.5,\n y: BISCUIT_BOARD_HEIGHT / 2,\n }}\n text={`${BISCUIT_BOARD_HEIGHT}mm`}\n />\n\n {children}\n </board>\n)\n","// index.ts\nvar svgAlphabet = {\n \"0\": \"M0.301025 0.257813 L0.206593 0.283385 L0.122042 0.361307 L0.075923 0.474441 L0.064942 0.642221 L0.091296 0.78289 L0.159376 0.899463 L0.257104 0.961214 L0.344948 0.961214 L0.442678 0.899463 L0.510757 0.78289 L0.537111 0.642221 L0.526131 0.474441 L0.480012 0.361307 L0.39546 0.283385 L0.301025 0.257813\",\n \"1\": \"M0.220426 0.40845 L0.381626 0.270996 L0.381626 0.948966\",\n \"2\": \"M0.110409 0.39212 L0.125621 0.342293 L0.170571 0.295823 L0.244237 0.26431 L0.291518 0.257813 L0.373319 0.263799 L0.434683 0.290705 L0.468239 0.331966 L0.480292 0.379913 L0.479492 0.411806 L0.465088 0.465192 L0.402571 0.568988 L0.245134 0.766438 L0.07959 0.948045 L0.522462 0.948045\",\n \"3\": \"M0.081606 0.345073 L0.119154 0.315633 L0.178996 0.284091 L0.255265 0.257813 L0.349133 0.263062 L0.43127 0.289348 L0.48994 0.336662 L0.525141 0.394491 L0.513407 0.457577 L0.466472 0.504892 L0.384334 0.541692 L0.290464 0.56272 L0.20833 0.573235 L0.290464 0.583749 L0.384334 0.610035 L0.466472 0.652092 L0.519274 0.709922 L0.531007 0.773007 L0.50754 0.841351 L0.454738 0.899179 L0.3726 0.946494 L0.310412 0.961214 L0.209503 0.959111 L0.127367 0.946494 L0.071046 0.929671\",\n \"4\": \"M0.418494 0.270996 L0.048828 0.724199 L0.553224 0.724199 M0.414181 0.578167 L0.414181 0.94897\",\n \"5\": \"M0.074951 0.270996 L0.074951 0.614701 L0.267655 0.5695 L0.405247 0.586502 L0.460002 0.617189 L0.498028 0.660731 L0.527101 0.779401 L0.513352 0.841049 L0.477274 0.889568 L0.406378 0.93463 L0.324445 0.958337 L0.247399 0.962139 L0.182516 0.949767 L0.130068 0.925508 L0.074951 0.875607 M0.074951 0.270996 L0.527101 0.270996\",\n \"6\": \"M0.428549 0.257813 L0.341433 0.285053 L0.26073 0.312099 L0.192188 0.360182 L0.138902 0.410969 L0.098219 0.500422 L0.070249 0.584267 L0.067264 0.670716 L0.065164 0.756863 L0.087163 0.820973 L0.108168 0.861042 L0.157916 0.913131 L0.210981 0.948192 L0.29279 0.961214 L0.384548 0.956206 L0.456409 0.924151 L0.507262 0.881077 L0.5349 0.821975 L0.537111 0.771889 L0.521634 0.718798 L0.498418 0.67372 L0.463042 0.636657 L0.414398 0.613617 L0.34696 0.598591 L0.28284 0.595587 L0.215403 0.605604 L0.145756 0.641665 L0.109274 0.678729 L0.064942 0.724006\",\n \"7\": \"M0.071534 0.270996 L0.530519 0.270996 L0.495935 0.291702 L0.477752 0.305407 L0.435186 0.346112 L0.412067 0.374136 L0.388565 0.40796 L0.365315 0.448098 L0.342943 0.495062 L0.322081 0.549366 L0.303364 0.611524 L0.287416 0.68205 L0.270077 0.80465 L0.26253 0.94897\",\n \"8\": \"M0.286761 0.257813 L0.210684 0.27162 L0.1414 0.305622 L0.092494 0.382125 L0.111513 0.450128 L0.16857 0.502193 L0.228345 0.539382 L0.377781 0.594635 L0.470161 0.645637 L0.52586 0.706203 L0.538087 0.792269 L0.506841 0.87621 L0.438915 0.927212 L0.339743 0.961214 L0.263666 0.959089 L0.174004 0.929337 L0.102003 0.881523 L0.063965 0.811395 L0.066682 0.741266 L0.102003 0.671139 L0.180797 0.608448 L0.259591 0.580822 L0.358762 0.548945 L0.456576 0.49688 L0.486463 0.446941 L0.487822 0.362999 L0.453859 0.302434 L0.384574 0.265245 L0.286761 0.257813\",\n \"9\": \"M0.511026 0.437812 L0.491026 0.347812 L0.451026 0.297812 L0.391026 0.267812 L0.311026 0.257813 L0.231026 0.267812 L0.161026 0.297812 L0.111026 0.347812 L0.091026 0.417812 L0.111026 0.487812 L0.161026 0.537812 L0.231026 0.567812 L0.311026 0.577812 L0.391026 0.557812 L0.451026 0.517812 L0.491026 0.477812 L0.511026 0.437812 M0.510026 0.438812 L0.434026 0.636812 L0.381026 0.777812 L0.337026 0.879812 L0.301026 0.957812\",\n \"!\": \"M0.301026 0.270996 L0.301026 0.749566 M0.251466 0.94897 L0.350587 0.94897\",\n '\"': \"M0.16504 0.270996 L0.16504 0.523022 M0.437013 0.270996 L0.437013 0.523022\",\n \"#\": \"M0.20958 0.282227 L0.146515 0.949754 M0.461844 0.282227 L0.398779 0.949754 M0.032999 0.526969 L0.600587 0.452796 M0.001465 0.82366 L0.569055 0.749486\",\n $: \"M0.307121 0.240234 L0.307121 1.083502 M0.490031 0.415915 L0.404676 0.328075 L0.23396 0.310507 L0.136407 0.398347 L0.099828 0.521324 L0.124213 0.591596 L0.197379 0.644299 L0.429061 0.697003 L0.502224 0.749708 L0.526613 0.837547 L0.477836 0.960526 L0.355897 1.013228 L0.197379 0.99566 L0.112021 0.942957 L0.07544 0.837547\",\n \"'\": \"M0.301026 0.270996 L0.301026 0.523022\",\n \"(\": \"M0.413087 0.241211 L0.372337 0.28347 L0.331589 0.334184 L0.290838 0.393349 L0.25009 0.460965 L0.219528 0.528584 L0.199153 0.5962 L0.188966 0.655364 L0.199153 0.714529 L0.219528 0.782146 L0.25009 0.849764 L0.290838 0.91738 L0.331589 0.976544 L0.372337 1.027258 L0.413087 1.069491\",\n \")\": \"M0.188966 0.241211 L0.229716 0.28347 L0.270466 0.334184 L0.311213 0.393349 L0.351964 0.460965 L0.382526 0.528584 L0.4029 0.5962 L0.413087 0.655364 L0.4029 0.714529 L0.382526 0.782146 L0.351964 0.849764 L0.311213 0.91738 L0.270466 0.976544 L0.229716 1.027258 L0.188966 1.069491\",\n \"*\": \"M0.301026 0.458702 L0.301026 0.681942 M0.301026 0.458702 L0.520997 0.536834 M0.301026 0.458702 L0.439954 0.257813 M0.301026 0.458702 L0.162098 0.257813 M0.301026 0.458702 L0.081055 0.536834\",\n \"+\": \"M0.042969 0.66845 L0.559083 0.66845 M0.301023 0.428223 L0.301023 0.908661\",\n \",\": \"M0.38672 0.852051 L0.215333 1.030661 L0.301025 1.119971\",\n \"-\": \"M0.173829 0.686035 L0.428224 0.686035\",\n \".\": \"M0.362549 0.851074 L0.239503 0.851074\",\n \"/\": \"M0.062501 1.035249 L0.539551 0.270996\",\n \"<\": \"M0.559083 0.441895 L0.042969 0.66939 L0.042969 0.66939 L0.559083 0.896902\",\n \"=\": \"M0.042969 0.545898 L0.559083 0.545898 M0.042969 0.80837 L0.559083 0.80837\",\n \">\": \"M0.042969 0.441895 L0.559083 0.66939 L0.559083 0.66939 L0.042969 0.896902\",\n A: \"M0.018067 0.94897 L0.290179 0.270996 L0.583986 0.94897 M0.155303 0.684521 L0.433548 0.684521\",\n B: \"M0.063965 0.94897 L0.063965 0.278953 L0.209356 0.270996 L0.342486 0.294394 L0.432179 0.37292 L0.418224 0.48773 L0.312686 0.549166 L0.084728 0.575531 L0.306377 0.589434 L0.468877 0.647456 L0.538087 0.736658 L0.5324 0.85202 L0.501247 0.902983 L0.42355 0.944398 L0.063965 0.94897\",\n C: \"M0.529054 0.419847 L0.498425 0.345196 L0.442238 0.292341 L0.33583 0.257813 L0.257199 0.268357 L0.187906 0.303748 L0.120243 0.385432 L0.072998 0.599844 L0.110073 0.815385 L0.165381 0.902183 L0.222883 0.942801 L0.334904 0.961214 L0.43253 0.937679 L0.504816 0.868999 L0.529054 0.772065\",\n D: \"M0.064454 0.94897 L0.071838 0.285078 L0.171217 0.270996 L0.247348 0.272633 L0.37101 0.306078 L0.462461 0.378304 L0.514748 0.475555 L0.535591 0.576392 L0.537599 0.652313 L0.528065 0.717381 L0.508562 0.772419 L0.445948 0.855695 L0.362356 0.90871 L0.225203 0.945862 L0.064454 0.94897\",\n E: \"M0.080078 0.270996 L0.080078 0.94897 M0.080078 0.270996 L0.521974 0.270996 M0.080078 0.609981 L0.389405 0.609981 M0.080078 0.94897 L0.521974 0.94897\",\n F: \"M0.086426 0.270996 L0.086426 0.94897 M0.091304 0.275607 L0.515626 0.275607 M0.091304 0.607677 L0.447344 0.607677\",\n G: \"M0.498034 0.284943 L0.374621 0.257813 L0.244219 0.268648 L0.160577 0.311997 L0.094556 0.398116 L0.056397 0.58404 L0.076752 0.785532 L0.120865 0.858197 L0.188947 0.916734 L0.271008 0.953591 L0.357069 0.961214 L0.43715 0.932047 L0.501262 0.858539 L0.545656 0.648611 L0.329595 0.648131\",\n H: \"M0.066895 0.270996 L0.066895 0.94897 M0.066895 0.595658 L0.530009 0.595658 M0.535157 0.270996 L0.535157 0.94897\",\n I: \"M0.301026 0.270996 L0.301026 0.94897\",\n J: \"M0.506839 0.270996 L0.507814 0.782193 L0.498468 0.846168 L0.480733 0.880789 L0.455864 0.90832 L0.426095 0.929408 L0.360746 0.954812 L0.302508 0.962139 L0.223573 0.953638 L0.16538 0.930312 L0.137072 0.907715 L0.116428 0.880312 L0.102822 0.848819 L0.095633 0.813947 L0.094239 0.776413\",\n K: \"M0.035401 0.270996 L0.035401 0.94897 M0.502258 0.316194 L0.035401 0.687823 M0.212484 0.582361 L0.566652 0.933903\",\n L: \"M0.07544 0.270996 L0.07544 0.94897 L0.526613 0.94897\",\n M: \"M0.042481 0.94897 L0.042481 0.270996 L0.301027 0.712492 L0.559571 0.270996 L0.559571 0.94897\",\n N: \"M0.067871 0.94897 L0.067871 0.270996 L0.534181 0.94897 L0.525031 0.270996\",\n O: \"M0.287293 0.961214 L0.19843 0.933567 L0.1172 0.849451 L0.057129 0.563945 L0.114348 0.350255 L0.18455 0.289392 L0.306101 0.257813 L0.42054 0.29572 L0.487543 0.365003 L0.544923 0.625294 L0.516366 0.789624 L0.465476 0.884596 L0.375084 0.949287 L0.287293 0.961214\",\n P: \"M0.070557 0.94897 L0.070557 0.28379 L0.20704 0.270996 L0.329134 0.278993 L0.408525 0.300514 L0.444022 0.317908 L0.500637 0.368929 L0.525796 0.423728 L0.531496 0.50384 L0.508934 0.554205 L0.473724 0.582043 L0.417577 0.604365 L0.336375 0.620372 L0.226014 0.629268 L0.082368 0.630258\",\n Q: \"M0.282435 1.050813 L0.195447 1.019646 L0.115933 0.924817 L0.057129 0.602943 L0.113139 0.362034 L0.18186 0.293418 L0.300844 0.257813 L0.412868 0.300553 L0.478457 0.37866 L0.534625 0.672103 L0.506671 0.857367 L0.456855 0.964437 L0.368371 1.037368 L0.282435 1.050813 M0.341225 0.815559 L0.544923 1.070653\",\n R: \"M0.034912 0.944112 L0.034912 0.288556 L0.227127 0.270996 L0.362038 0.276867 L0.443423 0.294907 L0.477644 0.309614 L0.505809 0.328757 L0.526616 0.352817 L0.544963 0.418061 L0.543241 0.475921 L0.524463 0.517817 L0.49076 0.546518 L0.444265 0.564799 L0.355195 0.578739 L0.047653 0.589627 M0.303054 0.617306 L0.56714 0.94897\",\n S: \"M0.483037 0.364333 L0.407613 0.267477 L0.22883 0.257813 L0.128623 0.327565 L0.087712 0.455539 L0.104656 0.518727 L0.168054 0.573307 L0.41928 0.617318 L0.503796 0.669342 L0.535157 0.759324 L0.493846 0.900055 L0.367668 0.961214 L0.205436 0.956661 L0.116711 0.907038 L0.066895 0.790334\",\n T: \"M0.022949 0.270996 L0.579103 0.270996 M0.309284 0.270996 L0.309284 0.94897\",\n U: \"M0.072022 0.270996 L0.07308 0.648875 L0.080372 0.75167 L0.099024 0.827813 L0.134786 0.885729 L0.181571 0.924023 L0.251464 0.95168 L0.339655 0.962139 L0.401553 0.951668 L0.45232 0.924086 L0.482701 0.891771 L0.495745 0.870529 L0.515699 0.81637 L0.525014 0.744626 L0.530031 0.272017\",\n V: \"M0.027832 0.270996 L0.320083 0.94897 L0.57422 0.270996\",\n W: \"M0 0.270996 L0.079799 0.940377 L0.285198 0.472884 L0.505255 0.94897 L0.602052 0.270996\",\n X: \"M0.009034 0.270996 L0.586805 0.94897 M0.593019 0.270996 L0.015246 0.94897\",\n Y: \"M0.018067 0.270996 L0.293132 0.574135 M0.583986 0.271959 L0.294954 0.57606 L0.305277 0.94897\",\n Z: \"M0.053711 0.270996 L0.548341 0.270996 L0.053711 0.94897 L0.548341 0.94897\",\n \"[\": \"M0.404542 0.240234 L0.197511 0.240234 L0.197511 1.069424 L0.404542 1.069424\",\n \"\\\\\": \"M0.062501 0.270996 L0.539551 1.035249\",\n \"]\": \"M0.19751 0.240234 L0.404542 0.240234 L0.404542 1.069424 L0.19751 1.069424\",\n \"^\": \"M0.035156 0.523931 L0.301024 0.270996 L0.566896 0.523931\",\n _: \"M0 1.160601 L0.602052 1.160601\",\n a: \"M0.527101 0.439941 L0.527101 0.973965 M0.527101 0.553824 L0.451366 0.477535 L0.376759 0.439941 L0.263722 0.439941 L0.187989 0.477535 L0.112255 0.553824 L0.074951 0.66881 L0.074951 0.745099 L0.112255 0.85898 L0.187989 0.93527 L0.263722 0.973965 L0.376759 0.973965 L0.451366 0.93527 L0.527101 0.85898\",\n b: \"M0.07666 0.240234 L0.07666 0.959985 M0.07666 0.582737 L0.151822 0.514237 L0.225865 0.480483 L0.338045 0.480483 L0.413211 0.514237 L0.488374 0.582737 L0.525392 0.685983 L0.525392 0.754485 L0.488374 0.856739 L0.413211 0.92524 L0.338045 0.959985 L0.225865 0.959985 L0.151822 0.92524 L0.07666 0.856739\",\n c: \"M0.512452 0.553823 L0.441624 0.477535 L0.371854 0.439941 L0.26614 0.439941 L0.195312 0.477535 L0.124486 0.553823 L0.0896 0.668808 L0.0896 0.745099 L0.124486 0.858979 L0.195312 0.93527 L0.26614 0.973965 L0.371854 0.973965 L0.441624 0.93527 L0.512452 0.858979\",\n d: \"M0.525392 0.240234 L0.525392 0.959985 M0.525392 0.582737 L0.450232 0.514237 L0.376189 0.480483 L0.264006 0.480483 L0.188844 0.514237 L0.11368 0.582737 L0.076661 0.685983 L0.076661 0.754485 L0.11368 0.856739 L0.188844 0.92524 L0.264006 0.959985 L0.376189 0.959985 L0.450232 0.92524 L0.525392 0.856739\",\n e: \"M0.059571 0.668808 L0.542482 0.668808 M0.542482 0.592521 L0.502641 0.516231 L0.461594 0.477535 L0.381914 0.439941 L0.261186 0.439941 L0.180299 0.477535 L0.099412 0.553823 L0.059571 0.668808 L0.059571 0.745099 L0.099412 0.858979 L0.180299 0.93527 L0.261186 0.973965 L0.381914 0.973965 L0.461594 0.93527 L0.542482 0.858979\",\n f: \"M0.512941 0.240234 L0.406984 0.240234 L0.301026 0.274346 L0.248047 0.374731 L0.248047 0.946817 M0.089112 0.476088 L0.459965 0.476088\",\n g: \"M0.525392 0.439941 L0.525392 0.989395 L0.488373 1.091918 L0.45023 1.126757 L0.376189 1.160601 L0.264004 1.160601 L0.188844 1.126757 L0.113681 1.058075 L0.076661 0.954555 M0.525392 0.542467 L0.45023 0.473786 L0.376189 0.439941 L0.264004 0.439941 L0.188844 0.473786 L0.113681 0.542467 L0.076661 0.645988 L0.076661 0.714669 L0.113681 0.817193 L0.188844 0.885875 L0.264004 0.920713 L0.376189 0.920713 L0.45023 0.885875 L0.525392 0.817193\",\n h: \"M0.092041 0.240234 L0.092041 0.946817 M0.092041 0.61058 L0.205937 0.509225 L0.282214 0.476086 L0.396109 0.476086 L0.47187 0.509225 L0.510011 0.61058 L0.510011 0.946817\",\n i: \"M0.261026 0.240234 L0.341026 0.240234 M0.300978 0.476089 L0.300978 0.946817\",\n j: \"M0.3853 0.240234 L0.447023 0.240234 M0.416159 0.465708 L0.416159 1.011689 L0.383887 1.108586 L0.252832 1.140264 L0.15503 1.108586\",\n k: \"M0.065186 0.240234 L0.065186 0.946817 M0.493824 0.476086 L0.065186 0.812323 M0.236758 0.677829 L0.536867 0.946817\",\n l: \"M0.301026 0.234863 L0.301026 0.946441\",\n m: \"M0.050538 0.439941 L0.050538 0.960796 M0.050538 0.588758 L0.114405 0.476607 L0.157178 0.439941 L0.236864 0.439941 L0.279637 0.476607 L0.32241 0.588758 L0.32241 0.960796 M0.32241 0.588758 L0.386281 0.476607 L0.428467 0.439941 L0.50874 0.439941 L0.551515 0.476607 L0.551515 0.960796\",\n n: \"M0.092041 0.439941 L0.092041 0.960796 M0.092041 0.588758 L0.205936 0.476607 L0.282216 0.439941 L0.396113 0.439941 L0.471871 0.476607 L0.510011 0.588758 L0.510011 0.960796\",\n o: \"M0.247175 0.439941 L0.175178 0.477535 L0.103186 0.553823 L0.066895 0.668808 L0.066895 0.745099 L0.103186 0.858979 L0.175178 0.93527 L0.247175 0.973965 L0.354874 0.973965 L0.426872 0.93527 L0.498866 0.858979 L0.535157 0.745099 L0.535157 0.668808 L0.498866 0.553823 L0.426872 0.477535 L0.354874 0.439941 L0.247175 0.439941\",\n p: \"M0.076904 0.439941 L0.076904 1.154244 M0.076904 0.541563 L0.151986 0.473487 L0.225944 0.439941 L0.338005 0.439941 L0.413087 0.473487 L0.488166 0.541563 L0.525148 0.644169 L0.525148 0.712246 L0.488166 0.813866 L0.413087 0.881942 L0.338005 0.916471 L0.225944 0.916471 L0.151986 0.881942 L0.076904 0.813866\",\n q: \"M0.525148 0.441895 L0.525148 1.156195 M0.525148 0.5435 L0.450067 0.47544 L0.376106 0.441895 L0.264042 0.441895 L0.188966 0.47544 L0.113885 0.5435 L0.076905 0.646108 L0.076905 0.714187 L0.113885 0.815809 L0.188966 0.883886 L0.264042 0.918418 L0.376106 0.918418 L0.450067 0.883886 L0.525148 0.815809\",\n r: \"M0.107422 0.439941 L0.107422 0.960796 M0.107422 0.663164 L0.155824 0.551014 L0.252626 0.476607 L0.349428 0.439941 L0.49463 0.439941\",\n s: \"M0.475556 0.477535 L0.400757 0.439941 L0.276092 0.439941 L0.176361 0.477535 L0.101563 0.553823 L0.101563 0.630112 L0.176361 0.668808 L0.301024 0.668808 L0.425688 0.745099 L0.50049 0.821387 L0.50049 0.897677 L0.425688 0.93527 L0.325956 0.973965 L0.201295 0.973965 L0.126496 0.93527 L0.101563 0.858979\",\n t: \"M0.246032 0.297852 L0.246032 0.826549 L0.301023 0.919323 L0.411011 0.950848 L0.520997 0.950848 M0.081055 0.515799 L0.466004 0.515799\",\n u: \"M0.092041 0.454102 L0.092041 0.826134 L0.13018 0.937211 L0.205936 0.974954 L0.319832 0.974954 L0.396113 0.937211 L0.510011 0.826134 M0.510011 0.454102 L0.510011 0.974954\",\n v: \"M0.048828 0.453125 L0.301026 0.961719 M0.553224 0.453125 L0.301026 0.961719\",\n w: \"M0 0.453125 L0.150512 0.961719 M0.301024 0.453125 L0.150512 0.961719 M0.301024 0.453125 L0.451539 0.961719 M0.602052 0.453125 L0.451539 0.961719\",\n x: \"M0.03711 0.453125 L0.564943 0.961719 M0.564943 0.453125 L0.03711 0.961719\",\n y: \"M0.084618 0.453125 L0.320232 0.921476 M0.55713 0.453125 L0.320232 0.921476 L0.242119 1.055289 L0.163369 1.122196 L0.084618 1.155166 L0.044922 1.155166\",\n z: \"M0.505373 0.452148 L0.09668 0.961651 M0.09668 0.452148 L0.505373 0.452148 M0.09668 0.961651 L0.505373 0.961651\"\n};\nvar lineAlphabet = {};\nfor (const letter in svgAlphabet) {\n lineAlphabet[letter] = [];\n const segs = svgAlphabet[letter].split(\"M\").slice(1).map(\n (seg) => seg.split(\"L\").map((pr) => pr.trim().split(\" \").map(parseFloat))\n );\n for (const seg of segs) {\n for (let i = 0; i < seg.length - 1; i++) {\n lineAlphabet[letter].push({\n x1: seg[i][0],\n y1: 1 - seg[i][1],\n x2: seg[i + 1][0],\n y2: 1 - seg[i + 1][1]\n });\n }\n }\n}\nvar strokeWidthRatio = 0.09;\nvar glyphWidthRatio = 0.692052;\nvar spaceWidthRatio = 0.692052;\nvar lineHeightRatio = 1.152;\nvar letterSpacingRatio = 0;\nvar glyphLineAlphabet = lineAlphabet;\nvar glyphAdvanceRatio = {\n \"0\": 0.692052,\n \"1\": 0.692052,\n \"2\": 0.692052,\n \"3\": 0.692052,\n \"4\": 0.692052,\n \"5\": 0.692052,\n \"6\": 0.692052,\n \"7\": 0.692052,\n \"8\": 0.692052,\n \"9\": 0.692052,\n \"!\": 0.692052,\n '\"': 0.692052,\n \"#\": 0.692052,\n $: 0.692052,\n \"'\": 0.692052,\n \"(\": 0.692052,\n \")\": 0.692052,\n \"*\": 0.692052,\n \"+\": 0.692052,\n \",\": 0.692052,\n \"-\": 0.692052,\n \".\": 0.692052,\n \"/\": 0.692052,\n \"<\": 0.692052,\n \"=\": 0.692052,\n \">\": 0.692052,\n A: 0.692052,\n B: 0.692052,\n C: 0.692052,\n D: 0.692052,\n E: 0.692052,\n F: 0.692052,\n G: 0.692052,\n H: 0.692052,\n I: 0.692052,\n J: 0.692052,\n K: 0.692052,\n L: 0.692052,\n M: 0.692052,\n N: 0.692052,\n O: 0.692052,\n P: 0.692052,\n Q: 0.692052,\n R: 0.692052,\n S: 0.692052,\n T: 0.692052,\n U: 0.692052,\n V: 0.692052,\n W: 0.692052,\n X: 0.692052,\n Y: 0.692052,\n Z: 0.692052,\n \"[\": 0.692052,\n \"\\\\\": 0.692052,\n \"]\": 0.692052,\n \"^\": 0.692052,\n _: 0.692052,\n a: 0.692052,\n b: 0.692052,\n c: 0.692052,\n d: 0.692052,\n e: 0.692052,\n f: 0.692052,\n g: 0.692052,\n h: 0.692052,\n i: 0.692052,\n j: 0.692052,\n k: 0.692052,\n l: 0.692052,\n m: 0.692052,\n n: 0.692052,\n o: 0.692052,\n p: 0.692052,\n q: 0.692052,\n r: 0.692052,\n s: 0.692052,\n t: 0.692052,\n u: 0.692052,\n v: 0.692052,\n w: 0.692052,\n x: 0.692052,\n y: 0.692052,\n z: 0.692052,\n \" \": 0.692052\n};\nvar kerningRatio = {};\nvar textMetrics = {\n glyphWidthRatio,\n spaceWidthRatio,\n lineHeightRatio,\n strokeWidthRatio,\n letterSpacingRatio\n};\nexport {\n glyphAdvanceRatio,\n glyphLineAlphabet,\n glyphWidthRatio,\n kerningRatio,\n letterSpacingRatio,\n lineAlphabet,\n lineHeightRatio,\n spaceWidthRatio,\n strokeWidthRatio,\n svgAlphabet,\n textMetrics\n};\n","/**\n * Decode bytes to text\n * @param bytes - Bytes to decode\n * @param encoding - Text encoding\n * @returns The decoded text\n */\nexport function decode(bytes: Uint8Array, encoding = 'utf8'): string {\n const decoder = new TextDecoder(encoding);\n return decoder.decode(bytes);\n}\n\nconst encoder = new TextEncoder();\n\n/**\n * Encode text to utf8\n * @param str - Text to encode\n * @returns The encoded bytes\n */\nexport function encode(str: string): Uint8Array {\n return encoder.encode(str);\n}\n","import { decode, encode } from './text.ts';\n\nconst defaultByteLength = 1024 * 8;\n\nconst hostBigEndian = (() => {\n const array = new Uint8Array(4);\n const view = new Uint32Array(array.buffer);\n return !((view[0] = 1) & (array[0] as number));\n})();\n\nexport type InputData = number | ArrayBufferLike | ArrayBufferView | IOBuffer;\n\nconst typedArrays = {\n int8: globalThis.Int8Array,\n uint8: globalThis.Uint8Array,\n int16: globalThis.Int16Array,\n uint16: globalThis.Uint16Array,\n int32: globalThis.Int32Array,\n uint32: globalThis.Uint32Array,\n uint64: globalThis.BigUint64Array,\n int64: globalThis.BigInt64Array,\n float32: globalThis.Float32Array,\n float64: globalThis.Float64Array,\n};\n\ntype TypedArrays = typeof typedArrays;\n\nexport interface IOBufferOptions {\n /**\n * Ignore the first n bytes of the ArrayBuffer.\n */\n offset?: number;\n}\n\nexport class IOBuffer {\n /**\n * Reference to the internal ArrayBuffer object.\n */\n public buffer: ArrayBufferLike;\n\n /**\n * Byte length of the internal ArrayBuffer.\n */\n public byteLength: number;\n\n /**\n * Byte offset of the internal ArrayBuffer.\n */\n public byteOffset: number;\n\n /**\n * Byte length of the internal ArrayBuffer.\n */\n public length: number;\n\n /**\n * The current offset of the buffer's pointer.\n */\n public offset: number;\n\n private lastWrittenByte: number;\n private littleEndian: boolean;\n\n private _data: DataView;\n private _mark: number;\n private _marks: number[];\n\n /**\n * Create a new IOBuffer.\n * @param data - The data to construct the IOBuffer with.\n * If data is a number, it will be the new buffer's length<br>\n * If data is `undefined`, the buffer will be initialized with a default length of 8Kb<br>\n * If data is an ArrayBuffer, SharedArrayBuffer, an ArrayBufferView (Typed Array), an IOBuffer instance,\n * or a Node.js Buffer, a view will be created over the underlying ArrayBuffer.\n * @param options - An object for the options.\n * @returns A new IOBuffer instance.\n */\n public constructor(\n data: InputData = defaultByteLength,\n options: IOBufferOptions = {},\n ) {\n let dataIsGiven = false;\n if (typeof data === 'number') {\n data = new ArrayBuffer(data);\n } else {\n dataIsGiven = true;\n this.lastWrittenByte = data.byteLength;\n }\n const offset = options.offset ? options.offset >>> 0 : 0;\n const byteLength = data.byteLength - offset;\n let dvOffset = offset;\n if (ArrayBuffer.isView(data) || data instanceof IOBuffer) {\n if (data.byteLength !== data.buffer.byteLength) {\n dvOffset = data.byteOffset + offset;\n }\n data = data.buffer;\n }\n if (dataIsGiven) {\n this.lastWrittenByte = byteLength;\n } else {\n this.lastWrittenByte = 0;\n }\n this.buffer = data;\n this.length = byteLength;\n this.byteLength = byteLength;\n this.byteOffset = dvOffset;\n this.offset = 0;\n this.littleEndian = true;\n this._data = new DataView(this.buffer, dvOffset, byteLength);\n this._mark = 0;\n this._marks = [];\n }\n\n /**\n * Checks if the memory allocated to the buffer is sufficient to store more\n * bytes after the offset.\n * @param byteLength - The needed memory in bytes.\n * @returns `true` if there is sufficient space and `false` otherwise.\n */\n public available(byteLength = 1): boolean {\n return this.offset + byteLength <= this.length;\n }\n\n /**\n * Check if little-endian mode is used for reading and writing multi-byte\n * values.\n * @returns `true` if little-endian mode is used, `false` otherwise.\n */\n public isLittleEndian(): boolean {\n return this.littleEndian;\n }\n\n /**\n * Set little-endian mode for reading and writing multi-byte values.\n * @returns This.\n */\n public setLittleEndian(): this {\n this.littleEndian = true;\n return this;\n }\n\n /**\n * Check if big-endian mode is used for reading and writing multi-byte values.\n * @returns `true` if big-endian mode is used, `false` otherwise.\n */\n public isBigEndian(): boolean {\n return !this.littleEndian;\n }\n\n /**\n * Switches to big-endian mode for reading and writing multi-byte values.\n * @returns This.\n */\n public setBigEndian(): this {\n this.littleEndian = false;\n return this;\n }\n\n /**\n * Move the pointer n bytes forward.\n * @param n - Number of bytes to skip.\n * @returns This.\n */\n public skip(n = 1): this {\n this.offset += n;\n return this;\n }\n\n /**\n * Move the pointer n bytes backward.\n * @param n - Number of bytes to move back.\n * @returns This.\n */\n public back(n = 1): this {\n this.offset -= n;\n return this;\n }\n\n /**\n * Move the pointer to the given offset.\n * @param offset - The offset to move to.\n * @returns This.\n */\n public seek(offset: number): this {\n this.offset = offset;\n return this;\n }\n\n /**\n * Store the current pointer offset.\n * @see {@link IOBuffer#reset}\n * @returns This.\n */\n public mark(): this {\n this._mark = this.offset;\n return this;\n }\n\n /**\n * Move the pointer back to the last pointer offset set by mark.\n * @see {@link IOBuffer#mark}\n * @returns This.\n */\n public reset(): this {\n this.offset = this._mark;\n return this;\n }\n\n /**\n * Push the current pointer offset to the mark stack.\n * @see {@link IOBuffer#popMark}\n * @returns This.\n */\n public pushMark(): this {\n this._marks.push(this.offset);\n return this;\n }\n\n /**\n * Pop the last pointer offset from the mark stack, and set the current\n * pointer offset to the popped value.\n * @see {@link IOBuffer#pushMark}\n * @returns This.\n */\n public popMark(): this {\n const offset = this._marks.pop();\n if (offset === undefined) {\n throw new Error('Mark stack empty');\n }\n this.seek(offset);\n return this;\n }\n\n /**\n * Move the pointer offset back to 0.\n * @returns This.\n */\n public rewind(): this {\n this.offset = 0;\n return this;\n }\n\n /**\n * Make sure the buffer has sufficient memory to write a given byteLength at\n * the current pointer offset.\n * If the buffer's memory is insufficient, this method will create a new\n * buffer (a copy) with a length that is twice (byteLength + current offset).\n * @param byteLength - The needed memory in bytes.\n * @returns This.\n */\n public ensureAvailable(byteLength = 1): this {\n if (!this.available(byteLength)) {\n const lengthNeeded = this.offset + byteLength;\n const newLength = lengthNeeded * 2;\n const newArray = new Uint8Array(newLength);\n newArray.set(new Uint8Array(this.buffer));\n this.buffer = newArray.buffer;\n this.length = newLength;\n this.byteLength = newLength;\n this._data = new DataView(this.buffer);\n }\n return this;\n }\n\n /**\n * Read a byte and return false if the byte's value is 0, or true otherwise.\n * Moves pointer forward by one byte.\n * @returns The read boolean.\n */\n public readBoolean(): boolean {\n return this.readUint8() !== 0;\n }\n\n /**\n * Read a signed 8-bit integer and move pointer forward by 1 byte.\n * @returns The read byte.\n */\n public readInt8(): number {\n return this._data.getInt8(this.offset++);\n }\n\n /**\n * Read an unsigned 8-bit integer and move pointer forward by 1 byte.\n * @returns The read byte.\n */\n public readUint8(): number {\n return this._data.getUint8(this.offset++);\n }\n\n /**\n * Alias for {@link IOBuffer#readUint8}.\n * @returns The read byte.\n */\n public readByte(): number {\n return this.readUint8();\n }\n\n /**\n * Read `n` bytes and move pointer forward by `n` bytes.\n * @param n - Number of bytes to read.\n * @returns The read bytes.\n */\n public readBytes(n = 1): Uint8Array {\n return this.readArray(n, 'uint8');\n }\n\n /**\n * Creates an array of corresponding to the type `type` and size `size`.\n * For example, type `uint8` will create a `Uint8Array`.\n * @param size - size of the resulting array\n * @param type - number type of elements to read\n * @returns The read array.\n */\n public readArray<T extends keyof typeof typedArrays>(\n size: number,\n type: T,\n ): InstanceType<TypedArrays[T]> {\n const bytes = typedArrays[type].BYTES_PER_ELEMENT * size;\n const offset = this.byteOffset + this.offset;\n const slice = this.buffer.slice(offset, offset + bytes);\n if (\n this.littleEndian === hostBigEndian &&\n type !== 'uint8' &&\n type !== 'int8'\n ) {\n const slice = new Uint8Array(this.buffer.slice(offset, offset + bytes));\n slice.reverse();\n const returnArray = new typedArrays[type](slice.buffer as ArrayBuffer);\n this.offset += bytes;\n returnArray.reverse();\n return returnArray as InstanceType<TypedArrays[T]>;\n }\n const returnArray = new typedArrays[type](slice as ArrayBuffer);\n this.offset += bytes;\n return returnArray as InstanceType<TypedArrays[T]>;\n }\n\n /**\n * Read a 16-bit signed integer and move pointer forward by 2 bytes.\n * @returns The read value.\n */\n public readInt16(): number {\n const value = this._data.getInt16(this.offset, this.littleEndian);\n this.offset += 2;\n return value;\n }\n\n /**\n * Read a 16-bit unsigned integer and move pointer forward by 2 bytes.\n * @returns The read value.\n */\n public readUint16(): number {\n const value = this._data.getUint16(this.offset, this.littleEndian);\n this.offset += 2;\n return value;\n }\n\n /**\n * Read a 32-bit signed integer and move pointer forward by 4 bytes.\n * @returns The read value.\n */\n public readInt32(): number {\n const value = this._data.getInt32(this.offset, this.littleEndian);\n this.offset += 4;\n return value;\n }\n\n /**\n * Read a 32-bit unsigned integer and move pointer forward by 4 bytes.\n * @returns The read value.\n */\n public readUint32(): number {\n const value = this._data.getUint32(this.offset, this.littleEndian);\n this.offset += 4;\n return value;\n }\n\n /**\n * Read a 32-bit floating number and move pointer forward by 4 bytes.\n * @returns The read value.\n */\n public readFloat32(): number {\n const value = this._data.getFloat32(this.offset, this.littleEndian);\n this.offset += 4;\n return value;\n }\n\n /**\n * Read a 64-bit floating number and move pointer forward by 8 bytes.\n * @returns The read value.\n */\n public readFloat64(): number {\n const value = this._data.getFloat64(this.offset, this.littleEndian);\n this.offset += 8;\n return value;\n }\n\n /**\n * Read a 64-bit signed integer number and move pointer forward by 8 bytes.\n * @returns The read value.\n */\n public readBigInt64(): bigint {\n const value = this._data.getBigInt64(this.offset, this.littleEndian);\n this.offset += 8;\n return value;\n }\n\n /**\n * Read a 64-bit unsigned integer number and move pointer forward by 8 bytes.\n * @returns The read value.\n */\n public readBigUint64(): bigint {\n const value = this._data.getBigUint64(this.offset, this.littleEndian);\n this.offset += 8;\n return value;\n }\n\n /**\n * Read a 1-byte ASCII character and move pointer forward by 1 byte.\n * @returns The read character.\n */\n public readChar(): string {\n // eslint-disable-next-line unicorn/prefer-code-point\n return String.fromCharCode(this.readInt8());\n }\n\n /**\n * Read `n` 1-byte ASCII characters and move pointer forward by `n` bytes.\n * @param n - Number of characters to read.\n * @returns The read characters.\n */\n public readChars(n = 1): string {\n let result = '';\n for (let i = 0; i < n; i++) {\n result += this.readChar();\n }\n return result;\n }\n\n /**\n * Read the next `n` bytes, return a UTF-8 decoded string and move pointer\n * forward by `n` bytes.\n * @param n - Number of bytes to read.\n * @returns The decoded string.\n */\n public readUtf8(n = 1): string {\n return decode(this.readBytes(n));\n }\n\n /**\n * Read the next `n` bytes, return a string decoded with `encoding` and move pointer\n * forward by `n` bytes.\n * If no encoding is passed, the function is equivalent to @see {@link IOBuffer#readUtf8}\n * @param n - Number of bytes to read.\n * @param encoding - The encoding to use. Default is 'utf8'.\n * @returns The decoded string.\n */\n public decodeText(n = 1, encoding = 'utf8'): string {\n return decode(this.readBytes(n), encoding);\n }\n\n /**\n * Write 0xff if the passed value is truthy, 0x00 otherwise and move pointer\n * forward by 1 byte.\n * @param value - The value to write.\n * @returns This.\n */\n public writeBoolean(value: unknown): this {\n this.writeUint8(value ? 0xff : 0x00);\n return this;\n }\n\n /**\n * Write `value` as an 8-bit signed integer and move pointer forward by 1 byte.\n * @param value - The value to write.\n * @returns This.\n */\n public writeInt8(value: number): this {\n this.ensureAvailable(1);\n this._data.setInt8(this.offset++, value);\n this._updateLastWrittenByte();\n return this;\n }\n\n /**\n * Write `value` as an 8-bit unsigned integer and move pointer forward by 1\n * byte.\n * @param value - The value to write.\n * @returns This.\n */\n public writeUint8(value: number): this {\n this.ensureAvailable(1);\n this._data.setUint8(this.offset++, value);\n this._updateLastWrittenByte();\n return this;\n }\n\n /**\n * An alias for {@link IOBuffer#writeUint8}.\n * @param value - The value to write.\n * @returns This.\n */\n public writeByte(value: number): this {\n return this.writeUint8(value);\n }\n\n /**\n * Write all elements of `bytes` as uint8 values and move pointer forward by\n * `bytes.length` bytes.\n * @param bytes - The array of bytes to write.\n * @returns This.\n */\n public writeBytes(bytes: ArrayLike<number>): this {\n this.ensureAvailable(bytes.length);\n // eslint-disable-next-line @typescript-eslint/prefer-for-of\n for (let i = 0; i < bytes.length; i++) {\n this._data.setUint8(this.offset++, bytes[i] as number);\n }\n this._updateLastWrittenByte();\n return this;\n }\n\n /**\n * Write `value` as a 16-bit signed integer and move pointer forward by 2\n * bytes.\n * @param value - The value to write.\n * @returns This.\n */\n public writeInt16(value: number): this {\n this.ensureAvailable(2);\n this._data.setInt16(this.offset, value, this.littleEndian);\n this.offset += 2;\n this._updateLastWrittenByte();\n return this;\n }\n\n /**\n * Write `value` as a 16-bit unsigned integer and move pointer forward by 2\n * bytes.\n * @param value - The value to write.\n * @returns This.\n */\n public writeUint16(value: number): this {\n this.ensureAvailable(2);\n this._data.setUint16(this.offset, value, this.littleEndian);\n this.offset += 2;\n this._updateLastWrittenByte();\n return this;\n }\n\n /**\n * Write `value` as a 32-bit signed integer and move pointer forward by 4\n * bytes.\n * @param value - The value to write.\n * @returns This.\n */\n public writeInt32(value: number): this {\n this.ensureAvailable(4);\n this._data.setInt32(this.offset, value, this.littleEndian);\n this.offset += 4;\n this._updateLastWrittenByte();\n return this;\n }\n\n /**\n * Write `value` as a 32-bit unsigned integer and move pointer forward by 4\n * bytes.\n * @param value - The value to write.\n * @returns This.\n */\n public writeUint32(value: number): this {\n this.ensureAvailable(4);\n this._data.setUint32(this.offset, value, this.littleEndian);\n this.offset += 4;\n this._updateLastWrittenByte();\n return this;\n }\n\n /**\n * Write `value` as a 32-bit floating number and move pointer forward by 4\n * bytes.\n * @param value - The value to write.\n * @returns This.\n */\n public writeFloat32(value: number): this {\n this.ensureAvailable(4);\n this._data.setFloat32(this.offset, value, this.littleEndian);\n this.offset += 4;\n this._updateLastWrittenByte();\n return this;\n }\n\n /**\n * Write `value` as a 64-bit floating number and move pointer forward by 8\n * bytes.\n * @param value - The value to write.\n * @returns This.\n */\n public writeFloat64(value: number): this {\n this.ensureAvailable(8);\n this._data.setFloat64(this.offset, value, this.littleEndian);\n this.offset += 8;\n this._updateLastWrittenByte();\n return this;\n }\n\n /**\n * Write `value` as a 64-bit signed bigint and move pointer forward by 8\n * bytes.\n * @param value - The value to write.\n * @returns This.\n */\n public writeBigInt64(value: bigint): this {\n this.ensureAvailable(8);\n this._data.setBigInt64(this.offset, value, this.littleEndian);\n this.offset += 8;\n this._updateLastWrittenByte();\n return this;\n }\n\n /**\n * Write `value` as a 64-bit unsigned bigint and move pointer forward by 8\n * bytes.\n * @param value - The value to write.\n * @returns This.\n */\n public writeBigUint64(value: bigint): this {\n this.ensureAvailable(8);\n this._data.setBigUint64(this.offset, value, this.littleEndian);\n this.offset += 8;\n this._updateLastWrittenByte();\n return this;\n }\n\n /**\n * Write the charCode of `str`'s first character as an 8-bit unsigned integer\n * and move pointer forward by 1 byte.\n * @param str - The character to write.\n * @returns This.\n */\n public writeChar(str: string): this {\n // eslint-disable-next-line unicorn/prefer-code-point\n return this.writeUint8(str.charCodeAt(0));\n }\n\n /**\n * Write the charCodes of all `str`'s characters as 8-bit unsigned integers\n * and move pointer forward by `str.length` bytes.\n * @param str - The characters to write.\n * @returns This.\n */\n public writeChars(str: string): this {\n for (let i = 0; i < str.length; i++) {\n // eslint-disable-next-line unicorn/prefer-code-point\n this.writeUint8(str.charCodeAt(i));\n }\n return this;\n }\n\n /**\n * UTF-8 encode and write `str` to the current pointer offset and move pointer\n * forward according to the encoded length.\n * @param str - The string to write.\n * @returns This.\n */\n public writeUtf8(str: string): this {\n return this.writeBytes(encode(str));\n }\n\n /**\n * Export a Uint8Array view of the internal buffer.\n * The view starts at the byte offset and its length\n * is calculated to stop at the last written byte or the original length.\n * @returns A new Uint8Array view.\n */\n public toArray(): Uint8Array {\n return new Uint8Array(this.buffer, this.byteOffset, this.lastWrittenByte);\n }\n\n /**\n * Get the total number of bytes written so far, regardless of the current offset.\n * @returns - Total number of bytes.\n */\n public getWrittenByteLength() {\n return this.lastWrittenByte - this.byteOffset;\n }\n\n /**\n * Update the last written byte offset\n * @private\n */\n private _updateLastWrittenByte(): void {\n if (this.offset > this.lastWrittenByte) {\n this.lastWrittenByte = this.offset;\n }\n }\n}\n","import type { IOBuffer } from 'iobuffer';\n\nconst crcTable: number[] = [];\nfor (let n = 0; n < 256; n++) {\n let c = n;\n for (let k = 0; k < 8; k++) {\n if (c & 1) {\n c = 0xedb88320 ^ (c >>> 1);\n } else {\n c = c >>> 1;\n }\n }\n crcTable[n] = c;\n}\n\nconst initialCrc = 0xffffffff;\nfunction updateCrc(\n currentCrc: number,\n data: Uint8Array,\n length: number,\n): number {\n let c = currentCrc;\n for (let n = 0; n < length; n++) {\n c = crcTable[(c ^ data[n]) & 0xff] ^ (c >>> 8);\n }\n return c;\n}\n\nfunction crc(data: Uint8Array, length: number): number {\n return (updateCrc(initialCrc, data, length) ^ initialCrc) >>> 0;\n}\n\nexport function checkCrc(\n buffer: IOBuffer,\n crcLength: number,\n chunkName: string,\n) {\n const expectedCrc = buffer.readUint32();\n const actualCrc = crc(\n new Uint8Array(\n buffer.buffer,\n buffer.byteOffset + buffer.offset - crcLength - 4,\n crcLength,\n ),\n crcLength,\n ); // \"- 4\" because we already advanced by reading the CRC\n if (actualCrc !== expectedCrc) {\n throw new Error(\n `CRC mismatch for chunk ${chunkName}. Expected ${expectedCrc}, found ${actualCrc}`,\n );\n }\n}\n\nexport function writeCrc(buffer: IOBuffer, length: number) {\n buffer.writeUint32(\n crc(\n new Uint8Array(\n buffer.buffer,\n buffer.byteOffset + buffer.offset - length,\n length,\n ),\n length,\n ),\n );\n}\n","import { applyUnfilter } from './apply_unfilter.ts';\nimport type { DecodeInterlaceNullParams } from './decode_interlace_null.ts';\n\nconst uint16 = new Uint16Array([0x00ff]);\nconst uint8 = new Uint8Array(uint16.buffer);\nconst osIsLittleEndian = uint8[0] === 0xff;\n/**\n * Decodes the Adam7 interlaced PNG data.\n * @param params - DecodeInterlaceNullParams\n * @returns - array of pixel data.\n */\nexport function decodeInterlaceAdam7(params: DecodeInterlaceNullParams) {\n const { data, width, height, channels, depth } = params;\n\n // Adam7 interlacing pattern\n const passes = [\n { x: 0, y: 0, xStep: 8, yStep: 8 }, // Pass 1\n { x: 4, y: 0, xStep: 8, yStep: 8 }, // Pass 2\n { x: 0, y: 4, xStep: 4, yStep: 8 }, // Pass 3\n { x: 2, y: 0, xStep: 4, yStep: 4 }, // Pass 4\n { x: 0, y: 2, xStep: 2, yStep: 4 }, // Pass 5\n { x: 1, y: 0, xStep: 2, yStep: 2 }, // Pass 6\n { x: 0, y: 1, xStep: 1, yStep: 2 }, // Pass 7\n ];\n\n const bytesPerPixel = Math.ceil(depth / 8) * channels;\n const resultData = new Uint8Array(height * width * bytesPerPixel);\n\n let offset = 0;\n\n // Process each pass\n for (let passIndex = 0; passIndex < 7; passIndex++) {\n const pass = passes[passIndex];\n\n // Calculate pass dimensions\n const passWidth = Math.ceil((width - pass.x) / pass.xStep);\n const passHeight = Math.ceil((height - pass.y) / pass.yStep);\n\n if (passWidth <= 0 || passHeight <= 0) continue;\n\n const passLineBytes = passWidth * bytesPerPixel;\n const prevLine = new Uint8Array(passLineBytes);\n\n // Process each scanline in this pass\n for (let y = 0; y < passHeight; y++) {\n // First byte is the filter type\n const filterType = data[offset++];\n const currentLine = data.subarray(offset, offset + passLineBytes);\n offset += passLineBytes;\n\n // Create a new line for the unfiltered data\n const newLine = new Uint8Array(passLineBytes);\n\n // Apply the appropriate unfilter\n applyUnfilter(\n filterType,\n currentLine,\n newLine,\n prevLine,\n passLineBytes,\n bytesPerPixel,\n );\n prevLine.set(newLine);\n\n for (let x = 0; x < passWidth; x++) {\n const outputX = pass.x + x * pass.xStep;\n const outputY = pass.y + y * pass.yStep;\n if (outputX >= width || outputY >= height) continue;\n for (let i = 0; i < bytesPerPixel; i++) {\n resultData[(outputY * width + outputX) * bytesPerPixel + i] =\n newLine[x * bytesPerPixel + i];\n }\n }\n }\n }\n if (depth === 16) {\n const uint16Data = new Uint16Array(resultData.buffer);\n if (osIsLittleEndian) {\n for (let k = 0; k < uint16Data.length; k++) {\n // PNG is always big endian. Swap the bytes.\n uint16Data[k] = swap16(uint16Data[k]);\n }\n }\n return uint16Data;\n } else {\n return resultData;\n }\n}\n\nfunction swap16(val: number): number {\n return ((val & 0xff) << 8) | ((val >> 8) & 0xff);\n}\n","import type { PngDataArray } from '../types.ts';\n\nimport {\n unfilterAverage,\n unfilterNone,\n unfilterPaeth,\n unfilterSub,\n unfilterUp,\n} from './unfilter.ts';\n\nconst uint16 = new Uint16Array([0x00ff]);\nconst uint8 = new Uint8Array(uint16.buffer);\nconst osIsLittleEndian = uint8[0] === 0xff;\n\nconst empty = new Uint8Array(0);\n\nexport interface DecodeInterlaceNullParams {\n data: Uint8Array;\n width: number;\n height: number;\n channels: number;\n depth: number;\n}\n\nexport function decodeInterlaceNull(\n params: DecodeInterlaceNullParams,\n): PngDataArray {\n const { data, width, height, channels, depth } = params;\n\n const bytesPerPixel = Math.ceil(depth / 8) * channels;\n\n const bytesPerLine = Math.ceil((depth / 8) * channels * width);\n const newData = new Uint8Array(height * bytesPerLine);\n\n let prevLine = empty;\n let offset = 0;\n let currentLine;\n let newLine;\n\n for (let i = 0; i < height; i++) {\n currentLine = data.subarray(offset + 1, offset + 1 + bytesPerLine);\n newLine = newData.subarray(i * bytesPerLine, (i + 1) * bytesPerLine);\n switch (data[offset]) {\n case 0:\n unfilterNone(currentLine, newLine, bytesPerLine);\n break;\n case 1:\n unfilterSub(currentLine, newLine, bytesPerLine, bytesPerPixel);\n break;\n case 2:\n unfilterUp(currentLine, newLine, prevLine, bytesPerLine);\n break;\n case 3:\n unfilterAverage(\n currentLine,\n newLine,\n prevLine,\n bytesPerLine,\n bytesPerPixel,\n );\n break;\n case 4:\n unfilterPaeth(\n currentLine,\n newLine,\n prevLine,\n bytesPerLine,\n bytesPerPixel,\n );\n break;\n default:\n throw new Error(`Unsupported filter: ${data[offset]}`);\n }\n prevLine = newLine;\n offset += bytesPerLine + 1;\n }\n\n if (depth === 16) {\n const uint16Data = new Uint16Array(newData.buffer);\n if (osIsLittleEndian) {\n for (let k = 0; k < uint16Data.length; k++) {\n // PNG is always big endian. Swap the bytes.\n uint16Data[k] = swap16(uint16Data[k]);\n }\n }\n return uint16Data;\n } else {\n return newData;\n }\n}\n\nfunction swap16(val: number): number {\n return ((val & 0xff) << 8) | ((val >> 8) & 0xff);\n}\n","import type { IOBuffer } from 'iobuffer';\n\n// https://www.w3.org/TR/PNG/#5PNG-file-signature\n\nconst pngSignature = Uint8Array.of(137, 80, 78, 71, 13, 10, 26, 10);\n\nexport function writeSignature(buffer: IOBuffer) {\n buffer.writeBytes(pngSignature);\n}\n\nexport function checkSignature(buffer: IOBuffer) {\n if (!hasPngSignature(buffer.readBytes(pngSignature.length))) {\n throw new Error('wrong PNG signature');\n }\n}\n\nexport function hasPngSignature(array: ArrayLike<number>) {\n if (array.length < pngSignature.length) {\n return false;\n }\n for (let i = 0; i < pngSignature.length; i++) {\n if (array[i] !== pngSignature[i]) {\n return false;\n }\n }\n return true;\n}\n","import type { IOBuffer } from 'iobuffer';\n\nimport { writeCrc } from './crc.ts';\n\n// https://www.w3.org/TR/png/#11tEXt\n\nexport const textChunkName = 'tEXt';\n\nconst NULL = 0;\n\nconst latin1Decoder = new TextDecoder('latin1');\n\nfunction validateKeyword(keyword: string) {\n validateLatin1(keyword);\n if (keyword.length === 0 || keyword.length > 79) {\n throw new Error('keyword length must be between 1 and 79');\n }\n}\n\n// eslint-disable-next-line no-control-regex\nconst latin1Regex = /^[\\u0000-\\u00FF]*$/;\nfunction validateLatin1(text: string) {\n if (!latin1Regex.test(text)) {\n throw new Error('invalid latin1 text');\n }\n}\n\nexport function decodetEXt(\n text: Record<string, string>,\n buffer: IOBuffer,\n length: number,\n) {\n const keyword = readKeyword(buffer);\n text[keyword] = readLatin1(buffer, length - keyword.length - 1);\n}\n\nexport function encodetEXt(buffer: IOBuffer, keyword: string, text: string) {\n validateKeyword(keyword);\n validateLatin1(text);\n const length = keyword.length + 1 /* NULL */ + text.length;\n\n buffer.writeUint32(length);\n buffer.writeChars(textChunkName);\n buffer.writeChars(keyword);\n buffer.writeByte(NULL);\n buffer.writeChars(text);\n writeCrc(buffer, length + 4);\n}\n\n// https://www.w3.org/TR/png/#11keywords\nexport function readKeyword(buffer: IOBuffer): string {\n buffer.mark();\n while (buffer.readByte() !== NULL) {\n /* advance */\n }\n const end = buffer.offset;\n buffer.reset();\n const keyword = latin1Decoder.decode(\n buffer.readBytes(end - buffer.offset - 1),\n );\n // NULL\n buffer.skip(1);\n\n validateKeyword(keyword);\n\n return keyword;\n}\n\nexport function readLatin1(buffer: IOBuffer, length: number): string {\n return latin1Decoder.decode(buffer.readBytes(length));\n}\n","import { isUndefined } from './utils'\nimport { translate } from './translate'\nimport { transform } from './transform'\n\nconst { cos, sin, PI } = Math\n/**\n * Calculate a rotation matrix\n * @param angle {number} Angle in radians\n * @param [cx] {number} If (cx,cy) are supplied the rotate is about this point\n * @param [cy] {number} If (cx,cy) are supplied the rotate is about this point\n * @returns {Matrix} Affine Matrix\n */\nexport function rotate (angle, cx, cy) {\n const cosAngle = cos(angle)\n const sinAngle = sin(angle)\n const rotationMatrix = {\n a: cosAngle,\n c: -sinAngle,\n e: 0,\n b: sinAngle,\n d: cosAngle,\n f: 0\n }\n if (isUndefined(cx) || isUndefined(cy)) {\n return rotationMatrix\n }\n\n return transform([\n translate(cx, cy),\n rotationMatrix,\n translate(-cx, -cy)\n ])\n}\n\n/**\n * Calculate a rotation matrix with a DEG angle\n * @param angle {number} Angle in degree\n * @param [cx] {number} If (cx,cy) are supplied the rotate is about this point\n * @param [cy] {number} If (cx,cy) are supplied the rotate is about this point\n * @returns {Matrix} Affine Matrix\n */\nexport function rotateDEG (angle, cx = undefined, cy = undefined) {\n return rotate(angle * PI / 180, cx, cy)\n}\n","// https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/skew\nconst { tan } = Math\n\n/**\n * Calculate a skew matrix\n * @param ax {number} Skew on axis x\n * @param ay {number} Skew on axis y\n * @returns {Matrix} Affine Matrix\n */\nexport function skew (ax, ay) {\n return {\n a: 1,\n c: tan(ax),\n e: 0,\n b: tan(ay),\n d: 1,\n f: 0\n }\n}\n\n/**\n * Calculate a skew matrix using DEG angles\n * @param ax {number} Skew on axis x\n * @param ay {number} Skew on axis y\n * @returns {Matrix} Affine Matrix\n */\nexport function skewDEG (ax, ay) {\n return skew(ax * Math.PI / 180, ay * Math.PI / 180)\n}\n","import rename from 'deep-rename-keys';\nimport { parseSync } from 'xml-reader';\n\nvar parseInput = function parseInput(input) {\n var parsed = parseSync(\"<root>\".concat(input, \"</root>\"), {\n parentNodes: false\n });\n var isValid = parsed.children && parsed.children.length > 0 && parsed.children.every(function (node) {\n return node.name === 'svg';\n });\n if (isValid) {\n return parsed.children.length === 1 ? parsed.children[0] : parsed.children;\n } else {\n throw Error('nothing to parse');\n }\n};\nvar camelize = function camelize(node) {\n return rename(node, function (key) {\n if (!notCamelcase(key)) {\n return toCamelCase(key);\n }\n return key;\n });\n};\nvar toCamelCase = function toCamelCase(prop) {\n return prop.replace(/[-|:]([a-z])/gi, function (all, letter) {\n return letter.toUpperCase();\n });\n};\nvar notCamelcase = function notCamelcase(prop) {\n return /^(data|aria)(-\\w+)/.test(prop);\n};\nvar escapeText = function escapeText(text) {\n if (text) {\n var str = String(text);\n return /[&<>]/.test(str) ? \"<![CDATA[\".concat(str.replace(/]]>/, ']]]]><![CDATA[>'), \"]]>\") : str;\n }\n return '';\n};\nvar escapeAttr = function escapeAttr(attr) {\n return String(attr).replace(/&/g, '&amp;').replace(/'/g, '&apos;').replace(/\"/g, '&quot;').replace(/</g, '&lt;').replace(/>/g, '&gt;');\n};\n\nvar svgsonSync = function svgsonSync(input) {\n var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n _ref$transformNode = _ref.transformNode,\n transformNode = _ref$transformNode === void 0 ? function (node) {\n return node;\n } : _ref$transformNode,\n _ref$camelcase = _ref.camelcase,\n camelcase = _ref$camelcase === void 0 ? false : _ref$camelcase;\n var applyFilters = function applyFilters(input) {\n var n;\n n = transformNode(input);\n if (camelcase) {\n n = camelize(n);\n }\n return n;\n };\n return applyFilters(parseInput(input));\n};\nfunction svgson() {\n for (var _len = arguments.length, args = new Array(_len), _key = 0; _key < _len; _key++) {\n args[_key] = arguments[_key];\n }\n return new Promise(function (resolve, reject) {\n try {\n var res = svgsonSync.apply(void 0, args);\n resolve(res);\n } catch (e) {\n reject(e);\n }\n });\n}\n\nvar stringify = function stringify(_ast) {\n var _ref = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : {},\n _ref$transformAttr = _ref.transformAttr,\n transformAttr = _ref$transformAttr === void 0 ? function (key, value, escape) {\n return \"\".concat(key, \"=\\\"\").concat(escape(value), \"\\\"\");\n } : _ref$transformAttr,\n _ref$transformNode = _ref.transformNode,\n transformNode = _ref$transformNode === void 0 ? function (node) {\n return node;\n } : _ref$transformNode,\n _ref$selfClose = _ref.selfClose,\n selfClose = _ref$selfClose === void 0 ? true : _ref$selfClose;\n if (Array.isArray(_ast)) {\n return _ast.map(function (ast) {\n return stringify(ast, {\n transformAttr: transformAttr,\n selfClose: selfClose,\n transformNode: transformNode\n });\n }).join('');\n }\n var ast = transformNode(_ast);\n if (ast.type === 'text') {\n return escapeText(ast.value);\n }\n var attributes = '';\n for (var attr in ast.attributes) {\n var attrStr = transformAttr(attr, ast.attributes[attr], escapeAttr, ast.name);\n attributes += attrStr ? \" \".concat(attrStr) : '';\n }\n return ast.children && ast.children.length > 0 || !selfClose ? \"<\".concat(ast.name).concat(attributes, \">\").concat(stringify(ast.children, {\n transformAttr: transformAttr,\n transformNode: transformNode,\n selfClose: selfClose\n }), \"</\").concat(ast.name, \">\") : \"<\".concat(ast.name).concat(attributes, \"/>\");\n};\n\nexport { svgson as default, svgson as parse, svgsonSync as parseSync, stringify };\n","import type { GraphicsObject } from \"./types\"\n\nexport function setStepOfAllObjects(\n graphics: GraphicsObject,\n step: number,\n): GraphicsObject {\n if (graphics.points) {\n for (const p of graphics.points) {\n p.step = step\n }\n }\n if (graphics.lines) {\n for (const line of graphics.lines) {\n line.step = step\n }\n }\n if (graphics.infiniteLines) {\n for (const infiniteLine of graphics.infiniteLines) {\n infiniteLine.step = step\n }\n }\n if (graphics.polygons) {\n for (const polygon of graphics.polygons) {\n polygon.step = step\n }\n }\n if (graphics.rects) {\n for (const rect of graphics.rects) {\n rect.step = step\n }\n }\n if (graphics.circles) {\n for (const circle of graphics.circles) {\n circle.step = step\n }\n }\n if (graphics.texts) {\n for (const text of graphics.texts) {\n text.step = step\n }\n }\n return graphics\n}\n","// lib/BaseSolver.ts\nvar BaseSolver = class {\n MAX_ITERATIONS = 1e5;\n solved = false;\n failed = false;\n iterations = 0;\n progress = 0;\n error = null;\n activeSubSolver;\n failedSubSolvers;\n timeToSolve;\n stats = {};\n _setupDone = false;\n getSolverName() {\n return this.constructor.name;\n }\n setup() {\n if (this._setupDone) return;\n this._setup();\n this._setupDone = true;\n }\n /** Override this method to perform setup logic */\n _setup() {\n }\n /** DO NOT OVERRIDE! Override _step() instead */\n step() {\n if (!this._setupDone) {\n this.setup();\n }\n if (this.solved) return;\n if (this.failed) return;\n this.iterations++;\n try {\n this._step();\n } catch (e) {\n this.error = `${this.getSolverName()} error: ${e}`;\n this.failed = true;\n throw e;\n }\n if (!this.solved && this.iterations >= this.MAX_ITERATIONS) {\n this.tryFinalAcceptance();\n }\n if (!this.solved && this.iterations >= this.MAX_ITERATIONS) {\n this.error = `${this.getSolverName()} ran out of iterations`;\n this.failed = true;\n }\n if (\"computeProgress\" in this) {\n this.progress = this.computeProgress();\n }\n }\n /** Override this method to implement solver logic */\n _step() {\n }\n getConstructorParams() {\n throw new Error(\"getConstructorParams not implemented\");\n }\n /**\n * Override this method to return the standardized output of the solver.\n * This method should only be called after the solver has completed successfully.\n * Returns null by default - solvers with outputs should override this method.\n */\n getOutput() {\n return null;\n }\n solve() {\n const startTime = Date.now();\n while (!this.solved && !this.failed) {\n this.step();\n }\n const endTime = Date.now();\n this.timeToSolve = endTime - startTime;\n }\n visualize() {\n return {\n lines: [],\n points: [],\n rects: [],\n circles: []\n };\n }\n /**\n * Called when the solver is about to fail, but we want to see if we have an\n * \"acceptable\" or \"passable\" solution. Mostly used for optimizers that\n * have an aggressive early stopping criterion.\n */\n tryFinalAcceptance() {\n }\n /**\n * A lightweight version of the visualize method that can be used to stream\n * progress\n */\n preview() {\n return {\n lines: [],\n points: [],\n rects: [],\n circles: []\n };\n }\n};\n\n// lib/BasePipelineSolver.ts\nimport { setStepOfAllObjects } from \"graphics-debug\";\nfunction definePipelineStep(solverName, solverClass, getConstructorParams, opts = {}) {\n return {\n solverName,\n solverClass,\n getConstructorParams,\n onSolved: opts.onSolved\n };\n}\nvar BasePipelineSolver = class extends BaseSolver {\n startTimeOfStage = {};\n endTimeOfStage = {};\n timeSpentOnStage = {};\n firstIterationOfStage = {};\n currentPipelineStageIndex = 0;\n inputProblem;\n /** Stores the outputs from each completed pipeline stage */\n pipelineOutputs = {};\n constructor(inputProblem) {\n super();\n this.inputProblem = inputProblem;\n this.MAX_ITERATIONS = 1e6;\n }\n _step() {\n const pipelineStageDef = this.pipelineDef[this.currentPipelineStageIndex];\n if (!pipelineStageDef) {\n this.solved = true;\n return;\n }\n if (this.activeSubSolver) {\n this.activeSubSolver.step();\n if (this.activeSubSolver.solved) {\n this.endTimeOfStage[pipelineStageDef.solverName] = performance.now();\n this.timeSpentOnStage[pipelineStageDef.solverName] = this.endTimeOfStage[pipelineStageDef.solverName] - this.startTimeOfStage[pipelineStageDef.solverName];\n const output = this.activeSubSolver.getOutput();\n if (output !== null) {\n this.pipelineOutputs[pipelineStageDef.solverName] = output;\n }\n pipelineStageDef.onSolved?.(this);\n this.activeSubSolver = null;\n this.currentPipelineStageIndex++;\n } else if (this.activeSubSolver.failed) {\n this.error = this.activeSubSolver?.error;\n this.failed = true;\n this.activeSubSolver = null;\n }\n return;\n }\n const constructorParams = pipelineStageDef.getConstructorParams(this);\n this.activeSubSolver = new pipelineStageDef.solverClass(\n ...constructorParams\n );\n this[pipelineStageDef.solverName] = this.activeSubSolver;\n this.timeSpentOnStage[pipelineStageDef.solverName] = 0;\n this.startTimeOfStage[pipelineStageDef.solverName] = performance.now();\n this.firstIterationOfStage[pipelineStageDef.solverName] = this.iterations;\n }\n solveUntilStage(stageName) {\n while (this.getCurrentStageName().toLowerCase() !== stageName.toLowerCase()) {\n this.step();\n if (this.failed || this.solved) break;\n }\n }\n getCurrentStageName() {\n return this.pipelineDef[this.currentPipelineStageIndex]?.solverName ?? \"none\";\n }\n getStageProgress() {\n const totalStages = this.pipelineDef.length;\n if (totalStages === 0) return 1;\n const currentStageProgress = this.activeSubSolver?.progress ?? 0;\n return (this.currentPipelineStageIndex + currentStageProgress) / totalStages;\n }\n getStageStats() {\n const stats = {};\n for (const stage of this.pipelineDef) {\n const timeSpent = this.timeSpentOnStage[stage.solverName] || 0;\n const firstIteration = this.firstIterationOfStage[stage.solverName] || 0;\n const currentIteration = this.iterations;\n const iterations = stage.solverName === this.getCurrentStageName() ? currentIteration - firstIteration : 0;\n const completed = this.currentPipelineStageIndex > this.pipelineDef.findIndex((s) => s.solverName === stage.solverName);\n stats[stage.solverName] = {\n timeSpent,\n iterations,\n completed\n };\n }\n return stats;\n }\n initialVisualize() {\n return null;\n }\n finalVisualize() {\n return null;\n }\n visualize() {\n if (!this.solved && this.activeSubSolver) {\n return this.activeSubSolver.visualize();\n }\n let stageStepOffset = 0;\n const initialVisualization = this.initialVisualize();\n if (initialVisualization) {\n setStepOfAllObjects(initialVisualization, 0);\n stageStepOffset = 1;\n }\n let finalVisualization = null;\n if (this.solved) {\n finalVisualization = this.finalVisualize();\n }\n const visualizations = [initialVisualization].filter(Boolean).concat(\n this.pipelineDef.map((stage, stageIndex) => {\n const solver = this[stage.solverName];\n const viz = solver?.visualize();\n if (!viz) return null;\n setStepOfAllObjects(viz, stageIndex + stageStepOffset);\n return viz;\n }).filter(Boolean)\n );\n if (visualizations.length === 0) {\n return { points: [], rects: [], lines: [], circles: [], texts: [] };\n }\n if (this.solved && finalVisualization) {\n setStepOfAllObjects(\n finalVisualization,\n visualizations.length + stageStepOffset + 1\n );\n visualizations.push(finalVisualization);\n }\n if (visualizations.length === 1) {\n return visualizations[0];\n }\n return {\n points: visualizations.flatMap((v) => v.points || []),\n rects: visualizations.flatMap((v) => v.rects || []),\n lines: visualizations.flatMap((v) => v.lines || []),\n circles: visualizations.flatMap((v) => v.circles || []),\n texts: visualizations.flatMap((v) => v.texts || [])\n };\n }\n preview() {\n if (this.activeSubSolver) {\n return this.activeSubSolver.preview();\n }\n return super.preview();\n }\n computeProgress() {\n return this.getStageProgress();\n }\n /**\n * Get the output from a specific pipeline stage\n */\n getStageOutput(stageOutput) {\n return this.pipelineOutputs[stageOutput];\n }\n /**\n * Get all pipeline outputs\n */\n getAllOutputs() {\n return { ...this.pipelineOutputs };\n }\n /**\n * Check if a step has completed and produced output\n */\n hasStageOutput(stageName) {\n return stageName in this.pipelineOutputs;\n }\n /**\n * Get a solver instance by name\n */\n getSolver(stageName) {\n return this[stageName];\n }\n};\nexport {\n BasePipelineSolver,\n BaseSolver,\n definePipelineStep\n};\n","import type { GraphicsObject } from \"graphics-debug\";\nimport type { SimpleRouteJson } from \"@tscircuit/core\";\nimport type {\n Point,\n PreparedBiscuitRoutingProblem,\n RectBounds,\n RoutedConnection,\n RoutingEdge,\n} from \"./types\";\n\nconst EPSILON = 1e-7;\n// Extra room needed so equivalent route/Circuit JSON representations do not\n// turn an exactly tangent nominal-width path into an expansion repair.\nexport const EXPANSION_CLEARANCE_GUARD = 0.04;\n\nexport const pointsEqual = (a: Point, b: Point, epsilon = EPSILON) =>\n Math.abs(a.x - b.x) <= epsilon && Math.abs(a.y - b.y) <= epsilon;\n\nexport const pointDistance = (a: Point, b: Point) =>\n Math.hypot(a.x - b.x, a.y - b.y);\n\nexport const getTerminalEscapeMinimumRun = (\n pad: Pick<SimpleRouteJson[\"obstacles\"][number], \"width\" | \"height\">,\n clearance: number,\n) => Math.max(pad.width, pad.height) / 2 + clearance + 0.2;\n\nexport const pointStrictlyInsideRect = (point: Point, rect: RectBounds) =>\n point.x > rect.minX + EPSILON &&\n point.x < rect.maxX - EPSILON &&\n point.y > rect.minY + EPSILON &&\n point.y < rect.maxY - EPSILON;\n\nexport const obstacleBounds = (\n obstacle: {\n center: Point;\n width: number;\n height: number;\n ccwRotationDegrees?: number;\n },\n margin = 0,\n respectRotation = true,\n): RectBounds => {\n const rotationRadians =\n (((respectRotation ? obstacle.ccwRotationDegrees : 0) ?? 0) * Math.PI) /\n 180;\n const cosine = Math.abs(Math.cos(rotationRadians));\n const sine = Math.abs(Math.sin(rotationRadians));\n const halfWidth = (cosine * obstacle.width + sine * obstacle.height) / 2;\n const halfHeight = (sine * obstacle.width + cosine * obstacle.height) / 2;\n return {\n minX: obstacle.center.x - halfWidth - margin,\n maxX: obstacle.center.x + halfWidth + margin,\n minY: obstacle.center.y - halfHeight - margin,\n maxY: obstacle.center.y + halfHeight + margin,\n };\n};\n\n/**\n * Interior rotated obstacles can be repaired cheaply after routing, while an\n * edge-adjacent obstacle may leave no room for a cleanup detour. Reserve the\n * exact rotated envelope for those edge obstacles during graph routing.\n */\nexport const shouldRespectObstacleRotationInGraph = (\n input: Pick<SimpleRouteJson, \"bounds\">,\n obstacle: SimpleRouteJson[\"obstacles\"][number],\n margin: number,\n enabled: boolean,\n edgeDistance: number,\n) => {\n if (!enabled) return false;\n const bounds = obstacleBounds(obstacle, margin, true);\n return (\n bounds.minX - input.bounds.minX <= edgeDistance ||\n input.bounds.maxX - bounds.maxX <= edgeDistance ||\n bounds.minY - input.bounds.minY <= edgeDistance ||\n input.bounds.maxY - bounds.maxY <= edgeDistance\n );\n};\n\n/** Liang-Barsky clipping against a slightly shrunken rectangle. */\nexport const segmentIntersectsRectInterior = (\n start: Point,\n end: Point,\n rect: RectBounds,\n) => {\n const interior = {\n minX: rect.minX + EPSILON,\n maxX: rect.maxX - EPSILON,\n minY: rect.minY + EPSILON,\n maxY: rect.maxY - EPSILON,\n };\n if (interior.minX >= interior.maxX || interior.minY >= interior.maxY) {\n return false;\n }\n\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const p = [-dx, dx, -dy, dy];\n const q = [\n start.x - interior.minX,\n interior.maxX - start.x,\n start.y - interior.minY,\n interior.maxY - start.y,\n ];\n let low = 0;\n let high = 1;\n for (let index = 0; index < 4; index++) {\n if (Math.abs(p[index]!) <= EPSILON) {\n if (q[index]! < 0) return false;\n continue;\n }\n const ratio = q[index]! / p[index]!;\n if (p[index]! < 0) low = Math.max(low, ratio);\n else high = Math.min(high, ratio);\n if (low > high) return false;\n }\n return high >= 0 && low <= 1;\n};\n\nconst cross = (a: Point, b: Point, c: Point) =>\n (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);\n\nconst onSegment = (a: Point, b: Point, point: Point) =>\n Math.abs(cross(a, b, point)) <= EPSILON &&\n point.x >= Math.min(a.x, b.x) - EPSILON &&\n point.x <= Math.max(a.x, b.x) + EPSILON &&\n point.y >= Math.min(a.y, b.y) - EPSILON &&\n point.y <= Math.max(a.y, b.y) + EPSILON;\n\nexport const segmentsIntersect = (\n firstStart: Point,\n firstEnd: Point,\n secondStart: Point,\n secondEnd: Point,\n) => {\n const c1 = cross(firstStart, firstEnd, secondStart);\n const c2 = cross(firstStart, firstEnd, secondEnd);\n const c3 = cross(secondStart, secondEnd, firstStart);\n const c4 = cross(secondStart, secondEnd, firstEnd);\n if (\n ((c1 > EPSILON && c2 < -EPSILON) || (c1 < -EPSILON && c2 > EPSILON)) &&\n ((c3 > EPSILON && c4 < -EPSILON) || (c3 < -EPSILON && c4 > EPSILON))\n ) {\n return true;\n }\n return (\n onSegment(firstStart, firstEnd, secondStart) ||\n onSegment(firstStart, firstEnd, secondEnd) ||\n onSegment(secondStart, secondEnd, firstStart) ||\n onSegment(secondStart, secondEnd, firstEnd)\n );\n};\n\nconst pointToSegmentDistance = (point: Point, start: Point, end: Point) => {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const lengthSquared = dx * dx + dy * dy;\n if (lengthSquared <= EPSILON) return pointDistance(point, start);\n const t = Math.max(\n 0,\n Math.min(\n 1,\n ((point.x - start.x) * dx + (point.y - start.y) * dy) / lengthSquared,\n ),\n );\n return pointDistance(point, { x: start.x + t * dx, y: start.y + t * dy });\n};\n\nexport const segmentDistance = (\n firstStart: Point,\n firstEnd: Point,\n secondStart: Point,\n secondEnd: Point,\n) => {\n if (segmentsIntersect(firstStart, firstEnd, secondStart, secondEnd)) return 0;\n return Math.min(\n pointToSegmentDistance(firstStart, secondStart, secondEnd),\n pointToSegmentDistance(firstEnd, secondStart, secondEnd),\n pointToSegmentDistance(secondStart, firstStart, firstEnd),\n pointToSegmentDistance(secondEnd, firstStart, firstEnd),\n );\n};\n\nexport const segmentToObstacleDistance = (\n start: Point,\n end: Point,\n obstacle: Pick<\n SimpleRouteJson[\"obstacles\"][number],\n \"center\" | \"width\" | \"height\" | \"shape\" | \"ccwRotationDegrees\"\n >,\n respectRotation = true,\n) => {\n if (obstacle.shape === \"circle\") {\n return Math.max(\n 0,\n pointToSegmentDistance(obstacle.center, start, end) -\n Math.max(obstacle.width, obstacle.height) / 2,\n );\n }\n\n const radians =\n (((respectRotation ? obstacle.ccwRotationDegrees : 0) ?? 0) * Math.PI) /\n 180;\n const cosine = Math.cos(radians);\n const sine = Math.sin(radians);\n const toLocal = (point: Point) => {\n const x = point.x - obstacle.center.x;\n const y = point.y - obstacle.center.y;\n return {\n x: x * cosine + y * sine,\n y: -x * sine + y * cosine,\n };\n };\n const localStart = toLocal(start);\n const localEnd = toLocal(end);\n const halfWidth = obstacle.width / 2;\n const halfHeight = obstacle.height / 2;\n const bounds = {\n minX: -halfWidth,\n maxX: halfWidth,\n minY: -halfHeight,\n maxY: halfHeight,\n };\n if (segmentIntersectsRectInterior(localStart, localEnd, bounds)) return 0;\n\n const corners = [\n { x: -halfWidth, y: -halfHeight },\n { x: halfWidth, y: -halfHeight },\n { x: halfWidth, y: halfHeight },\n { x: -halfWidth, y: halfHeight },\n ];\n return Math.min(\n ...corners.map((corner, index) =>\n segmentDistance(\n localStart,\n localEnd,\n corner,\n corners[(index + 1) % corners.length]!,\n ),\n ),\n );\n};\n\nexport const getEdgePoints = (\n prepared: PreparedBiscuitRoutingProblem,\n edge: RoutingEdge,\n) => [prepared.nodes[edge.fromNode]!, prepared.nodes[edge.toNode]!] as const;\n\nexport const netColor = (name: string) => {\n let hash = 0;\n for (const character of name)\n hash = (hash * 31 + character.charCodeAt(0)) | 0;\n const hue = Math.abs(hash) % 360;\n return `hsl(${hue} 72% 42%)`;\n};\n\nexport const visualizeSimpleRouteJsonInput = (\n input: SimpleRouteJson,\n): GraphicsObject => {\n const rects: NonNullable<GraphicsObject[\"rects\"]> = [\n {\n center: {\n x: (input.bounds.minX + input.bounds.maxX) / 2,\n y: (input.bounds.minY + input.bounds.maxY) / 2,\n },\n width: input.bounds.maxX - input.bounds.minX,\n height: input.bounds.maxY - input.bounds.minY,\n fill: \"rgba(255,255,255,0)\",\n stroke: \"rgba(15,23,42,0.45)\",\n label: \"routing bounds\",\n },\n ];\n const circles: NonNullable<GraphicsObject[\"circles\"]> = [];\n const points: NonNullable<GraphicsObject[\"points\"]> = [];\n const lines: NonNullable<GraphicsObject[\"lines\"]> = [];\n\n for (const [obstacleIndex, obstacle] of input.obstacles.entries()) {\n if (obstacle.isCopperPour) continue;\n const isPrefabricatedVia =\n obstacle.netIsAssignable === true &&\n obstacle.connectedTo.some((id) => id.startsWith(\"pcb_via\"));\n const label = isPrefabricatedVia\n ? `prefabricated via · ${obstacle.obstacleId ?? obstacleIndex}`\n : `obstacle · ${obstacle.obstacleId ?? obstacle.componentId ?? obstacleIndex}`;\n if (obstacle.shape === \"circle\") {\n circles.push({\n center: obstacle.center,\n radius: Math.max(obstacle.width, obstacle.height) / 2,\n fill: isPrefabricatedVia\n ? \"rgba(14,165,233,0.35)\"\n : \"rgba(239,68,68,0.22)\",\n stroke: isPrefabricatedVia ? \"#0284c7\" : \"#b91c1c\",\n label,\n });\n } else {\n rects.push({\n center: obstacle.center,\n width: obstacle.width,\n height: obstacle.height,\n fill: isPrefabricatedVia\n ? \"rgba(14,165,233,0.25)\"\n : \"rgba(239,68,68,0.16)\",\n stroke: isPrefabricatedVia ? \"#0284c7\" : \"#b91c1c\",\n label,\n });\n }\n }\n\n for (const connection of input.connections) {\n const color = netColor(connection.name);\n const [root, ...terminals] = connection.pointsToConnect;\n if (!root) continue;\n points.push({ ...root, color, label: `${connection.name} terminal` });\n for (const terminal of terminals) {\n points.push({\n ...terminal,\n color,\n label: `${connection.name} terminal`,\n });\n lines.push({\n points: [root, terminal],\n strokeColor: color,\n strokeWidth: 0.04,\n strokeDash: [0.15, 0.1],\n label: `${connection.name} unrouted`,\n });\n }\n }\n\n return {\n coordinateSystem: \"cartesian\",\n title: `Biscuit-board routing input (${input.connections.length} connections, ${input.obstacles.length} obstacles)`,\n rects,\n circles,\n points,\n lines,\n };\n};\n\nexport const visualizePreparedProblem = (\n prepared: PreparedBiscuitRoutingProblem,\n routes: Iterable<RoutedConnection> = [],\n): GraphicsObject => {\n const lines: NonNullable<GraphicsObject[\"lines\"]> = [];\n const points: NonNullable<GraphicsObject[\"points\"]> = [];\n const rects: NonNullable<GraphicsObject[\"rects\"]> = [];\n const maximumTraceWidth = Math.max(\n prepared.input.minTraceWidth,\n ...prepared.demands.map((demand) => demand.width),\n );\n const margin =\n maximumTraceWidth / 2 +\n Math.max(\n prepared.options.gridClearance,\n prepared.input.minTraceToPadEdgeClearance ?? 0,\n );\n\n for (const obstacle of prepared.input.obstacles) {\n if (obstacle.isCopperPour) continue;\n const bounds = obstacleBounds(obstacle, margin);\n rects.push({\n center: {\n x: (bounds.minX + bounds.maxX) / 2,\n y: (bounds.minY + bounds.maxY) / 2,\n },\n width: bounds.maxX - bounds.minX,\n height: bounds.maxY - bounds.minY,\n fill: obstacle.netIsAssignable\n ? \"rgba(14,165,233,0.20)\"\n : \"rgba(239,68,68,0.12)\",\n stroke: obstacle.netIsAssignable\n ? \"rgba(2,132,199,0.7)\"\n : \"rgba(220,38,38,0.35)\",\n });\n }\n\n for (const edge of prepared.edges) {\n const [from, to] = getEdgePoints(prepared, edge);\n if (edge.kind === \"trace\") {\n lines.push({\n points: [from, to],\n strokeColor: \"rgba(100,116,139,0.10)\",\n strokeWidth: 0.025,\n });\n } else {\n points.push({\n ...from,\n color: \"rgba(14,165,233,0.75)\",\n label: edge.prefabViaId,\n });\n }\n }\n\n for (const route of routes) {\n const color = netColor(route.netId);\n for (const edgeId of route.edgePath) {\n const edge = prepared.edges[edgeId]!;\n const [from, to] = getEdgePoints(prepared, edge);\n if (edge.kind === \"trace\") {\n lines.push({\n points: [from, to],\n strokeColor: color,\n strokeWidth: 0.18,\n });\n } else {\n points.push({ ...from, color, label: `fixed via · ${route.netId}` });\n }\n }\n }\n\n return {\n title: `Fixed-via routing hypergraph (${prepared.nodes.length} nodes, ${prepared.edges.length} hyperedges)`,\n lines,\n points,\n rects,\n };\n};\n","import { isUndefined } from './utils'\nimport { translate } from './translate'\nimport { transform } from './transform'\n\nconst { cos, sin, PI } = Math\n/**\n * Calculate a rotation matrix\n * @param angle {number} Angle in radians\n * @param [cx] {number} If (cx,cy) are supplied the rotate is about this point\n * @param [cy] {number} If (cx,cy) are supplied the rotate is about this point\n * @returns {Matrix} Affine Matrix\n */\nexport function rotate (angle, cx, cy) {\n const cosAngle = cos(angle)\n const sinAngle = sin(angle)\n const rotationMatrix = {\n a: cosAngle,\n c: -sinAngle,\n e: 0,\n b: sinAngle,\n d: cosAngle,\n f: 0\n }\n if (isUndefined(cx) || isUndefined(cy)) {\n return rotationMatrix\n }\n\n return transform([\n translate(cx, cy),\n rotationMatrix,\n translate(-cx, -cy)\n ])\n}\n\n/**\n * Calculate a rotation matrix with a DEG angle\n * @param angle {number} Angle in degree\n * @param [cx] {number} If (cx,cy) are supplied the rotate is about this point\n * @param [cy] {number} If (cx,cy) are supplied the rotate is about this point\n * @returns {Matrix} Affine Matrix\n */\nexport function rotateDEG (angle, cx = undefined, cy = undefined) {\n return rotate(angle * PI / 180, cx, cy)\n}\n","// https://developer.mozilla.org/en-US/docs/Web/CSS/transform-function/skew\nconst { tan } = Math\n\n/**\n * Calculate a skew matrix\n * @param ax {number} Skew on axis x\n * @param ay {number} Skew on axis y\n * @returns {Matrix} Affine Matrix\n */\nexport function skew (ax, ay) {\n return {\n a: 1,\n c: tan(ax),\n e: 0,\n b: tan(ay),\n d: 1,\n f: 0\n }\n}\n\n/**\n * Calculate a skew matrix using DEG angles\n * @param ax {number} Skew on axis x\n * @param ay {number} Skew on axis y\n * @returns {Matrix} Affine Matrix\n */\nexport function skewDEG (ax, ay) {\n return skew(ax * Math.PI / 180, ay * Math.PI / 180)\n}\n","// lib/BaseSolver.ts\nvar BaseSolver = class {\n MAX_ITERATIONS = 1e5;\n solved = false;\n failed = false;\n iterations = 0;\n progress = 0;\n error = null;\n activeSubSolver;\n failedSubSolvers;\n timeToSolve;\n stats = {};\n _setupDone = false;\n getSolverName() {\n return this.constructor.name;\n }\n setup() {\n if (this._setupDone) return;\n this._setup();\n this._setupDone = true;\n }\n /** Override this method to perform setup logic */\n _setup() {\n }\n /** DO NOT OVERRIDE! Override _step() instead */\n step() {\n if (!this._setupDone) {\n this.setup();\n }\n if (this.solved) return;\n if (this.failed) return;\n this.iterations++;\n try {\n this._step();\n } catch (e) {\n this.error = `${this.getSolverName()} error: ${e}`;\n this.failed = true;\n throw e;\n }\n if (!this.solved && this.iterations >= this.MAX_ITERATIONS) {\n this.tryFinalAcceptance();\n }\n if (!this.solved && this.iterations >= this.MAX_ITERATIONS) {\n this.error = `${this.getSolverName()} ran out of iterations`;\n this.failed = true;\n }\n if (\"computeProgress\" in this) {\n this.progress = this.computeProgress();\n }\n }\n /** Override this method to implement solver logic */\n _step() {\n }\n getConstructorParams() {\n throw new Error(\"getConstructorParams not implemented\");\n }\n /**\n * Override this method to return the standardized output of the solver.\n * This method should only be called after the solver has completed successfully.\n * Returns null by default - solvers with outputs should override this method.\n */\n getOutput() {\n return null;\n }\n solve() {\n const startTime = Date.now();\n while (!this.solved && !this.failed) {\n this.step();\n }\n const endTime = Date.now();\n this.timeToSolve = endTime - startTime;\n }\n visualize() {\n return {\n lines: [],\n points: [],\n rects: [],\n circles: []\n };\n }\n /**\n * Called when the solver is about to fail, but we want to see if we have an\n * \"acceptable\" or \"passable\" solution. Mostly used for optimizers that\n * have an aggressive early stopping criterion.\n */\n tryFinalAcceptance() {\n }\n /**\n * A lightweight version of the visualize method that can be used to stream\n * progress\n */\n preview() {\n return {\n lines: [],\n points: [],\n rects: [],\n circles: []\n };\n }\n};\n\n// lib/BasePipelineSolver.ts\nimport { setStepOfAllObjects } from \"graphics-debug\";\nfunction definePipelineStep(solverName, solverClass, getConstructorParams, opts = {}) {\n return {\n solverName,\n solverClass,\n getConstructorParams,\n onSolved: opts.onSolved\n };\n}\nvar BasePipelineSolver = class extends BaseSolver {\n startTimeOfStage = {};\n endTimeOfStage = {};\n timeSpentOnStage = {};\n firstIterationOfStage = {};\n currentPipelineStageIndex = 0;\n inputProblem;\n /** Stores the outputs from each completed pipeline stage */\n pipelineOutputs = {};\n constructor(inputProblem) {\n super();\n this.inputProblem = inputProblem;\n this.MAX_ITERATIONS = 1e6;\n }\n _step() {\n const pipelineStageDef = this.pipelineDef[this.currentPipelineStageIndex];\n if (!pipelineStageDef) {\n this.solved = true;\n return;\n }\n if (this.activeSubSolver) {\n this.activeSubSolver.step();\n if (this.activeSubSolver.solved) {\n this.endTimeOfStage[pipelineStageDef.solverName] = performance.now();\n this.timeSpentOnStage[pipelineStageDef.solverName] = this.endTimeOfStage[pipelineStageDef.solverName] - this.startTimeOfStage[pipelineStageDef.solverName];\n const output = this.activeSubSolver.getOutput();\n if (output !== null) {\n this.pipelineOutputs[pipelineStageDef.solverName] = output;\n }\n pipelineStageDef.onSolved?.(this);\n this.activeSubSolver = null;\n this.currentPipelineStageIndex++;\n } else if (this.activeSubSolver.failed) {\n this.error = this.activeSubSolver?.error;\n this.failed = true;\n this.activeSubSolver = null;\n }\n return;\n }\n const constructorParams = pipelineStageDef.getConstructorParams(this);\n this.activeSubSolver = new pipelineStageDef.solverClass(\n ...constructorParams\n );\n this[pipelineStageDef.solverName] = this.activeSubSolver;\n this.timeSpentOnStage[pipelineStageDef.solverName] = 0;\n this.startTimeOfStage[pipelineStageDef.solverName] = performance.now();\n this.firstIterationOfStage[pipelineStageDef.solverName] = this.iterations;\n }\n solveUntilStage(stageName) {\n while (this.getCurrentStageName().toLowerCase() !== stageName.toLowerCase()) {\n this.step();\n if (this.failed || this.solved) break;\n }\n }\n getCurrentStageName() {\n return this.pipelineDef[this.currentPipelineStageIndex]?.solverName ?? \"none\";\n }\n getStageProgress() {\n const totalStages = this.pipelineDef.length;\n if (totalStages === 0) return 1;\n const currentStageProgress = this.activeSubSolver?.progress ?? 0;\n return (this.currentPipelineStageIndex + currentStageProgress) / totalStages;\n }\n getStageStats() {\n const stats = {};\n for (const stage of this.pipelineDef) {\n const timeSpent = this.timeSpentOnStage[stage.solverName] || 0;\n const firstIteration = this.firstIterationOfStage[stage.solverName] || 0;\n const currentIteration = this.iterations;\n const iterations = stage.solverName === this.getCurrentStageName() ? currentIteration - firstIteration : 0;\n const completed = this.currentPipelineStageIndex > this.pipelineDef.findIndex((s) => s.solverName === stage.solverName);\n stats[stage.solverName] = {\n timeSpent,\n iterations,\n completed\n };\n }\n return stats;\n }\n initialVisualize() {\n return null;\n }\n finalVisualize() {\n return null;\n }\n visualize() {\n if (!this.solved && this.activeSubSolver) {\n return this.activeSubSolver.visualize();\n }\n let stageStepOffset = 0;\n const initialVisualization = this.initialVisualize();\n if (initialVisualization) {\n setStepOfAllObjects(initialVisualization, 0);\n stageStepOffset = 1;\n }\n let finalVisualization = null;\n if (this.solved) {\n finalVisualization = this.finalVisualize();\n }\n const visualizations = [initialVisualization].filter(Boolean).concat(\n this.pipelineDef.map((stage, stageIndex) => {\n const solver = this[stage.solverName];\n const viz = solver?.visualize();\n if (!viz) return null;\n setStepOfAllObjects(viz, stageIndex + stageStepOffset);\n return viz;\n }).filter(Boolean)\n );\n if (visualizations.length === 0) {\n return { points: [], rects: [], lines: [], circles: [], texts: [] };\n }\n if (this.solved && finalVisualization) {\n setStepOfAllObjects(\n finalVisualization,\n visualizations.length + stageStepOffset + 1\n );\n visualizations.push(finalVisualization);\n }\n if (visualizations.length === 1) {\n return visualizations[0];\n }\n return {\n points: visualizations.flatMap((v) => v.points || []),\n rects: visualizations.flatMap((v) => v.rects || []),\n lines: visualizations.flatMap((v) => v.lines || []),\n circles: visualizations.flatMap((v) => v.circles || []),\n texts: visualizations.flatMap((v) => v.texts || [])\n };\n }\n preview() {\n if (this.activeSubSolver) {\n return this.activeSubSolver.preview();\n }\n return super.preview();\n }\n computeProgress() {\n return this.getStageProgress();\n }\n /**\n * Get the output from a specific pipeline stage\n */\n getStageOutput(stageOutput) {\n return this.pipelineOutputs[stageOutput];\n }\n /**\n * Get all pipeline outputs\n */\n getAllOutputs() {\n return { ...this.pipelineOutputs };\n }\n /**\n * Check if a step has completed and produced output\n */\n hasStageOutput(stageName) {\n return stageName in this.pipelineOutputs;\n }\n /**\n * Get a solver instance by name\n */\n getSolver(stageName) {\n return this[stageName];\n }\n};\nexport {\n BasePipelineSolver,\n BaseSolver,\n definePipelineStep\n};\n","import type { SimpleRouteJson, SimplifiedPcbTrace } from \"./types\";\n\nconst definedNames = (names: Array<string | null | undefined>) =>\n names.filter((name): name is string => Boolean(name));\n\n/**\n * Canonicalizes the aliases used for one electrical net in SimpleRouteJson.\n * Imported subcircuits often use a different source-trace name at their\n * boundary, but both routes still share a pcb_port_id. Pads and vias also\n * carry the complete connectedTo alias set, so unioning these identifiers\n * reproduces the connectivity semantics used by @tscircuit/checks.\n */\nexport class ConnectionNameResolver {\n private readonly parent = new Map<string, string>();\n\n constructor(\n simpleRouteJson: SimpleRouteJson,\n traces: SimplifiedPcbTrace[] = simpleRouteJson.traces ?? [],\n ) {\n for (const connection of simpleRouteJson.connections) {\n this.unionAll(\n definedNames([\n connection.name,\n connection.source_trace_id,\n connection.rootConnectionName,\n ...(connection.mergedConnectionNames ?? []),\n ...connection.pointsToConnect.flatMap((point) => [\n point.pointId,\n point.pcb_port_id,\n ]),\n ]),\n );\n }\n for (const trace of [...traces, ...(simpleRouteJson.fixedTraces ?? [])]) {\n this.unionAll(\n definedNames([\n trace.pcb_trace_id,\n trace.connection_name,\n trace.source_trace_id,\n trace.rootConnectionName,\n ...(trace.mergedConnectionNames ?? []),\n ...(trace.connectsTo ?? []),\n ]),\n );\n }\n for (const obstacle of simpleRouteJson.obstacles) {\n this.unionAll(obstacle.connectedTo);\n }\n }\n\n canonicalize(names: string[]) {\n return [...new Set(names.map((name) => this.find(name)))];\n }\n\n private unionAll(names: string[]) {\n const first = names[0];\n if (!first) return;\n this.add(first);\n for (let index = 1; index < names.length; index++) {\n this.union(first, names[index]!);\n }\n }\n\n private add(name: string) {\n if (!this.parent.has(name)) this.parent.set(name, name);\n }\n\n private find(name: string): string {\n this.add(name);\n const parent = this.parent.get(name)!;\n if (parent === name) return name;\n const root = this.find(parent);\n this.parent.set(name, root);\n return root;\n }\n\n private union(a: string, b: string) {\n const rootA = this.find(a);\n const rootB = this.find(b);\n if (rootA !== rootB) this.parent.set(rootB, rootA);\n }\n}\n","import type {\n IndexedObstacle,\n Obstacle,\n Point,\n WireRoutePoint,\n} from \"./types\";\n\nexport const WIDTH_EPSILON = 1e-6;\n\nexport const distance = (a: Point, b: Point) =>\n Math.hypot(b.x - a.x, b.y - a.y);\n\nexport const distancePointToSegment = (\n point: Point,\n start: Point,\n end: Point,\n) => {\n const deltaX = end.x - start.x;\n const deltaY = end.y - start.y;\n const lengthSquared = deltaX * deltaX + deltaY * deltaY;\n if (lengthSquared <= 1e-12) return distance(point, start);\n const t = clamp(\n ((point.x - start.x) * deltaX + (point.y - start.y) * deltaY) /\n lengthSquared,\n 0,\n 1,\n );\n return Math.hypot(\n point.x - (start.x + deltaX * t),\n point.y - (start.y + deltaY * t),\n );\n};\n\nexport const pointsEqual = (a: Point, b: Point, epsilon = 1e-6) =>\n Math.abs(a.x - b.x) <= epsilon && Math.abs(a.y - b.y) <= epsilon;\n\nexport const clamp = (value: number, min: number, max: number) =>\n Math.max(min, Math.min(max, value));\n\nconst orientation = (a: Point, b: Point, c: Point) =>\n (b.x - a.x) * (c.y - a.y) - (b.y - a.y) * (c.x - a.x);\n\nconst pointOnSegment = (point: Point, start: Point, end: Point) =>\n Math.abs(orientation(start, end, point)) <= 1e-9 &&\n point.x >= Math.min(start.x, end.x) - 1e-9 &&\n point.x <= Math.max(start.x, end.x) + 1e-9 &&\n point.y >= Math.min(start.y, end.y) - 1e-9 &&\n point.y <= Math.max(start.y, end.y) + 1e-9;\n\nexport const segmentsIntersect = (\n aStart: Point,\n aEnd: Point,\n bStart: Point,\n bEnd: Point,\n) => {\n const o1 = orientation(aStart, aEnd, bStart);\n const o2 = orientation(aStart, aEnd, bEnd);\n const o3 = orientation(bStart, bEnd, aStart);\n const o4 = orientation(bStart, bEnd, aEnd);\n if (o1 * o2 < 0 && o3 * o4 < 0) return true;\n return (\n (Math.abs(o1) <= 1e-9 && pointOnSegment(bStart, aStart, aEnd)) ||\n (Math.abs(o2) <= 1e-9 && pointOnSegment(bEnd, aStart, aEnd)) ||\n (Math.abs(o3) <= 1e-9 && pointOnSegment(aStart, bStart, bEnd)) ||\n (Math.abs(o4) <= 1e-9 && pointOnSegment(aEnd, bStart, bEnd))\n );\n};\n\nexport const distanceSegmentToSegment = (\n aStart: Point,\n aEnd: Point,\n bStart: Point,\n bEnd: Point,\n) => {\n if (segmentsIntersect(aStart, aEnd, bStart, bEnd)) return 0;\n return Math.min(\n distancePointToSegment(aStart, bStart, bEnd),\n distancePointToSegment(aEnd, bStart, bEnd),\n distancePointToSegment(bStart, aStart, aEnd),\n distancePointToSegment(bEnd, aStart, aEnd),\n );\n};\n\nconst pointInPolygon = (point: Point, polygon: Point[]) => {\n let inside = false;\n for (\n let index = 0, previousIndex = polygon.length - 1;\n index < polygon.length;\n previousIndex = index++\n ) {\n const current = polygon[index]!;\n const previous = polygon[previousIndex]!;\n if (pointOnSegment(point, previous, current)) return true;\n const crosses =\n current.y > point.y !== previous.y > point.y &&\n point.x <\n ((previous.x - current.x) * (point.y - current.y)) /\n (previous.y - current.y) +\n current.x;\n if (crosses) inside = !inside;\n }\n return inside;\n};\n\nexport const distanceSegmentToPolygon = (\n start: Point,\n end: Point,\n polygon: Point[],\n) => {\n if (pointInPolygon(start, polygon) || pointInPolygon(end, polygon)) return 0;\n let minimumDistance = Number.POSITIVE_INFINITY;\n for (let index = 0; index < polygon.length; index++) {\n const edgeStart = polygon[index]!;\n const edgeEnd = polygon[(index + 1) % polygon.length]!;\n minimumDistance = Math.min(\n minimumDistance,\n distanceSegmentToSegment(start, end, edgeStart, edgeEnd),\n );\n }\n return minimumDistance;\n};\n\nexport const getApproximationChunkLength = (width: number) =>\n clamp(width * 1.25, 0.25, 0.75);\n\nexport function segmentIntersectsRect(\n start: Point,\n end: Point,\n rect: { minX: number; minY: number; maxX: number; maxY: number },\n) {\n let entry = 0;\n let exit = 1;\n const deltaX = end.x - start.x;\n const deltaY = end.y - start.y;\n const constraints: Array<[number, number]> = [\n [-deltaX, start.x - rect.minX],\n [deltaX, rect.maxX - start.x],\n [-deltaY, start.y - rect.minY],\n [deltaY, rect.maxY - start.y],\n ];\n\n for (const [direction, distanceToEdge] of constraints) {\n if (Math.abs(direction) < 1e-12) {\n if (distanceToEdge < 0) return false;\n continue;\n }\n const ratio = distanceToEdge / direction;\n if (direction < 0) entry = Math.max(entry, ratio);\n else exit = Math.min(exit, ratio);\n if (entry > exit) return false;\n }\n return true;\n}\n\nexport function approximateSegmentWithRects({\n start,\n end,\n width,\n base,\n}: {\n start: Point;\n end: Point;\n width: number;\n base: Omit<IndexedObstacle, \"minX\" | \"minY\" | \"maxX\" | \"maxY\">;\n}): IndexedObstacle[] {\n const length = distance(start, end);\n const chunkLength = getApproximationChunkLength(width);\n const chunkCount = Math.max(1, Math.ceil(length / chunkLength));\n const radius = width / 2;\n const rects: IndexedObstacle[] = [];\n\n for (let index = 0; index < chunkCount; index++) {\n const t0 = index / chunkCount;\n const t1 = (index + 1) / chunkCount;\n const x0 = start.x + (end.x - start.x) * t0;\n const y0 = start.y + (end.y - start.y) * t0;\n const x1 = start.x + (end.x - start.x) * t1;\n const y1 = start.y + (end.y - start.y) * t1;\n rects.push({\n ...base,\n minX: Math.min(x0, x1) - radius,\n minY: Math.min(y0, y1) - radius,\n maxX: Math.max(x0, x1) + radius,\n maxY: Math.max(y0, y1) + radius,\n exactShape: {\n type: \"segment\",\n start: { x: x0, y: y0 },\n end: { x: x1, y: y1 },\n width,\n },\n });\n }\n\n return rects;\n}\n\nconst rotatePoint = (point: Point, center: Point, radians: number): Point => {\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n const dx = point.x - center.x;\n const dy = point.y - center.y;\n return {\n x: center.x + dx * cos - dy * sin,\n y: center.y + dx * sin + dy * cos,\n };\n};\n\nexport function approximateObstacleWithRects(\n obstacle: Obstacle,\n maxCellSize = 0.6,\n): IndexedObstacle[] {\n const rotation = ((obstacle.ccwRotationDegrees ?? 0) * Math.PI) / 180;\n const columns = Math.max(1, Math.ceil(obstacle.width / maxCellSize));\n const rows = Math.max(1, Math.ceil(obstacle.height / maxCellSize));\n const cellWidth = obstacle.width / columns;\n const cellHeight = obstacle.height / rows;\n const rects: IndexedObstacle[] = [];\n\n for (let row = 0; row < rows; row++) {\n for (let column = 0; column < columns; column++) {\n const localCenter = {\n x: obstacle.center.x - obstacle.width / 2 + (column + 0.5) * cellWidth,\n y: obstacle.center.y - obstacle.height / 2 + (row + 0.5) * cellHeight,\n };\n const halfWidth = cellWidth / 2;\n const halfHeight = cellHeight / 2;\n const corners = [\n { x: localCenter.x - halfWidth, y: localCenter.y - halfHeight },\n { x: localCenter.x + halfWidth, y: localCenter.y - halfHeight },\n { x: localCenter.x + halfWidth, y: localCenter.y + halfHeight },\n { x: localCenter.x - halfWidth, y: localCenter.y + halfHeight },\n ].map((point) => rotatePoint(point, obstacle.center, rotation));\n\n rects.push({\n minX: Math.min(...corners.map((point) => point.x)),\n minY: Math.min(...corners.map((point) => point.y)),\n maxX: Math.max(...corners.map((point) => point.x)),\n maxY: Math.max(...corners.map((point) => point.y)),\n layers: obstacle.layers,\n kind: \"obstacle\",\n obstacleKind: obstacle.connectedTo[0]?.startsWith(\"pcb_via_\")\n ? \"via\"\n : obstacle.connectedTo[0]?.startsWith(\"pcb_smtpad_\") ||\n obstacle.connectedTo[0]?.startsWith(\"pcb_plated_hole_\")\n ? \"pad\"\n : \"other\",\n connectionNames: obstacle.connectedTo,\n exactShape: { type: \"polygon\", points: corners },\n });\n }\n }\n\n return rects;\n}\n\nexport function splitUnderWidthWireSegments(\n route: Array<WireRoutePoint | Record<string, unknown>>,\n nominalWidth: number,\n): Array<WireRoutePoint | Record<string, unknown>> {\n if (route.length < 2) return route.map((point) => ({ ...point }));\n\n const output: Array<WireRoutePoint | Record<string, unknown>> = [];\n for (let index = 0; index < route.length - 1; index++) {\n const current = route[index] as SimplifiedRoutePoint;\n const next = route[index + 1] as SimplifiedRoutePoint;\n output.push({ ...current });\n\n if (\n current.route_type !== \"wire\" ||\n next.route_type !== \"wire\" ||\n current.layer !== next.layer ||\n (current.width >= nominalWidth - WIDTH_EPSILON &&\n next.width >= nominalWidth - WIDTH_EPSILON)\n ) {\n continue;\n }\n\n const segmentLength = distance(current, next);\n const splitCount = Math.max(1, Math.ceil(segmentLength / nominalWidth));\n for (let splitIndex = 1; splitIndex < splitCount; splitIndex++) {\n const t = splitIndex / splitCount;\n output.push({\n route_type: \"wire\",\n x: current.x + (next.x - current.x) * t,\n y: current.y + (next.y - current.y) * t,\n width: current.width + (next.width - current.width) * t,\n layer: current.layer,\n });\n }\n }\n output.push({ ...route[route.length - 1] });\n return output;\n}\n\ntype SimplifiedRoutePoint = {\n route_type: string;\n x: number;\n y: number;\n width: number;\n layer: string;\n};\n","import { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { clamp, distance, pointsEqual } from \"./geometry\";\nimport type {\n CopperRoutePoint,\n LayerGridRouteOutput,\n LayerGridRouteProblem,\n Point,\n WireRoutePoint,\n} from \"./types\";\n\ntype SearchNode = {\n row: number;\n column: number;\n x: number;\n y: number;\n layerIndex: number;\n viaCount: number;\n viaPoints: Point[];\n g: number;\n f: number;\n parentIndex: number;\n};\n\nclass MinHeap {\n private nodeIndices: number[] = [];\n private priorities: number[] = [];\n\n get size() {\n return this.nodeIndices.length;\n }\n\n push(nodeIndex: number, priority: number) {\n let index = this.nodeIndices.length;\n this.nodeIndices.push(nodeIndex);\n this.priorities.push(priority);\n while (index > 0) {\n const parent = (index - 1) >> 1;\n if (this.priorities[parent]! <= priority) break;\n this.swap(index, parent);\n index = parent;\n }\n }\n\n pop() {\n const result = this.nodeIndices[0]!;\n const lastNode = this.nodeIndices.pop()!;\n const lastPriority = this.priorities.pop()!;\n if (this.nodeIndices.length === 0) return result;\n this.nodeIndices[0] = lastNode;\n this.priorities[0] = lastPriority;\n let index = 0;\n while (true) {\n const left = index * 2 + 1;\n const right = left + 1;\n if (left >= this.nodeIndices.length) break;\n let smallest = left;\n if (\n right < this.nodeIndices.length &&\n this.priorities[right]! < this.priorities[left]!\n ) {\n smallest = right;\n }\n if (this.priorities[index]! <= this.priorities[smallest]!) break;\n this.swap(index, smallest);\n index = smallest;\n }\n return result;\n }\n\n private swap(a: number, b: number) {\n [this.nodeIndices[a], this.nodeIndices[b]] = [\n this.nodeIndices[b]!,\n this.nodeIndices[a]!,\n ];\n [this.priorities[a], this.priorities[b]] = [\n this.priorities[b]!,\n this.priorities[a]!,\n ];\n }\n}\n\nconst DIRECTIONS = [\n [-1, -1],\n [-1, 0],\n [-1, 1],\n [0, -1],\n [0, 1],\n [1, -1],\n [1, 0],\n [1, 1],\n] as const;\n\nconst LAYER_COLORS = [\"#d53535\", \"#3478c8\", \"#8e44ad\", \"#15956f\"];\n\n/**\n * A bounded multilayer A* used only for power routes that remain necked after\n * local widening. Planar moves and via moves are each exposed as individual\n * BaseSolver steps, which keeps the search inspectable in the generic solver\n * debugger.\n */\nexport class LayerAwareGridRouteSolver extends BaseSolver {\n readonly problem: LayerGridRouteProblem;\n readonly searchBounds: LayerGridRouteProblem[\"bounds\"];\n readonly rows: number;\n readonly columns: number;\n readonly origin: Point;\n\n private readonly nodes: SearchNode[] = [];\n private readonly open = new MinHeap();\n private readonly bestCost = new Map<number, number>();\n private readonly closed = new Set<number>();\n private readonly baseStateCount: number;\n private readonly stateSpaceUpperBound: number;\n private readonly endLayerIndices: Set<number>;\n private readonly targetCell: { row: number; column: number };\n private readonly segmentWidthCache = new Map<string, number>();\n private closedStateCount = 0;\n private output: LayerGridRouteOutput | null = null;\n\n constructor(problem: LayerGridRouteProblem) {\n super();\n this.problem = problem;\n const radius =\n Math.max(problem.traceWidth, problem.viaDiameter) / 2 +\n problem.obstacleIndex.clearance;\n const minX = clamp(\n Math.min(problem.start.x, problem.end.x) - problem.searchPadding,\n problem.bounds.minX + radius,\n problem.bounds.maxX - radius,\n );\n const maxX = clamp(\n Math.max(problem.start.x, problem.end.x) + problem.searchPadding,\n problem.bounds.minX + radius,\n problem.bounds.maxX - radius,\n );\n const minY = clamp(\n Math.min(problem.start.y, problem.end.y) - problem.searchPadding,\n problem.bounds.minY + radius,\n problem.bounds.maxY - radius,\n );\n const maxY = clamp(\n Math.max(problem.start.y, problem.end.y) + problem.searchPadding,\n problem.bounds.minY + radius,\n problem.bounds.maxY - radius,\n );\n const alignedMinX =\n Math.floor((minX - problem.gridOffset.x) / problem.gridSize) *\n problem.gridSize +\n problem.gridOffset.x;\n const alignedMinY =\n Math.floor((minY - problem.gridOffset.y) / problem.gridSize) *\n problem.gridSize +\n problem.gridOffset.y;\n this.origin = { x: alignedMinX, y: alignedMinY };\n this.columns = Math.max(\n 2,\n Math.floor((maxX - alignedMinX) / problem.gridSize) + 1,\n );\n this.rows = Math.max(\n 2,\n Math.floor((maxY - alignedMinY) / problem.gridSize) + 1,\n );\n this.searchBounds = {\n minX: alignedMinX,\n minY: alignedMinY,\n maxX: alignedMinX + (this.columns - 1) * problem.gridSize,\n maxY: alignedMinY + (this.rows - 1) * problem.gridSize,\n };\n const stateCount =\n this.rows *\n this.columns *\n problem.layers.length *\n (problem.maxViaCount + 1);\n this.baseStateCount = stateCount;\n // The first via position changes where a second via may legally land.\n // Include it in dominance without allocating the sparse Cartesian product.\n this.stateSpaceUpperBound = stateCount * (this.rows * this.columns + 1);\n this.targetCell = this.pointToCell(problem.end);\n this.endLayerIndices = new Set(\n problem.endLayers\n .map((layer) => problem.layers.indexOf(layer))\n .filter((index) => index >= 0),\n );\n\n const startCell = this.pointToCell(problem.start);\n for (const startLayer of problem.startLayers) {\n const layerIndex = problem.layers.indexOf(startLayer);\n if (layerIndex < 0 || this.endpointCollides(problem.start, layerIndex)) {\n continue;\n }\n const node: SearchNode = {\n ...startCell,\n ...problem.start,\n layerIndex,\n viaCount: 0,\n viaPoints: [],\n g: 0,\n f: this.heuristic(problem.start),\n parentIndex: -1,\n };\n const nodeIndex = this.nodes.length;\n this.nodes.push(node);\n this.open.push(nodeIndex, node.f);\n this.bestCost.set(this.toStateIndex(node), 0);\n }\n\n if (this.open.size === 0 || this.endLayerIndices.size === 0) {\n this.failed = true;\n this.error = \"No collision-free multilayer route endpoint\";\n }\n this.MAX_ITERATIONS = Math.min(15_000, Math.max(2_000, stateCount * 2));\n this.stats = this.createStats();\n }\n\n override getSolverName() {\n return `LayerAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`;\n }\n\n override _step() {\n if (this.open.size === 0) {\n this.failed = true;\n this.error = \"No collision-free multilayer grid route found\";\n return;\n }\n\n const nodeIndex = this.open.pop();\n const node = this.nodes[nodeIndex]!;\n const stateIndex = this.toStateIndex(node);\n if (this.closed.has(stateIndex)) return;\n this.closed.add(stateIndex);\n this.closedStateCount++;\n\n if (\n node.row === this.targetCell.row &&\n node.column === this.targetCell.column &&\n this.endLayerIndices.has(node.layerIndex) &&\n node.viaCount >= this.problem.minViaCount &&\n !this.segmentCollides(node, this.problem.end)\n ) {\n this.output = this.reconstructRoute(nodeIndex);\n this.solved = true;\n this.stats = this.createStats();\n return;\n }\n\n this.expandPlanarMoves(nodeIndex, node);\n this.expandViaMoves(nodeIndex, node);\n this.stats = this.createStats();\n }\n\n private expandPlanarMoves(nodeIndex: number, node: SearchNode) {\n for (const [deltaRow, deltaColumn] of DIRECTIONS) {\n const row = node.row + deltaRow;\n const column = node.column + deltaColumn;\n if (row < 0 || row >= this.rows || column < 0 || column >= this.columns)\n continue;\n const point = this.cellToPoint(row, column);\n const segmentWidth = this.getSafeSegmentWidth(node, point);\n if (segmentWidth <= 0) continue;\n const geometricMoveCost =\n this.problem.gridSize *\n (deltaRow !== 0 && deltaColumn !== 0 ? Math.SQRT2 : 1);\n // Narrow copper is allowed for pad escape, but it is electrically more\n // expensive. Squaring the width ratio makes A* spend only the neck\n // length it needs and prefer a longer nominal-width route on another\n // layer instead of taking a deceptively short, thin pad escape.\n const moveCost =\n geometricMoveCost *\n Math.max(\n 1,\n (this.problem.traceWidth / segmentWidth) **\n this.problem.neckPenaltyExponent,\n );\n this.enqueueNode({\n row,\n column,\n ...point,\n layerIndex: node.layerIndex,\n viaCount: node.viaCount,\n viaPoints: node.viaPoints,\n g: node.g + moveCost,\n parentIndex: nodeIndex,\n });\n }\n }\n\n private expandViaMoves(nodeIndex: number, node: SearchNode) {\n if (node.viaCount >= this.problem.maxViaCount) return;\n const minimumEndpointEscape = this.problem.gridSize * 0.5;\n if (\n distance(node, this.problem.start) < minimumEndpointEscape - 1e-9 ||\n distance(node, this.problem.end) < minimumEndpointEscape - 1e-9\n ) {\n return;\n }\n const parent =\n node.parentIndex >= 0 ? this.nodes[node.parentIndex] : undefined;\n // A same-location layer reversal only burns two vias and can never improve\n // the path, so remove it from the search graph entirely.\n if (\n parent &&\n parent.layerIndex !== node.layerIndex &&\n pointsEqual(parent, node)\n ) {\n return;\n }\n\n for (\n let nextLayerIndex = 0;\n nextLayerIndex < this.problem.layers.length;\n nextLayerIndex++\n ) {\n if (nextLayerIndex === node.layerIndex) continue;\n if (\n this.problem.obstacleIndex.collidesVia({\n point: node,\n layers: this.problem.layers,\n padDiameter: this.problem.viaDiameter,\n holeDiameter: this.problem.viaHoleDiameter,\n connectionNames: this.problem.connectionNames,\n ignoreTraceIndex: this.problem.ignoreTraceIndex,\n ignoreTraceIndices: this.problem.softTraceIndices,\n ignoreRouteRange: this.problem.ignoreRouteRange,\n obstacleClearance: this.problem.obstacleClearance,\n blockSameNetObstacles: true,\n sameNetObstacleClearance: 0,\n otherNewViaPoints: node.viaPoints,\n fixedVias: this.problem.fixedVias,\n })\n ) {\n continue;\n }\n this.enqueueNode({\n row: node.row,\n column: node.column,\n x: node.x,\n y: node.y,\n layerIndex: nextLayerIndex,\n viaCount: node.viaCount + 1,\n viaPoints: [...node.viaPoints, { x: node.x, y: node.y }],\n g: node.g + this.problem.viaCost,\n parentIndex: nodeIndex,\n });\n }\n }\n\n private enqueueNode(node: Omit<SearchNode, \"f\">) {\n const stateIndex = this.toStateIndex(node);\n if (\n this.closed.has(stateIndex) ||\n node.g >= (this.bestCost.get(stateIndex) ?? Number.POSITIVE_INFINITY)\n ) {\n return;\n }\n this.bestCost.set(stateIndex, node.g);\n const f = node.g + this.heuristic(node);\n const nextNodeIndex = this.nodes.length;\n this.nodes.push({ ...node, f });\n this.open.push(nextNodeIndex, f);\n }\n\n private endpointCollides(point: Point, layerIndex: number) {\n return (\n this.getSafeSegmentWidth({ ...point, layerIndex, viaCount: 0 }, point) <=\n 0\n );\n }\n\n private segmentCollides(\n start: Pick<SearchNode, \"x\" | \"y\" | \"layerIndex\" | \"viaCount\">,\n end: Point,\n ) {\n return this.getSafeSegmentWidth(start, end) <= 0;\n }\n\n private getSafeSegmentWidth(\n start: Pick<SearchNode, \"x\" | \"y\" | \"layerIndex\" | \"viaCount\">,\n end: Point,\n ) {\n const layer = this.problem.layers[start.layerIndex]!;\n const inStartNeck =\n this.problem.startLayers.length === 1 &&\n start.viaCount === 0 &&\n layer === this.problem.originalStartLayer &&\n distance(this.problem.start, start) <=\n this.problem.maxStartNeckLength + 1e-9 &&\n distance(this.problem.start, end) <=\n this.problem.maxStartNeckLength + 1e-9;\n const inEndNeck =\n this.problem.endLayers.length === 1 &&\n layer === this.problem.originalEndLayer &&\n distance(this.problem.end, start) <=\n this.problem.maxEndNeckLength + 1e-9 &&\n distance(this.problem.end, end) <= this.problem.maxEndNeckLength + 1e-9;\n const minimumWidth = Math.max(\n inStartNeck ? this.problem.startNeckWidth : 0,\n inEndNeck ? this.problem.endNeckWidth : 0,\n );\n const cacheKey = [\n start.x,\n start.y,\n end.x,\n end.y,\n start.layerIndex,\n start.viaCount,\n minimumWidth,\n ].join(\":\");\n const cachedWidth = this.segmentWidthCache.get(cacheKey);\n if (cachedWidth !== undefined) return cachedWidth;\n\n const isSafe = (width: number) =>\n !this.problem.obstacleIndex.collides({\n start,\n end,\n layer,\n width,\n connectionNames: this.problem.connectionNames,\n ignoreTraceIndex: this.problem.ignoreTraceIndex,\n ignoreTraceIndices: this.problem.softTraceIndices,\n ignoreRouteRange: this.problem.ignoreRouteRange,\n obstacleClearance: this.problem.obstacleClearance,\n });\n let safeWidth = 0;\n if (!inStartNeck && !inEndNeck) {\n safeWidth = isSafe(this.problem.traceWidth) ? this.problem.traceWidth : 0;\n } else {\n // Probe the full continuum at a fabrication-meaningful 0.025 mm\n // quantization. A monotonic binary search gives finer intermediate neck\n // widths than a small fixed fraction list without adding a hot-loop\n // performance bottleneck.\n const widthStep = 0.025;\n let low = Math.ceil((minimumWidth - 1e-9) / widthStep);\n let high = Math.floor((this.problem.traceWidth + 1e-9) / widthStep);\n while (low <= high) {\n const middle = Math.floor((low + high) / 2);\n const width = Number((middle * widthStep).toFixed(6));\n if (isSafe(width)) {\n safeWidth = width;\n low = middle + 1;\n } else {\n high = middle - 1;\n }\n }\n if (safeWidth < minimumWidth - 1e-9 && isSafe(minimumWidth)) {\n safeWidth = minimumWidth;\n }\n }\n this.segmentWidthCache.set(cacheKey, safeWidth);\n return safeWidth;\n }\n\n private reconstructRoute(goalNodeIndex: number): LayerGridRouteOutput {\n const path: SearchNode[] = [];\n let nodeIndex = goalNodeIndex;\n while (nodeIndex >= 0) {\n const node = this.nodes[nodeIndex]!;\n path.push(node);\n nodeIndex = node.parentIndex;\n }\n path.reverse();\n const goal = path[path.length - 1]!;\n if (!pointsEqual(goal, this.problem.end)) {\n path.push({\n ...goal,\n ...this.problem.end,\n row: this.targetCell.row,\n column: this.targetCell.column,\n parentIndex: -1,\n });\n }\n\n const sections: SearchNode[][] = [];\n let section: SearchNode[] = [path[0]!];\n for (let index = 1; index < path.length; index++) {\n const previous = path[index - 1]!;\n const current = path[index]!;\n if (current.layerIndex !== previous.layerIndex) {\n sections.push(section);\n section = [current];\n } else {\n section.push(current);\n }\n }\n sections.push(section);\n\n const route: CopperRoutePoint[] = [];\n for (let sectionIndex = 0; sectionIndex < sections.length; sectionIndex++) {\n const simplified = this.simplifySection(sections[sectionIndex]!);\n const edgeWidths = simplified\n .slice(0, -1)\n .map((point, index) =>\n this.getSafeSegmentWidth(point, simplified[index + 1]!),\n );\n const wirePoints: WireRoutePoint[] = simplified.map((point, index) => ({\n route_type: \"wire\",\n x: point.x,\n y: point.y,\n layer: this.problem.layers[point.layerIndex]!,\n // A vertex takes the smaller capacity of its incident segments. This\n // ensures max(endpoint widths) never exceeds either segment's tested\n // capacity and naturally creates a short, DRC-safe neck transition.\n width:\n edgeWidths.length === 0\n ? Math.min(this.problem.startNeckWidth, this.problem.endNeckWidth)\n : index === 0\n ? edgeWidths[0]!\n : index === simplified.length - 1\n ? edgeWidths[edgeWidths.length - 1]!\n : Math.min(edgeWidths[index - 1]!, edgeWidths[index]!),\n }));\n route.push(...wirePoints);\n\n const nextSection = sections[sectionIndex + 1];\n if (nextSection) {\n const fromLayer = this.problem.layers[simplified.at(-1)!.layerIndex]!;\n const toLayer = this.problem.layers[nextSection[0]!.layerIndex]!;\n const point = simplified.at(-1)!;\n route.push({\n route_type: \"via\",\n x: point.x,\n y: point.y,\n from_layer: fromLayer,\n to_layer: toLayer,\n via_diameter: this.problem.viaDiameter,\n via_hole_diameter: this.problem.viaHoleDiameter,\n });\n }\n }\n\n return {\n route,\n traceWidth: this.problem.traceWidth,\n startNeckWidth: this.problem.startNeckWidth,\n endNeckWidth: this.problem.endNeckWidth,\n gridSize: this.problem.gridSize,\n gridOffset: this.problem.gridOffset,\n viaCount: sections.length - 1,\n };\n }\n\n private simplifySection(points: SearchNode[]) {\n if (points.length <= 2) return points;\n if (this.problem.neckPenaltyExponent > 1) {\n return this.simplifyStrictSection(points);\n }\n return this.simplifyWidthPreservingSection(points);\n }\n\n private simplifyStrictSection(points: SearchNode[]) {\n const edgeWidths = points\n .slice(0, -1)\n .map((point, index) =>\n this.getSafeSegmentWidth(point, points[index + 1]!),\n );\n const electricalCostPrefix = [0];\n for (let index = 0; index < edgeWidths.length; index++) {\n electricalCostPrefix.push(\n electricalCostPrefix[index]! +\n this.getWidthPenalizedCost(\n points[index]!,\n points[index + 1]!,\n edgeWidths[index]!,\n ),\n );\n }\n const simplified = [points[0]!];\n let anchorIndex = 0;\n while (anchorIndex < points.length - 1) {\n let nextIndex = points.length - 1;\n while (\n nextIndex > anchorIndex + 1 &&\n !this.shortcutPreservesRouteQuality(\n points,\n edgeWidths,\n electricalCostPrefix,\n anchorIndex,\n nextIndex,\n )\n ) {\n nextIndex--;\n }\n simplified.push(points[nextIndex]!);\n anchorIndex = nextIndex;\n }\n return this.removeRedundantCollinearPoints(simplified);\n }\n\n private shortcutPreservesRouteQuality(\n points: SearchNode[],\n edgeWidths: number[],\n electricalCostPrefix: number[],\n startIndex: number,\n endIndex: number,\n ) {\n const width = this.getSafeSegmentWidth(\n points[startIndex]!,\n points[endIndex]!,\n );\n if (width <= 0) return false;\n let minimumOriginalWidth = Number.POSITIVE_INFINITY;\n for (let index = startIndex; index < endIndex; index++) {\n minimumOriginalWidth = Math.min(minimumOriginalWidth, edgeWidths[index]!);\n }\n const originalCost =\n electricalCostPrefix[endIndex]! - electricalCostPrefix[startIndex]!;\n return (\n width >= minimumOriginalWidth - 1e-9 &&\n this.getWidthPenalizedCost(\n points[startIndex]!,\n points[endIndex]!,\n width,\n ) <=\n originalCost + 1e-9\n );\n }\n\n private getWidthPenalizedCost(start: Point, end: Point, width: number) {\n return (\n distance(start, end) *\n Math.max(\n 1,\n (this.problem.traceWidth / width) ** this.problem.neckPenaltyExponent,\n )\n );\n }\n\n private simplifyWidthPreservingSection(points: SearchNode[]) {\n const edgeWidths = points\n .slice(0, -1)\n .map((point, index) =>\n this.getSafeSegmentWidth(point, points[index + 1]!),\n );\n const electricalCostPrefix = [0];\n for (let index = 0; index < edgeWidths.length; index++) {\n electricalCostPrefix.push(\n electricalCostPrefix[index]! +\n distance(points[index]!, points[index + 1]!) *\n Math.max(\n 1,\n (this.problem.traceWidth / edgeWidths[index]!) **\n this.problem.neckPenaltyExponent,\n ),\n );\n }\n\n const deficitByIndex = new Float64Array(points.length).fill(\n Number.POSITIVE_INFINITY,\n );\n const lengthByIndex = new Float64Array(points.length).fill(\n Number.POSITIVE_INFINITY,\n );\n const previousIndex = new Int32Array(points.length).fill(-1);\n deficitByIndex[0] = 0;\n lengthByIndex[0] = 0;\n\n for (let endIndex = 1; endIndex < points.length; endIndex++) {\n let minimumOriginalWidth = Number.POSITIVE_INFINITY;\n for (let startIndex = endIndex - 1; startIndex >= 0; startIndex--) {\n minimumOriginalWidth = Math.min(\n minimumOriginalWidth,\n edgeWidths[startIndex]!,\n );\n if (!Number.isFinite(deficitByIndex[startIndex]!)) continue;\n const width = this.getSafeSegmentWidth(\n points[startIndex]!,\n points[endIndex]!,\n );\n if (width < minimumOriginalWidth - 1e-9) continue;\n const segmentLength = distance(points[startIndex]!, points[endIndex]!);\n const electricalCost =\n segmentLength *\n Math.max(\n 1,\n (this.problem.traceWidth / width) **\n this.problem.neckPenaltyExponent,\n );\n const originalElectricalCost =\n electricalCostPrefix[endIndex]! - electricalCostPrefix[startIndex]!;\n if (electricalCost > originalElectricalCost + 1e-9) continue;\n\n const candidateDeficit =\n deficitByIndex[startIndex]! +\n segmentLength * Math.max(0, this.problem.traceWidth - width);\n const candidateLength = lengthByIndex[startIndex]! + segmentLength;\n if (\n candidateDeficit < deficitByIndex[endIndex]! - 1e-9 ||\n (Math.abs(candidateDeficit - deficitByIndex[endIndex]!) <= 1e-9 &&\n candidateLength < lengthByIndex[endIndex]! - 1e-9)\n ) {\n deficitByIndex[endIndex] = candidateDeficit;\n lengthByIndex[endIndex] = candidateLength;\n previousIndex[endIndex] = startIndex;\n }\n }\n }\n\n const simplified: SearchNode[] = [];\n let cursor = points.length - 1;\n while (cursor >= 0) {\n simplified.push(points[cursor]!);\n if (cursor === 0) break;\n cursor = previousIndex[cursor]!;\n // Consecutive raw edges are always valid, so this is defensive only.\n if (cursor < 0) return points;\n }\n simplified.reverse();\n return this.removeRedundantCollinearPoints(simplified);\n }\n\n private removeRedundantCollinearPoints(points: SearchNode[]) {\n return points.filter((point, index, allPoints) => {\n if (index === 0 || index === allPoints.length - 1) return true;\n const previous = allPoints[index - 1]!;\n const next = allPoints[index + 1]!;\n const cross =\n (point.x - previous.x) * (next.y - point.y) -\n (point.y - previous.y) * (next.x - point.x);\n const sameWidth =\n Math.abs(\n this.getSafeSegmentWidth(previous, point) -\n this.getSafeSegmentWidth(point, next),\n ) < 1e-9;\n return Math.abs(cross) > 1e-8 || !sameWidth;\n });\n }\n\n private pointToCell(point: Point) {\n return {\n column: clamp(\n Math.round((point.x - this.origin.x) / this.problem.gridSize),\n 0,\n this.columns - 1,\n ),\n row: clamp(\n Math.round((point.y - this.origin.y) / this.problem.gridSize),\n 0,\n this.rows - 1,\n ),\n };\n }\n\n private cellToPoint(row: number, column: number): Point {\n return {\n x: this.origin.x + column * this.problem.gridSize,\n y: this.origin.y + row * this.problem.gridSize,\n };\n }\n\n private toStateIndex(\n node: Pick<\n SearchNode,\n \"row\" | \"column\" | \"x\" | \"y\" | \"layerIndex\" | \"viaCount\" | \"viaPoints\"\n >,\n ) {\n const baseStateIndex =\n ((node.viaCount * this.problem.layers.length + node.layerIndex) *\n this.rows +\n node.row) *\n this.columns +\n node.column;\n if (\n node.viaCount !== 1 ||\n node.viaPoints.length === 0 ||\n distance(node, node.viaPoints[0]!) >=\n this.problem.viaHoleDiameter +\n this.problem.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance -\n 1e-9\n ) {\n return baseStateIndex;\n }\n const firstViaCell = this.pointToCell(node.viaPoints[0]!);\n const viaHistoryIndex =\n 1 + firstViaCell.row * this.columns + firstViaCell.column;\n return baseStateIndex + viaHistoryIndex * this.baseStateCount;\n }\n\n private heuristic(point: Point) {\n return distance(point, this.problem.end);\n }\n\n private createStats() {\n return {\n phase: \"layer-aware-grid-search\",\n gridSize: this.problem.gridSize,\n traceWidth: this.problem.traceWidth,\n startNeckWidth: this.problem.startNeckWidth,\n endNeckWidth: this.problem.endNeckWidth,\n maxViaCount: this.problem.maxViaCount,\n minViaCount: this.problem.minViaCount,\n openStates: this.open.size,\n closedStates: this.closedStateCount,\n trackedStates: this.bestCost.size,\n stateSpaceUpperBound: this.stateSpaceUpperBound,\n };\n }\n\n computeProgress() {\n return Math.min(0.99, this.iterations / this.MAX_ITERATIONS);\n }\n\n override getOutput() {\n return this.output;\n }\n\n override getConstructorParams() {\n const { obstacleIndex: _obstacleIndex, ...serializableProblem } =\n this.problem;\n return [serializableProblem];\n }\n\n override visualize(): GraphicsObject {\n const visitedPoints = this.nodes\n .filter((node) => this.closed.has(this.toStateIndex(node)))\n .slice(-2_000)\n .map((node) => ({\n x: node.x,\n y: node.y,\n color: `${LAYER_COLORS[node.layerIndex % LAYER_COLORS.length]}55`,\n }));\n const lines: NonNullable<GraphicsObject[\"lines\"]> = [];\n const circles: NonNullable<GraphicsObject[\"circles\"]> = [];\n const outputRoute = this.output?.route ?? [];\n for (let index = 0; index < outputRoute.length - 1; index++) {\n const start = outputRoute[index];\n const end = outputRoute[index + 1];\n if (\n start?.route_type === \"wire\" &&\n end?.route_type === \"wire\" &&\n start.layer === end.layer\n ) {\n const layerIndex = this.problem.layers.indexOf(start.layer);\n lines.push({\n points: [start, end],\n strokeColor: LAYER_COLORS[layerIndex % LAYER_COLORS.length] ?? \"#333\",\n strokeWidth: start.width,\n });\n }\n if (start?.route_type === \"via\") {\n circles.push({\n center: start,\n radius: (start.via_diameter ?? this.problem.viaDiameter) / 2,\n fill: \"#d4a017\",\n });\n }\n }\n return {\n coordinateSystem: \"cartesian\",\n title: this.getSolverName(),\n rects: [\n {\n center: {\n x: (this.searchBounds.minX + this.searchBounds.maxX) / 2,\n y: (this.searchBounds.minY + this.searchBounds.maxY) / 2,\n },\n width: this.searchBounds.maxX - this.searchBounds.minX,\n height: this.searchBounds.maxY - this.searchBounds.minY,\n stroke: \"#777\",\n },\n ],\n points: [\n ...visitedPoints,\n { ...this.problem.start, color: \"green\", label: \"reroute start\" },\n { ...this.problem.end, color: \"purple\", label: \"reroute target\" },\n ],\n lines,\n circles,\n texts: [],\n };\n }\n}\n","import { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { clamp, distance, pointsEqual } from \"./geometry\";\nimport type {\n ElasticTracePushOutput,\n ElasticTracePushProblem,\n InflationCorridorSegment,\n Point,\n} from \"./types\";\n\ntype ElasticPhase =\n | \"prepare-candidate\"\n | \"relax-candidate\"\n | \"validate-candidate\"\n | \"complete\";\n\nconst CANDIDATE_VARIANTS = [\n { direction: 1, strength: 0.7 },\n { direction: -1, strength: 0.7 },\n { direction: 1, strength: 1 },\n { direction: -1, strength: 1 },\n] as const;\n\nconst closestPointOnSegment = (point: Point, start: Point, end: Point) => {\n const deltaX = end.x - start.x;\n const deltaY = end.y - start.y;\n const lengthSquared = deltaX * deltaX + deltaY * deltaY;\n if (lengthSquared <= 1e-12) return { ...start };\n const t = clamp(\n ((point.x - start.x) * deltaX + (point.y - start.y) * deltaY) /\n lengthSquared,\n 0,\n 1,\n );\n return { x: start.x + deltaX * t, y: start.y + deltaY * t };\n};\n\n/**\n * Applies a small, smooth displacement to a blocking trace before falling\n * back to A*. Each relaxation pass is one debugger step, so the inflation\n * force and its eventual acceptance remain inspectable.\n */\nexport class ElasticTracePushSolver extends BaseSolver {\n readonly problem: ElasticTracePushProblem;\n phase: ElasticPhase = \"prepare-candidate\";\n variantCursor = 0;\n relaxationIteration = 0;\n candidatePoints: Point[] = [];\n\n private readonly sampledPoints: Point[];\n private output: ElasticTracePushOutput | null = null;\n\n constructor(problem: ElasticTracePushProblem) {\n super();\n this.problem = problem;\n this.sampledPoints = this.sampleRoute();\n this.MAX_ITERATIONS = 100;\n this.stats = this.createStats();\n }\n\n override getSolverName() {\n return \"ElasticTracePushSolver\";\n }\n\n override _step() {\n switch (this.phase) {\n case \"prepare-candidate\":\n if (this.variantCursor >= CANDIDATE_VARIANTS.length) {\n this.failed = true;\n this.error = \"No collision-free elastic displacement found\";\n return;\n }\n this.candidatePoints = this.sampledPoints.map((point) => ({\n ...point,\n }));\n this.relaxationIteration = 0;\n this.phase = \"relax-candidate\";\n break;\n case \"relax-candidate\":\n this.relaxCandidate();\n this.relaxationIteration++;\n if (this.relaxationIteration >= 10) {\n this.phase = \"validate-candidate\";\n }\n break;\n case \"validate-candidate\": {\n const simplified = this.simplifyCandidate(this.candidatePoints);\n if (!this.pathCollides(simplified)) {\n this.output = {\n points: simplified,\n traceWidth: this.problem.traceWidth,\n };\n this.phase = \"complete\";\n } else {\n this.variantCursor++;\n this.phase = \"prepare-candidate\";\n }\n break;\n }\n case \"complete\":\n this.solved = true;\n break;\n }\n this.stats = this.createStats();\n }\n\n private sampleRoute() {\n const points: Point[] = [];\n const spacing = clamp(this.problem.traceWidth * 2, 0.2, 0.45);\n const route = this.problem.trace.route;\n for (\n let index = this.problem.range.startIndex;\n index < this.problem.range.endIndex;\n index++\n ) {\n const start = route[index];\n const end = route[index + 1];\n if (\n start?.route_type !== \"wire\" ||\n end?.route_type !== \"wire\" ||\n start.layer !== end.layer\n )\n continue;\n if (points.length === 0) points.push({ x: start.x, y: start.y });\n const segmentLength = distance(start, end);\n const sampleCount = Math.max(1, Math.ceil(segmentLength / spacing));\n for (let sample = 1; sample <= sampleCount; sample++) {\n const t = sample / sampleCount;\n points.push({\n x: start.x + (end.x - start.x) * t,\n y: start.y + (end.y - start.y) * t,\n });\n }\n }\n return points;\n }\n\n private relaxCandidate() {\n const variant = CANDIDATE_VARIANTS[this.variantCursor]!;\n const nextPoints = this.candidatePoints.map((point) => ({ ...point }));\n const moved = new Uint8Array(this.candidatePoints.length);\n\n for (let index = 1; index < this.candidatePoints.length - 1; index++) {\n const point = this.candidatePoints[index]!;\n const nearest = this.findNearestCorridorSegment(point);\n if (!nearest) continue;\n const segmentLength = distance(\n nearest.segment.start,\n nearest.segment.end,\n );\n if (segmentLength <= 1e-9) continue;\n const requiredDistance =\n nearest.segment.width / 2 +\n this.problem.traceWidth / 2 +\n this.problem.obstacleIndex.clearance +\n 0.025;\n if (nearest.distance > requiredDistance + 0.35) continue;\n const normal = {\n x:\n ((nearest.segment.start.y - nearest.segment.end.y) / segmentLength) *\n variant.direction,\n y:\n ((nearest.segment.end.x - nearest.segment.start.x) / segmentLength) *\n variant.direction,\n };\n const signedDistance =\n (point.x - nearest.closest.x) * normal.x +\n (point.y - nearest.closest.y) * normal.y;\n const penetration = requiredDistance - signedDistance;\n if (penetration <= 0) continue;\n const step = Math.min(0.35, penetration * variant.strength);\n nextPoints[index] = {\n x: point.x + normal.x * step,\n y: point.y + normal.y * step,\n };\n moved[index] = 1;\n }\n\n for (let index = 1; index < nextPoints.length - 1; index++) {\n if (!moved[index]) continue;\n const previous = nextPoints[index - 1]!;\n const current = nextPoints[index]!;\n const next = nextPoints[index + 1]!;\n nextPoints[index] = {\n x: current.x * 0.85 + ((previous.x + next.x) / 2) * 0.15,\n y: current.y * 0.85 + ((previous.y + next.y) / 2) * 0.15,\n };\n }\n this.candidatePoints = nextPoints;\n }\n\n private findNearestCorridorSegment(point: Point) {\n let nearest:\n | {\n segment: InflationCorridorSegment;\n closest: Point;\n distance: number;\n }\n | undefined;\n for (const segment of this.problem.corridor) {\n if (segment.layer !== this.problem.layer) continue;\n const closest = closestPointOnSegment(point, segment.start, segment.end);\n const pointDistance = distance(point, closest);\n if (!nearest || pointDistance < nearest.distance) {\n nearest = { segment, closest, distance: pointDistance };\n }\n }\n return nearest;\n }\n\n private simplifyCandidate(points: Point[]) {\n if (points.length <= 2) return points;\n const simplified = [points[0]!];\n let anchorIndex = 0;\n while (anchorIndex < points.length - 1) {\n let nextIndex = points.length - 1;\n while (\n nextIndex > anchorIndex + 1 &&\n this.segmentCollides(points[anchorIndex]!, points[nextIndex]!)\n ) {\n nextIndex--;\n }\n simplified.push(points[nextIndex]!);\n anchorIndex = nextIndex;\n }\n return simplified.filter(\n (point, index, allPoints) =>\n index === 0 || !pointsEqual(point, allPoints[index - 1]!),\n );\n }\n\n private pathCollides(points: Point[]) {\n if (points.length < 2) return true;\n for (let index = 0; index < points.length - 1; index++) {\n if (this.segmentCollides(points[index]!, points[index + 1]!)) return true;\n }\n return false;\n }\n\n private segmentCollides(start: Point, end: Point) {\n return this.problem.obstacleIndex.collides({\n start,\n end,\n layer: this.problem.layer,\n width: this.problem.traceWidth,\n connectionNames: this.problem.connectionNames,\n ignoreTraceIndex: -1,\n });\n }\n\n private createStats() {\n const variant = CANDIDATE_VARIANTS[this.variantCursor];\n return {\n phase: this.phase,\n direction: variant?.direction,\n strength: variant?.strength,\n variantCursor: this.variantCursor,\n relaxationIteration: this.relaxationIteration,\n sampledPointCount: this.sampledPoints.length,\n };\n }\n\n computeProgress() {\n return Math.min(\n 0.99,\n (this.variantCursor + this.relaxationIteration / 12) /\n CANDIDATE_VARIANTS.length,\n );\n }\n\n override getOutput() {\n return this.output;\n }\n\n override getConstructorParams() {\n return [this.problem];\n }\n\n override visualize(): GraphicsObject {\n return {\n coordinateSystem: \"cartesian\",\n title: `Elastic trace push: ${this.phase}`,\n lines: [\n ...this.problem.corridor.map((segment) => ({\n points: [segment.start, segment.end],\n strokeColor: \"rgba(255, 128, 0, 0.6)\",\n strokeWidth: segment.width,\n })),\n ...(this.candidatePoints.length > 1\n ? [\n {\n points: this.candidatePoints,\n strokeColor: \"#1769d2\",\n strokeWidth: this.problem.traceWidth,\n },\n ]\n : []),\n ],\n points: [],\n rects: [],\n circles: [],\n texts: [],\n };\n }\n}\n","import { distance, pointsEqual, WIDTH_EPSILON } from \"./geometry\";\nimport type { Point } from \"./types\";\n\nexport const isOctilinearSegment = (start: Point, end: Point) => {\n const deltaX = Math.abs(end.x - start.x);\n const deltaY = Math.abs(end.y - start.y);\n return (\n deltaX <= WIDTH_EPSILON ||\n deltaY <= WIDTH_EPSILON ||\n Math.abs(deltaX - deltaY) <= WIDTH_EPSILON\n );\n};\n\nexport const countNonOctilinearSegments = (points: Point[]) => {\n let count = 0;\n for (let index = 0; index < points.length - 1; index++) {\n if (!isOctilinearSegment(points[index]!, points[index + 1]!)) count++;\n }\n return count;\n};\n\nexport const getPathLength = (points: Point[]) => {\n let length = 0;\n for (let index = 0; index < points.length - 1; index++) {\n length += distance(points[index]!, points[index + 1]!);\n }\n return length;\n};\n\nconst removeDuplicatePoints = (points: Point[]) =>\n points.filter(\n (point, index) => index === 0 || !pointsEqual(point, points[index - 1]!),\n );\n\n/**\n * Returns the compact 0/45/90-degree paths used by the autorouter's path\n * simplifier. Direct, one-bend Manhattan, and one-bend diagonal variants are\n * deliberately kept separate so an obstacle index can rank them cheaply.\n */\nexport const calculateOctilinearPaths = (start: Point, end: Point) => {\n const deltaX = end.x - start.x;\n const deltaY = end.y - start.y;\n const absoluteX = Math.abs(deltaX);\n const absoluteY = Math.abs(deltaY);\n const signX = Math.sign(deltaX);\n const signY = Math.sign(deltaY);\n const candidates: Point[][] = [];\n\n if (isOctilinearSegment(start, end)) candidates.push([start, end]);\n candidates.push(\n [start, { x: end.x, y: start.y }, end],\n [start, { x: start.x, y: end.y }, end],\n );\n\n if (absoluteX >= absoluteY) {\n candidates.push(\n [start, { x: end.x - signX * absoluteY, y: start.y }, end],\n [start, { x: start.x + signX * absoluteY, y: end.y }, end],\n );\n } else {\n candidates.push(\n [start, { x: start.x, y: end.y - signY * absoluteX }, end],\n [start, { x: end.x, y: start.y + signY * absoluteX }, end],\n );\n }\n\n const uniquePaths = new Map<string, Point[]>();\n for (const candidate of candidates) {\n const path = removeDuplicatePoints(candidate);\n if (\n path.length < 2 ||\n path.some(\n (point, index) =>\n index < path.length - 1 &&\n !isOctilinearSegment(point, path[index + 1]!),\n )\n ) {\n continue;\n }\n const key = path\n .map((point) => `${point.x.toFixed(6)},${point.y.toFixed(6)}`)\n .join(\";\");\n uniquePaths.set(key, path);\n }\n return [...uniquePaths.values()].sort(\n (a, b) => getPathLength(a) - getPathLength(b) || a.length - b.length,\n );\n};\n","import { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { clamp, pointsEqual } from \"./geometry\";\nimport {\n calculateOctilinearPaths,\n getPathLength,\n isOctilinearSegment,\n} from \"./octilinear\";\nimport type { GridRouteOutput, GridRouteProblem, Point } from \"./types\";\n\ntype SearchNode = {\n row: number;\n column: number;\n x: number;\n y: number;\n g: number;\n f: number;\n parentIndex: number;\n};\n\nclass MinHeap {\n private nodeIndices: number[] = [];\n private priorities: number[] = [];\n\n get size() {\n return this.nodeIndices.length;\n }\n\n push(nodeIndex: number, priority: number) {\n let index = this.nodeIndices.length;\n this.nodeIndices.push(nodeIndex);\n this.priorities.push(priority);\n while (index > 0) {\n const parent = (index - 1) >> 1;\n if (this.priorities[parent]! <= priority) break;\n this.swap(index, parent);\n index = parent;\n }\n }\n\n pop(): number {\n const result = this.nodeIndices[0]!;\n const lastNode = this.nodeIndices.pop()!;\n const lastPriority = this.priorities.pop()!;\n if (this.nodeIndices.length === 0) return result;\n this.nodeIndices[0] = lastNode;\n this.priorities[0] = lastPriority;\n let index = 0;\n while (true) {\n const left = index * 2 + 1;\n const right = left + 1;\n if (left >= this.nodeIndices.length) break;\n let smallest = left;\n if (\n right < this.nodeIndices.length &&\n this.priorities[right]! < this.priorities[left]!\n ) {\n smallest = right;\n }\n if (this.priorities[index]! <= this.priorities[smallest]!) break;\n this.swap(index, smallest);\n index = smallest;\n }\n return result;\n }\n\n private swap(a: number, b: number) {\n [this.nodeIndices[a], this.nodeIndices[b]] = [\n this.nodeIndices[b]!,\n this.nodeIndices[a]!,\n ];\n [this.priorities[a], this.priorities[b]] = [\n this.priorities[b]!,\n this.priorities[a]!,\n ];\n }\n}\n\nconst DIRECTIONS = [\n [-1, -1],\n [-1, 0],\n [-1, 1],\n [0, -1],\n [0, 1],\n [1, -1],\n [1, 0],\n [1, 1],\n] as const;\n\nexport class ObstacleAwareGridRouteSolver extends BaseSolver {\n readonly problem: GridRouteProblem;\n readonly searchBounds: GridRouteProblem[\"bounds\"];\n readonly rows: number;\n readonly columns: number;\n readonly origin: Point;\n\n private readonly nodes: SearchNode[] = [];\n private readonly open = new MinHeap();\n private readonly bestCost: Float64Array;\n private readonly closed: Uint8Array;\n private closedCellCount = 0;\n private targetCell: { row: number; column: number };\n private output: GridRouteOutput | null = null;\n\n constructor(problem: GridRouteProblem) {\n super();\n this.problem = problem;\n const radius = problem.traceWidth / 2 + problem.obstacleIndex.clearance;\n const minX = clamp(\n Math.min(problem.start.x, problem.end.x) - problem.searchPadding,\n problem.bounds.minX + radius,\n problem.bounds.maxX - radius,\n );\n const maxX = clamp(\n Math.max(problem.start.x, problem.end.x) + problem.searchPadding,\n problem.bounds.minX + radius,\n problem.bounds.maxX - radius,\n );\n const minY = clamp(\n Math.min(problem.start.y, problem.end.y) - problem.searchPadding,\n problem.bounds.minY + radius,\n problem.bounds.maxY - radius,\n );\n const maxY = clamp(\n Math.max(problem.start.y, problem.end.y) + problem.searchPadding,\n problem.bounds.minY + radius,\n problem.bounds.maxY - radius,\n );\n const alignedMinX =\n Math.floor((minX - problem.gridOffset.x) / problem.gridSize) *\n problem.gridSize +\n problem.gridOffset.x;\n const alignedMinY =\n Math.floor((minY - problem.gridOffset.y) / problem.gridSize) *\n problem.gridSize +\n problem.gridOffset.y;\n this.origin = { x: alignedMinX, y: alignedMinY };\n this.columns = Math.max(\n 2,\n Math.floor((maxX - alignedMinX) / problem.gridSize) + 1,\n );\n this.rows = Math.max(\n 2,\n Math.floor((maxY - alignedMinY) / problem.gridSize) + 1,\n );\n this.searchBounds = {\n minX: alignedMinX,\n minY: alignedMinY,\n maxX: alignedMinX + (this.columns - 1) * problem.gridSize,\n maxY: alignedMinY + (this.rows - 1) * problem.gridSize,\n };\n this.bestCost = new Float64Array(this.rows * this.columns).fill(\n Number.POSITIVE_INFINITY,\n );\n this.closed = new Uint8Array(this.rows * this.columns);\n if (\n this.endpointCollides(problem.start) ||\n this.endpointCollides(problem.end)\n ) {\n this.failed = true;\n this.error = \"Grid-route endpoint violates obstacle clearance\";\n this.targetCell = { row: 0, column: 0 };\n this.MAX_ITERATIONS = 1;\n this.stats = this.createStats();\n return;\n }\n const startCell = this.pointToCell(problem.start);\n this.targetCell = this.pointToCell(problem.end);\n const startNode: SearchNode = {\n ...startCell,\n x: problem.start.x,\n y: problem.start.y,\n g: 0,\n f: this.heuristic(problem.start),\n parentIndex: -1,\n };\n this.nodes.push(startNode);\n this.open.push(0, startNode.f);\n this.bestCost[this.toFlatIndex(startCell.row, startCell.column)] = 0;\n this.MAX_ITERATIONS = Math.min(\n 5_000,\n Math.max(1_000, this.rows * this.columns * 2),\n );\n this.stats = this.createStats();\n }\n\n private endpointCollides(point: Point) {\n return this.problem.obstacleIndex.collides({\n start: point,\n end: point,\n layer: this.problem.layer,\n width: this.problem.traceWidth,\n connectionNames: this.problem.connectionNames,\n ignoreTraceIndex: this.problem.ignoreTraceIndex,\n ignoreRouteRange: this.problem.ignoreRouteRange,\n obstacleClearance: this.problem.obstacleClearance,\n });\n }\n\n override getSolverName() {\n return `ObstacleAwareGridRouteSolver(${this.problem.gridSize.toFixed(3)}mm)`;\n }\n\n override _step() {\n if (this.open.size === 0) {\n this.failed = true;\n this.error = \"No collision-free grid route found\";\n return;\n }\n\n const nodeIndex = this.open.pop();\n const node = this.nodes[nodeIndex]!;\n const flatIndex = this.toFlatIndex(node.row, node.column);\n if (this.closed[flatIndex]) return;\n this.closed[flatIndex] = 1;\n this.closedCellCount++;\n\n if (\n node.row === this.targetCell.row &&\n node.column === this.targetCell.column &&\n this.getAllowedConnector(node, this.problem.end) !== null\n ) {\n this.output = {\n points: this.reconstructPath(nodeIndex),\n traceWidth: this.problem.traceWidth,\n gridSize: this.problem.gridSize,\n gridOffset: this.problem.gridOffset,\n };\n this.solved = true;\n this.stats = this.createStats();\n return;\n }\n\n for (const [deltaRow, deltaColumn] of DIRECTIONS) {\n const row = node.row + deltaRow;\n const column = node.column + deltaColumn;\n if (row < 0 || row >= this.rows || column < 0 || column >= this.columns)\n continue;\n const nextFlatIndex = this.toFlatIndex(row, column);\n if (this.closed[nextFlatIndex]) continue;\n const point = this.cellToPoint(row, column);\n const connector = this.getAllowedConnector(node, point);\n if (connector === null) continue;\n\n const moveCost =\n node.parentIndex === -1 && this.problem.requireOctilinear\n ? getPathLength(connector)\n : this.problem.gridSize *\n (deltaRow !== 0 && deltaColumn !== 0 ? Math.SQRT2 : 1);\n const g = node.g + moveCost;\n if (g >= this.bestCost[nextFlatIndex]!) continue;\n this.bestCost[nextFlatIndex] = g;\n const f = g + this.heuristic(point);\n const nextNodeIndex = this.nodes.length;\n this.nodes.push({\n row,\n column,\n ...point,\n g,\n f,\n parentIndex: nodeIndex,\n });\n this.open.push(nextNodeIndex, f);\n }\n this.stats = this.createStats();\n }\n\n private segmentCollides(start: Point, end: Point) {\n return this.problem.obstacleIndex.collides({\n start,\n end,\n layer: this.problem.layer,\n width: this.problem.traceWidth,\n connectionNames: this.problem.connectionNames,\n ignoreTraceIndex: this.problem.ignoreTraceIndex,\n ignoreRouteRange: this.problem.ignoreRouteRange,\n obstacleClearance: this.problem.obstacleClearance,\n });\n }\n\n private getAllowedConnector(start: SearchNode | Point, end: Point) {\n const isTerminalConnector =\n this.problem.requireOctilinear &&\n ((\"parentIndex\" in start && start.parentIndex === -1) ||\n pointsEqual(end, this.problem.end));\n if (!isTerminalConnector) {\n return this.segmentCollides(start, end) ? null : [start, end];\n }\n return (\n calculateOctilinearPaths(start, end).find((path) =>\n path\n .slice(0, -1)\n .every(\n (point, index) => !this.segmentCollides(point, path[index + 1]!),\n ),\n ) ?? null\n );\n }\n\n private pointToCell(point: Point) {\n return {\n column: clamp(\n Math.round((point.x - this.origin.x) / this.problem.gridSize),\n 0,\n this.columns - 1,\n ),\n row: clamp(\n Math.round((point.y - this.origin.y) / this.problem.gridSize),\n 0,\n this.rows - 1,\n ),\n };\n }\n\n private cellToPoint(row: number, column: number): Point {\n return {\n x: this.origin.x + column * this.problem.gridSize,\n y: this.origin.y + row * this.problem.gridSize,\n };\n }\n\n private toFlatIndex(row: number, column: number) {\n return row * this.columns + column;\n }\n\n private heuristic(point: Point) {\n return Math.hypot(\n this.problem.end.x - point.x,\n this.problem.end.y - point.y,\n );\n }\n\n private reconstructPath(goalNodeIndex: number) {\n const points: Point[] = [];\n let nodeIndex = goalNodeIndex;\n while (nodeIndex >= 0) {\n const node = this.nodes[nodeIndex]!;\n points.push({ x: node.x, y: node.y });\n nodeIndex = node.parentIndex;\n }\n points.reverse();\n if (!pointsEqual(points[0]!, this.problem.start)) {\n points.unshift({ ...this.problem.start });\n }\n if (!pointsEqual(points[points.length - 1]!, this.problem.end)) {\n points.push({ ...this.problem.end });\n }\n if (this.problem.requireOctilinear) {\n const octilinearPoints: Point[] = [points[0]!];\n for (let index = 0; index < points.length - 1; index++) {\n const start = points[index]!;\n const end = points[index + 1]!;\n const isTerminal = index === 0 || index === points.length - 2;\n const connector = isTerminal\n ? this.getAllowedConnector(\n index === 0\n ? ({ ...start, parentIndex: -1 } as SearchNode)\n : start,\n end,\n )\n : [start, end];\n if (!connector) return points;\n octilinearPoints.push(...connector.slice(1));\n }\n return octilinearPoints.filter((point, index, allPoints) => {\n if (index === 0 || index === allPoints.length - 1) return true;\n const previous = allPoints[index - 1]!;\n const next = allPoints[index + 1]!;\n const cross =\n (point.x - previous.x) * (next.y - point.y) -\n (point.y - previous.y) * (next.x - point.x);\n return Math.abs(cross) > 1e-8 || !isOctilinearSegment(previous, next);\n });\n }\n const lineOfSightPoints: Point[] = [points[0]!];\n let anchorIndex = 0;\n while (anchorIndex < points.length - 1) {\n let nextIndex = points.length - 1;\n while (\n nextIndex > anchorIndex + 1 &&\n this.segmentCollides(points[anchorIndex]!, points[nextIndex]!)\n ) {\n nextIndex--;\n }\n lineOfSightPoints.push(points[nextIndex]!);\n anchorIndex = nextIndex;\n }\n return lineOfSightPoints.filter((point, index, allPoints) => {\n if (index === 0 || index === allPoints.length - 1) return true;\n const previous = allPoints[index - 1]!;\n const next = allPoints[index + 1]!;\n const cross =\n (point.x - previous.x) * (next.y - point.y) -\n (point.y - previous.y) * (next.x - point.x);\n return Math.abs(cross) > 1e-8;\n });\n }\n\n private createStats() {\n return {\n phase: \"obstacle-aware-grid-search\",\n gridSize: this.problem.gridSize,\n traceWidth: this.problem.traceWidth,\n gridOffset: this.problem.gridOffset,\n openCells: this.open.size,\n closedCells: this.closedCellCount,\n gridCells: this.rows * this.columns,\n };\n }\n\n computeProgress() {\n return Math.min(0.99, this.iterations / this.MAX_ITERATIONS);\n }\n\n override getOutput(): GridRouteOutput | null {\n return this.output;\n }\n\n override getConstructorParams() {\n const { obstacleIndex: _obstacleIndex, ...serializableProblem } =\n this.problem;\n return [serializableProblem];\n }\n\n override visualize(): GraphicsObject {\n const visitedPoints = this.nodes\n .filter((node) => this.closed[this.toFlatIndex(node.row, node.column)])\n .slice(-2_000)\n .map((node) => ({ x: node.x, y: node.y, color: \"rgba(0,90,255,0.22)\" }));\n const output = this.output?.points ?? [];\n return {\n coordinateSystem: \"cartesian\",\n title: this.getSolverName(),\n rects: [\n {\n center: {\n x: (this.searchBounds.minX + this.searchBounds.maxX) / 2,\n y: (this.searchBounds.minY + this.searchBounds.maxY) / 2,\n },\n width: this.searchBounds.maxX - this.searchBounds.minX,\n height: this.searchBounds.maxY - this.searchBounds.minY,\n stroke: \"#777\",\n },\n ],\n points: [\n ...visitedPoints,\n { ...this.problem.start, color: \"green\", label: \"reroute start\" },\n { ...this.problem.end, color: \"purple\", label: \"reroute target\" },\n ],\n lines:\n output.length > 1\n ? [\n {\n points: output,\n strokeColor: \"#00a050\",\n strokeWidth: this.problem.traceWidth,\n },\n ]\n : [],\n circles: [],\n texts: [],\n };\n }\n}\n","\n/**\n * @typedef {Float64ArrayConstructor | Float32ArrayConstructor |\n * Uint32ArrayConstructor | Int32ArrayConstructor | Uint16ArrayConstructor |\n * Int16ArrayConstructor | Uint8ArrayConstructor | Int8ArrayConstructor} TypedArrayConstructor\n */\n\n/** @template [T=number] */\nexport default class FlatQueue {\n\n /**\n * Creates an empty queue. If `capacity` is provided, the queue is backed by fixed-size typed\n * arrays for better performance and memory use, but can't grow beyond `capacity`. `values` uses\n * `ValuesArray` (default `Float64Array`) and `ids` uses `IdsArray` (default `Uint32Array`); pass\n * narrower constructors like `Uint16Array` if your values or ids are known to fit them.\n *\n * @param {number} [capacity]\n * @param {TypedArrayConstructor} [ValuesArray]\n * @param {TypedArrayConstructor} [IdsArray]\n */\n constructor(capacity = Infinity, ValuesArray = Float64Array, IdsArray = Uint32Array) {\n const fixed = capacity !== Infinity;\n\n /** @type {T[]} */\n this.ids = fixed ? /** @type {T[]} */ (/** @type {unknown} */ (new IdsArray(capacity))) : [];\n\n /** @type {number[]} */\n this.values = fixed ? /** @type {number[]} */ (/** @type {unknown} */ (new ValuesArray(capacity))) : [];\n\n /** Maximum number of items the queue can hold; `Infinity` for regular-array queues, which grow on demand. */\n this.capacity = capacity;\n\n /** Number of items in the queue. */\n this.length = 0;\n }\n\n /** Removes all items from the queue. */\n clear() {\n this.length = 0;\n }\n\n /**\n * Adds `item` to the queue with the specified `priority`.\n *\n * `priority` must be a number. Items are sorted and returned from low to high priority. Multiple items\n * with the same priority value can be added to the queue, but there is no guaranteed order between these items.\n *\n * For fixed-capacity queues, throws a `RangeError` if the queue is already full.\n *\n * @param {T} item\n * @param {number} priority\n */\n push(item, priority) {\n if (this.length === this.capacity) throw new RangeError('Queue is at capacity.');\n\n let pos = this.length++;\n\n while (pos > 0) {\n const parent = (pos - 1) >> 1;\n const parentValue = this.values[parent];\n if (priority >= parentValue) break;\n this.ids[pos] = this.ids[parent];\n this.values[pos] = parentValue;\n pos = parent;\n }\n\n this.ids[pos] = item;\n this.values[pos] = priority;\n }\n\n /**\n * Removes and returns the item from the head of this queue, which is one of\n * the items with the lowest priority. If this queue is empty, returns `undefined`.\n */\n pop() {\n if (this.length === 0) return undefined;\n\n const ids = this.ids,\n values = this.values,\n top = ids[0],\n last = --this.length;\n\n if (last > 0) {\n const id = ids[last];\n const value = values[last];\n let pos = 0;\n const halfLen = last >> 1;\n\n while (pos < halfLen) {\n const left = (pos << 1) + 1;\n const right = left + 1;\n const child = left + (+(right < last) & +(values[right] < values[left]));\n if (values[child] >= value) break;\n ids[pos] = ids[child];\n values[pos] = values[child];\n pos = child;\n }\n\n ids[pos] = id;\n values[pos] = value;\n }\n\n return top;\n }\n\n /** Returns the item from the head of this queue without removing it. If this queue is empty, returns `undefined`. */\n peek() {\n return this.length > 0 ? this.ids[0] : undefined;\n }\n\n /**\n * Returns the priority value of the item at the head of this queue without\n * removing it. If this queue is empty, returns `undefined`.\n */\n peekValue() {\n return this.length > 0 ? this.values[0] : undefined;\n }\n\n /**\n * Shrinks the internal arrays to `this.length`. No-op for queues with fixed capacity.\n *\n * `pop()` and `clear()` calls don't free memory automatically to avoid unnecessary resize operations.\n * This also means that items that have been added to the queue can't be garbage collected until\n * a new item is pushed in their place, or this method is called.\n */\n shrink() {\n if (Array.isArray(this.ids)) this.ids.length = this.length;\n if (Array.isArray(this.values)) this.values.length = this.length;\n }\n}\n","import FlatQueue from 'flatqueue';\n\nconst ARRAY_TYPES = [Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array, Int32Array, Uint32Array, Float32Array, Float64Array];\nconst VERSION = 3; // serialized format version\n\n/** @typedef {Int8ArrayConstructor | Uint8ArrayConstructor | Uint8ClampedArrayConstructor | Int16ArrayConstructor | Uint16ArrayConstructor | Int32ArrayConstructor | Uint32ArrayConstructor | Float32ArrayConstructor | Float64ArrayConstructor} TypedArrayConstructor */\n/** @typedef {Int8Array | Uint8Array | Uint8ClampedArray | Int16Array | Uint16Array | Int32Array | Uint32Array | Float32Array | Float64Array} TypedArray */\n\nexport default class Flatbush {\n\n /**\n * Recreate a Flatbush index from raw `ArrayBuffer` or `SharedArrayBuffer` data.\n * @param {ArrayBufferLike} data\n * @param {number} [byteOffset=0] byte offset to the start of the Flatbush buffer in the referenced ArrayBuffer.\n * @returns {Flatbush} index\n */\n static from(data, byteOffset = 0) {\n if (byteOffset % 8 !== 0) {\n throw new Error('byteOffset must be 8-byte aligned.');\n }\n\n if (!data || data.byteLength === undefined || 'buffer' in data) {\n throw new Error('Data must be an instance of ArrayBuffer or SharedArrayBuffer.');\n }\n\n const [magic, versionAndType] = new Uint8Array(data, byteOffset + 0, 2);\n if (magic !== 0xfb) {\n throw new Error('Data does not appear to be in a Flatbush format.');\n }\n const version = versionAndType >> 4;\n if (version !== VERSION) {\n throw new Error(`Got v${version} data when expected v${VERSION}.`);\n }\n const ArrayType = ARRAY_TYPES[versionAndType & 0x0f];\n if (!ArrayType) {\n throw new Error('Unrecognized array type.');\n }\n const [nodeSize] = new Uint16Array(data, byteOffset + 2, 1);\n const [numItems] = new Uint32Array(data, byteOffset + 4, 1);\n\n return new Flatbush(numItems, nodeSize, ArrayType, undefined, data, byteOffset);\n }\n\n /**\n * Create a Flatbush index that will hold a given number of items.\n * @param {number} numItems\n * @param {number} [nodeSize=16] Size of the tree node (16 by default).\n * @param {TypedArrayConstructor} [ArrayType=Float64Array] The array type used for coordinates storage (`Float64Array` by default).\n * @param {ArrayBufferConstructor | SharedArrayBufferConstructor} [ArrayBufferType=ArrayBuffer] The array buffer type used to store data (`ArrayBuffer` by default).\n * @param {ArrayBufferLike} [data] (Only used internally)\n * @param {number} [byteOffset=0] (Only used internally)\n */\n constructor(numItems, nodeSize = 16, ArrayType = Float64Array, ArrayBufferType = ArrayBuffer, data, byteOffset = 0) {\n if (numItems === undefined) throw new Error('Missing required argument: numItems.');\n if (isNaN(numItems) || numItems <= 0) throw new Error(`Unexpected numItems value: ${numItems}.`);\n\n this.numItems = +numItems;\n this.nodeSize = Math.min(Math.max(+nodeSize, 2), 65535);\n this.byteOffset = byteOffset;\n\n // calculate the total number of nodes in the R-tree to allocate space for\n // and the index of each tree level (used in search later)\n let n = numItems;\n let numNodes = n;\n this._levelBounds = [n * 4];\n do {\n n = Math.ceil(n / this.nodeSize);\n numNodes += n;\n this._levelBounds.push(numNodes * 4);\n } while (n !== 1);\n\n this.ArrayType = ArrayType;\n this.IndexArrayType = numNodes < 16384 ? Uint16Array : Uint32Array;\n\n const arrayTypeIndex = ARRAY_TYPES.indexOf(ArrayType);\n const nodesByteSize = numNodes * 4 * ArrayType.BYTES_PER_ELEMENT;\n\n if (arrayTypeIndex < 0) {\n throw new Error(`Unexpected typed array class: ${ArrayType}.`);\n }\n\n /** @type {new(b: ArrayBufferLike, o: number, l: number) => TypedArray} */\n const BoxCtor = ArrayType;\n /** @type {new(b: ArrayBufferLike, o: number, l: number) => Uint16Array | Uint32Array} */\n const IdxCtor = this.IndexArrayType;\n\n if (data) {\n this.data = data;\n this._boxes = new BoxCtor(data, byteOffset + 8, numNodes * 4);\n this._indices = new IdxCtor(data, byteOffset + 8 + nodesByteSize, numNodes);\n\n this._pos = numNodes * 4;\n this.minX = this._boxes[this._pos - 4];\n this.minY = this._boxes[this._pos - 3];\n this.maxX = this._boxes[this._pos - 2];\n this.maxY = this._boxes[this._pos - 1];\n\n } else {\n const data = this.data = new ArrayBufferType(8 + nodesByteSize + numNodes * this.IndexArrayType.BYTES_PER_ELEMENT);\n this._boxes = new BoxCtor(data, 8, numNodes * 4);\n this._indices = new IdxCtor(data, 8 + nodesByteSize, numNodes);\n this._pos = 0;\n this.minX = Infinity;\n this.minY = Infinity;\n this.maxX = -Infinity;\n this.maxY = -Infinity;\n\n new Uint8Array(data, 0, 2).set([0xfb, (VERSION << 4) + arrayTypeIndex]);\n new Uint16Array(data, 2, 1)[0] = nodeSize;\n new Uint32Array(data, 4, 1)[0] = numItems;\n }\n\n // a priority queue for k-nearest-neighbors queries\n /** @type FlatQueue<number> */\n this._queue = new FlatQueue();\n }\n\n /**\n * Add a given rectangle to the index.\n * @param {number} minX\n * @param {number} minY\n * @param {number} maxX\n * @param {number} maxY\n * @returns {number} A zero-based, incremental number that represents the newly added rectangle.\n */\n add(minX, minY, maxX = minX, maxY = minY) {\n const pos = this._pos;\n const index = pos >> 2;\n const boxes = this._boxes;\n this._indices[index] = index;\n boxes[pos] = minX;\n boxes[pos + 1] = minY;\n boxes[pos + 2] = maxX;\n boxes[pos + 3] = maxY;\n this._pos = pos + 4;\n\n if (minX < this.minX) this.minX = minX;\n if (minY < this.minY) this.minY = minY;\n if (maxX > this.maxX) this.maxX = maxX;\n if (maxY > this.maxY) this.maxY = maxY;\n\n return index;\n }\n\n /** Perform indexing of the added rectangles. */\n finish() {\n if (this._pos >> 2 !== this.numItems) {\n throw new Error(`Added ${this._pos >> 2} items when expected ${this.numItems}.`);\n }\n const boxes = this._boxes;\n\n if (this.numItems <= this.nodeSize) {\n // only one node, skip sorting and just fill the root box\n boxes[this._pos++] = this.minX;\n boxes[this._pos++] = this.minY;\n boxes[this._pos++] = this.maxX;\n boxes[this._pos++] = this.maxY;\n return;\n }\n\n const {numItems, minX, minY, nodeSize, _indices: indices, _levelBounds: levelBounds} = this;\n const width = (this.maxX - minX) || 1;\n const height = (this.maxY - minY) || 1;\n const hilbertValues = new Int32Array(numItems);\n const hilbertMax = (1 << 16) - 1;\n const sx = hilbertMax / width;\n const sy = hilbertMax / height;\n\n // map item centers into Hilbert coordinate space and calculate Hilbert values\n for (let i = 0, pos = 0; i < numItems; i++) {\n const itemMinX = boxes[pos++];\n const itemMinY = boxes[pos++];\n const itemMaxX = boxes[pos++];\n const itemMaxY = boxes[pos++];\n const x = (sx * ((itemMinX + itemMaxX) / 2 - minX)) | 0;\n const y = (sy * ((itemMinY + itemMaxY) / 2 - minY)) | 0;\n hilbertValues[i] = hilbert(x, y);\n }\n\n // sort items by their Hilbert value (for packing later)\n sort(hilbertValues, boxes, indices, 0, numItems - 1, nodeSize);\n\n // generate nodes at each tree level, bottom-up\n let pos = numItems * 4;\n for (let i = 0, readPos = 0; i < levelBounds.length - 1; i++) {\n const end = levelBounds[i];\n\n // generate a parent node for each block of consecutive <nodeSize> nodes\n while (readPos < end) {\n const nodeIndex = readPos;\n\n // calculate bbox for the new node\n let nodeMinX = boxes[readPos++];\n let nodeMinY = boxes[readPos++];\n let nodeMaxX = boxes[readPos++];\n let nodeMaxY = boxes[readPos++];\n for (let j = 1; j < nodeSize && readPos < end; j++) {\n nodeMinX = Math.min(nodeMinX, boxes[readPos++]);\n nodeMinY = Math.min(nodeMinY, boxes[readPos++]);\n nodeMaxX = Math.max(nodeMaxX, boxes[readPos++]);\n nodeMaxY = Math.max(nodeMaxY, boxes[readPos++]);\n }\n\n // add the new node to the tree data\n indices[pos >> 2] = nodeIndex;\n boxes[pos++] = nodeMinX;\n boxes[pos++] = nodeMinY;\n boxes[pos++] = nodeMaxX;\n boxes[pos++] = nodeMaxY;\n }\n }\n this._pos = pos;\n }\n\n /**\n * Search the index by a bounding box.\n * @param {number} minX\n * @param {number} minY\n * @param {number} maxX\n * @param {number} maxY\n * @param {(index: number, x0: number, y0: number, x1: number, y1: number) => boolean} [filterFn] An optional function that is called on every found item; if supplied, only items for which this function returns true will be included in the results array.\n * @returns {number[]} An array of indices of items intersecting or touching the given bounding box.\n */\n search(minX, minY, maxX, maxY, filterFn) {\n if (this._pos !== this._boxes.length) {\n throw new Error('Data not yet indexed - call index.finish().');\n }\n const {_boxes: boxes, _levelBounds: levelBounds, _indices: indices, nodeSize} = this;\n const numItems4 = this.numItems * 4;\n\n /** @type number | undefined */\n let nodeIndex = boxes.length - 4;\n let level = levelBounds.length - 1; // start at the root level\n const q = [];\n const results = [];\n\n let contained = false; // whether the current node's bbox is fully inside the query\n\n while (nodeIndex !== undefined) {\n // find the end index of the node, capped at the level boundary\n const end = Math.min(nodeIndex + nodeSize * 4, levelBounds[level]);\n const isNode = nodeIndex >= numItems4;\n\n if (contained) {\n this._collectContained(nodeIndex, end, level, numItems4, results, filterFn);\n\n } else {\n // search through child nodes\n for (let /** @type {number} */ pos = nodeIndex; pos < end; pos += 4) {\n // check if node bbox intersects with query bbox\n const x0 = boxes[pos];\n if (maxX < x0) continue;\n const y0 = boxes[pos + 1];\n if (maxY < y0) continue;\n const x1 = boxes[pos + 2];\n if (minX > x1) continue;\n const y1 = boxes[pos + 3];\n if (minY > y1) continue;\n\n const index = indices[pos >> 2] | 0;\n\n if (isNode) {\n // node intersects; flag it as contained if its bbox is fully inside the query\n const c = +(minX <= x0 && minY <= y0 && maxX >= x1 && maxY >= y1);\n q.push(index | c, level - 1); // node; add it and its level to the search queue\n\n } else if (filterFn === undefined || filterFn(index, x0, y0, x1, y1)) {\n results.push(index); // leaf item\n }\n }\n }\n\n level = /** @type {number} */ (q.pop());\n nodeIndex = q.pop();\n if (nodeIndex !== undefined) {\n contained = (nodeIndex & 1) === 1;\n nodeIndex &= ~1;\n }\n }\n\n return results;\n }\n\n /**\n * Collect all leaves of a subtree that's fully inside the query, skipping intersection tests.\n * Because the tree is packed bottom-up, those leaves occupy one contiguous block of the leaf\n * level, so we skip traversal entirely: descend to the first leaf, then sweep the flat range.\n * @param {number} nodeIndex\n * @param {number} end\n * @param {number} level\n * @param {number} numItems4\n * @param {number[]} results\n * @param {((index: number, x0: number, y0: number, x1: number, y1: number) => boolean) | undefined} filterFn\n */\n _collectContained(nodeIndex, end, level, numItems4, results, filterFn) {\n const boxes = this._boxes;\n const indices = this._indices;\n let pos = nodeIndex;\n for (let l = level; l > 0; l--) pos = indices[pos >> 2];\n const leafEnd = Math.min(pos + (end - nodeIndex) * this.nodeSize ** level, numItems4);\n if (filterFn === undefined) {\n for (; pos < leafEnd; pos += 4) results.push(indices[pos >> 2] | 0);\n } else {\n for (; pos < leafEnd; pos += 4) {\n const index = indices[pos >> 2] | 0;\n if (filterFn(index, boxes[pos], boxes[pos + 1], boxes[pos + 2], boxes[pos + 3])) results.push(index);\n }\n }\n }\n\n /**\n * Search items in order of distance from the given point.\n * @param {number} x\n * @param {number} y\n * @param {number} [maxResults=Infinity]\n * @param {number} [maxDistance=Infinity]\n * @param {(index: number) => boolean} [filterFn] An optional function for filtering the results.\n * @returns {number[]} An array of indices of items found.\n */\n neighbors(x, y, maxResults = Infinity, maxDistance = Infinity, filterFn) {\n if (this._pos !== this._boxes.length) {\n throw new Error('Data not yet indexed - call index.finish().');\n }\n const {_boxes: boxes, _levelBounds: levelBounds, _indices: indices, _queue: q, nodeSize} = this;\n const numItems4 = this.numItems * 4;\n const nodeSize4 = nodeSize * 4;\n const results = [];\n const maxDistSquared = maxDistance * maxDistance;\n\n // For a single nearest neighbor (maxResults === 1), track the closest leaf seen so far and use\n // it as a tightened distance bound, skipping pushes of nodes/leaves that can't beat it\n const trackNearest = maxResults === 1;\n let bound = maxDistSquared;\n\n // Tree nodes and leaves share the queue; encode leaves with LSB = 1 so we can tell them\n // apart with `& 1`. Seed with the root node — any priority works since the queue is empty.\n q.push((boxes.length - 4) << 1, 0);\n\n while (q.length) {\n const top = q.ids[0];\n // if the closest queued entry is a leaf, it's the next result in distance order\n if (top & 1) {\n q.pop();\n results.push(top >> 1);\n if (results.length === maxResults) break;\n continue;\n }\n\n q.pop();\n const nodeIndex = top >> 1;\n const isLeafLevel = nodeIndex < numItems4;\n const end = Math.min(nodeIndex + nodeSize4, upperBound(nodeIndex, levelBounds));\n\n for (let pos = nodeIndex; pos < end; pos += 4) {\n const minX = boxes[pos];\n const minY = boxes[pos + 1];\n const maxX = boxes[pos + 2];\n const maxY = boxes[pos + 3];\n const dx = Math.max(Math.max(minX - x, x - maxX), 0);\n const dy = Math.max(Math.max(minY - y, y - maxY), 0);\n const dist = dx * dx + dy * dy;\n if (dist > bound) continue;\n\n const childIndex = indices[pos >> 2] | 0;\n if (isLeafLevel) {\n if (filterFn === undefined || filterFn(childIndex)) {\n q.push((childIndex << 1) | 1, dist); // leaf item (odd id)\n if (trackNearest && dist < bound) bound = dist; // tighten bound to the closest leaf so far\n }\n } else {\n q.push(childIndex << 1, dist); // node (even id)\n }\n }\n }\n\n q.clear();\n return results;\n }\n}\n\n/**\n * Binary search for the first value in the array bigger than the given.\n * @param {number} value\n * @param {number[]} arr\n */\nfunction upperBound(value, arr) {\n let i = 0;\n let j = arr.length - 1;\n while (i < j) {\n const m = (i + j) >> 1;\n if (arr[m] > value) {\n j = m;\n } else {\n i = m + 1;\n }\n }\n return arr[i];\n}\n\n/**\n * Custom quicksort that partially sorts bbox data alongside the hilbert values.\n * @param {Int32Array} values\n * @param {TypedArray} boxes\n * @param {Uint16Array | Uint32Array} indices\n * @param {number} left\n * @param {number} right\n * @param {number} nodeSize\n */\nfunction sort(values, boxes, indices, left, right, nodeSize) {\n const stack = [left, right];\n\n while (stack.length) {\n const r = stack.pop() || 0;\n const l = stack.pop() || 0;\n\n if (r - l <= nodeSize && Math.floor(l / nodeSize) >= Math.floor(r / nodeSize)) continue;\n\n const a = values[l];\n const b = values[(l + r) >> 1];\n const c = values[r];\n const pivot = ((a > b) !== (a > c)) ? a :\n ((b < a) !== (b < c)) ? b : c;\n\n let i = l - 1;\n let j = r + 1;\n\n while (true) {\n do i++; while (values[i] < pivot);\n do j--; while (values[j] > pivot);\n if (i >= j) break;\n swap(values, boxes, indices, i, j);\n }\n\n stack.push(l, j, j + 1, r);\n }\n}\n\n/**\n * Swap two values and two corresponding boxes.\n * @param {Int32Array} values\n * @param {TypedArray} boxes\n * @param {Uint16Array | Uint32Array} indices\n * @param {number} i\n * @param {number} j\n */\nfunction swap(values, boxes, indices, i, j) {\n const temp = values[i];\n values[i] = values[j];\n values[j] = temp;\n\n const k = 4 * i;\n const m = 4 * j;\n\n const a = boxes[k];\n const b = boxes[k + 1];\n const c = boxes[k + 2];\n const d = boxes[k + 3];\n boxes[k] = boxes[m];\n boxes[k + 1] = boxes[m + 1];\n boxes[k + 2] = boxes[m + 2];\n boxes[k + 3] = boxes[m + 3];\n boxes[m] = a;\n boxes[m + 1] = b;\n boxes[m + 2] = c;\n boxes[m + 3] = d;\n\n const e = indices[i];\n indices[i] = indices[j];\n indices[j] = e;\n}\n\n/**\n * Fast Hilbert curve algorithm by http://threadlocalmutex.com/\n * Ported from C++ https://github.com/rawrunprotected/hilbert_curves (public domain)\n * @param {number} x\n * @param {number} y\n */\nfunction hilbert(x, y) {\n let a = x ^ y;\n let b = 0xFFFF ^ a;\n let c = 0xFFFF ^ (x | y);\n let d = x & (y ^ 0xFFFF);\n\n let A = a | (b >> 1);\n let B = (a >> 1) ^ a;\n let C = c ^ ((c >> 1) ^ (b & (d >> 1)));\n let D = d ^ ((a & (c >> 1)) ^ (d >> 1));\n\n a = (A & (A >> 2)) ^ (B & (B >> 2));\n b = (A & (B >> 2)) ^ (B & ((A ^ B) >> 2));\n c = C ^ ((A & (C >> 2)) ^ (B & (D >> 2)));\n d = D ^ ((B & (C >> 2)) ^ ((A ^ B) & (D >> 2)));\n\n A = (a & (a >> 4)) ^ (b & (b >> 4));\n B = (a & (b >> 4)) ^ (b & ((a ^ b) >> 4));\n C = c ^ ((a & (c >> 4)) ^ (b & (d >> 4)));\n D = d ^ ((b & (c >> 4)) ^ ((a ^ b) & (d >> 4)));\n\n c = C ^ ((A & (C >> 8)) ^ (B & (D >> 8)));\n d = D ^ ((B & (C >> 8)) ^ ((A ^ B) & (D >> 8)));\n\n c ^= c >> 1;\n d ^= d >> 1;\n a = x ^ y;\n b = d | (0xFFFF ^ (a | c));\n\n a = (a | (a << 8)) & 0x00FF00FF;\n a = (a | (a << 4)) & 0x0F0F0F0F;\n a = (a | (a << 2)) & 0x33333333;\n a = (a | (a << 1)) & 0x55555555;\n\n b = (b | (b << 8)) & 0x00FF00FF;\n b = (b | (b << 4)) & 0x0F0F0F0F;\n b = (b | (b << 2)) & 0x33333333;\n b = (b | (b << 1)) & 0x55555555;\n\n // shift into signed SMI range for performance\n return (((b << 1) | a) >>> 0) - 0x80000000;\n}\n","import Flatbush from \"flatbush\";\nimport { ConnectionNameResolver } from \"./ConnectionNameResolver\";\nimport {\n approximateObstacleWithRects,\n approximateSegmentWithRects,\n distancePointToSegment,\n distanceSegmentToPolygon,\n distanceSegmentToSegment,\n segmentIntersectsRect,\n} from \"./geometry\";\nimport type {\n CollisionQuery,\n IndexedObstacle,\n Obstacle,\n SimpleRouteJson,\n SimplifiedPcbTrace,\n ViaCollisionQuery,\n} from \"./types\";\n\ntype ConnectedPad = {\n obstacle: Obstacle;\n canonicalConnectionNames: ReadonlySet<string>;\n};\n\nconst getBoardLayers = (layerCount: number) => [\n \"top\",\n ...Array.from(\n { length: Math.max(0, layerCount - 2) },\n (_, index) => `inner${index + 1}`,\n ),\n ...(layerCount > 1 ? [\"bottom\"] : []),\n];\n\nexport class SpatialObstacleIndex {\n readonly items: IndexedObstacle[];\n readonly clearance: number;\n readonly boardEdgeClearance: number;\n readonly boardLayers: string[];\n readonly minViaHoleEdgeToViaHoleEdgeClearance: number;\n readonly defaultViaHoleDiameter: number;\n readonly bounds: SimpleRouteJson[\"bounds\"];\n private readonly maxIndexedViaHoleDiameter: number;\n private readonly index: Flatbush | null;\n private readonly connectionNameSets: ReadonlySet<string>[];\n private readonly connectionNameResolver: ConnectionNameResolver;\n private readonly connectedPads: ConnectedPad[];\n private readonly dynamicTraceIndex?: number;\n\n constructor(\n simpleRouteJson: SimpleRouteJson,\n traces: SimplifiedPcbTrace[],\n dynamicTraceIndex?: number,\n extraItems: IndexedObstacle[] = [],\n connectionNameResolver = new ConnectionNameResolver(\n simpleRouteJson,\n traces,\n ),\n ) {\n this.bounds = simpleRouteJson.bounds;\n this.boardLayers = getBoardLayers(simpleRouteJson.layerCount);\n this.dynamicTraceIndex = dynamicTraceIndex;\n this.clearance = Math.max(\n simpleRouteJson.defaultObstacleMargin ?? 0,\n simpleRouteJson.minTraceToPadEdgeClearance ?? 0,\n 0.1,\n );\n this.boardEdgeClearance =\n simpleRouteJson.minBoardEdgeClearance ?? this.clearance;\n this.minViaHoleEdgeToViaHoleEdgeClearance = Math.max(\n simpleRouteJson.minViaHoleEdgeToViaHoleEdgeClearance ?? 0,\n 0.1,\n );\n this.defaultViaHoleDiameter =\n simpleRouteJson.min_via_hole_diameter ??\n simpleRouteJson.minViaHoleDiameter ??\n 0.3;\n this.items = [\n ...simpleRouteJson.obstacles.flatMap((obstacle) =>\n approximateObstacleWithRects(obstacle),\n ),\n ...this.createTraceItems(simpleRouteJson.fixedTraces ?? [], true),\n ...this.createTraceItems(traces),\n ...extraItems,\n ];\n this.maxIndexedViaHoleDiameter = this.items.reduce(\n (maximum, item) =>\n item.kind === \"via\"\n ? Math.max(\n maximum,\n item.viaHoleDiameter ?? this.defaultViaHoleDiameter,\n )\n : maximum,\n this.defaultViaHoleDiameter,\n );\n this.connectionNameResolver = connectionNameResolver;\n this.connectionNameSets = this.items.map(\n (item) =>\n new Set(connectionNameResolver.canonicalize(item.connectionNames)),\n );\n this.connectedPads = simpleRouteJson.obstacles.flatMap((obstacle) => {\n if (\n !obstacle.connectedTo.some(\n (name) =>\n name.startsWith(\"pcb_smtpad_\") ||\n name.startsWith(\"pcb_plated_hole_\"),\n )\n ) {\n return [];\n }\n return [\n {\n obstacle,\n canonicalConnectionNames: new Set(\n connectionNameResolver.canonicalize(obstacle.connectedTo),\n ),\n },\n ];\n });\n this.index = this.items.length > 0 ? new Flatbush(this.items.length) : null;\n for (const item of this.items) {\n this.index!.add(item.minX, item.minY, item.maxX, item.maxY);\n }\n this.index?.finish();\n }\n\n private createTraceItems(\n traces: SimplifiedPcbTrace[],\n fixed = false,\n ): IndexedObstacle[] {\n const items: IndexedObstacle[] = [];\n for (let traceIndex = 0; traceIndex < traces.length; traceIndex++) {\n const trace = traces[traceIndex]!;\n const indexedTraceIndex = fixed ? undefined : traceIndex;\n const isDynamicTrace = !fixed && traceIndex === this.dynamicTraceIndex;\n const connectionNames = [\n trace.connection_name,\n trace.source_trace_id,\n trace.rootConnectionName,\n ...(trace.mergedConnectionNames ?? []),\n ...(trace.connectsTo ?? []),\n ].filter((name): name is string => Boolean(name));\n\n for (let routeIndex = 0; routeIndex < trace.route.length; routeIndex++) {\n const point = trace.route[routeIndex]!;\n if (point.route_type === \"via\") {\n const diameter = point.via_diameter ?? 0.6;\n items.push({\n minX: point.x - diameter / 2,\n minY: point.y - diameter / 2,\n maxX: point.x + diameter / 2,\n maxY: point.y + diameter / 2,\n // Core emits a through via on every copper layer between the\n // requested endpoints. Treating it as board-wide is conservative\n // for the common two-layer case and correct for multilayer boards.\n layers: this.boardLayers,\n kind: \"via\",\n connectionNames,\n traceIndex: indexedTraceIndex,\n routeStartIndex: routeIndex,\n routeEndIndex: routeIndex,\n viaHoleDiameter:\n point.via_hole_diameter ?? this.defaultViaHoleDiameter,\n exactShape: {\n type: \"circle\",\n center: { x: point.x, y: point.y },\n radius: diameter / 2,\n },\n });\n continue;\n }\n\n // Dynamic wire copper is replaced in place and must not block its own\n // reroute. Its existing vias remain mechanically fixed, though, and\n // must participate in same-net drill spacing checks.\n if (isDynamicTrace) continue;\n\n const next = trace.route[routeIndex + 1];\n if (\n point.route_type !== \"wire\" ||\n next?.route_type !== \"wire\" ||\n point.layer !== next.layer\n ) {\n continue;\n }\n items.push(\n ...approximateSegmentWithRects({\n start: point,\n end: next,\n // Circuit JSON and @tscircuit/checks assign each wire segment the\n // width of its first route point.\n width: point.width,\n base: {\n layers: [point.layer],\n kind: \"trace\",\n connectionNames,\n traceIndex: indexedTraceIndex,\n routeStartIndex: routeIndex,\n routeEndIndex: routeIndex + 1,\n },\n }),\n );\n }\n }\n return items;\n }\n\n collides(query: CollisionQuery): boolean {\n if (this.isOutsideBounds(query)) return true;\n const { radius, candidates, canonicalConnectionNames } =\n this.getCollisionCandidates(query);\n for (const itemIndex of candidates) {\n if (this.itemCollides(itemIndex, query, radius, canonicalConnectionNames))\n return true;\n }\n return false;\n }\n\n findCollisions(query: CollisionQuery): IndexedObstacle[] {\n const { radius, candidates, canonicalConnectionNames } =\n this.getCollisionCandidates(query);\n const collisions: IndexedObstacle[] = [];\n for (const itemIndex of candidates) {\n if (\n this.itemCollides(itemIndex, query, radius, canonicalConnectionNames)\n ) {\n collisions.push(this.items[itemIndex]!);\n }\n }\n return collisions;\n }\n\n getConnectedPadWidthLimit(query: CollisionQuery): number | null {\n if (\n Math.hypot(query.end.x - query.start.x, query.end.y - query.start.y) <=\n 1e-5\n ) {\n return null;\n }\n const startLimit = this.getConnectedPadWidthLimitAtPoint(\n query,\n query.start,\n );\n const endLimit = this.getConnectedPadWidthLimitAtPoint(query, query.end);\n if (startLimit === null) return endLimit;\n if (endLimit === null) return startLimit;\n return Math.min(startLimit, endLimit);\n }\n\n getConnectedPadWidthLimitAtPoint(\n query: CollisionQuery,\n point: { x: number; y: number },\n ): number | null {\n const padsAtPoint = this.getConnectedPadsAtPoint(query, point);\n if (padsAtPoint.length === 0) return null;\n return Math.max(\n ...padsAtPoint.map(({ obstacle }) =>\n this.getPadWidthNormalToQuery(obstacle, query),\n ),\n );\n }\n\n getConnectedPadEndpointWidthLimitAtPoint(\n query: CollisionQuery,\n point: { x: number; y: number },\n ): number | null {\n const padsAtPoint = this.getConnectedPadsAtPoint(query, point);\n if (padsAtPoint.length === 0) return null;\n return Math.max(\n ...padsAtPoint.map(({ obstacle }) => {\n const localPoint = this.getObstacleLocalPoint(point, obstacle);\n return Math.max(\n 0,\n 2 *\n Math.min(\n obstacle.width / 2 - Math.abs(localPoint.x),\n obstacle.height / 2 - Math.abs(localPoint.y),\n ),\n );\n }),\n );\n }\n\n getConnectedPadBoundaryPoint(\n query: CollisionQuery,\n endpoint: \"start\" | \"end\",\n ): { x: number; y: number } | null {\n const inside = endpoint === \"start\" ? query.start : query.end;\n const outside = endpoint === \"start\" ? query.end : query.start;\n const padsAtPoint = this.getConnectedPadsAtPoint(query, inside);\n const pad = padsAtPoint.sort(\n (a, b) =>\n this.getPadWidthNormalToQuery(b.obstacle, query) -\n this.getPadWidthNormalToQuery(a.obstacle, query),\n )[0];\n if (!pad || this.pointIsInsideObstacle(outside, pad.obstacle)) return null;\n return this.getObstacleBoundaryPoint(inside, outside, pad.obstacle);\n }\n\n private getConnectedPadsAtPoint(\n query: CollisionQuery,\n point: { x: number; y: number },\n ): ConnectedPad[] {\n const canonicalConnectionNames = new Set(\n this.connectionNameResolver.canonicalize(query.connectionNames),\n );\n return this.connectedPads.filter(\n ({ obstacle, canonicalConnectionNames: padConnectionNames }) =>\n obstacle.layers.includes(query.layer) &&\n [...padConnectionNames].some((name) =>\n canonicalConnectionNames.has(name),\n ) &&\n this.pointIsInsideObstacle(point, obstacle),\n );\n }\n\n private pointIsInsideObstacle(\n point: { x: number; y: number },\n obstacle: Obstacle,\n ) {\n const { x: localX, y: localY } = this.getObstacleLocalPoint(\n point,\n obstacle,\n );\n return (\n Math.abs(localX) <= obstacle.width / 2 + 1e-9 &&\n Math.abs(localY) <= obstacle.height / 2 + 1e-9\n );\n }\n\n private getObstacleLocalPoint(\n point: { x: number; y: number },\n obstacle: Obstacle,\n ) {\n const radians = -((obstacle.ccwRotationDegrees ?? 0) * Math.PI) / 180;\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n const dx = point.x - obstacle.center.x;\n const dy = point.y - obstacle.center.y;\n return { x: dx * cos - dy * sin, y: dx * sin + dy * cos };\n }\n\n private getPadWidthNormalToQuery(\n obstacle: Obstacle,\n query: CollisionQuery,\n ): number {\n const dx = query.end.x - query.start.x;\n const dy = query.end.y - query.start.y;\n const length = Math.hypot(dx, dy);\n if (length <= 1e-9) return Math.min(obstacle.width, obstacle.height);\n\n const normalX = -dy / length;\n const normalY = dx / length;\n const radians = -((obstacle.ccwRotationDegrees ?? 0) * Math.PI) / 180;\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n const localNormalX = normalX * cos - normalY * sin;\n const localNormalY = normalX * sin + normalY * cos;\n return (\n Math.abs(localNormalX) * obstacle.width +\n Math.abs(localNormalY) * obstacle.height\n );\n }\n\n private getObstacleBoundaryPoint(\n inside: { x: number; y: number },\n outside: { x: number; y: number },\n obstacle: Obstacle,\n ): { x: number; y: number } | null {\n const radians = -((obstacle.ccwRotationDegrees ?? 0) * Math.PI) / 180;\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n const toLocal = (point: { x: number; y: number }) => {\n const dx = point.x - obstacle.center.x;\n const dy = point.y - obstacle.center.y;\n return { x: dx * cos - dy * sin, y: dx * sin + dy * cos };\n };\n const localInside = toLocal(inside);\n const localOutside = toLocal(outside);\n const delta = {\n x: localOutside.x - localInside.x,\n y: localOutside.y - localInside.y,\n };\n const candidates: number[] = [];\n if (Math.abs(delta.x) > 1e-12) {\n const boundaryX = delta.x > 0 ? obstacle.width / 2 : -obstacle.width / 2;\n candidates.push((boundaryX - localInside.x) / delta.x);\n }\n if (Math.abs(delta.y) > 1e-12) {\n const boundaryY =\n delta.y > 0 ? obstacle.height / 2 : -obstacle.height / 2;\n candidates.push((boundaryY - localInside.y) / delta.y);\n }\n const exitT = Math.min(\n ...candidates.filter((value) => value >= 0 && value <= 1),\n );\n if (!Number.isFinite(exitT)) return null;\n return {\n x: inside.x + (outside.x - inside.x) * exitT,\n y: inside.y + (outside.y - inside.y) * exitT,\n };\n }\n\n getConnectedLayersAtPoint(point: { x: number; y: number }, names: string[]) {\n const canonicalNames = new Set(\n this.connectionNameResolver.canonicalize(names),\n );\n const layers = new Set<string>();\n const candidates =\n this.index?.search(point.x, point.y, point.x, point.y) ?? [];\n for (const itemIndex of candidates) {\n const item = this.items[itemIndex]!;\n if (item.kind !== \"obstacle\") continue;\n if (\n ![...this.connectionNameSets[itemIndex]!].some((name) =>\n canonicalNames.has(name),\n )\n ) {\n continue;\n }\n const containsPoint =\n item.exactShape?.type === \"polygon\"\n ? distanceSegmentToPolygon(point, point, item.exactShape.points) <=\n 1e-9\n : item.exactShape?.type === \"circle\"\n ? Math.hypot(\n item.exactShape.center.x - point.x,\n item.exactShape.center.y - point.y,\n ) <=\n item.exactShape.radius + 1e-9\n : point.x >= item.minX - 1e-9 &&\n point.x <= item.maxX + 1e-9 &&\n point.y >= item.minY - 1e-9 &&\n point.y <= item.maxY + 1e-9;\n if (containsPoint) {\n for (const layer of item.layers) layers.add(layer);\n }\n }\n return [...layers];\n }\n\n /**\n * Checks a prospective through via. Copper clearance follows ordinary\n * same-net semantics, while drill-to-drill clearance applies even to vias\n * on the same net because the fabrication constraint is mechanical.\n */\n collidesVia(query: ViaCollisionQuery): boolean {\n for (const layer of query.layers) {\n if (\n this.collides({\n start: query.point,\n end: query.point,\n layer,\n width: query.padDiameter,\n connectionNames: query.connectionNames,\n ignoreTraceIndex: query.ignoreTraceIndex,\n ignoreTraceIndices: query.ignoreTraceIndices,\n ignoreRouteRange: query.ignoreRouteRange,\n obstacleClearance: query.obstacleClearance,\n blockSameNetObstacles: query.blockSameNetObstacles,\n sameNetObstacleClearance: query.sameNetObstacleClearance,\n })\n ) {\n return true;\n }\n }\n\n const minimumNewViaSpacing =\n query.holeDiameter + this.minViaHoleEdgeToViaHoleEdgeClearance;\n for (const point of query.otherNewViaPoints ?? []) {\n if (\n Math.hypot(point.x - query.point.x, point.y - query.point.y) <\n minimumNewViaSpacing - 1e-9\n ) {\n return true;\n }\n }\n\n for (const via of query.fixedVias ?? []) {\n const minimumSpacing =\n query.holeDiameter / 2 +\n via.holeDiameter / 2 +\n this.minViaHoleEdgeToViaHoleEdgeClearance;\n if (\n Math.hypot(via.point.x - query.point.x, via.point.y - query.point.y) <\n minimumSpacing - 1e-9\n ) {\n return true;\n }\n }\n\n const indexedViaSearchRadius =\n query.holeDiameter / 2 +\n this.maxIndexedViaHoleDiameter / 2 +\n this.minViaHoleEdgeToViaHoleEdgeClearance;\n const indexedViaCandidates =\n this.index?.search(\n query.point.x - indexedViaSearchRadius,\n query.point.y - indexedViaSearchRadius,\n query.point.x + indexedViaSearchRadius,\n query.point.y + indexedViaSearchRadius,\n ) ?? [];\n const seenTraceRoutePairs = new Set<string>();\n for (const itemIndex of indexedViaCandidates) {\n const item = this.items[itemIndex]!;\n if (item.kind !== \"via\" || item.exactShape?.type !== \"circle\") continue;\n if (\n item.traceIndex === query.ignoreTraceIndex &&\n query.ignoreRouteRange &&\n (item.routeEndIndex ?? -1) >= query.ignoreRouteRange.start &&\n (item.routeStartIndex ?? Number.POSITIVE_INFINITY) <=\n query.ignoreRouteRange.end\n ) {\n continue;\n }\n if (query.ignoreTraceIndices?.includes(item.traceIndex ?? -1)) {\n continue;\n }\n const key = `${item.traceIndex ?? -1}:${item.routeStartIndex ?? -1}`;\n if (seenTraceRoutePairs.has(key)) continue;\n seenTraceRoutePairs.add(key);\n const existingHoleDiameter =\n item.viaHoleDiameter ?? this.defaultViaHoleDiameter;\n const minimumSpacing =\n query.holeDiameter / 2 +\n existingHoleDiameter / 2 +\n this.minViaHoleEdgeToViaHoleEdgeClearance;\n if (\n Math.hypot(\n item.exactShape.center.x - query.point.x,\n item.exactShape.center.y - query.point.y,\n ) <\n minimumSpacing - 1e-9\n ) {\n return true;\n }\n }\n return false;\n }\n\n private getCollisionCandidates(query: CollisionQuery) {\n const maximumClearance = Math.max(\n this.clearance,\n query.obstacleClearance ?? this.clearance,\n query.sameNetObstacleClearance ?? 0,\n );\n const radius = query.width / 2 + maximumClearance;\n const queryBounds = {\n minX: Math.min(query.start.x, query.end.x) - radius,\n minY: Math.min(query.start.y, query.end.y) - radius,\n maxX: Math.max(query.start.x, query.end.x) + radius,\n maxY: Math.max(query.start.y, query.end.y) + radius,\n };\n const candidates =\n this.index?.search(\n queryBounds.minX,\n queryBounds.minY,\n queryBounds.maxX,\n queryBounds.maxY,\n ) ?? [];\n return {\n radius,\n candidates,\n canonicalConnectionNames: this.connectionNameResolver.canonicalize(\n query.connectionNames,\n ),\n };\n }\n\n private itemCollides(\n itemIndex: number,\n query: CollisionQuery,\n radius: number,\n canonicalConnectionNames: string[],\n ) {\n const item = this.items[itemIndex]!;\n if (!item.layers.includes(query.layer)) return false;\n // Connected copper is one obstacle-free routing region. This mirrors\n // @tscircuit/checks, which exempts same-net trace/trace, trace/pad, and\n // trace/via pairs from clearance errors. Different-net copper continues\n // to participate in both overlap and margin checks.\n const itemConnectionNames = this.connectionNameSets[itemIndex]!;\n const isSameNet = canonicalConnectionNames.some((name) =>\n itemConnectionNames.has(name),\n );\n if (\n isSameNet &&\n !(\n query.blockSameNetObstacles &&\n item.kind === \"obstacle\" &&\n item.obstacleKind !== \"via\"\n )\n ) {\n return false;\n }\n if (\n item.kind === \"trace\" &&\n query.ignoreTraceIndices?.includes(item.traceIndex ?? -1)\n ) {\n return false;\n }\n if (\n item.kind === \"trace\" &&\n item.traceIndex === query.ignoreTraceIndex &&\n query.ignoreRouteRange &&\n (item.routeEndIndex ?? -1) >= query.ignoreRouteRange.start &&\n (item.routeStartIndex ?? Number.POSITIVE_INFINITY) <=\n query.ignoreRouteRange.end\n ) {\n return false;\n }\n const itemClearance =\n item.kind === \"obstacle\" && item.obstacleKind === \"pad\"\n ? isSameNet && query.blockSameNetObstacles\n ? (query.sameNetObstacleClearance ??\n query.obstacleClearance ??\n this.clearance)\n : (query.obstacleClearance ?? this.clearance)\n : this.clearance;\n const itemRadius = query.width / 2 + itemClearance;\n if (item.exactShape?.type === \"segment\") {\n return (\n distanceSegmentToSegment(\n query.start,\n query.end,\n item.exactShape.start,\n item.exactShape.end,\n ) <=\n itemRadius + item.exactShape.width / 2 + 1e-9\n );\n }\n if (item.exactShape?.type === \"polygon\") {\n return (\n distanceSegmentToPolygon(\n query.start,\n query.end,\n item.exactShape.points,\n ) <=\n itemRadius + 1e-9\n );\n }\n if (item.exactShape?.type === \"circle\") {\n return (\n distancePointToSegment(\n item.exactShape.center,\n query.start,\n query.end,\n ) <=\n itemRadius + item.exactShape.radius + 1e-9\n );\n }\n return segmentIntersectsRect(query.start, query.end, {\n minX: item.minX - itemRadius,\n minY: item.minY - itemRadius,\n maxX: item.maxX + itemRadius,\n maxY: item.maxY + itemRadius,\n });\n }\n\n private isOutsideBounds(query: CollisionQuery) {\n const radius = query.width / 2 + this.boardEdgeClearance;\n return (\n Math.min(query.start.x, query.end.x) - radius < this.bounds.minX ||\n Math.max(query.start.x, query.end.x) + radius > this.bounds.maxX ||\n Math.min(query.start.y, query.end.y) - radius < this.bounds.minY ||\n Math.max(query.start.y, query.end.y) + radius > this.bounds.maxY\n );\n }\n}\n","import { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { ConnectionNameResolver } from \"./ConnectionNameResolver\";\nimport { ElasticTracePushSolver } from \"./ElasticTracePushSolver\";\nimport {\n approximateSegmentWithRects,\n clamp,\n distance,\n distancePointToSegment,\n WIDTH_EPSILON,\n} from \"./geometry\";\nimport { ObstacleAwareGridRouteSolver } from \"./ObstacleAwareGridRouteSolver\";\nimport { SpatialObstacleIndex } from \"./SpatialObstacleIndex\";\nimport type {\n GridOffset,\n GridRouteOutput,\n ElasticTracePushOutput,\n IndexedObstacle,\n InflationCorridorSegment,\n LocalTraceInflationOutput,\n LocalTraceInflationProblem,\n SimpleRouteConnection,\n SimplifiedPcbTrace,\n WireRoutePoint,\n} from \"./types\";\n\ntype InflationPhase =\n | \"scan-corridor\"\n | \"select-blocker\"\n | \"try-elastic-push\"\n | \"try-grid-candidate\"\n | \"complete\";\n\ntype BlockingTrace = {\n traceIndex: number;\n firstRouteIndex: number;\n lastRouteIndex: number;\n};\n\nconst GRID_OFFSETS: GridOffset[] = [\n { x: 0, y: 0 },\n { x: 0.5, y: 0 },\n { x: 0, y: 0.5 },\n { x: 0.5, y: 0.5 },\n];\n\nconst isWire = (\n point: SimplifiedPcbTrace[\"route\"][number] | undefined,\n): point is WireRoutePoint => point?.route_type === \"wire\";\n\n/**\n * Moves a lower-width trace out of a local, nominal-width power corridor.\n * Endpoints outside the corridor remain fixed, so the displacement preserves\n * the trace's electrical topology and never moves a pad or via.\n */\nexport class LocalTraceInflationSolver extends BaseSolver {\n readonly inputProblem: LocalTraceInflationProblem;\n traces: SimplifiedPcbTrace[];\n readonly corridor: InflationCorridorSegment[];\n\n phase: InflationPhase = \"scan-corridor\";\n corridorCursor = 0;\n blockerCursor = 0;\n offsetCursor = 0;\n resolutionCursor = 0;\n attemptedGridCount = 0;\n\n private readonly blockerIndex: SpatialObstacleIndex;\n private readonly connectionNameResolver: ConnectionNameResolver;\n private readonly blockersByTrace = new Map<number, BlockingTrace>();\n private blockers: BlockingTrace[] = [];\n private currentBlocker: BlockingTrace | null = null;\n private currentRange: { startIndex: number; endIndex: number } | null = null;\n private currentTraceWidth = 0;\n private gridResolutions: number[] = [];\n private currentObstacleIndex: SpatialObstacleIndex | null = null;\n private output: LocalTraceInflationOutput | null = null;\n\n declare activeSubSolver:\n | ObstacleAwareGridRouteSolver\n | ElasticTracePushSolver\n | null;\n\n constructor(\n inputProblem: LocalTraceInflationProblem,\n connectionNameResolver = new ConnectionNameResolver(\n inputProblem.simpleRouteJson,\n inputProblem.traces,\n ),\n ) {\n super();\n this.inputProblem = structuredClone(inputProblem);\n this.traces = structuredClone(inputProblem.traces);\n this.corridor = structuredClone(inputProblem.corridor);\n this.connectionNameResolver = connectionNameResolver;\n this.blockerIndex = new SpatialObstacleIndex(\n this.inputProblem.simpleRouteJson,\n this.traces,\n inputProblem.powerTraceIndex,\n [],\n this.connectionNameResolver,\n );\n this.activeSubSolver = null;\n this.MAX_ITERATIONS = 25_000;\n this.stats = this.createStats();\n }\n\n override getSolverName() {\n return \"LocalTraceInflationSolver\";\n }\n\n override _step() {\n if (this.activeSubSolver) {\n this.stepActiveSubSolver();\n this.stats = this.createStats();\n return;\n }\n\n switch (this.phase) {\n case \"scan-corridor\":\n this.scanNextCorridorSegment();\n break;\n case \"select-blocker\":\n this.selectNextBlocker();\n break;\n case \"try-elastic-push\":\n // The elastic solver is stepped before the phase switch.\n break;\n case \"try-grid-candidate\":\n this.startNextGridCandidate();\n break;\n case \"complete\":\n if (this.output) this.solved = true;\n else {\n this.failed = true;\n this.error = \"No locally reroutable trace blocks the power corridor\";\n }\n break;\n }\n this.stats = this.createStats();\n }\n\n private scanNextCorridorSegment() {\n const corridorSegment = this.corridor[this.corridorCursor];\n if (!corridorSegment) {\n this.blockers = [...this.blockersByTrace.values()].sort(\n (a, b) => a.traceIndex - b.traceIndex,\n );\n this.phase = \"select-blocker\";\n return;\n }\n\n const powerTrace = this.traces[this.inputProblem.powerTraceIndex];\n const collisions = this.blockerIndex.findCollisions({\n start: corridorSegment.start,\n end: corridorSegment.end,\n layer: corridorSegment.layer,\n width: corridorSegment.width,\n connectionNames: powerTrace\n ? this.getTraceConnectionNames(powerTrace)\n : [],\n });\n\n for (const item of collisions) this.recordBlockingTrace(item);\n this.corridorCursor++;\n }\n\n private recordBlockingTrace(item: IndexedObstacle) {\n if (\n item.kind !== \"trace\" ||\n item.traceIndex === undefined ||\n item.routeStartIndex === undefined ||\n item.routeEndIndex === undefined ||\n item.traceIndex === this.inputProblem.powerTraceIndex\n ) {\n return;\n }\n\n const trace = this.traces[item.traceIndex];\n if (!trace) return;\n const connection = this.findConnectionForTrace(trace);\n // Locally routed subcircuits can contribute fixed traces without exposing\n // their connections in the parent routing problem. Their routed geometry\n // still gives us stable endpoints and a conservative nominal width, so\n // they are safe to shove without inventing connectivity metadata.\n const traceWidth = connection\n ? this.resolveNominalTraceWidth(connection)\n : this.getTraceNominalWidth(trace);\n if (\n traceWidth >=\n (this.inputProblem.pushOnlyNominalWidthsBelow ??\n this.inputProblem.nominalPowerWidth) -\n WIDTH_EPSILON\n ) {\n return;\n }\n\n const existing = this.blockersByTrace.get(item.traceIndex);\n if (existing) {\n existing.firstRouteIndex = Math.min(\n existing.firstRouteIndex,\n item.routeStartIndex,\n );\n existing.lastRouteIndex = Math.max(\n existing.lastRouteIndex,\n item.routeEndIndex,\n );\n return;\n }\n this.blockersByTrace.set(item.traceIndex, {\n traceIndex: item.traceIndex,\n firstRouteIndex: item.routeStartIndex,\n lastRouteIndex: item.routeEndIndex,\n });\n }\n\n private selectNextBlocker() {\n this.currentBlocker = this.blockers[this.blockerCursor] ?? null;\n if (!this.currentBlocker) {\n this.phase = \"complete\";\n return;\n }\n\n const range = this.findStableAnchorRange(this.currentBlocker);\n if (!range) {\n this.blockerCursor++;\n return;\n }\n\n const trace = this.traces[this.currentBlocker.traceIndex]!;\n this.currentRange = range;\n this.currentTraceWidth = this.getRangeWidth(trace, range);\n this.gridResolutions = this.getGridResolutions(this.currentTraceWidth);\n this.resolutionCursor = 0;\n this.offsetCursor = 0;\n this.currentObstacleIndex = new SpatialObstacleIndex(\n this.inputProblem.simpleRouteJson,\n this.traces,\n this.currentBlocker.traceIndex,\n this.createInflatedCorridorItems(),\n this.connectionNameResolver,\n );\n this.activeSubSolver = new ElasticTracePushSolver({\n trace,\n range,\n layer: (trace.route[range.startIndex] as WireRoutePoint).layer,\n traceWidth: this.currentTraceWidth,\n corridor: this.corridor,\n obstacleIndex: this.currentObstacleIndex,\n connectionNames: this.getTraceConnectionNames(trace),\n });\n this.phase = \"try-elastic-push\";\n }\n\n private findStableAnchorRange(blocker: BlockingTrace) {\n const trace = this.traces[blocker.traceIndex];\n if (!trace) return null;\n let startIndex = blocker.firstRouteIndex;\n let endIndex = blocker.lastRouteIndex;\n\n while (startIndex > 0) {\n const point = trace.route[startIndex];\n if (isWire(point) && this.pointClearsCorridor(point)) break;\n startIndex--;\n }\n while (endIndex < trace.route.length - 1) {\n const point = trace.route[endIndex];\n if (isWire(point) && this.pointClearsCorridor(point)) break;\n endIndex++;\n }\n\n const start = trace.route[startIndex];\n const end = trace.route[endIndex];\n if (\n !isWire(start) ||\n !isWire(end) ||\n start.layer !== end.layer ||\n !this.pointClearsCorridor(start) ||\n !this.pointClearsCorridor(end) ||\n startIndex >= endIndex\n ) {\n return null;\n }\n\n const range = { startIndex, endIndex };\n const routeLength = this.getRangeLength(trace, range);\n if (\n !Number.isFinite(routeLength) ||\n routeLength > (this.inputProblem.maxRerouteLength ?? 10) + WIDTH_EPSILON\n ) {\n return null;\n }\n return range;\n }\n\n private pointClearsCorridor(point: WireRoutePoint) {\n return this.corridor.every((segment) => {\n if (segment.layer !== point.layer) return true;\n const requiredDistance =\n segment.width / 2 + point.width / 2 + this.blockerIndex.clearance;\n return (\n distancePointToSegment(point, segment.start, segment.end) >=\n requiredDistance - WIDTH_EPSILON\n );\n });\n }\n\n private startNextGridCandidate() {\n if (!this.currentBlocker || !this.currentRange) {\n this.phase = \"select-blocker\";\n return;\n }\n if (this.resolutionCursor >= this.gridResolutions.length) {\n this.blockerCursor++;\n this.phase = \"select-blocker\";\n return;\n }\n if (this.offsetCursor >= GRID_OFFSETS.length) {\n this.resolutionCursor++;\n this.offsetCursor = 0;\n return;\n }\n\n const trace = this.traces[this.currentBlocker.traceIndex]!;\n const start = trace.route[this.currentRange.startIndex];\n const end = trace.route[this.currentRange.endIndex];\n if (!isWire(start) || !isWire(end)) {\n this.blockerCursor++;\n this.phase = \"select-blocker\";\n return;\n }\n\n const gridSize = this.gridResolutions[this.resolutionCursor]!;\n const normalizedOffset = GRID_OFFSETS[this.offsetCursor]!;\n const obstacleIndex = this.currentObstacleIndex;\n if (!obstacleIndex) {\n this.blockerCursor++;\n this.phase = \"select-blocker\";\n return;\n }\n this.attemptedGridCount++;\n this.activeSubSolver = new ObstacleAwareGridRouteSolver({\n start,\n end,\n layer: start.layer,\n traceWidth: this.currentTraceWidth,\n gridSize,\n gridOffset: {\n x: normalizedOffset.x * gridSize,\n y: normalizedOffset.y * gridSize,\n },\n connectionNames: this.getTraceConnectionNames(trace),\n obstacleIndex,\n ignoreTraceIndex: this.currentBlocker.traceIndex,\n ignoreRouteRange: {\n start: this.currentRange.startIndex,\n end: this.currentRange.endIndex,\n },\n bounds: this.inputProblem.simpleRouteJson.bounds,\n searchPadding: clamp(this.inputProblem.nominalPowerWidth * 2.5, 1.5, 4),\n });\n }\n\n private stepActiveSubSolver() {\n const solver = this.activeSubSolver!;\n solver.step();\n if (!solver.solved && !solver.failed) return;\n\n if (solver.solved) {\n const output = solver.getOutput();\n if (output) {\n this.applyRoute(\n output,\n solver instanceof ElasticTracePushSolver ? \"elastic\" : \"grid\",\n );\n this.activeSubSolver = null;\n this.phase = \"complete\";\n return;\n }\n }\n\n this.failedSubSolvers ??= [];\n this.failedSubSolvers.push(solver);\n this.activeSubSolver = null;\n if (solver instanceof ElasticTracePushSolver) {\n this.phase = \"try-grid-candidate\";\n return;\n }\n this.offsetCursor++;\n }\n\n private applyRoute(\n output: GridRouteOutput | ElasticTracePushOutput,\n strategy: \"elastic\" | \"grid\",\n ) {\n const blocker = this.currentBlocker!;\n const range = this.currentRange!;\n const trace = this.traces[blocker.traceIndex]!;\n const originalStart = trace.route[range.startIndex] as WireRoutePoint;\n const originalEnd = trace.route[range.endIndex] as WireRoutePoint;\n const replacement: WireRoutePoint[] = output.points.map((point) => ({\n route_type: \"wire\",\n x: point.x,\n y: point.y,\n width: this.currentTraceWidth,\n layer: originalStart.layer,\n }));\n replacement[0]!.width = Math.max(\n replacement[0]!.width,\n originalStart.width,\n );\n replacement[replacement.length - 1]!.width = Math.max(\n replacement[replacement.length - 1]!.width,\n originalEnd.width,\n );\n trace.route.splice(\n range.startIndex,\n range.endIndex - range.startIndex + 1,\n ...replacement,\n );\n this.output = {\n traces: this.traces,\n pushedTraceIndex: blocker.traceIndex,\n replacedRange: range,\n strategy,\n };\n }\n\n private createInflatedCorridorItems() {\n return this.corridor.flatMap((segment) =>\n approximateSegmentWithRects({\n start: segment.start,\n end: segment.end,\n width: segment.width,\n base: {\n layers: [segment.layer],\n kind: \"obstacle\",\n connectionNames: [],\n },\n }),\n );\n }\n\n private getGridResolutions(traceWidth: number) {\n return [\n clamp(traceWidth * 1.5, 0.1, 0.3),\n clamp(traceWidth * 0.75, 0.08, 0.18),\n ].filter(\n (value, index, values) =>\n values.findIndex(\n (candidate) => Math.abs(candidate - value) < WIDTH_EPSILON,\n ) === index,\n );\n }\n\n private getRangeWidth(\n trace: SimplifiedPcbTrace,\n range: { startIndex: number; endIndex: number },\n ) {\n let width = this.inputProblem.simpleRouteJson.minTraceWidth;\n for (let index = range.startIndex; index <= range.endIndex; index++) {\n const point = trace.route[index];\n if (isWire(point)) width = Math.max(width, point.width);\n }\n return width;\n }\n\n private getRangeLength(\n trace: SimplifiedPcbTrace,\n range: { startIndex: number; endIndex: number },\n ) {\n let length = 0;\n for (let index = range.startIndex; index < range.endIndex; index++) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) {\n return Number.POSITIVE_INFINITY;\n }\n length += distance(start, end);\n }\n return length;\n }\n\n private resolveNominalTraceWidth(connection: SimpleRouteConnection) {\n return Math.max(\n connection.nominalTraceWidth ??\n connection.width ??\n this.inputProblem.simpleRouteJson.nominalTraceWidth ??\n this.inputProblem.simpleRouteJson.minTraceWidth,\n this.inputProblem.simpleRouteJson.minTraceWidth,\n );\n }\n\n private getTraceNominalWidth(trace: SimplifiedPcbTrace) {\n return trace.route.reduce(\n (width, point) =>\n point.route_type === \"wire\" ? Math.max(width, point.width) : width,\n this.inputProblem.simpleRouteJson.minTraceWidth,\n );\n }\n\n private findConnectionForTrace(trace: SimplifiedPcbTrace) {\n const names = this.getTraceConnectionNames(trace);\n return this.inputProblem.simpleRouteJson.connections.find((connection) =>\n [\n connection.name,\n connection.source_trace_id,\n connection.rootConnectionName,\n ...(connection.mergedConnectionNames ?? []),\n ]\n .filter((name): name is string => Boolean(name))\n .some((name) => names.includes(name)),\n );\n }\n\n private getTraceConnectionNames(trace: SimplifiedPcbTrace) {\n return [\n trace.connection_name,\n trace.source_trace_id,\n trace.rootConnectionName,\n ...(trace.mergedConnectionNames ?? []),\n ].filter((name): name is string => Boolean(name));\n }\n\n private createStats() {\n return {\n phase: this.phase,\n corridorSegment: this.corridorCursor,\n corridorSegmentCount: this.corridor.length,\n blockingTraceCount: this.blockersByTrace.size,\n blockerCursor: this.blockerCursor,\n pushedTraceIndex: this.currentBlocker?.traceIndex,\n anchorRange: this.currentRange,\n traceWidth: this.currentTraceWidth,\n gridSize: this.gridResolutions[this.resolutionCursor],\n gridOffsetVariant: this.offsetCursor,\n attemptedGridCount: this.attemptedGridCount,\n };\n }\n\n computeProgress() {\n if (this.phase === \"scan-corridor\") {\n return this.corridor.length === 0\n ? 0.25\n : (this.corridorCursor / this.corridor.length) * 0.25;\n }\n if (this.blockers.length === 0) return 0.5;\n return Math.min(0.99, 0.25 + this.blockerCursor / this.blockers.length);\n }\n\n override getOutput() {\n return this.output;\n }\n\n override getConstructorParams() {\n return [this.inputProblem];\n }\n\n override visualize(): GraphicsObject {\n const lines: NonNullable<GraphicsObject[\"lines\"]> = [];\n for (let traceIndex = 0; traceIndex < this.traces.length; traceIndex++) {\n const trace = this.traces[traceIndex]!;\n for (let index = 0; index < trace.route.length - 1; index++) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer)\n continue;\n lines.push({\n points: [start, end],\n strokeColor:\n traceIndex === this.currentBlocker?.traceIndex ? \"#1769d2\" : \"#777\",\n strokeWidth: Math.max(start.width, end.width),\n });\n }\n }\n for (const segment of this.corridor) {\n lines.push({\n points: [segment.start, segment.end],\n strokeColor: \"rgba(255, 128, 0, 0.55)\",\n strokeWidth: segment.width,\n });\n }\n return {\n coordinateSystem: \"cartesian\",\n title: this.getSolverName(),\n lines,\n points: [],\n rects: [],\n circles: [],\n texts: [],\n };\n }\n}\n","import { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { ConnectionNameResolver } from \"./ConnectionNameResolver\";\nimport { clamp, distance, WIDTH_EPSILON } from \"./geometry\";\nimport { LocalTraceInflationSolver } from \"./LocalTraceInflationSolver\";\nimport { ObstacleAwareGridRouteSolver } from \"./ObstacleAwareGridRouteSolver\";\nimport {\n calculateOctilinearPaths,\n countNonOctilinearSegments,\n getPathLength,\n} from \"./octilinear\";\nimport { SpatialObstacleIndex } from \"./SpatialObstacleIndex\";\nimport type {\n InflationCorridorSegment,\n Point,\n PowerTraceCleanupOutput,\n PowerTraceCleanupProblem,\n SimpleRouteConnection,\n SimplifiedPcbTrace,\n ViaRoutePoint,\n WireRoutePoint,\n} from \"./types\";\n\ntype CleanupPhase =\n | \"repair-vias\"\n | \"scan-via-pairs\"\n | \"scan-pad-clearance\"\n | \"scan-simplification\"\n | \"evaluate-candidate\"\n | \"shove-clearance\"\n | \"route-via-pair\"\n | \"complete\";\n\ntype CleanupKind = \"via-pair\" | \"pad-clearance\" | \"simplification\";\n\ntype RouteQuality = {\n length: number;\n deficitArea: number;\n conservativeDeficitArea: number;\n nominalLength: number;\n conservativeNominalLength: number;\n nonOctilinearSegmentCount: number;\n pointCount: number;\n};\n\ntype CleanupCandidate = {\n kind: CleanupKind;\n traceIndex: number;\n startIndex: number;\n endIndex: number;\n layer: string;\n points: Point[];\n width: number;\n padClearance: number;\n originalQuality: RouteQuality;\n};\n\ntype ViaGridAttempt = {\n kind: CleanupKind;\n traceIndex: number;\n startIndex: number;\n endIndex: number;\n layer: string;\n padClearances: number[];\n padClearanceCursor: number;\n originalQuality: RouteQuality;\n widths: number[];\n widthCursor: number;\n gridSizes: number[];\n gridSizeCursor: number;\n offsetCursor: number;\n};\n\ntype ViaRepairReplacement = {\n startIndex: number;\n endIndex: number;\n route: SimplifiedPcbTrace[\"route\"];\n};\n\ntype PushedViaRepair = {\n traceIndex: number;\n viaIndex: number;\n point: Point;\n padClearance: number;\n corridor: InflationCorridorSegment[];\n};\n\ntype ViaRepairContext = {\n trace: SimplifiedPcbTrace;\n viaIndex: number;\n via: ViaRoutePoint;\n leftWire: WireRoutePoint;\n rightWire: WireRoutePoint;\n leftIsEndpoint: boolean;\n rightIsEndpoint: boolean;\n leftAnchor: WireRoutePoint;\n rightAnchor: WireRoutePoint;\n originalLength: number;\n connectionNames: string[];\n viaDiameter: number;\n holeDiameter: number;\n ignoreRouteRange: { start: number; end: number };\n candidates: Point[];\n};\n\nconst GRID_OFFSETS = [\n { x: 0, y: 0 },\n { x: 0.5, y: 0.5 },\n] as const;\n\nconst PAD_CLEARANCE_MEASUREMENT_TIERS = [0.15, 0.2, 0.25, 0.3, 0.4, 0.5];\nconst VIA_PAIR_PREFERRED_PAD_CLEARANCE = 0.15;\n\nconst isWire = (\n point: SimplifiedPcbTrace[\"route\"][number] | undefined,\n): point is WireRoutePoint => point?.route_type === \"wire\";\n\nconst isVia = (\n point: SimplifiedPcbTrace[\"route\"][number] | undefined,\n): point is ViaRoutePoint => point?.route_type === \"via\";\n\nconst VIA_REPAIR_DIRECTIONS = Array.from({ length: 24 }, (_, index) => {\n const angle = (index * Math.PI) / 12;\n return { x: Math.cos(angle), y: Math.sin(angle) };\n});\n\nconst uniqueDescending = (values: number[]) =>\n [...new Set(values.map((value) => Number(value.toFixed(6))))].sort(\n (a, b) => b - a,\n );\n\n/**\n * Post-route cleanup for wide traces. It removes same-layer via excursions,\n * then rewrites unnecessarily complex or arbitrary-angle paths as compact\n * 0/45/90-degree paths. A lower-width neighboring trace may be displaced to\n * create extra clearance, but that displacement is transactional: it is\n * rolled back unless the proposed power path is ultimately accepted.\n */\nexport class PowerTraceCleanupSolver extends BaseSolver {\n readonly inputProblem: PowerTraceCleanupProblem;\n traces: SimplifiedPcbTrace[];\n obstacleIndex: SpatialObstacleIndex;\n phase: CleanupPhase = \"repair-vias\";\n\n traceCursor = 0;\n routeCursor = 0;\n candidateCursor = 0;\n clearanceTierCursor = 0;\n attemptedCandidateCount = 0;\n attemptedClearanceShoveCount = 0;\n attemptedViaGridCount = 0;\n committedClearanceShoveCount = 0;\n viaPairCountRemoved = 0;\n viaCountRemoved = 0;\n simplifiedPathCount = 0;\n normalizedSegmentCount = 0;\n achievedExtraClearanceCount = 0;\n relocatedViaCount = 0;\n unresolvedViaCount = 0;\n attemptedPushedViaRepairCount = 0;\n committedPushedViaRepairCount = 0;\n padClearanceRerouteCount = 0;\n unresolvedPadClearanceCount = 0;\n initialPadClearanceViolationCount = 0;\n remainingPadClearanceViolationCount = 0;\n initialPadClearanceViolationCountByClearance: Record<string, number> = {};\n remainingPadClearanceViolationCountByClearance: Record<string, number> = {};\n\n private readonly connectionNameResolver: ConnectionNameResolver;\n private readonly traceIndices: number[];\n private readonly maxRerouteLength: number;\n private readonly clearancePaddingTiers: number[];\n private readonly desiredPadClearance?: number;\n private readonly initialTraceLengths = new Map<number, number>();\n private candidates: CleanupCandidate[] = [];\n private candidateShoveCount = 0;\n private rollbackTraces: SimplifiedPcbTrace[] | null = null;\n private baseCandidateValidated = false;\n private activeShovePadding = 0;\n private viaGridAttempt: ViaGridAttempt | null = null;\n private candidateSetMayUseGridFallback = false;\n private pendingPushedViaRepair: PushedViaRepair | null = null;\n private alternatePushedViaRepairs: PushedViaRepair[] = [];\n private pushedViaRepairRollbackTraces: SimplifiedPcbTrace[] | null = null;\n private resumePhase: Exclude<\n CleanupPhase,\n \"evaluate-candidate\" | \"shove-clearance\" | \"complete\"\n > = \"scan-via-pairs\";\n\n declare activeSubSolver:\n | LocalTraceInflationSolver\n | ObstacleAwareGridRouteSolver\n | null;\n\n constructor(inputProblem: PowerTraceCleanupProblem) {\n super();\n this.inputProblem = structuredClone(inputProblem);\n this.traces = structuredClone(inputProblem.traces);\n this.connectionNameResolver = new ConnectionNameResolver(\n inputProblem.simpleRouteJson,\n this.traces,\n );\n this.maxRerouteLength = inputProblem.maxRerouteLength ?? 10;\n this.desiredPadClearance = inputProblem.desiredPadClearance;\n this.clearancePaddingTiers = uniqueDescending([\n ...(inputProblem.clearancePaddingTiers ?? [0.1, 0.05, 0]),\n 0,\n ]).filter((padding) => padding >= 0);\n const requestedIndices = inputProblem.traceIndices\n ? new Set(inputProblem.traceIndices)\n : null;\n this.traceIndices = this.traces.flatMap((trace, traceIndex) =>\n (!requestedIndices || requestedIndices.has(traceIndex)) &&\n this.resolveNominalTraceWidth(trace) >= 0.5 - WIDTH_EPSILON\n ? [traceIndex]\n : [],\n );\n for (const traceIndex of this.traceIndices) {\n this.initialTraceLengths.set(\n traceIndex,\n this.measureTraceLength(this.traces[traceIndex]!),\n );\n }\n this.obstacleIndex = this.createObstacleIndex();\n this.initialPadClearanceViolationCount = this.countPadClearanceViolations();\n this.remainingPadClearanceViolationCount =\n this.initialPadClearanceViolationCount;\n this.initialPadClearanceViolationCountByClearance =\n this.countPadClearanceViolationsByTier();\n this.remainingPadClearanceViolationCountByClearance = {\n ...this.initialPadClearanceViolationCountByClearance,\n };\n this.activeSubSolver = null;\n this.MAX_ITERATIONS = 1_000_000;\n this.stats = this.createStats();\n }\n\n override getSolverName() {\n return \"PowerTraceCleanupSolver\";\n }\n\n override _step() {\n if (this.activeSubSolver) {\n this.stepActiveShoveSolver();\n this.stats = this.createStats();\n return;\n }\n\n switch (this.phase) {\n case \"repair-vias\":\n this.repairNextVia();\n break;\n case \"scan-via-pairs\":\n this.scanNextViaPair();\n break;\n case \"scan-pad-clearance\":\n this.scanNextPadClearance();\n break;\n case \"scan-simplification\":\n this.scanNextSimplification();\n break;\n case \"evaluate-candidate\":\n this.evaluateCurrentCandidate();\n break;\n case \"shove-clearance\":\n // The active shove solver is stepped above.\n break;\n case \"route-via-pair\":\n this.startNextViaGridCandidate();\n break;\n case \"complete\":\n this.solved = true;\n break;\n }\n this.stats = this.createStats();\n }\n\n private repairNextVia() {\n const trace = this.traces[this.traceCursor];\n if (!trace) {\n this.traceCursor = 0;\n this.routeCursor = 0;\n this.phase = \"scan-via-pairs\";\n this.rebuildObstacleIndex();\n return;\n }\n const viaIndex = trace.route.findIndex(\n (point, index) => index >= this.routeCursor && isVia(point),\n );\n if (viaIndex === -1) {\n this.traceCursor++;\n this.routeCursor = 0;\n return;\n }\n this.routeCursor = viaIndex + 1;\n const via = trace.route[viaIndex];\n const leftWire = trace.route[viaIndex - 1];\n const rightWire = trace.route[viaIndex + 1];\n if (!isVia(via) || !isWire(leftWire) || !isWire(rightWire)) return;\n\n const connectionNames = this.getTraceConnectionNames(trace);\n // Via repair is a DFM pass, not a power-clearance pass: vias must clear\n // unrelated copper by the board minimum and must never overlap connected\n // pads. Applying the larger power-to-pad target to the via annulus creates\n // unnecessarily long necks in otherwise healthy power routes.\n const padClearance = this.getBaseObstacleClearance();\n if (\n !this.obstacleIndex.collidesVia({\n point: via,\n layers: this.obstacleIndex.boardLayers,\n padDiameter: via.via_diameter ?? 0.6,\n holeDiameter:\n via.via_hole_diameter ?? this.obstacleIndex.defaultViaHoleDiameter,\n connectionNames,\n ignoreTraceIndex: this.traceCursor,\n ignoreRouteRange: { start: viaIndex, end: viaIndex },\n obstacleClearance: padClearance,\n blockSameNetObstacles: true,\n sameNetObstacleClearance: 0,\n })\n ) {\n return;\n }\n\n const replacement = this.findViaRepair(trace, viaIndex, padClearance);\n if (!replacement) {\n const pushedRepairs = this.findPushableViaRepairs(\n trace,\n viaIndex,\n padClearance,\n );\n const pushedRepair = pushedRepairs.shift();\n if (pushedRepair) {\n this.alternatePushedViaRepairs = pushedRepairs;\n this.startPushedViaRepair(pushedRepair);\n return;\n }\n this.unresolvedViaCount++;\n return;\n }\n trace.route.splice(\n replacement.startIndex,\n replacement.endIndex - replacement.startIndex + 1,\n ...replacement.route,\n );\n this.relocatedViaCount++;\n this.routeCursor = replacement.startIndex + replacement.route.length;\n this.rebuildObstacleIndex();\n }\n\n private findViaRepair(\n trace: SimplifiedPcbTrace,\n viaIndex: number,\n padClearance: number,\n ) {\n const context = this.createViaRepairContext(trace, viaIndex);\n if (!context) return null;\n const candidates = context.candidates\n .map((point) => ({\n point,\n movedLength:\n distance(context.leftAnchor, point) +\n distance(point, context.rightAnchor),\n }))\n .filter(\n ({ movedLength }) =>\n movedLength <=\n context.originalLength +\n Math.min(6, this.maxRerouteLength) +\n WIDTH_EPSILON,\n );\n candidates.sort(\n (a, b) =>\n a.movedLength - b.movedLength ||\n distance(a.point, context.via) - distance(b.point, context.via),\n );\n for (const candidate of candidates) {\n if (this.isViaRepairPointSafe(context, candidate.point, padClearance)) {\n return this.createViaRepairReplacement(context, candidate.point);\n }\n }\n return null;\n }\n\n private findPushableViaRepairs(\n trace: SimplifiedPcbTrace,\n viaIndex: number,\n padClearance: number,\n ): PushedViaRepair[] {\n const context = this.createViaRepairContext(trace, viaIndex);\n if (!context) return [];\n const pushableCandidates = context.candidates.flatMap((point) => {\n const movedLength =\n distance(context.leftAnchor, point) +\n distance(point, context.rightAnchor);\n if (\n movedLength >\n context.originalLength +\n Math.min(6, this.maxRerouteLength) +\n WIDTH_EPSILON\n ) {\n return [];\n }\n const blockers = new Set<number>();\n const collisionQueries = this.getViaRepairCollisionQueries(\n context,\n point,\n padClearance,\n );\n for (const query of collisionQueries) {\n for (const collision of this.obstacleIndex.findCollisions(query)) {\n if (\n collision.kind !== \"trace\" ||\n collision.traceIndex === undefined ||\n collision.traceIndex === this.traceCursor\n ) {\n return [];\n }\n blockers.add(collision.traceIndex);\n }\n }\n if (blockers.size === 0 || blockers.size > 2) return [];\n const ignoredTraceIndices = [...blockers];\n if (\n !this.isViaRepairPointSafe(\n context,\n point,\n padClearance,\n ignoredTraceIndices,\n )\n ) {\n return [];\n }\n return [\n {\n point,\n movedLength,\n blockerCount: blockers.size,\n blockerKey: [...blockers].sort((a, b) => a - b).join(\",\"),\n },\n ];\n });\n pushableCandidates.sort(\n (a, b) =>\n a.blockerCount - b.blockerCount ||\n a.movedLength - b.movedLength ||\n distance(a.point, context.via) - distance(b.point, context.via),\n );\n const selectedCandidates = [\n ...new Map(\n [...pushableCandidates]\n .reverse()\n .map((candidate) => [candidate.blockerKey, candidate]),\n ).values(),\n ...pushableCandidates,\n ].filter(\n (candidate, index, candidates) =>\n candidates.findIndex(\n (other) =>\n other.point.x === candidate.point.x &&\n other.point.y === candidate.point.y,\n ) === index,\n );\n return selectedCandidates.slice(0, 12).map((candidate) => ({\n traceIndex: this.traceCursor,\n viaIndex,\n point: candidate.point,\n padClearance,\n corridor: [\n {\n start: context.leftAnchor,\n end: candidate.point,\n layer: context.leftWire.layer,\n width: context.leftWire.width,\n },\n {\n start: candidate.point,\n end: context.rightAnchor,\n layer: context.rightWire.layer,\n width: context.rightWire.width,\n },\n ...this.obstacleIndex.boardLayers.map((layer) => ({\n start: candidate.point,\n end: candidate.point,\n layer,\n width: context.viaDiameter,\n })),\n ],\n }));\n }\n\n private createViaRepairContext(\n trace: SimplifiedPcbTrace,\n viaIndex: number,\n ): ViaRepairContext | null {\n const via = trace.route[viaIndex];\n const leftWire = trace.route[viaIndex - 1];\n const rightWire = trace.route[viaIndex + 1];\n if (!isVia(via) || !isWire(leftWire) || !isWire(rightWire)) return null;\n\n const leftIsEndpoint =\n viaIndex - 1 === 0 || !isWire(trace.route[viaIndex - 2]);\n const rightIsEndpoint =\n viaIndex + 1 === trace.route.length - 1 ||\n !isWire(trace.route[viaIndex + 2]);\n const leftAnchor = leftIsEndpoint\n ? leftWire\n : (trace.route[viaIndex - 2] as WireRoutePoint);\n const rightAnchor = rightIsEndpoint\n ? rightWire\n : (trace.route[viaIndex + 2] as WireRoutePoint);\n const originalLength =\n distance(leftAnchor, via) + distance(via, rightAnchor);\n const connectionNames = this.getTraceConnectionNames(trace);\n const viaDiameter = via.via_diameter ?? 0.6;\n const holeDiameter =\n via.via_hole_diameter ?? this.obstacleIndex.defaultViaHoleDiameter;\n const minimumRadius = Math.max(\n 0.3,\n holeDiameter +\n this.obstacleIndex.minViaHoleEdgeToViaHoleEdgeClearance +\n 0.05,\n );\n const radialCandidates = [\n minimumRadius,\n minimumRadius + 0.15,\n minimumRadius + 0.3,\n minimumRadius + 0.5,\n minimumRadius + 0.75,\n minimumRadius + 1,\n minimumRadius + 1.5,\n minimumRadius + 2,\n ].flatMap((radius) =>\n VIA_REPAIR_DIRECTIONS.map((direction) => ({\n x: Math.round((via.x + direction.x * radius) / 0.025) * 0.025,\n y: Math.round((via.y + direction.y * radius) / 0.025) * 0.025,\n })),\n );\n const candidates = [\n ...radialCandidates,\n ...radialCandidates.flatMap((point) => [\n { x: point.x, y: Math.floor(via.y * 10) / 10 },\n { x: point.x, y: Math.ceil(via.y * 10) / 10 },\n { x: Math.floor(via.x * 10) / 10, y: point.y },\n { x: Math.ceil(via.x * 10) / 10, y: point.y },\n ]),\n ].filter(\n (point, index, points) =>\n points.findIndex(\n (other) => other.x === point.x && other.y === point.y,\n ) === index,\n );\n return {\n trace,\n viaIndex,\n via,\n leftWire,\n rightWire,\n leftIsEndpoint,\n rightIsEndpoint,\n leftAnchor,\n rightAnchor,\n originalLength,\n connectionNames,\n viaDiameter,\n holeDiameter,\n ignoreRouteRange: {\n start: Math.max(0, viaIndex - 2),\n end: Math.min(trace.route.length - 1, viaIndex + 2),\n },\n candidates,\n };\n }\n\n private getViaRepairCollisionQueries(\n context: ViaRepairContext,\n point: Point,\n padClearance: number,\n ignoreTraceIndices?: number[],\n ) {\n const common = {\n connectionNames: context.connectionNames,\n ignoreTraceIndex: this.traceCursor,\n ignoreTraceIndices,\n ignoreRouteRange: context.ignoreRouteRange,\n obstacleClearance: padClearance,\n };\n return [\n ...this.obstacleIndex.boardLayers.map((layer) => ({\n ...common,\n start: point,\n end: point,\n layer,\n width: context.viaDiameter,\n blockSameNetObstacles: true,\n sameNetObstacleClearance: 0,\n })),\n {\n ...common,\n start: context.leftAnchor,\n end: point,\n layer: context.leftWire.layer,\n width: context.leftWire.width,\n },\n {\n ...common,\n start: point,\n end: context.rightAnchor,\n layer: context.rightWire.layer,\n width: context.rightWire.width,\n },\n ];\n }\n\n private isViaRepairPointSafe(\n context: ViaRepairContext,\n point: Point,\n padClearance: number,\n ignoreTraceIndices?: number[],\n ) {\n if (\n this.obstacleIndex.collidesVia({\n point,\n layers: this.obstacleIndex.boardLayers,\n padDiameter: context.viaDiameter,\n holeDiameter: context.holeDiameter,\n connectionNames: context.connectionNames,\n ignoreTraceIndex: this.traceCursor,\n ignoreTraceIndices,\n ignoreRouteRange: { start: context.viaIndex, end: context.viaIndex },\n obstacleClearance: padClearance,\n blockSameNetObstacles: true,\n sameNetObstacleClearance: 0,\n })\n ) {\n return false;\n }\n return !this.getViaRepairCollisionQueries(\n context,\n point,\n padClearance,\n ignoreTraceIndices,\n )\n .slice(this.obstacleIndex.boardLayers.length)\n .some((query) => this.obstacleIndex.collides(query));\n }\n\n private createViaRepairReplacement(\n context: ViaRepairContext,\n point: Point,\n ): ViaRepairReplacement {\n const movedLeft: WireRoutePoint = { ...context.leftWire, ...point };\n const movedVia: ViaRoutePoint = { ...context.via, ...point };\n const movedRight: WireRoutePoint = { ...context.rightWire, ...point };\n return {\n startIndex: context.viaIndex - 1,\n endIndex: context.viaIndex + 1,\n route: [\n ...(context.leftIsEndpoint ? [context.leftWire] : []),\n movedLeft,\n movedVia,\n movedRight,\n ...(context.rightIsEndpoint ? [context.rightWire] : []),\n ],\n };\n }\n\n private startPushedViaRepair(repair: PushedViaRepair) {\n this.pendingPushedViaRepair = repair;\n this.pushedViaRepairRollbackTraces = structuredClone(this.traces);\n this.attemptedPushedViaRepairCount++;\n this.activeSubSolver = new LocalTraceInflationSolver(\n {\n simpleRouteJson: this.inputProblem.simpleRouteJson,\n traces: this.traces,\n powerTraceIndex: repair.traceIndex,\n nominalPowerWidth: Math.max(\n ...repair.corridor.map((segment) => segment.width),\n ),\n pushOnlyNominalWidthsBelow: Number.POSITIVE_INFINITY,\n corridor: repair.corridor,\n maxRerouteLength: this.maxRerouteLength,\n },\n this.connectionNameResolver,\n );\n }\n\n private finishPushedViaRepairSolver(solver: LocalTraceInflationSolver) {\n const repair = this.pendingPushedViaRepair;\n this.activeSubSolver = null;\n if (!repair) return;\n\n if (solver.solved) {\n const output = solver.getOutput();\n if (output) {\n this.traces = output.traces;\n this.rebuildObstacleIndex();\n const trace = this.traces[repair.traceIndex];\n const context = trace\n ? this.createViaRepairContext(trace, repair.viaIndex)\n : null;\n if (\n context &&\n this.isViaRepairPointSafe(context, repair.point, repair.padClearance)\n ) {\n const replacement = this.createViaRepairReplacement(\n context,\n repair.point,\n );\n trace!.route.splice(\n replacement.startIndex,\n replacement.endIndex - replacement.startIndex + 1,\n ...replacement.route,\n );\n this.relocatedViaCount++;\n this.committedPushedViaRepairCount++;\n this.routeCursor = replacement.startIndex + replacement.route.length;\n this.pendingPushedViaRepair = null;\n this.alternatePushedViaRepairs = [];\n this.pushedViaRepairRollbackTraces = null;\n this.rebuildObstacleIndex();\n return;\n }\n }\n }\n\n if (this.pushedViaRepairRollbackTraces) {\n this.traces = this.pushedViaRepairRollbackTraces;\n }\n this.pendingPushedViaRepair = null;\n this.pushedViaRepairRollbackTraces = null;\n const alternateRepair = this.alternatePushedViaRepairs.shift();\n if (alternateRepair) {\n this.rebuildObstacleIndex();\n this.startPushedViaRepair(alternateRepair);\n return;\n }\n this.alternatePushedViaRepairs = [];\n this.unresolvedViaCount++;\n this.rebuildObstacleIndex();\n }\n\n private scanNextViaPair() {\n const traceIndex = this.traceIndices[this.traceCursor];\n if (traceIndex === undefined) {\n this.traceCursor = 0;\n this.routeCursor = 0;\n this.phase = \"scan-pad-clearance\";\n return;\n }\n const trace = this.traces[traceIndex]!;\n const firstViaIndex = trace.route.findIndex(\n (point, index) => index >= this.routeCursor && point.route_type === \"via\",\n );\n if (firstViaIndex === -1) {\n this.advanceTrace();\n return;\n }\n const secondViaRelativeIndex = trace.route\n .slice(firstViaIndex + 1)\n .findIndex((point) => point.route_type === \"via\");\n if (secondViaRelativeIndex === -1) {\n this.advanceTrace();\n return;\n }\n const secondViaIndex = firstViaIndex + 1 + secondViaRelativeIndex;\n const startIndex = firstViaIndex - 1;\n const endIndex = secondViaIndex + 1;\n const start = trace.route[startIndex];\n const end = trace.route[endIndex];\n this.routeCursor = firstViaIndex + 1;\n if (\n !isWire(start) ||\n !isWire(end) ||\n start.layer !== end.layer ||\n distance(start, end) > this.maxRerouteLength + WIDTH_EPSILON\n ) {\n return;\n }\n\n const baseCandidates = this.createCandidates({\n kind: \"via-pair\",\n traceIndex,\n startIndex,\n endIndex,\n });\n const candidateWidth =\n baseCandidates[0]?.width ?? Math.max(start.width, end.width);\n const padClearance =\n baseCandidates[0]?.padClearance ??\n this.getCandidatePadClearance(\n \"via-pair\",\n traceIndex,\n startIndex,\n endIndex,\n );\n const endpointCollidesWithPad = (routeIndex: number) => {\n const point = trace.route[routeIndex];\n if (!isWire(point)) return false;\n return this.obstacleIndex\n .findCollisions({\n start: point,\n end: point,\n layer: point.layer,\n width: candidateWidth,\n connectionNames: this.getTraceConnectionNames(trace),\n ignoreTraceIndex: traceIndex,\n ignoreRouteRange: {\n start: Math.max(0, startIndex - 1),\n end: Math.min(trace.route.length - 1, endIndex + 1),\n },\n obstacleClearance: padClearance,\n })\n .some(\n (collision) =>\n collision.kind === \"obstacle\" && collision.obstacleKind === \"pad\",\n );\n };\n\n // A layer detour can place its vias just inside a pad's clearance\n // envelope even though the neighboring same-layer anchors have a clear\n // path around that pad. Give cleanup those anchors as alternate route\n // boundaries instead of asking the grid router to start from an invalid\n // endpoint.\n const priorStart = trace.route[startIndex - 1];\n const nextEnd = trace.route[endIndex + 1];\n const expandedStartIndex =\n baseCandidates.length > 0 &&\n endpointCollidesWithPad(startIndex) &&\n isWire(priorStart) &&\n priorStart.layer === start.layer\n ? startIndex - 1\n : startIndex;\n const expandedEndIndex =\n baseCandidates.length > 0 &&\n endpointCollidesWithPad(endIndex) &&\n isWire(nextEnd) &&\n nextEnd.layer === end.layer\n ? endIndex + 1\n : endIndex;\n const intervals = [\n { startIndex, endIndex },\n { startIndex: expandedStartIndex, endIndex },\n { startIndex, endIndex: expandedEndIndex },\n { startIndex: expandedStartIndex, endIndex: expandedEndIndex },\n ].filter(\n (interval, index, allIntervals) =>\n allIntervals.findIndex(\n (candidate) =>\n candidate.startIndex === interval.startIndex &&\n candidate.endIndex === interval.endIndex,\n ) === index,\n );\n const candidates = intervals.flatMap((interval) =>\n interval.startIndex === startIndex && interval.endIndex === endIndex\n ? baseCandidates\n : this.createCandidates({\n kind: \"via-pair\",\n traceIndex,\n startIndex: interval.startIndex,\n endIndex: interval.endIndex,\n }),\n );\n if (candidates.length === 0) return;\n this.beginCandidates(candidates, \"scan-via-pairs\", true);\n }\n\n private scanNextPadClearance() {\n const traceIndex = this.traceIndices[this.traceCursor];\n if (traceIndex === undefined) {\n this.traceCursor = 0;\n this.routeCursor = 0;\n this.phase = \"scan-simplification\";\n return;\n }\n const trace = this.traces[traceIndex]!;\n if (this.resolveNominalTraceWidth(trace) < 0.5 - WIDTH_EPSILON) {\n this.advanceTrace();\n return;\n }\n const segmentIndex = this.routeCursor;\n const start = trace.route[segmentIndex];\n const end = trace.route[segmentIndex + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) {\n if (segmentIndex >= trace.route.length - 1) this.advanceTrace();\n else this.routeCursor++;\n return;\n }\n this.routeCursor++;\n if (!this.segmentHasPadClearanceViolation(traceIndex, segmentIndex)) {\n return;\n }\n\n const intervals = this.getPadClearanceIntervals(trace, segmentIndex);\n const candidates = intervals.flatMap((interval) => {\n const padClearances = this.getImprovedPadClearanceTiers(\n traceIndex,\n interval.startIndex,\n interval.endIndex,\n );\n return padClearances.flatMap((padClearance) =>\n this.createCandidates({\n kind: \"pad-clearance\",\n traceIndex,\n startIndex: interval.startIndex,\n endIndex: interval.endIndex,\n padClearance,\n }).slice(0, 8),\n );\n });\n if (candidates.length === 0) {\n this.unresolvedPadClearanceCount++;\n return;\n }\n this.beginCandidates(candidates.slice(0, 72), \"scan-pad-clearance\", true);\n }\n\n private segmentHasPadClearanceViolation(\n traceIndex: number,\n segmentIndex: number,\n ) {\n const trace = this.traces[traceIndex]!;\n const start = trace.route[segmentIndex];\n const end = trace.route[segmentIndex + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) {\n return false;\n }\n return this.obstacleIndex\n .findCollisions({\n start,\n end,\n layer: start.layer,\n width: Math.max(start.width, end.width),\n connectionNames: this.getTraceConnectionNames(trace),\n ignoreTraceIndex: traceIndex,\n ignoreRouteRange: {\n start: Math.max(0, segmentIndex - 1),\n end: Math.min(trace.route.length - 1, segmentIndex + 2),\n },\n obstacleClearance: this.getPadClearanceForTrace(trace),\n })\n .some((item) => item.kind === \"obstacle\" && item.obstacleKind === \"pad\");\n }\n\n private getPadClearanceIntervals(\n trace: SimplifiedPcbTrace,\n segmentIndex: number,\n ) {\n const segmentStart = trace.route[segmentIndex];\n if (!isWire(segmentStart)) return [];\n const startIndices = [segmentIndex];\n let accumulated = 0;\n for (let index = segmentIndex - 1; index >= 0; index--) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (\n !isWire(start) ||\n !isWire(end) ||\n start.layer !== segmentStart.layer ||\n end.layer !== segmentStart.layer\n ) {\n break;\n }\n accumulated += distance(start, end);\n if (accumulated > this.maxRerouteLength / 2 + WIDTH_EPSILON) break;\n startIndices.push(index);\n }\n\n const endIndices = [segmentIndex + 1];\n accumulated = 0;\n for (\n let index = segmentIndex + 1;\n index < trace.route.length - 1;\n index++\n ) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (\n !isWire(start) ||\n !isWire(end) ||\n start.layer !== segmentStart.layer ||\n end.layer !== segmentStart.layer\n ) {\n break;\n }\n accumulated += distance(start, end);\n if (accumulated > this.maxRerouteLength / 2 + WIDTH_EPSILON) break;\n endIndices.push(index + 1);\n }\n\n return startIndices\n .flatMap((startIndex) =>\n endIndices.map((endIndex) => ({\n startIndex,\n endIndex,\n length: this.measureRouteRange(trace, startIndex, endIndex).length,\n })),\n )\n .filter(\n (interval) =>\n interval.length <= this.maxRerouteLength + WIDTH_EPSILON &&\n interval.startIndex < interval.endIndex,\n )\n .sort((a, b) => b.length - a.length)\n .slice(0, 8);\n }\n\n private scanNextSimplification() {\n const traceIndex = this.traceIndices[this.traceCursor];\n if (traceIndex === undefined) {\n this.remainingPadClearanceViolationCount =\n this.countPadClearanceViolations();\n this.remainingPadClearanceViolationCountByClearance =\n this.countPadClearanceViolationsByTier();\n this.phase = \"complete\";\n return;\n }\n const trace = this.traces[traceIndex]!;\n const startIndex = this.routeCursor;\n const start = trace.route[startIndex];\n if (!isWire(start) || startIndex >= trace.route.length - 1) {\n if (startIndex >= trace.route.length - 1) this.advanceTrace();\n else this.routeCursor++;\n return;\n }\n\n let accumulatedLength = 0;\n const endIndices: number[] = [];\n for (\n let endIndex = startIndex + 1;\n endIndex < trace.route.length;\n endIndex++\n ) {\n const prior = trace.route[endIndex - 1];\n const end = trace.route[endIndex];\n if (\n !isWire(prior) ||\n !isWire(end) ||\n prior.layer !== start.layer ||\n end.layer !== start.layer\n )\n break;\n accumulatedLength += distance(prior, end);\n if (accumulatedLength > this.maxRerouteLength + WIDTH_EPSILON) break;\n const quality = this.measureRouteRange(trace, startIndex, endIndex);\n if (quality.nonOctilinearSegmentCount > 0 || quality.pointCount > 3) {\n endIndices.push(endIndex);\n }\n }\n\n const candidates = endIndices\n .slice(-6)\n .reverse()\n .flatMap((endIndex) =>\n this.createCandidates({\n kind: \"simplification\",\n traceIndex,\n startIndex,\n endIndex,\n }),\n );\n if (candidates.length === 0) {\n this.routeCursor++;\n return;\n }\n this.beginCandidates(candidates, \"scan-simplification\");\n }\n\n private createCandidates({\n kind,\n traceIndex,\n startIndex,\n endIndex,\n padClearance: requestedPadClearance,\n }: {\n kind: CleanupKind;\n traceIndex: number;\n startIndex: number;\n endIndex: number;\n padClearance?: number;\n }) {\n const trace = this.traces[traceIndex]!;\n const start = trace.route[startIndex];\n const end = trace.route[endIndex];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) return [];\n const nominalWidth = this.resolveNominalTraceWidth(trace);\n const originalQuality = this.measureRouteRange(trace, startIndex, endIndex);\n const padClearance =\n requestedPadClearance ??\n this.getCandidatePadClearance(kind, traceIndex, startIndex, endIndex);\n const candidates: CleanupCandidate[] = [];\n const pointCandidates = calculateOctilinearPaths(start, end);\n if (\n kind === \"pad-clearance\" &&\n countNonOctilinearSegments([start, end]) === 0\n ) {\n const segmentLength = distance(start, end);\n if (segmentLength > WIDTH_EPSILON) {\n const normal = {\n x: -(end.y - start.y) / segmentLength,\n y: (end.x - start.x) / segmentLength,\n };\n for (const offset of [0.25, 0.5, 0.75, 1, 1.5, 2]) {\n for (const direction of [-1, 1]) {\n pointCandidates.push([\n start,\n {\n x: start.x + normal.x * offset * direction,\n y: start.y + normal.y * offset * direction,\n },\n {\n x: end.x + normal.x * offset * direction,\n y: end.y + normal.y * offset * direction,\n },\n end,\n ]);\n }\n }\n }\n }\n\n const uniquePointCandidates = new Map(\n pointCandidates.map((points) => [\n points\n .map((point) => `${point.x.toFixed(6)},${point.y.toFixed(6)}`)\n .join(\";\"),\n points,\n ]),\n );\n for (const points of uniquePointCandidates.values()) {\n const pathLength = getPathLength(points);\n if (\n pathLength > this.maxRerouteLength + WIDTH_EPSILON ||\n (kind === \"pad-clearance\" &&\n pathLength > originalQuality.length * 1.35 + 0.5) ||\n (kind === \"simplification\" &&\n (pathLength > originalQuality.length * 1.1 + WIDTH_EPSILON ||\n this.measureTraceLength(trace) -\n originalQuality.length +\n pathLength >\n (this.initialTraceLengths.get(traceIndex) ??\n this.measureTraceLength(trace)) *\n 1.01 +\n WIDTH_EPSILON))\n ) {\n continue;\n }\n const requiredWidth =\n pathLength <= WIDTH_EPSILON\n ? nominalWidth\n : nominalWidth - originalQuality.deficitArea / pathLength;\n if (requiredWidth > nominalWidth + WIDTH_EPSILON) continue;\n const quantizedRequiredWidth =\n Math.ceil(\n Math.max(\n this.inputProblem.simpleRouteJson.minTraceWidth,\n requiredWidth,\n ) /\n 0.05 -\n WIDTH_EPSILON,\n ) * 0.05;\n const widths = uniqueDescending(\n [\n nominalWidth,\n Math.min(nominalWidth, quantizedRequiredWidth),\n Math.min(\n nominalWidth,\n Math.max(\n this.inputProblem.simpleRouteJson.minTraceWidth,\n requiredWidth,\n ),\n ),\n ].map((width) => Math.max(width, start.width)),\n );\n for (const width of widths) {\n const candidateQuality = this.measureCandidate(\n points,\n width,\n nominalWidth,\n end.width,\n start.width,\n );\n if (\n candidateQuality.deficitArea >\n originalQuality.deficitArea + WIDTH_EPSILON ||\n candidateQuality.conservativeDeficitArea >\n originalQuality.conservativeDeficitArea + WIDTH_EPSILON ||\n !this.preservesCoverage(candidateQuality, originalQuality)\n ) {\n continue;\n }\n if (\n kind === \"simplification\" &&\n originalQuality.nonOctilinearSegmentCount === 0 &&\n !(\n candidateQuality.pointCount < originalQuality.pointCount &&\n candidateQuality.length < originalQuality.length - WIDTH_EPSILON\n )\n ) {\n continue;\n }\n candidates.push({\n kind,\n traceIndex,\n startIndex,\n endIndex,\n layer: start.layer,\n points,\n width,\n padClearance,\n originalQuality,\n });\n }\n }\n return candidates.slice(0, 18);\n }\n\n private beginCandidates(\n candidates: CleanupCandidate[],\n resumePhase: typeof this.resumePhase,\n mayUseGridFallback = false,\n ) {\n this.candidates = candidates;\n this.candidateCursor = 0;\n this.clearanceTierCursor = 0;\n this.candidateShoveCount = 0;\n this.rollbackTraces = null;\n this.baseCandidateValidated = false;\n this.resumePhase = resumePhase;\n this.candidateSetMayUseGridFallback = mayUseGridFallback;\n this.phase = \"evaluate-candidate\";\n }\n\n private evaluateCurrentCandidate() {\n const candidate = this.candidates[this.candidateCursor];\n if (!candidate) {\n this.finishCandidateSet(false);\n return;\n }\n if (!this.baseCandidateValidated) {\n if (!this.candidateCollides(candidate, 0)) {\n if (this.candidateShoveCount > 0) {\n this.applyCandidate(candidate, 0);\n return;\n }\n this.baseCandidateValidated = true;\n this.clearanceTierCursor = 0;\n return;\n }\n const requiredPushes = this.getPushableTraceIndices(candidate, 0);\n if (\n requiredPushes &&\n this.candidateShoveCount < 2 &&\n this.attemptedClearanceShoveCount < 48\n ) {\n this.startClearanceShove(candidate, 0);\n return;\n }\n this.advanceCandidate();\n return;\n }\n\n const clearancePadding =\n this.clearancePaddingTiers[this.clearanceTierCursor];\n if (clearancePadding === undefined || clearancePadding <= WIDTH_EPSILON) {\n this.applyCandidate(candidate, 0);\n return;\n }\n this.attemptedCandidateCount++;\n if (!this.candidateCollides(candidate, clearancePadding)) {\n this.applyCandidate(candidate, clearancePadding);\n return;\n }\n\n const pushableTraceIndices = this.getPushableTraceIndices(\n candidate,\n clearancePadding,\n );\n if (\n pushableTraceIndices &&\n this.candidateShoveCount < 2 &&\n this.attemptedClearanceShoveCount < 48\n ) {\n this.startClearanceShove(candidate, clearancePadding);\n return;\n }\n this.rollbackCandidateShoves();\n this.clearanceTierCursor++;\n this.candidateShoveCount = 0;\n }\n\n private advanceCandidate() {\n this.rollbackCandidateShoves();\n this.candidateCursor++;\n this.clearanceTierCursor = 0;\n this.candidateShoveCount = 0;\n this.baseCandidateValidated = false;\n }\n\n private candidateCollides(\n candidate: CleanupCandidate,\n clearancePadding: number,\n ) {\n const trace = this.traces[candidate.traceIndex]!;\n const connectionNames = this.getTraceConnectionNames(trace);\n for (let index = 0; index < candidate.points.length - 1; index++) {\n const segmentWidth = this.getCandidateSegmentWidth(candidate, index);\n if (\n this.obstacleIndex.collides({\n start: candidate.points[index]!,\n end: candidate.points[index + 1]!,\n layer: candidate.layer,\n width: segmentWidth + clearancePadding * 2,\n connectionNames,\n ignoreTraceIndex: candidate.traceIndex,\n ignoreRouteRange: {\n start: Math.max(0, candidate.startIndex - 1),\n end: Math.min(trace.route.length - 1, candidate.endIndex + 1),\n },\n obstacleClearance: candidate.padClearance,\n })\n ) {\n return true;\n }\n }\n return false;\n }\n\n private getPushableTraceIndices(\n candidate: CleanupCandidate,\n clearancePadding: number,\n ) {\n const trace = this.traces[candidate.traceIndex]!;\n const connectionNames = this.getTraceConnectionNames(trace);\n const pushableTraceIndices = new Set<number>();\n for (let index = 0; index < candidate.points.length - 1; index++) {\n const segmentWidth = this.getCandidateSegmentWidth(candidate, index);\n const query = {\n start: candidate.points[index]!,\n end: candidate.points[index + 1]!,\n layer: candidate.layer,\n width: segmentWidth + clearancePadding * 2,\n connectionNames,\n ignoreTraceIndex: candidate.traceIndex,\n ignoreRouteRange: {\n start: Math.max(0, candidate.startIndex - 1),\n end: Math.min(trace.route.length - 1, candidate.endIndex + 1),\n },\n obstacleClearance: candidate.padClearance,\n };\n if (!this.obstacleIndex.collides(query)) continue;\n const collisions = this.obstacleIndex.findCollisions(query);\n if (collisions.length === 0) return null;\n for (const collision of collisions) {\n if (\n collision.kind !== \"trace\" ||\n collision.traceIndex === undefined ||\n collision.traceIndex === candidate.traceIndex\n ) {\n return null;\n }\n const blockingTrace = this.traces[collision.traceIndex];\n if (\n !blockingTrace ||\n this.resolveNominalTraceWidth(blockingTrace) >=\n candidate.width - WIDTH_EPSILON\n ) {\n return null;\n }\n pushableTraceIndices.add(collision.traceIndex);\n }\n }\n return pushableTraceIndices.size > 0 && pushableTraceIndices.size <= 2\n ? [...pushableTraceIndices]\n : null;\n }\n\n private startClearanceShove(\n candidate: CleanupCandidate,\n clearancePadding: number,\n ) {\n this.rollbackTraces ??= structuredClone(this.traces);\n this.activeShovePadding = clearancePadding;\n const corridorWidth = candidate.width + clearancePadding * 2;\n const corridor: InflationCorridorSegment[] = candidate.points\n .slice(0, -1)\n .map((start, index) => ({\n start,\n end: candidate.points[index + 1]!,\n layer: candidate.layer,\n width:\n this.getCandidateSegmentWidth(candidate, index) +\n clearancePadding * 2,\n }));\n this.attemptedClearanceShoveCount++;\n this.activeSubSolver = new LocalTraceInflationSolver(\n {\n simpleRouteJson: this.inputProblem.simpleRouteJson,\n traces: this.traces,\n powerTraceIndex: candidate.traceIndex,\n nominalPowerWidth: corridorWidth,\n pushOnlyNominalWidthsBelow: candidate.width,\n corridor,\n maxRerouteLength: this.maxRerouteLength,\n },\n this.connectionNameResolver,\n );\n this.phase = \"shove-clearance\";\n }\n\n private getCandidateSegmentWidth(\n candidate: CleanupCandidate,\n segmentIndex: number,\n ) {\n const trace = this.traces[candidate.traceIndex]!;\n const originalStart = trace.route[candidate.startIndex];\n const originalEnd = trace.route[candidate.endIndex];\n const startWidth =\n segmentIndex === 0 && isWire(originalStart)\n ? originalStart.width\n : candidate.width;\n const endWidth =\n segmentIndex === candidate.points.length - 2 && isWire(originalEnd)\n ? originalEnd.width\n : candidate.width;\n // Core may reverse a route while associating it with its source trace.\n // Validate the larger endpoint width so clearance is independent of that\n // serialization direction.\n return Math.max(startWidth, endWidth);\n }\n\n private stepActiveShoveSolver() {\n const solver = this.activeSubSolver!;\n solver.step();\n if (!solver.solved && !solver.failed) return;\n if (\n this.pendingPushedViaRepair &&\n solver instanceof LocalTraceInflationSolver\n ) {\n this.finishPushedViaRepairSolver(solver);\n return;\n }\n if (solver instanceof ObstacleAwareGridRouteSolver) {\n this.finishViaGridSolver(solver);\n return;\n }\n this.activeSubSolver = null;\n this.phase = \"evaluate-candidate\";\n if (solver.solved) {\n const output = solver.getOutput();\n if (output) {\n this.traces = output.traces;\n this.candidateShoveCount++;\n this.rebuildObstacleIndex();\n return;\n }\n }\n this.failedSubSolvers ??= [];\n this.failedSubSolvers.push(solver);\n this.rollbackCandidateShoves();\n if (this.activeShovePadding <= WIDTH_EPSILON) {\n this.advanceCandidate();\n } else {\n this.clearanceTierCursor++;\n }\n this.candidateShoveCount = 0;\n }\n\n private rollbackCandidateShoves() {\n if (!this.rollbackTraces) return;\n this.traces = this.rollbackTraces;\n this.rollbackTraces = null;\n this.rebuildObstacleIndex();\n }\n\n private applyCandidate(\n candidate: CleanupCandidate,\n clearancePadding: number,\n ) {\n const trace = this.traces[candidate.traceIndex]!;\n const originalStart = trace.route[candidate.startIndex] as WireRoutePoint;\n const originalEnd = trace.route[candidate.endIndex] as WireRoutePoint;\n const replacement: WireRoutePoint[] = candidate.points.map(\n (point, index) => ({\n ...(index === 0\n ? originalStart\n : index === candidate.points.length - 1\n ? originalEnd\n : {\n route_type: \"wire\" as const,\n layer: candidate.layer,\n width: candidate.width,\n }),\n x: point.x,\n y: point.y,\n layer: candidate.layer,\n width:\n index === 0\n ? originalStart.width\n : index === candidate.points.length - 1\n ? originalEnd.width\n : candidate.width,\n }),\n );\n const removedRoute = trace.route.slice(\n candidate.startIndex,\n candidate.endIndex + 1,\n );\n const removedNonOctilinearCount =\n candidate.originalQuality.nonOctilinearSegmentCount;\n trace.route.splice(\n candidate.startIndex,\n candidate.endIndex - candidate.startIndex + 1,\n ...replacement,\n );\n\n if (candidate.kind === \"via-pair\") {\n const removedViaCount = removedRoute.filter(\n (point) => point.route_type === \"via\",\n ).length;\n this.viaPairCountRemoved++;\n this.viaCountRemoved += removedViaCount;\n this.routeCursor = Math.max(0, candidate.startIndex - 1);\n } else if (candidate.kind === \"pad-clearance\") {\n this.padClearanceRerouteCount++;\n this.routeCursor =\n candidate.startIndex + Math.max(1, replacement.length - 1);\n } else {\n this.simplifiedPathCount++;\n this.normalizedSegmentCount += removedNonOctilinearCount;\n this.routeCursor =\n candidate.startIndex + Math.max(1, replacement.length - 1);\n }\n this.committedClearanceShoveCount += this.candidateShoveCount;\n if (clearancePadding > WIDTH_EPSILON) {\n this.achievedExtraClearanceCount++;\n }\n this.rollbackTraces = null;\n this.candidateShoveCount = 0;\n this.rebuildObstacleIndex();\n this.finishCandidateSet(true);\n }\n\n private finishCandidateSet(accepted: boolean) {\n const gridFallbackCandidate = this.candidates[0];\n const gridFallbackWidths = uniqueDescending(\n this.candidates\n .filter((candidate) => candidate.kind === gridFallbackCandidate?.kind)\n .map((candidate) => candidate.width),\n );\n const gridFallbackPadClearances = uniqueDescending(\n this.candidates\n .filter(\n (candidate) =>\n candidate.kind === gridFallbackCandidate?.kind &&\n candidate.traceIndex === gridFallbackCandidate.traceIndex &&\n candidate.startIndex === gridFallbackCandidate.startIndex &&\n candidate.endIndex === gridFallbackCandidate.endIndex,\n )\n .map((candidate) => candidate.padClearance),\n );\n this.rollbackCandidateShoves();\n this.candidates = [];\n this.candidateCursor = 0;\n this.clearanceTierCursor = 0;\n this.candidateShoveCount = 0;\n this.baseCandidateValidated = false;\n if (\n !accepted &&\n this.candidateSetMayUseGridFallback &&\n gridFallbackCandidate\n ) {\n this.candidateSetMayUseGridFallback = false;\n this.beginViaGridAttempt(\n gridFallbackCandidate,\n gridFallbackWidths,\n gridFallbackPadClearances,\n );\n return;\n }\n this.candidateSetMayUseGridFallback = false;\n if (!accepted) this.routeCursor++;\n this.phase = this.resumePhase;\n }\n\n private beginViaGridAttempt(\n candidate: CleanupCandidate,\n widths: number[],\n padClearances = [candidate.padClearance],\n ) {\n this.viaGridAttempt = {\n kind: candidate.kind,\n traceIndex: candidate.traceIndex,\n startIndex: candidate.startIndex,\n endIndex: candidate.endIndex,\n layer: candidate.layer,\n padClearances,\n padClearanceCursor: 0,\n originalQuality: candidate.originalQuality,\n widths,\n widthCursor: 0,\n gridSizes: [],\n gridSizeCursor: 0,\n offsetCursor: 0,\n };\n this.phase = \"route-via-pair\";\n }\n\n private startNextViaGridCandidate() {\n const attempt = this.viaGridAttempt;\n if (!attempt) {\n this.phase = this.resumePhase;\n return;\n }\n if (attempt.padClearanceCursor >= attempt.padClearances.length) {\n if (attempt.kind === \"pad-clearance\") {\n this.unresolvedPadClearanceCount++;\n }\n this.viaGridAttempt = null;\n this.routeCursor++;\n this.phase = this.resumePhase;\n return;\n }\n if (attempt.widthCursor >= attempt.widths.length) {\n attempt.padClearanceCursor++;\n attempt.widthCursor = 0;\n attempt.gridSizes = [];\n attempt.gridSizeCursor = 0;\n attempt.offsetCursor = 0;\n return;\n }\n const width = attempt.widths[attempt.widthCursor]!;\n const padClearance = attempt.padClearances[attempt.padClearanceCursor]!;\n if (attempt.gridSizes.length === 0) {\n attempt.gridSizes = uniqueDescending([\n clamp(width / 2, 0.2, 0.4),\n clamp(width / 3, 0.15, 0.25),\n ]);\n }\n if (attempt.gridSizeCursor >= attempt.gridSizes.length) {\n attempt.widthCursor++;\n attempt.gridSizes = [];\n attempt.gridSizeCursor = 0;\n attempt.offsetCursor = 0;\n return;\n }\n if (attempt.offsetCursor >= GRID_OFFSETS.length) {\n attempt.gridSizeCursor++;\n attempt.offsetCursor = 0;\n return;\n }\n\n const trace = this.traces[attempt.traceIndex]!;\n const start = trace.route[attempt.startIndex];\n const end = trace.route[attempt.endIndex];\n if (!isWire(start) || !isWire(end)) {\n this.viaGridAttempt = null;\n this.routeCursor++;\n this.phase = this.resumePhase;\n return;\n }\n const gridSize = attempt.gridSizes[attempt.gridSizeCursor]!;\n const offset = GRID_OFFSETS[attempt.offsetCursor]!;\n this.attemptedViaGridCount++;\n this.activeSubSolver = new ObstacleAwareGridRouteSolver({\n start,\n end,\n layer: attempt.layer,\n traceWidth: width,\n gridSize,\n gridOffset: { x: offset.x * gridSize, y: offset.y * gridSize },\n connectionNames: this.getTraceConnectionNames(trace),\n obstacleIndex: this.obstacleIndex,\n ignoreTraceIndex: attempt.traceIndex,\n ignoreRouteRange: {\n start: Math.max(0, attempt.startIndex - 1),\n end: Math.min(trace.route.length - 1, attempt.endIndex + 1),\n },\n bounds: this.inputProblem.simpleRouteJson.bounds,\n obstacleClearance: padClearance,\n searchPadding: Math.min(\n 4,\n Math.max(2, distance(start, end) / 2, width * 3),\n ),\n requireOctilinear: true,\n });\n }\n\n private finishViaGridSolver(solver: ObstacleAwareGridRouteSolver) {\n const attempt = this.viaGridAttempt;\n this.activeSubSolver = null;\n if (solver.solved && attempt) {\n const output = solver.getOutput();\n const trace = this.traces[attempt.traceIndex];\n if (output && trace) {\n const nominalWidth = this.resolveNominalTraceWidth(trace);\n const quality = this.measureCandidate(\n output.points,\n output.traceWidth,\n nominalWidth,\n (trace.route[attempt.endIndex] as WireRoutePoint).width,\n (trace.route[attempt.startIndex] as WireRoutePoint).width,\n );\n if (\n quality.nonOctilinearSegmentCount === 0 &&\n quality.length <= this.maxRerouteLength + WIDTH_EPSILON &&\n quality.deficitArea <=\n attempt.originalQuality.deficitArea + WIDTH_EPSILON &&\n quality.conservativeDeficitArea <=\n attempt.originalQuality.conservativeDeficitArea + WIDTH_EPSILON &&\n this.preservesCoverage(quality, attempt.originalQuality)\n ) {\n const candidate: CleanupCandidate = {\n kind: attempt.kind,\n traceIndex: attempt.traceIndex,\n startIndex: attempt.startIndex,\n endIndex: attempt.endIndex,\n layer: attempt.layer,\n points: output.points,\n width: output.traceWidth,\n padClearance: attempt.padClearances[attempt.padClearanceCursor]!,\n originalQuality: attempt.originalQuality,\n };\n this.viaGridAttempt = null;\n this.beginCandidates([candidate], this.resumePhase, false);\n return;\n }\n }\n }\n if (solver.failed) {\n this.failedSubSolvers ??= [];\n this.failedSubSolvers.push(solver);\n }\n if (attempt) attempt.offsetCursor++;\n this.phase = \"route-via-pair\";\n }\n\n private measureRouteRange(\n trace: SimplifiedPcbTrace,\n startIndex: number,\n endIndex: number,\n ): RouteQuality {\n const nominalWidth = this.resolveNominalTraceWidth(trace);\n let length = 0;\n let deficitArea = 0;\n let conservativeDeficitArea = 0;\n let nominalLength = 0;\n let conservativeNominalLength = 0;\n let nonOctilinearSegmentCount = 0;\n let pointCount = 0;\n for (let index = startIndex; index <= endIndex; index++) {\n if (isWire(trace.route[index])) pointCount++;\n if (index >= endIndex) continue;\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) continue;\n const segmentLength = distance(start, end);\n length += segmentLength;\n deficitArea += segmentLength * Math.max(0, nominalWidth - start.width);\n if (start.width >= nominalWidth - WIDTH_EPSILON) {\n nominalLength += segmentLength;\n }\n conservativeDeficitArea +=\n segmentLength *\n Math.max(0, nominalWidth - Math.min(start.width, end.width));\n if (Math.min(start.width, end.width) >= nominalWidth - WIDTH_EPSILON) {\n conservativeNominalLength += segmentLength;\n }\n nonOctilinearSegmentCount += countNonOctilinearSegments([start, end]);\n }\n return {\n length,\n deficitArea,\n conservativeDeficitArea,\n nominalLength,\n conservativeNominalLength,\n nonOctilinearSegmentCount,\n pointCount,\n };\n }\n\n private measureTraceLength(trace: SimplifiedPcbTrace) {\n let length = 0;\n for (let index = 0; index < trace.route.length - 1; index++) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (isWire(start) && isWire(end) && start.layer === end.layer) {\n length += distance(start, end);\n }\n }\n return length;\n }\n\n private measureCandidate(\n points: Point[],\n width: number,\n nominalWidth: number,\n endWidth = width,\n startWidth = width,\n ): RouteQuality {\n const length = getPathLength(points);\n let deficitArea = 0;\n let conservativeDeficitArea = 0;\n let nominalLength = 0;\n let conservativeNominalLength = 0;\n for (let index = 0; index < points.length - 1; index++) {\n const segmentLength = distance(points[index]!, points[index + 1]!);\n const segmentStartWidth = index === 0 ? startWidth : width;\n const segmentEndWidth = index === points.length - 2 ? endWidth : width;\n const segmentWidth = Math.min(segmentStartWidth, segmentEndWidth);\n deficitArea +=\n segmentLength * Math.max(0, nominalWidth - segmentStartWidth);\n conservativeDeficitArea +=\n segmentLength * Math.max(0, nominalWidth - segmentWidth);\n if (segmentStartWidth >= nominalWidth - WIDTH_EPSILON) {\n nominalLength += segmentLength;\n }\n if (segmentWidth >= nominalWidth - WIDTH_EPSILON) {\n conservativeNominalLength += segmentLength;\n }\n }\n return {\n length,\n deficitArea,\n conservativeDeficitArea,\n nominalLength,\n conservativeNominalLength,\n nonOctilinearSegmentCount: countNonOctilinearSegments(points),\n pointCount: points.length,\n };\n }\n\n private preservesCoverage(after: RouteQuality, before: RouteQuality) {\n const beforeCoverage =\n before.length <= WIDTH_EPSILON ? 1 : before.nominalLength / before.length;\n const afterCoverage =\n after.length <= WIDTH_EPSILON ? 1 : after.nominalLength / after.length;\n const beforeConservativeCoverage =\n before.length <= WIDTH_EPSILON\n ? 1\n : before.conservativeNominalLength / before.length;\n const afterConservativeCoverage =\n after.length <= WIDTH_EPSILON\n ? 1\n : after.conservativeNominalLength / after.length;\n if (\n afterCoverage + WIDTH_EPSILON < beforeCoverage ||\n afterConservativeCoverage + WIDTH_EPSILON < beforeConservativeCoverage\n ) {\n return false;\n }\n return !(\n after.length > before.length + WIDTH_EPSILON &&\n afterCoverage < 1 - WIDTH_EPSILON\n );\n }\n\n private advanceTrace() {\n this.traceCursor++;\n this.routeCursor = 0;\n this.rebuildObstacleIndex();\n }\n\n private createObstacleIndex() {\n return new SpatialObstacleIndex(\n this.inputProblem.simpleRouteJson,\n this.traces,\n this.phase === \"repair-vias\"\n ? undefined\n : this.traceIndices?.[this.traceCursor],\n [],\n this.connectionNameResolver,\n );\n }\n\n private rebuildObstacleIndex() {\n this.obstacleIndex = this.createObstacleIndex();\n }\n\n private resolveNominalTraceWidth(trace: SimplifiedPcbTrace) {\n const connection = this.findConnectionForTrace(trace);\n return Math.max(\n connection?.nominalTraceWidth ??\n connection?.width ??\n this.inputProblem.simpleRouteJson.nominalTraceWidth ??\n this.inputProblem.simpleRouteJson.minTraceWidth,\n this.inputProblem.simpleRouteJson.minTraceWidth,\n );\n }\n\n private getPadClearanceForTrace(trace: SimplifiedPcbTrace) {\n const baseClearance = this.getBaseObstacleClearance();\n return this.resolveNominalTraceWidth(trace) >= 0.5 - WIDTH_EPSILON\n ? Math.max(\n baseClearance,\n this.desiredPadClearance ?? this.resolveNominalTraceWidth(trace) / 2,\n )\n : baseClearance;\n }\n\n private getBaseObstacleClearance() {\n return Math.max(\n this.inputProblem.simpleRouteJson.defaultObstacleMargin ?? 0,\n this.inputProblem.simpleRouteJson.minTraceToPadEdgeClearance ?? 0,\n 0.1,\n );\n }\n\n private getCandidatePadClearance(\n kind: CleanupKind,\n traceIndex: number,\n startIndex: number,\n endIndex: number,\n ) {\n const trace = this.traces[traceIndex]!;\n const baseClearance = this.getBaseObstacleClearance();\n const targetClearance = this.getPadClearanceForTrace(trace);\n if (kind === \"pad-clearance\") return targetClearance;\n\n // Via-pair removal runs before the dedicated clearance pass. Requiring it\n // to preserve the full half-width target can retain a redundant layer\n // excursion even when the direct route is DRC-safe. Preserve the former\n // preferred-clearance tier here; the following pass can then shove and\n // reroute the direct path toward the per-trace target.\n const preservationTarget =\n kind === \"via-pair\"\n ? Math.min(\n targetClearance,\n Math.max(baseClearance, VIA_PAIR_PREFERRED_PAD_CLEARANCE),\n )\n : targetClearance;\n\n // Do not trade away clearance that a route already has. For unavoidable\n // package escapes, preserve the clearance the preceding pass achieved.\n // A short binary search avoids dozens of indexed collision queries when\n // the target is half of a 1 mm power trace.\n return this.findExistingPadClearance(\n traceIndex,\n startIndex,\n endIndex,\n baseClearance,\n preservationTarget,\n );\n }\n\n private getImprovedPadClearanceTiers(\n traceIndex: number,\n startIndex: number,\n endIndex: number,\n ) {\n const trace = this.traces[traceIndex]!;\n const baseClearance = this.getBaseObstacleClearance();\n const targetClearance = this.getPadClearanceForTrace(trace);\n const existingClearance = this.findExistingPadClearance(\n traceIndex,\n startIndex,\n endIndex,\n baseClearance,\n targetClearance,\n );\n const step = Math.max(0.025, Math.min(0.05, targetClearance / 10));\n const tiers: number[] = [targetClearance];\n for (\n let clearance = targetClearance - step;\n clearance > existingClearance + step / 2;\n clearance -= step\n ) {\n tiers.push(clearance);\n }\n return uniqueDescending(tiers).filter(\n (clearance) => clearance > existingClearance + WIDTH_EPSILON,\n );\n }\n\n private findExistingPadClearance(\n traceIndex: number,\n startIndex: number,\n endIndex: number,\n baseClearance: number,\n targetClearance: number,\n ) {\n if (\n this.routeRangeHasPadClearanceViolation(\n traceIndex,\n startIndex,\n endIndex,\n baseClearance,\n )\n ) {\n return baseClearance;\n }\n if (\n !this.routeRangeHasPadClearanceViolation(\n traceIndex,\n startIndex,\n endIndex,\n targetClearance,\n )\n ) {\n return targetClearance;\n }\n let low = baseClearance;\n let high = targetClearance;\n for (let iteration = 0; iteration < 7; iteration++) {\n const midpoint = (low + high) / 2;\n if (\n this.routeRangeHasPadClearanceViolation(\n traceIndex,\n startIndex,\n endIndex,\n midpoint,\n )\n ) {\n high = midpoint;\n } else {\n low = midpoint;\n }\n }\n return Math.max(baseClearance, Number((low - 0.001).toFixed(6)));\n }\n\n private routeRangeHasPadClearanceViolation(\n traceIndex: number,\n startIndex: number,\n endIndex: number,\n clearance: number,\n ) {\n const trace = this.traces[traceIndex]!;\n const connectionNames = this.getTraceConnectionNames(trace);\n for (let routeIndex = startIndex; routeIndex < endIndex; routeIndex++) {\n const start = trace.route[routeIndex];\n const end = trace.route[routeIndex + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) {\n continue;\n }\n const collisions = this.obstacleIndex.findCollisions({\n start,\n end,\n layer: start.layer,\n width: Math.max(start.width, end.width),\n connectionNames,\n ignoreTraceIndex: traceIndex,\n ignoreRouteRange: {\n start: Math.max(0, startIndex - 1),\n end: Math.min(trace.route.length - 1, endIndex + 1),\n },\n obstacleClearance: clearance,\n });\n if (\n collisions.some(\n (item) => item.kind === \"obstacle\" && item.obstacleKind === \"pad\",\n )\n ) {\n return true;\n }\n }\n return false;\n }\n\n private countPadClearanceViolations(clearanceOverride?: number) {\n let violationCount = 0;\n for (const traceIndex of this.traceIndices) {\n const trace = this.traces[traceIndex];\n if (!trace) continue;\n const connectionNames = this.getTraceConnectionNames(trace);\n for (\n let routeIndex = 0;\n routeIndex < trace.route.length - 1;\n routeIndex++\n ) {\n const start = trace.route[routeIndex];\n const end = trace.route[routeIndex + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) {\n continue;\n }\n const collisions = this.obstacleIndex.findCollisions({\n start,\n end,\n layer: start.layer,\n width: Math.max(start.width, end.width),\n connectionNames,\n ignoreTraceIndex: traceIndex,\n ignoreRouteRange: {\n start: Math.max(0, routeIndex - 1),\n end: Math.min(trace.route.length - 1, routeIndex + 2),\n },\n obstacleClearance:\n clearanceOverride ?? this.getPadClearanceForTrace(trace),\n });\n if (\n collisions.some(\n (item) => item.kind === \"obstacle\" && item.obstacleKind === \"pad\",\n )\n ) {\n violationCount++;\n }\n }\n }\n return violationCount;\n }\n\n private countPadClearanceViolationsByTier() {\n return Object.fromEntries(\n PAD_CLEARANCE_MEASUREMENT_TIERS.map((clearance) => [\n clearance.toFixed(2),\n this.countPadClearanceViolations(clearance),\n ]),\n );\n }\n\n private findConnectionForTrace(trace: SimplifiedPcbTrace) {\n const traceNames = new Set(\n this.connectionNameResolver.canonicalize(\n this.getTraceConnectionNames(trace),\n ),\n );\n return this.inputProblem.simpleRouteJson.connections.find((connection) =>\n this.connectionNameResolver\n .canonicalize(this.getConnectionNames(connection))\n .some((name) => traceNames.has(name)),\n );\n }\n\n private getConnectionNames(connection: SimpleRouteConnection) {\n return [\n connection.name,\n connection.source_trace_id,\n connection.rootConnectionName,\n ...(connection.mergedConnectionNames ?? []),\n ].filter((name): name is string => Boolean(name));\n }\n\n private getTraceConnectionNames(trace: SimplifiedPcbTrace) {\n return [\n trace.pcb_trace_id,\n trace.connection_name,\n trace.source_trace_id,\n trace.rootConnectionName,\n ...(trace.mergedConnectionNames ?? []),\n ...(trace.connectsTo ?? []),\n ].filter((name): name is string => Boolean(name));\n }\n\n private createStats() {\n const candidate = this.candidates[this.candidateCursor];\n return {\n phase: this.phase,\n traceCursor: this.traceCursor,\n traceCount: this.traceIndices.length,\n traceIndex: this.traceIndices[this.traceCursor],\n routeCursor: this.routeCursor,\n candidateCursor: this.candidateCursor,\n candidateCount: this.candidates.length,\n candidateKind: candidate?.kind,\n candidateWidth: candidate?.width,\n candidatePointCount: candidate?.points.length,\n clearancePadding: this.clearancePaddingTiers[this.clearanceTierCursor],\n candidateShoveCount: this.candidateShoveCount,\n attemptedCandidateCount: this.attemptedCandidateCount,\n attemptedClearanceShoveCount: this.attemptedClearanceShoveCount,\n attemptedViaGridCount: this.attemptedViaGridCount,\n committedClearanceShoveCount: this.committedClearanceShoveCount,\n viaPairCountRemoved: this.viaPairCountRemoved,\n viaCountRemoved: this.viaCountRemoved,\n simplifiedPathCount: this.simplifiedPathCount,\n normalizedSegmentCount: this.normalizedSegmentCount,\n achievedExtraClearanceCount: this.achievedExtraClearanceCount,\n relocatedViaCount: this.relocatedViaCount,\n unresolvedViaCount: this.unresolvedViaCount,\n attemptedPushedViaRepairCount: this.attemptedPushedViaRepairCount,\n committedPushedViaRepairCount: this.committedPushedViaRepairCount,\n padClearanceRerouteCount: this.padClearanceRerouteCount,\n unresolvedPadClearanceCount: this.unresolvedPadClearanceCount,\n initialPadClearanceViolationCount: this.initialPadClearanceViolationCount,\n remainingPadClearanceViolationCount:\n this.remainingPadClearanceViolationCount,\n initialPadClearanceViolationCountByClearance: {\n ...this.initialPadClearanceViolationCountByClearance,\n },\n remainingPadClearanceViolationCountByClearance: {\n ...this.remainingPadClearanceViolationCountByClearance,\n },\n spatialIndexRectCount: this.obstacleIndex.items.length,\n };\n }\n\n computeProgress() {\n if (this.traceIndices.length === 0) return 1;\n const phaseOffset = this.resumePhase === \"scan-via-pairs\" ? 0 : 0.5;\n return Math.min(\n 0.99,\n phaseOffset + (this.traceCursor / this.traceIndices.length) * 0.5,\n );\n }\n\n override getConstructorParams() {\n return [this.inputProblem];\n }\n\n override getOutput(): PowerTraceCleanupOutput {\n return this.traces;\n }\n\n override visualize(): GraphicsObject {\n const lines: NonNullable<GraphicsObject[\"lines\"]> = [];\n const circles: NonNullable<GraphicsObject[\"circles\"]> = [];\n const candidate = this.candidates[this.candidateCursor];\n for (let traceIndex = 0; traceIndex < this.traces.length; traceIndex++) {\n const trace = this.traces[traceIndex]!;\n for (const point of trace.route) {\n if (point.route_type !== \"via\") continue;\n circles.push({\n center: point,\n radius: (point.via_diameter ?? 0.6) / 2,\n fill: \"#d4a017\",\n stroke: \"#7a5700\",\n });\n }\n for (let index = 0; index < trace.route.length - 1; index++) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer)\n continue;\n lines.push({\n points: [start, end],\n strokeColor: start.layer === \"bottom\" ? \"#376fc4\" : \"#777\",\n strokeWidth: start.width,\n });\n }\n }\n if (candidate) {\n for (let index = 0; index < candidate.points.length - 1; index++) {\n lines.push({\n points: [candidate.points[index]!, candidate.points[index + 1]!],\n strokeColor: \"#ff7400\",\n strokeWidth:\n candidate.width +\n (this.clearancePaddingTiers[this.clearanceTierCursor] ?? 0) * 2,\n });\n }\n }\n return {\n coordinateSystem: \"cartesian\",\n title: `Power trace cleanup: ${this.phase}`,\n lines,\n points: [],\n circles,\n rects: [],\n texts: [],\n };\n }\n}\n","import { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { ConnectionNameResolver } from \"./ConnectionNameResolver\";\nimport { WIDTH_EPSILON } from \"./geometry\";\nimport { SpatialObstacleIndex } from \"./SpatialObstacleIndex\";\nimport type {\n CollisionQuery,\n SimpleRouteJson,\n SimplifiedPcbTrace,\n WireRoutePoint,\n} from \"./types\";\n\nexport type PowerTraceClearanceRepairProblem = {\n simpleRouteJson: SimpleRouteJson;\n traces: SimplifiedPcbTrace[];\n /** Restrict repair to these traces while retaining all traces as obstacles. */\n traceIndices?: readonly number[];\n};\n\nconst isWire = (\n point: SimplifiedPcbTrace[\"route\"][number] | undefined,\n): point is WireRoutePoint => point?.route_type === \"wire\";\n\n/**\n * Direction-independent final copper-clearance guard.\n *\n * Core can reverse a solver route while associating it with a source trace,\n * which changes which endpoint width is serialized onto a segment. This pass\n * therefore validates every segment at the larger of its endpoint widths and\n * necks only the colliding transition. It never changes route geometry.\n */\nexport class PowerTraceClearanceRepairSolver extends BaseSolver {\n readonly inputProblem: PowerTraceClearanceRepairProblem;\n traces: SimplifiedPcbTrace[];\n obstacleIndex: SpatialObstacleIndex;\n traceCursor = 0;\n routeCursor = 0;\n repairedSegmentCount = 0;\n repairedPadNeckSegmentCount = 0;\n unresolvedSegmentCount = 0;\n totalWidthReduction = 0;\n\n private readonly connectionNameResolver: ConnectionNameResolver;\n private readonly minimumTraceWidth: number;\n private readonly traceIndices: number[];\n\n constructor(inputProblem: PowerTraceClearanceRepairProblem) {\n super();\n this.inputProblem = structuredClone(inputProblem);\n this.traces = structuredClone(inputProblem.traces);\n this.connectionNameResolver = new ConnectionNameResolver(\n inputProblem.simpleRouteJson,\n this.traces,\n );\n this.minimumTraceWidth = inputProblem.simpleRouteJson.minTraceWidth;\n const requestedIndices = inputProblem.traceIndices\n ? new Set(inputProblem.traceIndices)\n : null;\n this.traceIndices = this.traces.flatMap((_, traceIndex) =>\n !requestedIndices || requestedIndices.has(traceIndex) ? [traceIndex] : [],\n );\n this.obstacleIndex = this.createConservativeObstacleIndex();\n const initialSegmentCount = this.traceIndices.reduce(\n (count, traceIndex) =>\n count + Math.max(0, this.traces[traceIndex]!.route.length - 1),\n 0,\n );\n // A pad-boundary repair inserts two points and rewinds one segment. Leave\n // enough headroom to visit those new segments and both trace terminals.\n this.MAX_ITERATIONS = Math.max(\n 10,\n initialSegmentCount * 8 + this.traceIndices.length * 2,\n );\n this.stats = this.createStats();\n }\n\n override getSolverName() {\n return \"PowerTraceClearanceRepairSolver\";\n }\n\n override _step() {\n const traceIndex = this.traceIndices[this.traceCursor];\n const trace =\n traceIndex === undefined ? undefined : this.traces[traceIndex];\n if (!trace) {\n this.solved = true;\n this.stats = this.createStats();\n return;\n }\n if (this.routeCursor >= trace.route.length - 1) {\n this.traceCursor++;\n this.routeCursor = 0;\n this.stats = this.createStats();\n return;\n }\n\n const routeIndex = this.routeCursor++;\n const start = trace.route[routeIndex];\n const end = trace.route[routeIndex + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) {\n this.stats = this.createStats();\n return;\n }\n\n const currentWidth = Math.max(start.width, end.width);\n const padQuery: CollisionQuery = {\n start,\n end,\n layer: start.layer,\n width: currentWidth,\n connectionNames: this.getTraceConnectionNames(trace),\n ignoreTraceIndex: traceIndex,\n ignoreRouteRange: { start: routeIndex, end: routeIndex + 1 },\n };\n if (this.repairConnectedPadNeck(trace, routeIndex, padQuery)) {\n this.stats = this.createStats();\n return;\n }\n if (!this.segmentHasForeignTraceCollision(routeIndex, currentWidth)) {\n this.stats = this.createStats();\n return;\n }\n if (\n this.segmentHasForeignTraceCollision(routeIndex, this.minimumTraceWidth)\n ) {\n this.unresolvedSegmentCount++;\n this.stats = this.createStats();\n return;\n }\n\n let safeWidth = this.minimumTraceWidth;\n let unsafeWidth = currentWidth;\n for (let probe = 0; probe < 10; probe++) {\n const candidateWidth = (safeWidth + unsafeWidth) / 2;\n if (this.segmentHasForeignTraceCollision(routeIndex, candidateWidth)) {\n unsafeWidth = candidateWidth;\n } else {\n safeWidth = candidateWidth;\n }\n }\n const quantum = currentWidth >= 0.5 ? 0.025 : 0.0125;\n const quantizedSafeWidth = Math.max(\n this.minimumTraceWidth,\n Math.floor((safeWidth + WIDTH_EPSILON) / quantum) * quantum,\n );\n const repairedWidth = this.segmentHasForeignTraceCollision(\n routeIndex,\n quantizedSafeWidth,\n )\n ? safeWidth\n : quantizedSafeWidth;\n\n const previousStartWidth = start.width;\n const previousEndWidth = end.width;\n start.width = Math.min(start.width, repairedWidth);\n end.width = Math.min(end.width, repairedWidth);\n const reduction =\n previousStartWidth - start.width + (previousEndWidth - end.width);\n if (reduction <= WIDTH_EPSILON) {\n this.unresolvedSegmentCount++;\n this.stats = this.createStats();\n return;\n }\n\n this.repairedSegmentCount++;\n this.totalWidthReduction += reduction;\n this.obstacleIndex = this.createConservativeObstacleIndex();\n // Recheck the segment before this one because the shared endpoint width\n // participates in both directions after core serializes the final route.\n this.routeCursor = Math.max(0, routeIndex - 1);\n this.stats = this.createStats();\n }\n\n private repairConnectedPadNeck(\n trace: SimplifiedPcbTrace,\n routeIndex: number,\n query: CollisionQuery,\n ): boolean {\n const start = trace.route[routeIndex];\n const end = trace.route[routeIndex + 1];\n if (!isWire(start) || !isWire(end)) return false;\n let startLimit = this.obstacleIndex.getConnectedPadWidthLimitAtPoint(\n query,\n start,\n );\n let endLimit = this.obstacleIndex.getConnectedPadWidthLimitAtPoint(\n query,\n end,\n );\n if (routeIndex === 0) {\n startLimit = this.getSmallerLimit(\n startLimit,\n this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(\n query,\n start,\n ),\n );\n }\n if (routeIndex + 1 === trace.route.length - 1) {\n endLimit = this.getSmallerLimit(\n endLimit,\n this.obstacleIndex.getConnectedPadEndpointWidthLimitAtPoint(query, end),\n );\n }\n // A component pad can be narrower than the board's global minimum trace\n // width. Copper must still neck to the physical pad cross-section while it\n // is inside the pad; the minimum applies again immediately outside it.\n const effectiveStartLimit = startLimit;\n const effectiveEndLimit = endLimit;\n if (\n (effectiveStartLimit === null ||\n start.width <= effectiveStartLimit + WIDTH_EPSILON) &&\n (effectiveEndLimit === null ||\n end.width <= effectiveEndLimit + WIDTH_EPSILON)\n ) {\n return false;\n }\n\n const previousStartWidth = start.width;\n const previousEndWidth = end.width;\n if (effectiveStartLimit !== null) {\n start.width = Math.min(start.width, effectiveStartLimit);\n }\n if (effectiveEndLimit !== null) {\n end.width = Math.min(end.width, effectiveEndLimit);\n }\n\n if (effectiveStartLimit !== null && effectiveEndLimit === null) {\n this.insertPadBoundaryTransition(\n trace,\n routeIndex,\n query,\n \"start\",\n start.width,\n previousEndWidth,\n );\n } else if (effectiveStartLimit === null && effectiveEndLimit !== null) {\n this.insertPadBoundaryTransition(\n trace,\n routeIndex,\n query,\n \"end\",\n end.width,\n previousStartWidth,\n );\n } else if (effectiveStartLimit !== null && effectiveEndLimit !== null) {\n const startBoundary = this.obstacleIndex.getConnectedPadBoundaryPoint(\n query,\n \"start\",\n );\n const endBoundary = this.obstacleIndex.getConnectedPadBoundaryPoint(\n query,\n \"end\",\n );\n if (startBoundary && endBoundary) {\n this.insertPadBoundaryTransition(\n trace,\n routeIndex,\n query,\n \"start\",\n start.width,\n previousEndWidth,\n );\n this.insertPadBoundaryTransition(\n trace,\n routeIndex + 2,\n query,\n \"end\",\n end.width,\n previousStartWidth,\n );\n }\n }\n\n this.totalWidthReduction +=\n previousStartWidth - start.width + (previousEndWidth - end.width);\n this.repairedPadNeckSegmentCount++;\n this.obstacleIndex = this.createConservativeObstacleIndex();\n this.routeCursor = Math.max(0, routeIndex - 1);\n return true;\n }\n\n private getSmallerLimit(a: number | null, b: number | null): number | null {\n if (a === null) return b;\n if (b === null) return a;\n return Math.min(a, b);\n }\n\n private insertPadBoundaryTransition(\n trace: SimplifiedPcbTrace,\n routeIndex: number,\n query: CollisionQuery,\n insideEndpoint: \"start\" | \"end\",\n insideWidth: number,\n outsideWidth: number,\n ): void {\n const boundary = this.obstacleIndex.getConnectedPadBoundaryPoint(\n query,\n insideEndpoint,\n );\n if (!boundary) return;\n const inside = insideEndpoint === \"start\" ? query.start : query.end;\n const outside = insideEndpoint === \"start\" ? query.end : query.start;\n const length = Math.hypot(outside.x - inside.x, outside.y - inside.y);\n if (length <= 1e-9) return;\n const epsilon = Math.min(1e-6, length / 4);\n const direction = {\n x: (outside.x - inside.x) / length,\n y: (outside.y - inside.y) / length,\n };\n const insideBoundary: WireRoutePoint = {\n route_type: \"wire\",\n x: boundary.x - direction.x * epsilon,\n y: boundary.y - direction.y * epsilon,\n width: insideWidth,\n layer: query.layer,\n };\n const outsideBoundary: WireRoutePoint = {\n ...insideBoundary,\n x: boundary.x + direction.x * epsilon,\n y: boundary.y + direction.y * epsilon,\n width: outsideWidth,\n };\n const outsideRoutePoint =\n insideEndpoint === \"start\"\n ? trace.route[routeIndex + 1]\n : trace.route[routeIndex];\n const pointBeyondOutside =\n insideEndpoint === \"start\"\n ? trace.route[routeIndex + 2]\n : trace.route[routeIndex - 1];\n if (isWire(outsideRoutePoint) && pointBeyondOutside?.route_type === \"via\") {\n const nominalWidth = this.resolveNominalTraceWidth(trace);\n if (\n !this.obstacleIndex.collides({\n ...query,\n start: outsideRoutePoint,\n end: outsideBoundary,\n width: nominalWidth,\n })\n ) {\n outsideRoutePoint.width = Math.max(\n outsideRoutePoint.width,\n nominalWidth,\n );\n outsideBoundary.width = outsideRoutePoint.width;\n }\n }\n trace.route.splice(\n routeIndex + 1,\n 0,\n ...(insideEndpoint === \"start\"\n ? [insideBoundary, outsideBoundary]\n : [outsideBoundary, insideBoundary]),\n );\n }\n\n private resolveNominalTraceWidth(trace: SimplifiedPcbTrace): number {\n const traceNames = new Set(\n this.connectionNameResolver.canonicalize(\n this.getTraceConnectionNames(trace),\n ),\n );\n const connection = this.inputProblem.simpleRouteJson.connections.find(\n (candidate) =>\n this.connectionNameResolver\n .canonicalize(\n [\n candidate.name,\n candidate.source_trace_id,\n candidate.rootConnectionName,\n ...(candidate.mergedConnectionNames ?? []),\n ].filter((name): name is string => Boolean(name)),\n )\n .some((name) => traceNames.has(name)),\n );\n return Math.max(\n connection?.nominalTraceWidth ??\n connection?.width ??\n this.inputProblem.simpleRouteJson.nominalTraceWidth ??\n this.minimumTraceWidth,\n this.minimumTraceWidth,\n );\n }\n\n private segmentHasForeignTraceCollision(routeIndex: number, width: number) {\n const traceIndex = this.traceIndices[this.traceCursor];\n const trace =\n traceIndex === undefined ? undefined : this.traces[traceIndex];\n const start = trace?.route[routeIndex];\n const end = trace?.route[routeIndex + 1];\n if (!trace || !isWire(start) || !isWire(end) || start.layer !== end.layer) {\n return false;\n }\n return this.obstacleIndex\n .findCollisions({\n start,\n end,\n layer: start.layer,\n width,\n connectionNames: this.getTraceConnectionNames(trace),\n ignoreTraceIndex: traceIndex,\n ignoreRouteRange: {\n start: routeIndex,\n end: routeIndex + 1,\n },\n })\n .some(\n (collision) =>\n collision.kind === \"trace\" &&\n collision.traceIndex !== undefined &&\n collision.traceIndex !== traceIndex,\n );\n }\n\n private createConservativeObstacleIndex() {\n const conservativeTraces = structuredClone(this.traces);\n for (const trace of conservativeTraces) {\n for (let index = 0; index < trace.route.length - 1; index++) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) {\n continue;\n }\n start.width = Math.max(start.width, end.width);\n }\n }\n return new SpatialObstacleIndex(\n this.inputProblem.simpleRouteJson,\n conservativeTraces,\n undefined,\n [],\n this.connectionNameResolver,\n );\n }\n\n private getTraceConnectionNames(trace: SimplifiedPcbTrace) {\n return [\n trace.pcb_trace_id,\n trace.connection_name,\n trace.source_trace_id,\n trace.rootConnectionName,\n ...(trace.mergedConnectionNames ?? []),\n ...(trace.connectsTo ?? []),\n ].filter((name): name is string => Boolean(name));\n }\n\n private createStats() {\n return {\n phase: this.solved ? \"complete\" : \"repair-trace-clearance\",\n traceCursor: this.traceCursor,\n traceCount: this.traceIndices.length,\n traceIndex: this.traceIndices[this.traceCursor],\n routeCursor: this.routeCursor,\n repairedSegmentCount: this.repairedSegmentCount,\n repairedPadNeckSegmentCount: this.repairedPadNeckSegmentCount,\n unresolvedSegmentCount: this.unresolvedSegmentCount,\n totalWidthReduction: this.totalWidthReduction,\n spatialIndexRectCount: this.obstacleIndex.items.length,\n };\n }\n\n computeProgress() {\n if (this.traceIndices.length === 0) return 1;\n return Math.min(0.99, this.traceCursor / this.traceIndices.length);\n }\n\n override getConstructorParams() {\n return [this.inputProblem];\n }\n\n override getOutput() {\n return this.traces;\n }\n\n override visualize(): GraphicsObject {\n const lines: NonNullable<GraphicsObject[\"lines\"]> = [];\n for (let traceIndex = 0; traceIndex < this.traces.length; traceIndex++) {\n const trace = this.traces[traceIndex]!;\n for (\n let routeIndex = 0;\n routeIndex < trace.route.length - 1;\n routeIndex++\n ) {\n const start = trace.route[routeIndex];\n const end = trace.route[routeIndex + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) {\n continue;\n }\n lines.push({\n points: [start, end],\n strokeColor:\n traceIndex === this.traceIndices[this.traceCursor] &&\n routeIndex === this.routeCursor\n ? \"#ff7400\"\n : start.layer === \"bottom\"\n ? \"#376fc4\"\n : \"#777\",\n strokeWidth: Math.max(start.width, end.width),\n });\n }\n }\n return {\n coordinateSystem: \"cartesian\",\n title: \"Power trace direction-independent clearance repair\",\n lines,\n points: [],\n circles: [],\n rects: [],\n texts: [],\n };\n }\n}\n","import { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { ConnectionNameResolver } from \"./ConnectionNameResolver\";\nimport {\n clamp,\n distance,\n splitUnderWidthWireSegments,\n WIDTH_EPSILON,\n} from \"./geometry\";\nimport { LayerAwareGridRouteSolver } from \"./LayerAwareGridRouteSolver\";\nimport { LocalTraceInflationSolver } from \"./LocalTraceInflationSolver\";\nimport { ObstacleAwareGridRouteSolver } from \"./ObstacleAwareGridRouteSolver\";\nimport { PowerTraceCleanupSolver } from \"./PowerTraceCleanupSolver\";\nimport { PowerTraceClearanceRepairSolver } from \"./PowerTraceClearanceRepairSolver\";\nimport { SpatialObstacleIndex } from \"./SpatialObstacleIndex\";\nimport type {\n GridOffset,\n GridRouteOutput,\n InflationCorridorSegment,\n LayerGridRouteOutput,\n PowerTraceExpanderInput,\n PowerTraceExpanderOptions,\n PowerTraceExpanderOutput,\n SimpleRouteConnection,\n SimplifiedPcbTrace,\n ViaRoutePoint,\n WireRoutePoint,\n} from \"./types\";\n\ntype SolverPhase =\n | \"scan-trace\"\n | \"evaluate-segment\"\n | \"try-trace-inflation\"\n | \"try-layer-candidate\"\n | \"try-grid-candidate\"\n | \"cleanup\"\n | \"repair-trace-clearance\"\n | \"complete\";\n\ntype RouteInterval = { startIndex: number; endIndex: number };\n\ntype LayerRouteAttempt = {\n interval: RouteInterval;\n minViaCount: number;\n maxViaCount: number;\n candidateWidths: number[];\n widthCursor: number;\n gridResolutions: number[];\n resolutionCursor: number;\n offsetCursor: number;\n startLayers: string[];\n endLayers: string[];\n startNeckWidth: number;\n endNeckWidth: number;\n softTraceIndices: number[];\n};\n\nconst GRID_OFFSETS: GridOffset[] = [\n { x: 0, y: 0 },\n { x: 0.5, y: 0 },\n { x: 0, y: 0.5 },\n { x: 0.5, y: 0.5 },\n];\n\nconst LAYER_GRID_VARIANTS: Array<{\n offset: GridOffset;\n strictNecking: boolean;\n}> = [\n { offset: { x: 0, y: 0 }, strictNecking: true },\n { offset: { x: 0.5, y: 0.5 }, strictNecking: true },\n { offset: { x: 0, y: 0 }, strictNecking: false },\n { offset: { x: 0.5, y: 0.5 }, strictNecking: false },\n];\n\nconst uniqueDescending = (values: number[]) =>\n [...new Set(values.map((value) => Number(value.toFixed(6))))].sort(\n (a, b) => b - a,\n );\n\nconst isWire = (\n point: SimplifiedPcbTrace[\"route\"][number] | undefined,\n): point is WireRoutePoint => point?.route_type === \"wire\";\n\nexport class PowerTraceExpanderSolver extends BaseSolver {\n readonly inputProblem: PowerTraceExpanderInput;\n readonly options: PowerTraceExpanderOptions;\n traces: SimplifiedPcbTrace[];\n obstacleIndex: SpatialObstacleIndex;\n private readonly connectionNameResolver: ConnectionNameResolver;\n private readonly traceOrder: number[];\n private traceOrderCursor = -1;\n private readonly maxPassCount = 4;\n private previousWidthDeficit = 0;\n passIndex = 0;\n completedPassCount = 0;\n lastNormalizedWidthDeficitGain = 0;\n readonly normalizedWidthDeficitGainByPass: number[] = [];\n plateauReached = false;\n\n phase: SolverPhase = \"scan-trace\";\n traceIndex = -1;\n routeSegmentIndex = 0;\n nominalTraceWidth = 0;\n currentIntervals: Array<{ startIndex: number; endIndex: number }> = [];\n intervalCursor = 0;\n candidateWidths: number[] = [];\n widthCursor = 0;\n gridResolutions: number[] = [];\n resolutionCursor = 0;\n offsetCursor = 0;\n\n keptTraceCount = 0;\n recreatedTraceCount = 0;\n expandedSegmentCount = 0;\n intermediateExpandedSegmentCount = 0;\n pathWidthUpgradeCount = 0;\n inPlaceWidthProbeCount = 0;\n reroutedSegmentCount = 0;\n unresolvedSegmentCount = 0;\n attemptedGridCount = 0;\n attemptedLayerGridCount = 0;\n attemptedInflationCount = 0;\n pushedTraceCount = 0;\n elasticPushedTraceCount = 0;\n layerReroutedTraceCount = 0;\n insertedViaCount = 0;\n neckedLayerSegmentCount = 0;\n removedViaPairCount = 0;\n removedViaCount = 0;\n simplifiedPathCount = 0;\n normalizedSegmentCount = 0;\n cleanupClearanceShoveCount = 0;\n relocatedViaCount = 0;\n unresolvedViaCount = 0;\n padClearanceRerouteCount = 0;\n unresolvedPadClearanceCount = 0;\n repairedTraceClearanceSegmentCount = 0;\n repairedPadNeckSegmentCount = 0;\n unresolvedTraceClearanceSegmentCount = 0;\n initialPadClearanceViolationCount = 0;\n remainingPadClearanceViolationCount = 0;\n initialPadClearanceViolationCountByClearance: Record<string, number> = {};\n remainingPadClearanceViolationCountByClearance: Record<string, number> = {};\n\n private readonly inflationAttemptsBySegment = new Map<string, number>();\n private readonly layerAttemptCountByTrace = new Map<number, number>();\n private readonly layerRerouteCountByTrace = new Map<number, number>();\n private activeInflationKey: string | null = null;\n private activeInflationWidth: number | null = null;\n private layerAttempt: LayerRouteAttempt | null = null;\n private pendingLayerOutput: LayerGridRouteOutput | null = null;\n private pendingLayerPushCount = 0;\n\n declare activeSubSolver:\n | ObstacleAwareGridRouteSolver\n | LayerAwareGridRouteSolver\n | LocalTraceInflationSolver\n | PowerTraceCleanupSolver\n | PowerTraceClearanceRepairSolver\n | null;\n\n constructor(\n inputProblem: PowerTraceExpanderInput,\n options: PowerTraceExpanderOptions = {},\n ) {\n super();\n this.inputProblem = structuredClone(inputProblem);\n this.options = structuredClone(options);\n this.traces = structuredClone(inputProblem.traces ?? []);\n this.connectionNameResolver = new ConnectionNameResolver(\n this.inputProblem,\n this.traces,\n );\n const selectedConnectionNames = options.onlyConnectionNames\n ? new Set(\n this.connectionNameResolver.canonicalize([\n ...options.onlyConnectionNames,\n ]),\n )\n : null;\n const selectedTraceIndices = this.traces.flatMap((trace, traceIndex) => {\n if (!selectedConnectionNames) return [traceIndex];\n const canonicalTraceNames = this.connectionNameResolver.canonicalize(\n this.getTraceConnectionNames(trace),\n );\n return canonicalTraceNames.some((name) =>\n selectedConnectionNames.has(name),\n )\n ? [traceIndex]\n : [];\n });\n const initialPriorityByTrace = new Map(\n selectedTraceIndices.map((traceIndex) => [\n traceIndex,\n this.getInitialTracePriority(this.traces[traceIndex]!),\n ]),\n );\n // Route the largest copper deficits first. This gives long, badly necked\n // power paths first choice of the scarce wide corridors, while narrow\n // logic traces remain movable inflation candidates later in the pass.\n this.traceOrder = selectedTraceIndices.sort(\n (a, b) =>\n initialPriorityByTrace.get(b)! - initialPriorityByTrace.get(a)! ||\n a - b,\n );\n this.previousWidthDeficit = this.calculateWidthDeficit().deficit;\n this.obstacleIndex = new SpatialObstacleIndex(\n this.inputProblem,\n this.traces,\n this.traceIndex >= 0 ? this.traceIndex : undefined,\n [],\n this.connectionNameResolver,\n );\n this.activeSubSolver = null;\n this.MAX_ITERATIONS = 8_000_000;\n this.stats = this.createStats();\n }\n\n override getSolverName() {\n return \"PowerTraceExpanderSolver\";\n }\n\n override _step() {\n if (this.activeSubSolver) {\n this.stepActiveGridSolver();\n this.stats = this.createStats();\n return;\n }\n\n switch (this.phase) {\n case \"scan-trace\":\n this.scanNextTrace();\n break;\n case \"evaluate-segment\":\n this.evaluateNextSegment();\n break;\n case \"try-trace-inflation\":\n // The active inflation solver is stepped before the phase switch.\n break;\n case \"try-layer-candidate\":\n this.startNextLayerCandidate();\n break;\n case \"try-grid-candidate\":\n this.startNextGridCandidate();\n break;\n case \"cleanup\":\n // The active cleanup solver is stepped before the phase switch.\n break;\n case \"repair-trace-clearance\":\n // The active clearance repair solver is stepped before the phase switch.\n break;\n case \"complete\":\n this.solved = true;\n break;\n }\n this.stats = this.createStats();\n }\n\n private scanNextTrace() {\n this.traceOrderCursor++;\n this.routeSegmentIndex = 0;\n if (this.traceOrderCursor >= this.traceOrder.length) {\n this.finishOrStartNextPass();\n return;\n }\n this.traceIndex = this.traceOrder[this.traceOrderCursor]!;\n\n const trace = this.traces[this.traceIndex]!;\n if (!this.findConnectionForTrace(trace)) {\n // Preserved child-subcircuit traces are supplied as fixed routing\n // geometry but have no connection in the current board SRJ. Re-emit them\n // byte-for-byte and use them only as obstacles for board-level traces.\n this.keptTraceCount++;\n return;\n }\n this.nominalTraceWidth = this.resolveNominalTraceWidth(trace);\n if (this.traceMeetsNominalWidth(trace, this.nominalTraceWidth)) {\n this.keptTraceCount++;\n return;\n }\n\n // Flatbush is immutable, so rebuild once per trace that will actually be\n // mutated. Fixed and already-conforming traces need no private index.\n this.rebuildObstacleIndex();\n\n trace.route = splitUnderWidthWireSegments(\n trace.route,\n this.nominalTraceWidth,\n ) as SimplifiedPcbTrace[\"route\"];\n this.recreatedTraceCount++;\n this.phase = \"evaluate-segment\";\n }\n\n private finishOrStartNextPass() {\n const { deficit, nominalArea } = this.calculateWidthDeficit();\n const deficitGain = this.previousWidthDeficit - deficit;\n this.lastNormalizedWidthDeficitGain =\n nominalArea <= WIDTH_EPSILON ? 0 : deficitGain / nominalArea;\n this.normalizedWidthDeficitGainByPass.push(\n this.lastNormalizedWidthDeficitGain,\n );\n this.plateauReached = this.lastNormalizedWidthDeficitGain < 0.001;\n this.completedPassCount = this.passIndex + 1;\n\n // A sub-0.1% copper-area gain is the practical plateau. This keeps the\n // production fixture to three passes while still allowing one follow-up\n // pass to exploit geometry displaced during the initial solve.\n if (\n this.passIndex + 1 < this.maxPassCount &&\n this.lastNormalizedWidthDeficitGain >= 0.001\n ) {\n this.previousWidthDeficit = deficit;\n this.passIndex++;\n this.traceOrderCursor = -1;\n this.traceIndex = -1;\n this.routeSegmentIndex = 0;\n this.inflationAttemptsBySegment.clear();\n this.phase = \"scan-trace\";\n return;\n }\n\n this.traceIndex = this.traces.length;\n this.phase = \"cleanup\";\n this.activeSubSolver = new PowerTraceCleanupSolver({\n simpleRouteJson: this.inputProblem,\n traces: this.traces,\n traceIndices: this.traceOrder,\n maxRerouteLength: 10,\n desiredPadClearance: this.options.powerTraceToPadClearance,\n });\n }\n\n private calculateWidthDeficit() {\n let deficit = 0;\n let nominalArea = 0;\n for (const traceIndex of this.traceOrder) {\n const trace = this.traces[traceIndex]!;\n if (!this.findConnectionForTrace(trace)) continue;\n const nominalWidth = this.resolveNominalTraceWidth(trace);\n for (let index = 0; index < trace.route.length - 1; index++) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer)\n continue;\n const segmentLength = distance(start, end);\n // Circuit JSON assigns a wire segment the width of its first point.\n const segmentWidth = start.width;\n nominalArea += segmentLength * nominalWidth;\n deficit += segmentLength * Math.max(0, nominalWidth - segmentWidth);\n }\n }\n return { deficit, nominalArea };\n }\n\n private getInitialTracePriority(trace: SimplifiedPcbTrace) {\n const nominalWidth = this.resolveNominalTraceWidth(trace);\n let deficitArea = 0;\n for (let index = 0; index < trace.route.length - 1; index++) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) continue;\n deficitArea +=\n distance(start, end) *\n Math.max(0, nominalWidth - Math.min(start.width, end.width));\n }\n return nominalWidth * deficitArea;\n }\n\n private evaluateNextSegment() {\n const trace = this.traces[this.traceIndex];\n if (!trace) {\n this.phase = \"scan-trace\";\n return;\n }\n\n const segmentIndex = this.findNextUnderWidthSegment(\n trace,\n this.routeSegmentIndex,\n this.nominalTraceWidth,\n );\n if (segmentIndex === -1) {\n this.phase = \"scan-trace\";\n return;\n }\n this.routeSegmentIndex = segmentIndex;\n const start = trace.route[segmentIndex]!;\n const end = trace.route[segmentIndex + 1]!;\n if (!isWire(start) || !isWire(end)) {\n this.routeSegmentIndex++;\n return;\n }\n\n const connectionNames = this.getTraceConnectionNames(trace);\n const currentWidth = Math.min(start.width, end.width);\n const bestInPlaceWidth = this.findMaximumSafeInPlaceWidth(\n trace,\n segmentIndex,\n connectionNames,\n );\n\n if (bestInPlaceWidth > currentWidth + WIDTH_EPSILON) {\n start.width = Math.max(start.width, bestInPlaceWidth);\n end.width = Math.max(end.width, bestInPlaceWidth);\n if (bestInPlaceWidth >= this.nominalTraceWidth - WIDTH_EPSILON) {\n this.expandedSegmentCount++;\n this.routeSegmentIndex++;\n return;\n }\n this.intermediateExpandedSegmentCount++;\n }\n\n if (this.startTraceInflation(trace, segmentIndex)) return;\n\n if (this.prepareLayerRouteAttempt(trace, segmentIndex)) return;\n\n this.prepareRegularGridCandidates(trace, segmentIndex);\n }\n\n private prepareRegularGridCandidates(\n trace: SimplifiedPcbTrace,\n segmentIndex: number,\n ) {\n this.currentIntervals = this.getExponentialIntervalCandidates(\n trace,\n segmentIndex,\n this.nominalTraceWidth,\n );\n this.intervalCursor = 0;\n this.candidateWidths = this.getCandidateWidths(this.nominalTraceWidth);\n this.widthCursor = 0;\n this.gridResolutions = [];\n this.resolutionCursor = 0;\n this.offsetCursor = 0;\n if (this.currentIntervals.length === 0) {\n this.unresolvedSegmentCount++;\n this.routeSegmentIndex++;\n return;\n }\n this.phase = \"try-grid-candidate\";\n }\n\n private prepareLayerRouteAttempt(\n trace: SimplifiedPcbTrace,\n segmentIndex: number,\n ) {\n if (this.nominalTraceWidth < 0.5 - WIDTH_EPSILON) {\n return false;\n }\n // The layer-aware search also supports a zero-via mode. Unlike the\n // regular planar search, it can leave a constrained interval endpoint\n // through a short narrow neck and reach a nearby full-width corridor.\n const canUseVias =\n this.options.allowNewVias !== false && this.inputProblem.layerCount >= 2;\n // Planar escapes may need several bounded, 10 mm reroutes to walk a long\n // necked trace into the clear corridor, so allow one attempt per pass.\n const maximumAttemptCount = canUseVias ? 2 : this.maxPassCount;\n const priorAttemptCount =\n this.layerAttemptCountByTrace.get(this.traceIndex) ?? 0;\n const priorRerouteCount =\n this.layerRerouteCountByTrace.get(this.traceIndex) ?? 0;\n if (\n priorRerouteCount >= maximumAttemptCount ||\n priorAttemptCount >= maximumAttemptCount ||\n priorAttemptCount > this.passIndex ||\n // Do not repeat an expensive failed search. A second attempt is only\n // useful after the first layer route changed this trace's geometry.\n (priorAttemptCount > 0 && priorRerouteCount === 0)\n ) {\n return false;\n }\n const blockedStart = trace.route[segmentIndex];\n const blockedEnd = trace.route[segmentIndex + 1];\n if (\n !isWire(blockedStart) ||\n !isWire(blockedEnd) ||\n Math.min(blockedStart.width, blockedEnd.width) >=\n this.nominalTraceWidth * 0.5 - WIDTH_EPSILON\n ) {\n return false;\n }\n\n const interval = this.getExponentialIntervalCandidates(\n trace,\n segmentIndex,\n this.nominalTraceWidth,\n )\n .filter((candidate) =>\n this.intervalSupportsLayerRouting(trace, candidate),\n )\n .sort(\n (a, b) =>\n // First reach as far as possible beyond the choke. A longest-only\n // sort can spend the whole 10 mm budget behind the blocked segment\n // and stop before the constrained pad that actually needs escape.\n b.endIndex - a.endIndex ||\n a.startIndex - b.startIndex ||\n this.getRouteIntervalLength(trace, b.startIndex, b.endIndex) -\n this.getRouteIntervalLength(trace, a.startIndex, a.endIndex),\n )[0];\n if (!interval) return false;\n const intervalQuality = this.getRouteQuality(\n trace.route.slice(interval.startIndex, interval.endIndex + 1),\n );\n if (intervalQuality.deficitArea < this.nominalTraceWidth) return false;\n if (\n priorAttemptCount > 0 &&\n intervalQuality.deficitArea /\n Math.max(intervalQuality.length, WIDTH_EPSILON) <\n 0.25\n ) {\n return false;\n }\n\n const start = trace.route[interval.startIndex] as WireRoutePoint;\n const end = trace.route[interval.endIndex] as WireRoutePoint;\n const connectionNames = this.getTraceConnectionNames(trace);\n const startLayers = canUseVias\n ? this.getEndpointLayers(start, connectionNames)\n : [start.layer];\n const endLayers = canUseVias\n ? this.getEndpointLayers(end, connectionNames)\n : [end.layer];\n const startNeckWidth = Math.min(\n this.nominalTraceWidth,\n Math.max(\n start.width,\n this.findMaximumSafeInPlaceWidth(\n trace,\n interval.startIndex,\n connectionNames,\n ),\n ),\n );\n const endNeckWidth = Math.min(\n this.nominalTraceWidth,\n Math.max(\n end.width,\n this.findMaximumSafeInPlaceWidth(\n trace,\n interval.endIndex - 1,\n connectionNames,\n ),\n ),\n );\n const softTraceIndices = this.getSoftTraceIndices(this.nominalTraceWidth);\n\n this.layerAttemptCountByTrace.set(this.traceIndex, priorAttemptCount + 1);\n this.layerAttempt = {\n interval,\n minViaCount: canUseVias ? 1 : 0,\n maxViaCount: canUseVias ? 2 : 0,\n candidateWidths: [this.nominalTraceWidth],\n widthCursor: 0,\n gridResolutions: [clamp(this.nominalTraceWidth / 4, 0.2, 0.3)],\n resolutionCursor: 0,\n offsetCursor: 0,\n startLayers,\n endLayers,\n startNeckWidth,\n endNeckWidth,\n softTraceIndices,\n };\n this.phase = \"try-layer-candidate\";\n return true;\n }\n\n private intervalSupportsLayerRouting(\n trace: SimplifiedPcbTrace,\n interval: RouteInterval,\n ) {\n if (interval.startIndex >= interval.endIndex) return false;\n for (let index = interval.startIndex; index <= interval.endIndex; index++) {\n const point = trace.route[index];\n if (!isWire(point)) return false;\n }\n const start = trace.route[interval.startIndex] as WireRoutePoint;\n const end = trace.route[interval.endIndex] as WireRoutePoint;\n return start.layer === end.layer;\n }\n\n private getEndpointLayers(point: WireRoutePoint, connectionNames: string[]) {\n return [\n ...new Set([\n point.layer,\n ...this.obstacleIndex.getConnectedLayersAtPoint(\n { x: point.x, y: point.y },\n connectionNames,\n ),\n ]),\n ].filter((layer) => this.obstacleIndex.boardLayers.includes(layer));\n }\n\n private getSoftTraceIndices(targetWidth: number) {\n const indices: number[] = [];\n for (let traceIndex = 0; traceIndex < this.traces.length; traceIndex++) {\n if (traceIndex === this.traceIndex) continue;\n const trace = this.traces[traceIndex]!;\n const connection = this.findConnectionForTrace(trace);\n if (!connection) continue;\n const width = Math.max(\n connection.nominalTraceWidth ??\n connection.width ??\n this.inputProblem.nominalTraceWidth ??\n this.inputProblem.minTraceWidth,\n this.inputProblem.minTraceWidth,\n );\n if (width < targetWidth - WIDTH_EPSILON) indices.push(traceIndex);\n }\n return indices;\n }\n\n private startNextLayerCandidate() {\n const attempt = this.layerAttempt;\n const trace = this.traces[this.traceIndex];\n if (!attempt || !trace) {\n this.layerAttempt = null;\n this.phase = \"evaluate-segment\";\n return;\n }\n if (attempt.widthCursor >= attempt.candidateWidths.length) {\n const segmentIndex = this.routeSegmentIndex;\n this.layerAttempt = null;\n this.prepareRegularGridCandidates(trace, segmentIndex);\n return;\n }\n const candidateWidth = attempt.candidateWidths[attempt.widthCursor]!;\n if (attempt.gridResolutions.length === 0) {\n attempt.gridResolutions = this.getGridResolutions(candidateWidth);\n }\n if (attempt.resolutionCursor >= attempt.gridResolutions.length) {\n attempt.widthCursor++;\n attempt.gridResolutions = [];\n attempt.resolutionCursor = 0;\n attempt.offsetCursor = 0;\n return;\n }\n if (attempt.offsetCursor >= LAYER_GRID_VARIANTS.length) {\n attempt.resolutionCursor++;\n attempt.offsetCursor = 0;\n return;\n }\n\n const start = trace.route[attempt.interval.startIndex];\n const end = trace.route[attempt.interval.endIndex];\n if (!isWire(start) || !isWire(end)) {\n this.layerAttempt = null;\n this.prepareRegularGridCandidates(trace, this.routeSegmentIndex);\n return;\n }\n const gridSize = attempt.gridResolutions[attempt.resolutionCursor]!;\n const variant = LAYER_GRID_VARIANTS[attempt.offsetCursor]!;\n const normalizedOffset = variant.offset;\n const balancedNeckWidth = Math.min(\n attempt.startNeckWidth,\n attempt.endNeckWidth,\n );\n const viaHoleDiameter =\n this.inputProblem.min_via_hole_diameter ??\n this.inputProblem.minViaHoleDiameter ??\n 0.3;\n const viaDiameter = Math.max(\n viaHoleDiameter,\n this.inputProblem.min_via_pad_diameter ??\n this.inputProblem.minViaPadDiameter ??\n this.inputProblem.minViaDiameter ??\n 0.6,\n );\n const startNeckWidth = Math.max(\n this.inputProblem.minTraceWidth,\n Math.min(\n variant.strictNecking ? attempt.startNeckWidth : balancedNeckWidth,\n candidateWidth,\n ),\n );\n const endNeckWidth = Math.max(\n this.inputProblem.minTraceWidth,\n Math.min(\n variant.strictNecking ? attempt.endNeckWidth : balancedNeckWidth,\n candidateWidth,\n ),\n );\n const maximumNeckLength = clamp(this.nominalTraceWidth * 3, 1.5, 3);\n\n if (attempt.maxViaCount > 0) {\n this.attemptedLayerGridCount++;\n } else {\n this.attemptedGridCount++;\n }\n this.activeSubSolver = new LayerAwareGridRouteSolver({\n start,\n end,\n originalStartLayer: start.layer,\n originalEndLayer: end.layer,\n startLayers: attempt.startLayers,\n endLayers: attempt.endLayers,\n layers: this.obstacleIndex.boardLayers,\n traceWidth: candidateWidth,\n startNeckWidth,\n endNeckWidth,\n maxStartNeckLength: maximumNeckLength,\n maxEndNeckLength: maximumNeckLength,\n neckPenaltyExponent: variant.strictNecking ? 2 : 1,\n viaDiameter,\n viaHoleDiameter,\n minViaCount: attempt.minViaCount,\n maxViaCount: attempt.maxViaCount,\n viaCost: Math.max(1, this.nominalTraceWidth * 2),\n gridSize,\n gridOffset: {\n x: normalizedOffset.x * gridSize,\n y: normalizedOffset.y * gridSize,\n },\n connectionNames: this.getTraceConnectionNames(trace),\n obstacleIndex: this.obstacleIndex,\n ignoreTraceIndex: this.traceIndex,\n ignoreRouteRange: {\n start: Math.max(0, attempt.interval.startIndex - 1),\n end: Math.min(trace.route.length - 1, attempt.interval.endIndex + 1),\n },\n softTraceIndices: attempt.softTraceIndices,\n fixedVias: this.getFixedViasOutsideInterval(trace, attempt.interval),\n bounds: this.inputProblem.bounds,\n obstacleClearance: this.getDesiredPadClearance(candidateWidth),\n searchPadding: Math.min(\n 5,\n Math.max(2.5, distance(start, end) / 2, candidateWidth * 4),\n ),\n });\n }\n\n private startNextGridCandidate() {\n const trace = this.traces[this.traceIndex];\n if (!trace) {\n this.phase = \"scan-trace\";\n return;\n }\n if (this.widthCursor >= this.candidateWidths.length) {\n this.unresolvedSegmentCount++;\n this.routeSegmentIndex++;\n this.phase = \"evaluate-segment\";\n return;\n }\n if (this.intervalCursor >= this.currentIntervals.length) {\n this.widthCursor++;\n this.intervalCursor = 0;\n this.gridResolutions = [];\n this.resolutionCursor = 0;\n this.offsetCursor = 0;\n return;\n }\n const candidateWidth = this.candidateWidths[this.widthCursor]!;\n const blockedStart = trace.route[this.routeSegmentIndex];\n const blockedEnd = trace.route[this.routeSegmentIndex + 1];\n if (\n isWire(blockedStart) &&\n isWire(blockedEnd) &&\n candidateWidth <=\n Math.min(blockedStart.width, blockedEnd.width) + WIDTH_EPSILON\n ) {\n this.widthCursor = this.candidateWidths.length;\n return;\n }\n if (this.gridResolutions.length === 0) {\n this.gridResolutions = this.getGridResolutions(candidateWidth);\n }\n if (this.resolutionCursor >= this.gridResolutions.length) {\n this.intervalCursor++;\n this.resolutionCursor = 0;\n this.offsetCursor = 0;\n return;\n }\n if (this.offsetCursor >= GRID_OFFSETS.length) {\n this.resolutionCursor++;\n this.offsetCursor = 0;\n return;\n }\n\n const interval = this.currentIntervals[this.intervalCursor]!;\n const start = trace.route[interval.startIndex]!;\n const end = trace.route[interval.endIndex]!;\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) {\n this.intervalCursor++;\n this.resolutionCursor = 0;\n this.offsetCursor = 0;\n return;\n }\n if (\n this.endpointCollides(trace, interval, start, candidateWidth) ||\n this.endpointCollides(trace, interval, end, candidateWidth)\n ) {\n this.intervalCursor++;\n this.resolutionCursor = 0;\n this.offsetCursor = 0;\n return;\n }\n\n const gridSize = this.gridResolutions[this.resolutionCursor]!;\n const normalizedOffset = GRID_OFFSETS[this.offsetCursor]!;\n const gridOffset = {\n x: normalizedOffset.x * gridSize,\n y: normalizedOffset.y * gridSize,\n };\n this.attemptedGridCount++;\n this.activeSubSolver = new ObstacleAwareGridRouteSolver({\n start,\n end,\n layer: start.layer,\n traceWidth: candidateWidth,\n gridSize,\n gridOffset,\n connectionNames: this.getTraceConnectionNames(trace),\n obstacleIndex: this.obstacleIndex,\n ignoreTraceIndex: this.traceIndex,\n ignoreRouteRange: {\n start: Math.max(0, interval.startIndex - 1),\n end: Math.min(trace.route.length - 1, interval.endIndex + 1),\n },\n bounds: this.inputProblem.bounds,\n obstacleClearance: this.getDesiredPadClearance(candidateWidth),\n searchPadding: Math.min(\n 5,\n Math.max(1.5, distance(start, end) / 2, candidateWidth * 3),\n ),\n });\n }\n\n private endpointCollides(\n trace: SimplifiedPcbTrace,\n interval: { startIndex: number; endIndex: number },\n point: WireRoutePoint,\n width: number,\n ) {\n return this.obstacleIndex.collides({\n start: point,\n end: point,\n layer: point.layer,\n width,\n connectionNames: this.getTraceConnectionNames(trace),\n ignoreTraceIndex: this.traceIndex,\n ignoreRouteRange: {\n start: Math.max(0, interval.startIndex - 1),\n end: Math.min(trace.route.length - 1, interval.endIndex + 1),\n },\n obstacleClearance: this.getDesiredPadClearance(width),\n });\n }\n\n private stepActiveGridSolver() {\n if (this.activeSubSolver instanceof PowerTraceClearanceRepairSolver) {\n this.stepActiveTraceClearanceRepairSolver();\n return;\n }\n if (this.activeSubSolver instanceof PowerTraceCleanupSolver) {\n this.stepActiveCleanupSolver();\n return;\n }\n if (this.activeSubSolver instanceof LocalTraceInflationSolver) {\n this.stepActiveInflationSolver();\n return;\n }\n if (this.activeSubSolver instanceof LayerAwareGridRouteSolver) {\n this.stepActiveLayerSolver();\n return;\n }\n const solver = this.activeSubSolver!;\n solver.step();\n if (!solver.solved && !solver.failed) return;\n\n if (solver.solved) {\n const output = solver.getOutput();\n if (\n output &&\n !this.gridRouteReplacementCollides(output) &&\n !this.gridRouteBoundaryCollides(output)\n ) {\n this.applyGridRoute(this.maximizeGridRouteWidth(output));\n this.activeSubSolver = null;\n return;\n }\n }\n\n this.failedSubSolvers ??= [];\n this.failedSubSolvers.push(solver);\n this.activeSubSolver = null;\n this.offsetCursor++;\n }\n\n private stepActiveCleanupSolver() {\n const solver = this.activeSubSolver as PowerTraceCleanupSolver;\n solver.step();\n if (!solver.solved && !solver.failed) return;\n\n if (solver.solved) {\n this.traces = solver.getOutput();\n const stats = solver.stats as Record<string, unknown>;\n this.removedViaPairCount = Number(stats.viaPairCountRemoved ?? 0);\n this.removedViaCount = Number(stats.viaCountRemoved ?? 0);\n this.simplifiedPathCount = Number(stats.simplifiedPathCount ?? 0);\n this.normalizedSegmentCount = Number(stats.normalizedSegmentCount ?? 0);\n this.cleanupClearanceShoveCount = Number(\n stats.committedClearanceShoveCount ?? 0,\n );\n this.relocatedViaCount = Number(stats.relocatedViaCount ?? 0);\n this.unresolvedViaCount = Number(stats.unresolvedViaCount ?? 0);\n this.padClearanceRerouteCount = Number(\n stats.padClearanceRerouteCount ?? 0,\n );\n this.unresolvedPadClearanceCount = Number(\n stats.unresolvedPadClearanceCount ?? 0,\n );\n this.initialPadClearanceViolationCount = Number(\n stats.initialPadClearanceViolationCount ?? 0,\n );\n this.remainingPadClearanceViolationCount = Number(\n stats.remainingPadClearanceViolationCount ?? 0,\n );\n this.initialPadClearanceViolationCountByClearance = {\n ...((stats.initialPadClearanceViolationCountByClearance ??\n {}) as Record<string, number>),\n };\n this.remainingPadClearanceViolationCountByClearance = {\n ...((stats.remainingPadClearanceViolationCountByClearance ??\n {}) as Record<string, number>),\n };\n this.activeSubSolver = null;\n this.startTraceClearanceRepair();\n this.rebuildObstacleIndex();\n return;\n }\n\n this.failedSubSolvers ??= [];\n this.failedSubSolvers.push(solver);\n this.activeSubSolver = null;\n this.startTraceClearanceRepair();\n }\n\n private startTraceClearanceRepair() {\n this.phase = \"repair-trace-clearance\";\n this.activeSubSolver = new PowerTraceClearanceRepairSolver({\n simpleRouteJson: this.inputProblem,\n traces: this.traces,\n traceIndices: this.traceOrder,\n });\n }\n\n private stepActiveTraceClearanceRepairSolver() {\n const solver = this.activeSubSolver as PowerTraceClearanceRepairSolver;\n solver.step();\n if (!solver.solved && !solver.failed) return;\n\n if (solver.solved) {\n this.traces = solver.getOutput();\n const stats = solver.stats as Record<string, unknown>;\n this.repairedTraceClearanceSegmentCount = Number(\n stats.repairedSegmentCount ?? 0,\n );\n this.repairedPadNeckSegmentCount = Number(\n stats.repairedPadNeckSegmentCount ?? 0,\n );\n this.unresolvedTraceClearanceSegmentCount = Number(\n stats.unresolvedSegmentCount ?? 0,\n );\n this.activeSubSolver = null;\n this.phase = \"complete\";\n this.rebuildObstacleIndex();\n return;\n }\n\n this.failedSubSolvers ??= [];\n this.failedSubSolvers.push(solver);\n this.activeSubSolver = null;\n this.phase = \"complete\";\n }\n\n private stepActiveLayerSolver() {\n const solver = this.activeSubSolver as LayerAwareGridRouteSolver;\n solver.step();\n if (!solver.solved && !solver.failed) return;\n\n if (solver.solved) {\n const output = solver.getOutput();\n if (\n output &&\n !this.layerRouteReplacementCollides(output, true) &&\n this.layerRouteImprovesInterval(output)\n ) {\n this.activeSubSolver = null;\n this.pendingLayerOutput = output;\n this.pendingLayerPushCount = 0;\n if (!this.layerRouteReplacementCollides(output, false)) {\n this.applyLayerRoute(output);\n return;\n }\n if (this.startPendingLayerInflation()) return;\n this.pendingLayerOutput = null;\n }\n }\n\n this.failedSubSolvers ??= [];\n this.failedSubSolvers.push(solver);\n this.activeSubSolver = null;\n if (this.layerAttempt) this.layerAttempt.offsetCursor++;\n this.phase = \"try-layer-candidate\";\n }\n\n private layerRouteReplacementCollides(\n output: LayerGridRouteOutput,\n ignoreSoftTraces: boolean,\n ) {\n const trace = this.traces[this.traceIndex];\n const attempt = this.layerAttempt;\n if (!trace || !attempt) return true;\n const connectionNames = this.getTraceConnectionNames(trace);\n const ignoreTraceIndices = ignoreSoftTraces\n ? attempt.softTraceIndices\n : undefined;\n const ignoreRouteRange = {\n start: Math.max(0, attempt.interval.startIndex - 1),\n end: Math.min(trace.route.length - 1, attempt.interval.endIndex + 1),\n };\n const fixedVias = this.getFixedViasOutsideInterval(trace, attempt.interval);\n\n for (let index = 0; index < output.route.length; index++) {\n const point = output.route[index];\n if (point?.route_type === \"via\") {\n if (\n this.obstacleIndex.collidesVia({\n point,\n layers: this.obstacleIndex.boardLayers,\n padDiameter: point.via_diameter ?? 0.6,\n holeDiameter:\n point.via_hole_diameter ??\n this.obstacleIndex.defaultViaHoleDiameter,\n connectionNames,\n ignoreTraceIndex: this.traceIndex,\n ignoreTraceIndices,\n otherNewViaPoints: output.route\n .slice(0, index)\n .filter(\n (candidate): candidate is ViaRoutePoint =>\n candidate.route_type === \"via\",\n )\n .map((candidate) => ({ x: candidate.x, y: candidate.y })),\n fixedVias,\n ignoreRouteRange,\n obstacleClearance: this.getDesiredPadClearance(output.traceWidth),\n blockSameNetObstacles: true,\n sameNetObstacleClearance: 0,\n })\n ) {\n return true;\n }\n continue;\n }\n const next = output.route[index + 1];\n if (\n point?.route_type !== \"wire\" ||\n next?.route_type !== \"wire\" ||\n point.layer !== next.layer\n ) {\n continue;\n }\n if (\n this.obstacleIndex.collides({\n start: point,\n end: next,\n layer: point.layer,\n // Core validates the joint using both endpoint widths.\n width: Math.max(point.width, next.width),\n connectionNames,\n ignoreTraceIndex: this.traceIndex,\n ignoreTraceIndices,\n ignoreRouteRange,\n obstacleClearance: this.getDesiredPadClearance(output.traceWidth),\n })\n ) {\n return true;\n }\n }\n return this.layerRouteBoundaryCollides(output, ignoreSoftTraces);\n }\n\n private getFixedViasOutsideInterval(\n trace: SimplifiedPcbTrace,\n interval: RouteInterval,\n ) {\n return trace.route.flatMap((point, routeIndex) => {\n if (\n point.route_type !== \"via\" ||\n (routeIndex >= interval.startIndex && routeIndex <= interval.endIndex)\n ) {\n return [];\n }\n return [\n {\n point: { x: point.x, y: point.y },\n padDiameter: point.via_diameter ?? 0.6,\n holeDiameter:\n point.via_hole_diameter ??\n this.obstacleIndex.defaultViaHoleDiameter,\n },\n ];\n });\n }\n\n private layerRouteBoundaryCollides(\n output: LayerGridRouteOutput,\n ignoreSoftTraces: boolean,\n ) {\n const trace = this.traces[this.traceIndex]!;\n const attempt = this.layerAttempt!;\n const firstWire = output.route.find(\n (point): point is WireRoutePoint => point.route_type === \"wire\",\n );\n let lastWire: WireRoutePoint | undefined;\n for (let index = output.route.length - 1; index >= 0; index--) {\n const point = output.route[index];\n if (point?.route_type === \"wire\") {\n lastWire = point;\n break;\n }\n }\n if (!firstWire || !lastWire) return true;\n const boundaries = [\n {\n outside: trace.route[attempt.interval.startIndex - 1],\n inside: firstWire,\n },\n {\n outside: trace.route[attempt.interval.endIndex + 1],\n inside: lastWire,\n },\n ];\n for (const boundary of boundaries) {\n if (\n !isWire(boundary.outside) ||\n boundary.outside.layer !== boundary.inside.layer\n ) {\n continue;\n }\n if (\n this.obstacleIndex.collides({\n start: boundary.outside,\n end: boundary.inside,\n layer: boundary.inside.layer,\n width: Math.max(boundary.outside.width, boundary.inside.width),\n connectionNames: this.getTraceConnectionNames(trace),\n ignoreTraceIndex: this.traceIndex,\n ignoreTraceIndices: ignoreSoftTraces\n ? attempt.softTraceIndices\n : undefined,\n ignoreRouteRange: {\n start: Math.max(0, attempt.interval.startIndex - 1),\n end: Math.min(\n trace.route.length - 1,\n attempt.interval.endIndex + 1,\n ),\n },\n obstacleClearance: this.getDesiredPadClearance(output.traceWidth),\n })\n ) {\n return true;\n }\n }\n return false;\n }\n\n private layerRouteImprovesInterval(output: LayerGridRouteOutput) {\n const trace = this.traces[this.traceIndex]!;\n const interval = this.layerAttempt!.interval;\n const before = this.getRouteQuality(\n trace.route.slice(interval.startIndex, interval.endIndex + 1),\n );\n const after = this.getRouteQuality(output.route);\n return (\n after.length <= before.length + 10 + WIDTH_EPSILON &&\n after.deficitArea <=\n before.deficitArea - Math.max(0.05, before.deficitArea * 0.1)\n );\n }\n\n private getRouteQuality(route: SimplifiedPcbTrace[\"route\"]) {\n let length = 0;\n let deficitArea = 0;\n for (let index = 0; index < route.length - 1; index++) {\n const start = route[index];\n const end = route[index + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) continue;\n const segmentLength = distance(start, end);\n const conservativeWidth = Math.min(start.width, end.width);\n length += segmentLength;\n deficitArea +=\n segmentLength * Math.max(0, this.nominalTraceWidth - conservativeWidth);\n }\n return { length, deficitArea };\n }\n\n private getLayerInflationCorridor(output: LayerGridRouteOutput) {\n const corridor: InflationCorridorSegment[] = [];\n for (let index = 0; index < output.route.length; index++) {\n const point = output.route[index];\n if (point?.route_type === \"via\") {\n for (const layer of this.obstacleIndex.boardLayers) {\n corridor.push({\n start: point,\n end: point,\n layer,\n width: point.via_diameter ?? 0.6,\n });\n }\n continue;\n }\n const next = output.route[index + 1];\n if (\n point?.route_type === \"wire\" &&\n next?.route_type === \"wire\" &&\n point.layer === next.layer\n ) {\n corridor.push({\n start: point,\n end: next,\n layer: point.layer,\n width: Math.max(point.width, next.width),\n });\n }\n }\n return corridor;\n }\n\n private startPendingLayerInflation() {\n const output = this.pendingLayerOutput;\n if (!output || this.pendingLayerPushCount >= 2) return false;\n const corridor = this.getLayerInflationCorridor(output);\n if (corridor.length === 0) return false;\n this.pendingLayerPushCount++;\n this.attemptedInflationCount++;\n this.activeSubSolver = new LocalTraceInflationSolver(\n {\n simpleRouteJson: this.inputProblem,\n traces: this.traces,\n powerTraceIndex: this.traceIndex,\n nominalPowerWidth: output.traceWidth,\n corridor,\n maxRerouteLength: 10,\n },\n this.connectionNameResolver,\n );\n this.phase = \"try-trace-inflation\";\n return true;\n }\n\n private applyLayerRoute(output: LayerGridRouteOutput) {\n const trace = this.traces[this.traceIndex]!;\n const interval = this.layerAttempt!.interval;\n const originalStart = trace.route[interval.startIndex] as WireRoutePoint;\n const originalEnd = trace.route[interval.endIndex] as WireRoutePoint;\n const replacement = structuredClone(output.route);\n const firstWireIndex = replacement.findIndex(\n (point) => point.route_type === \"wire\",\n );\n let lastWireIndex = -1;\n for (let index = replacement.length - 1; index >= 0; index--) {\n if (replacement[index]?.route_type === \"wire\") {\n lastWireIndex = index;\n break;\n }\n }\n if (firstWireIndex >= 0) {\n replacement[firstWireIndex] = {\n ...originalStart,\n ...replacement[firstWireIndex],\n } as WireRoutePoint;\n }\n if (lastWireIndex >= 0) {\n replacement[lastWireIndex] = {\n ...originalEnd,\n ...replacement[lastWireIndex],\n } as WireRoutePoint;\n }\n\n trace.route.splice(\n interval.startIndex,\n interval.endIndex - interval.startIndex + 1,\n ...replacement,\n );\n if (output.viaCount > 0) this.layerReroutedTraceCount++;\n this.layerRerouteCountByTrace.set(\n this.traceIndex,\n (this.layerRerouteCountByTrace.get(this.traceIndex) ?? 0) + 1,\n );\n this.reroutedSegmentCount++;\n this.insertedViaCount += output.viaCount;\n if (output.viaCount > 0) {\n this.neckedLayerSegmentCount += replacement.filter(\n (point) =>\n point.route_type === \"wire\" &&\n point.width < this.nominalTraceWidth - WIDTH_EPSILON,\n ).length;\n }\n this.routeSegmentIndex = interval.startIndex;\n this.currentIntervals = [];\n this.layerAttempt = null;\n this.pendingLayerOutput = null;\n this.pendingLayerPushCount = 0;\n this.phase = \"evaluate-segment\";\n }\n\n private startTraceInflation(trace: SimplifiedPcbTrace, segmentIndex: number) {\n const segmentStart = trace.route[segmentIndex];\n const segmentEnd = trace.route[segmentIndex + 1];\n if (!isWire(segmentStart) || !isWire(segmentEnd)) return false;\n const currentWidth = Math.min(segmentStart.width, segmentEnd.width);\n const targetWidth = this.findBestPushableInflationWidth(\n trace,\n segmentIndex,\n currentWidth,\n );\n if (!targetWidth) return false;\n const corridor = this.getLocalInflationCorridor(\n trace,\n segmentIndex,\n targetWidth,\n );\n if (corridor.length === 0) return false;\n const key = [\n this.traceIndex,\n segmentStart.x,\n segmentStart.y,\n segmentEnd.x,\n segmentEnd.y,\n ].join(\":\");\n const attemptCount = this.inflationAttemptsBySegment.get(key) ?? 0;\n if (attemptCount >= 2) return false;\n\n this.inflationAttemptsBySegment.set(key, attemptCount + 1);\n this.activeInflationKey = key;\n this.activeInflationWidth = targetWidth;\n this.attemptedInflationCount++;\n this.activeSubSolver = new LocalTraceInflationSolver(\n {\n simpleRouteJson: this.inputProblem,\n traces: this.traces,\n powerTraceIndex: this.traceIndex,\n nominalPowerWidth: targetWidth,\n corridor,\n maxRerouteLength: 10,\n },\n this.connectionNameResolver,\n );\n this.phase = \"try-trace-inflation\";\n return true;\n }\n\n private hasOnlyPushableTraceBlockers(\n trace: SimplifiedPcbTrace,\n segmentIndex: number,\n targetWidth: number,\n ) {\n const firstAffectedSegment = Math.max(0, segmentIndex - 1);\n const lastAffectedSegment = Math.min(\n trace.route.length - 2,\n segmentIndex + 1,\n );\n const pushableTraceIndices = new Set<number>();\n\n for (\n let affectedIndex = firstAffectedSegment;\n affectedIndex <= lastAffectedSegment;\n affectedIndex++\n ) {\n const start = trace.route[affectedIndex];\n const end = trace.route[affectedIndex + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) continue;\n const query = {\n start,\n end,\n layer: start.layer,\n width: targetWidth,\n connectionNames: this.getTraceConnectionNames(trace),\n ignoreTraceIndex: this.traceIndex,\n ignoreRouteRange: {\n start: firstAffectedSegment,\n end: lastAffectedSegment + 1,\n },\n obstacleClearance: this.getDesiredPadClearance(targetWidth),\n };\n const collisions = this.obstacleIndex.findCollisions(query);\n if (collisions.length === 0 && this.obstacleIndex.collides(query)) {\n return false;\n }\n for (const collision of collisions) {\n if (collision.kind !== \"trace\" || collision.traceIndex === undefined) {\n return false;\n }\n const blockingTrace = this.traces[collision.traceIndex];\n if (!blockingTrace) return false;\n const connection = this.findConnectionForTrace(blockingTrace);\n if (\n !connection ||\n (connection.nominalTraceWidth ??\n connection.width ??\n this.inputProblem.nominalTraceWidth ??\n this.inputProblem.minTraceWidth) >=\n targetWidth - WIDTH_EPSILON\n ) {\n return false;\n }\n pushableTraceIndices.add(collision.traceIndex);\n }\n }\n\n // Pushing a small local bundle remains predictable; larger bundles should\n // be handled by the board-level router rather than a post-route repair.\n return pushableTraceIndices.size > 0 && pushableTraceIndices.size <= 2;\n }\n\n private findBestPushableInflationWidth(\n trace: SimplifiedPcbTrace,\n segmentIndex: number,\n currentWidth: number,\n ) {\n const quantum = this.nominalTraceWidth >= 0.5 ? 0.05 : 0.0125;\n for (\n let targetWidth = this.nominalTraceWidth;\n targetWidth > currentWidth + WIDTH_EPSILON;\n targetWidth -= quantum\n ) {\n const quantizedTarget = Number(targetWidth.toFixed(6));\n if (\n this.hasOnlyPushableTraceBlockers(trace, segmentIndex, quantizedTarget)\n ) {\n return quantizedTarget;\n }\n }\n return null;\n }\n\n private stepActiveInflationSolver() {\n const solver = this.activeSubSolver as LocalTraceInflationSolver;\n solver.step();\n if (!solver.solved && !solver.failed) return;\n\n if (solver.solved) {\n const output = solver.getOutput();\n if (output) {\n this.traces = output.traces;\n this.pushedTraceCount++;\n if (output.strategy === \"elastic\") this.elasticPushedTraceCount++;\n this.activeSubSolver = null;\n this.activeInflationKey = null;\n this.activeInflationWidth = null;\n this.rebuildObstacleIndex();\n if (this.pendingLayerOutput) {\n if (\n !this.layerRouteReplacementCollides(this.pendingLayerOutput, false)\n ) {\n this.applyLayerRoute(this.pendingLayerOutput);\n return;\n }\n if (this.startPendingLayerInflation()) return;\n this.pendingLayerOutput = null;\n this.pendingLayerPushCount = 0;\n if (this.layerAttempt) this.layerAttempt.offsetCursor++;\n this.phase = \"try-layer-candidate\";\n return;\n }\n this.phase = \"evaluate-segment\";\n return;\n }\n }\n\n this.failedSubSolvers ??= [];\n this.failedSubSolvers.push(solver);\n if (this.activeInflationKey) {\n this.inflationAttemptsBySegment.set(this.activeInflationKey, 2);\n }\n this.activeInflationKey = null;\n this.activeInflationWidth = null;\n this.activeSubSolver = null;\n if (this.pendingLayerOutput) {\n this.pendingLayerOutput = null;\n this.pendingLayerPushCount = 0;\n if (this.layerAttempt) this.layerAttempt.offsetCursor++;\n this.phase = \"try-layer-candidate\";\n return;\n }\n this.phase = \"evaluate-segment\";\n }\n\n private getLocalInflationCorridor(\n trace: SimplifiedPcbTrace,\n segmentIndex: number,\n targetWidth: number,\n ): InflationCorridorSegment[] {\n const firstPoint = trace.route[segmentIndex];\n const secondPoint = trace.route[segmentIndex + 1];\n if (\n !isWire(firstPoint) ||\n !isWire(secondPoint) ||\n firstPoint.layer !== secondPoint.layer\n ) {\n return [];\n }\n\n const maximumCorridorLength = clamp(targetWidth * 4, 2, 4);\n const halfCorridorLength = maximumCorridorLength / 2;\n let startIndex = segmentIndex;\n let distanceBefore = 0;\n while (startIndex > 0) {\n const start = trace.route[startIndex - 1];\n const end = trace.route[startIndex];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) break;\n const segmentLength = distance(start, end);\n if (distanceBefore + segmentLength > halfCorridorLength + WIDTH_EPSILON)\n break;\n distanceBefore += segmentLength;\n startIndex--;\n }\n\n let endIndex = segmentIndex + 1;\n let distanceAfter = 0;\n while (endIndex < trace.route.length - 1) {\n const start = trace.route[endIndex];\n const end = trace.route[endIndex + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) break;\n const segmentLength = distance(start, end);\n if (distanceAfter + segmentLength > halfCorridorLength + WIDTH_EPSILON)\n break;\n distanceAfter += segmentLength;\n endIndex++;\n }\n\n // Spend unused room from either half of the 10 mm window on the other\n // side. This keeps the affected area small while still covering a full\n // corridor when the blocked segment is close to one endpoint.\n let remainingDistance =\n maximumCorridorLength - distanceBefore - distanceAfter;\n while (remainingDistance > WIDTH_EPSILON && startIndex > 0) {\n const start = trace.route[startIndex - 1];\n const end = trace.route[startIndex];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) break;\n const segmentLength = distance(start, end);\n if (segmentLength > remainingDistance + WIDTH_EPSILON) break;\n remainingDistance -= segmentLength;\n startIndex--;\n }\n while (\n remainingDistance > WIDTH_EPSILON &&\n endIndex < trace.route.length - 1\n ) {\n const start = trace.route[endIndex];\n const end = trace.route[endIndex + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) break;\n const segmentLength = distance(start, end);\n if (segmentLength > remainingDistance + WIDTH_EPSILON) break;\n remainingDistance -= segmentLength;\n endIndex++;\n }\n\n const corridor: InflationCorridorSegment[] = [];\n for (let index = startIndex; index < endIndex; index++) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) continue;\n corridor.push({\n start,\n end,\n layer: start.layer,\n width: targetWidth,\n });\n }\n return corridor;\n }\n\n private applyGridRoute(output: GridRouteOutput) {\n const trace = this.traces[this.traceIndex]!;\n const interval = this.currentIntervals[this.intervalCursor]!;\n const startPoint = trace.route[interval.startIndex] as WireRoutePoint;\n const endPoint = trace.route[interval.endIndex] as WireRoutePoint;\n const replacement: WireRoutePoint[] = output.points.map((point) => ({\n route_type: \"wire\",\n x: point.x,\n y: point.y,\n width: output.traceWidth,\n layer: startPoint.layer,\n }));\n replacement[0]!.width = Math.max(startPoint.width, output.traceWidth);\n replacement[replacement.length - 1]!.width = Math.max(\n endPoint.width,\n output.traceWidth,\n );\n trace.route.splice(\n interval.startIndex,\n interval.endIndex - interval.startIndex + 1,\n ...replacement,\n );\n this.reroutedSegmentCount++;\n this.routeSegmentIndex = interval.startIndex + replacement.length - 1;\n this.currentIntervals = [];\n this.phase = \"evaluate-segment\";\n }\n\n private gridRouteReplacementCollides(output: GridRouteOutput) {\n const trace = this.traces[this.traceIndex]!;\n const interval = this.currentIntervals[this.intervalCursor]!;\n const originalStart = trace.route[interval.startIndex] as WireRoutePoint;\n const originalEnd = trace.route[interval.endIndex] as WireRoutePoint;\n const connectionNames = this.getTraceConnectionNames(trace);\n\n for (let index = 0; index < output.points.length - 1; index++) {\n const proposedWidth = Math.max(\n output.traceWidth,\n index === 0 ? originalStart.width : 0,\n index === output.points.length - 2 ? originalEnd.width : 0,\n );\n if (\n this.obstacleIndex.collides({\n start: output.points[index]!,\n end: output.points[index + 1]!,\n layer: originalStart.layer,\n width: proposedWidth,\n connectionNames,\n ignoreTraceIndex: this.traceIndex,\n ignoreRouteRange: {\n start: Math.max(0, interval.startIndex - 1),\n end: Math.min(trace.route.length - 1, interval.endIndex + 1),\n },\n obstacleClearance: this.getDesiredPadClearance(proposedWidth),\n })\n ) {\n return true;\n }\n }\n return false;\n }\n\n private gridRouteBoundaryCollides(output: GridRouteOutput) {\n const trace = this.traces[this.traceIndex]!;\n const interval = this.currentIntervals[this.intervalCursor]!;\n const connectionNames = this.getTraceConnectionNames(trace);\n const boundaries = [\n {\n startIndex: interval.startIndex - 1,\n endIndex: interval.startIndex,\n },\n { startIndex: interval.endIndex, endIndex: interval.endIndex + 1 },\n ];\n\n for (const boundary of boundaries) {\n const start = trace.route[boundary.startIndex];\n const end = trace.route[boundary.endIndex];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) {\n continue;\n }\n if (\n this.obstacleIndex.collides({\n start,\n end,\n layer: start.layer,\n // Core's joint/transition clearance is conservative around route\n // points, so validate both endpoint widths at splice boundaries.\n width: Math.max(start.width, end.width, output.traceWidth),\n connectionNames,\n ignoreTraceIndex: this.traceIndex,\n ignoreRouteRange: {\n start: boundary.startIndex,\n end: boundary.endIndex,\n },\n obstacleClearance: this.getDesiredPadClearance(\n Math.max(start.width, end.width, output.traceWidth),\n ),\n })\n ) {\n return true;\n }\n }\n return false;\n }\n\n private canExpandSegmentAndEndpoints(\n trace: SimplifiedPcbTrace,\n segmentIndex: number,\n connectionNames: string[],\n targetWidth = this.nominalTraceWidth,\n ) {\n const firstAffectedSegment = Math.max(0, segmentIndex - 1);\n const lastAffectedSegment = Math.min(\n trace.route.length - 2,\n segmentIndex + 1,\n );\n\n for (\n let affectedIndex = firstAffectedSegment;\n affectedIndex <= lastAffectedSegment;\n affectedIndex++\n ) {\n const affectedStart = trace.route[affectedIndex];\n const affectedEnd = trace.route[affectedIndex + 1];\n if (\n !isWire(affectedStart) ||\n !isWire(affectedEnd) ||\n affectedStart.layer !== affectedEnd.layer\n ) {\n continue;\n }\n const touchesExpandedPoint =\n affectedIndex <= segmentIndex + 1 && affectedIndex + 1 >= segmentIndex;\n // Although a serialized wire segment takes its width from its first\n // point, core validates the copper transition around both endpoints.\n // Checking adjacent segments at the larger endpoint width keeps the\n // standalone solver aligned with the fully rendered board DRC.\n const proposedWidth = Math.max(\n affectedStart.width,\n affectedEnd.width,\n touchesExpandedPoint ? targetWidth : 0,\n );\n if (\n this.obstacleIndex.collides({\n start: affectedStart,\n end: affectedEnd,\n layer: affectedStart.layer,\n width: proposedWidth,\n connectionNames,\n ignoreTraceIndex: this.traceIndex,\n ignoreRouteRange: {\n start: firstAffectedSegment,\n end: lastAffectedSegment + 1,\n },\n obstacleClearance: this.getDesiredPadClearance(proposedWidth),\n })\n ) {\n return false;\n }\n }\n return true;\n }\n\n private findMaximumSafeInPlaceWidth(\n trace: SimplifiedPcbTrace,\n segmentIndex: number,\n connectionNames: string[],\n ) {\n const start = trace.route[segmentIndex];\n const end = trace.route[segmentIndex + 1];\n if (!isWire(start) || !isWire(end)) return 0;\n const currentWidth = Math.min(start.width, end.width);\n if (\n this.probeInPlaceWidth(\n trace,\n segmentIndex,\n connectionNames,\n this.nominalTraceWidth,\n )\n ) {\n return this.nominalTraceWidth;\n }\n\n let lowerWidth = currentWidth;\n let upperWidth = this.nominalTraceWidth;\n for (let probe = 0; probe < 7; probe++) {\n const candidateWidth = (lowerWidth + upperWidth) / 2;\n if (candidateWidth <= lowerWidth + WIDTH_EPSILON) break;\n if (\n this.probeInPlaceWidth(\n trace,\n segmentIndex,\n connectionNames,\n candidateWidth,\n )\n ) {\n lowerWidth = candidateWidth;\n } else {\n upperWidth = candidateWidth;\n }\n }\n\n const quantum = this.nominalTraceWidth >= 0.5 ? 0.025 : 0.0125;\n const quantizedWidth = Math.max(\n currentWidth,\n Math.floor((lowerWidth + WIDTH_EPSILON) / quantum) * quantum,\n );\n if (\n quantizedWidth > currentWidth + WIDTH_EPSILON &&\n this.probeInPlaceWidth(\n trace,\n segmentIndex,\n connectionNames,\n quantizedWidth,\n )\n ) {\n return quantizedWidth;\n }\n return currentWidth;\n }\n\n private probeInPlaceWidth(\n trace: SimplifiedPcbTrace,\n segmentIndex: number,\n connectionNames: string[],\n width: number,\n ) {\n this.inPlaceWidthProbeCount++;\n return this.canExpandSegmentAndEndpoints(\n trace,\n segmentIndex,\n connectionNames,\n width,\n );\n }\n\n private maximizeGridRouteWidth(output: GridRouteOutput) {\n if (output.traceWidth >= this.nominalTraceWidth - WIDTH_EPSILON) {\n return output;\n }\n let lowerWidth = output.traceWidth;\n let upperWidth = this.nominalTraceWidth;\n for (let probe = 0; probe < 7; probe++) {\n const candidateWidth = (lowerWidth + upperWidth) / 2;\n const candidate = { ...output, traceWidth: candidateWidth };\n if (\n !this.gridRouteReplacementCollides(candidate) &&\n !this.gridRouteBoundaryCollides(candidate)\n ) {\n lowerWidth = candidateWidth;\n } else {\n upperWidth = candidateWidth;\n }\n }\n\n const quantum = this.nominalTraceWidth >= 0.5 ? 0.025 : 0.0125;\n const quantizedWidth = Math.max(\n output.traceWidth,\n Math.floor((lowerWidth + WIDTH_EPSILON) / quantum) * quantum,\n );\n if (quantizedWidth > output.traceWidth + WIDTH_EPSILON) {\n const candidate = { ...output, traceWidth: quantizedWidth };\n if (\n !this.gridRouteReplacementCollides(candidate) &&\n !this.gridRouteBoundaryCollides(candidate)\n ) {\n this.pathWidthUpgradeCount++;\n return candidate;\n }\n }\n return output;\n }\n\n private getExponentialIntervalCandidates(\n trace: SimplifiedPcbTrace,\n blockedSegmentIndex: number,\n nominalWidth: number,\n ) {\n const anchors = this.getExponentialIndices(\n trace,\n blockedSegmentIndex,\n -1,\n nominalWidth,\n 5,\n );\n const targets = this.getExponentialIndices(\n trace,\n blockedSegmentIndex,\n 1,\n nominalWidth,\n 10,\n ).filter((index) => index > blockedSegmentIndex);\n const intervals: Array<{\n startIndex: number;\n endIndex: number;\n routeLength: number;\n }> = [];\n\n for (const startIndex of anchors) {\n for (const endIndex of targets) {\n const routeLength = this.getRouteIntervalLength(\n trace,\n startIndex,\n endIndex,\n );\n if (routeLength > 10 + WIDTH_EPSILON) continue;\n intervals.push({ startIndex, endIndex, routeLength });\n }\n }\n\n return intervals\n .sort((a, b) => a.routeLength - b.routeLength)\n .filter(\n (interval, index, all) =>\n all.findIndex(\n (candidate) =>\n candidate.startIndex === interval.startIndex &&\n candidate.endIndex === interval.endIndex,\n ) === index,\n )\n .slice(0, 10)\n .map(({ startIndex, endIndex }) => ({ startIndex, endIndex }));\n }\n\n private getExponentialIndices(\n trace: SimplifiedPcbTrace,\n originIndex: number,\n direction: -1 | 1,\n nominalWidth: number,\n maximumDistance: number,\n ) {\n const indices = [originIndex];\n let cumulativeDistance = 0;\n let threshold = Math.max(nominalWidth, 0.3);\n let currentIndex = originIndex;\n let furthestIndex = originIndex;\n\n while (true) {\n const nextIndex = currentIndex + direction;\n if (nextIndex < 0 || nextIndex >= trace.route.length) break;\n const current = trace.route[currentIndex];\n const next = trace.route[nextIndex];\n if (!isWire(current) || !isWire(next) || current.layer !== next.layer)\n break;\n const segmentLength = distance(current, next);\n if (cumulativeDistance + segmentLength > maximumDistance + WIDTH_EPSILON)\n break;\n cumulativeDistance += segmentLength;\n currentIndex = nextIndex;\n furthestIndex = nextIndex;\n if (cumulativeDistance + WIDTH_EPSILON >= threshold) {\n indices.push(nextIndex);\n threshold *= 2;\n }\n }\n if (!indices.includes(furthestIndex)) indices.push(furthestIndex);\n return indices;\n }\n\n private getRouteIntervalLength(\n trace: SimplifiedPcbTrace,\n startIndex: number,\n endIndex: number,\n ) {\n let length = 0;\n for (let index = startIndex; index < endIndex; index++) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) {\n return Number.POSITIVE_INFINITY;\n }\n length += distance(start, end);\n }\n return length;\n }\n\n private getCandidateWidths(nominalWidth: number) {\n const minimumWidth = this.inputProblem.minTraceWidth;\n return uniqueDescending([\n nominalWidth,\n nominalWidth * 0.875,\n nominalWidth * 0.75,\n nominalWidth * 0.625,\n nominalWidth * 0.5,\n nominalWidth * 0.375,\n nominalWidth * 0.25,\n minimumWidth,\n ]).filter((width) => width >= minimumWidth - WIDTH_EPSILON);\n }\n\n private getGridResolutions(traceWidth: number) {\n return uniqueDescending([\n Math.max(0.1, Math.min(0.5, traceWidth / 2)),\n Math.max(0.1, Math.min(0.25, traceWidth / 3)),\n ]);\n }\n\n private resolveNominalTraceWidth(trace: SimplifiedPcbTrace) {\n const connection = this.findConnectionForTrace(trace);\n return Math.max(\n connection?.nominalTraceWidth ??\n connection?.width ??\n this.inputProblem.nominalTraceWidth ??\n this.inputProblem.minTraceWidth,\n this.inputProblem.minTraceWidth,\n );\n }\n\n private getDesiredPadClearance(nominalWidth = this.nominalTraceWidth) {\n const baseClearance = Math.max(\n this.inputProblem.defaultObstacleMargin ?? 0,\n this.inputProblem.minTraceToPadEdgeClearance ?? 0,\n 0.1,\n );\n if (nominalWidth < 0.5 - WIDTH_EPSILON) return baseClearance;\n // Width recovery gets first choice of the existing corridor. The cleanup\n // phase then reroutes full-width copper away from pads transactionally,\n // avoiding an early clearance constraint that would preserve long necks.\n if (this.phase !== \"cleanup\") return baseClearance;\n return Math.max(\n baseClearance,\n this.options.powerTraceToPadClearance ?? nominalWidth / 2,\n );\n }\n\n private findConnectionForTrace(trace: SimplifiedPcbTrace) {\n const traceNames = this.getTraceConnectionNames(trace);\n return this.inputProblem.connections.find((candidate) =>\n this.connectionMatchesTrace(candidate, traceNames),\n );\n }\n\n private connectionMatchesTrace(\n connection: SimpleRouteConnection,\n traceNames: string[],\n ) {\n return [\n connection.name,\n connection.source_trace_id,\n connection.rootConnectionName,\n ...(connection.mergedConnectionNames ?? []),\n ]\n .filter((name): name is string => Boolean(name))\n .some((name) => traceNames.includes(name));\n }\n\n private getTraceConnectionNames(trace: SimplifiedPcbTrace) {\n return [\n trace.connection_name,\n trace.source_trace_id,\n trace.rootConnectionName,\n ...(trace.mergedConnectionNames ?? []),\n ].filter((name): name is string => Boolean(name));\n }\n\n private traceMeetsNominalWidth(\n trace: SimplifiedPcbTrace,\n nominalWidth: number,\n ) {\n return trace.route.every(\n (point) =>\n point.route_type !== \"wire\" ||\n point.width >= nominalWidth - WIDTH_EPSILON,\n );\n }\n\n private findNextUnderWidthSegment(\n trace: SimplifiedPcbTrace,\n startIndex: number,\n nominalWidth: number,\n ) {\n for (let index = startIndex; index < trace.route.length - 1; index++) {\n const start = trace.route[index];\n const end = trace.route[index + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer) continue;\n if (\n start.width < nominalWidth - WIDTH_EPSILON ||\n end.width < nominalWidth - WIDTH_EPSILON\n ) {\n return index;\n }\n }\n return -1;\n }\n\n private rebuildObstacleIndex() {\n this.obstacleIndex = new SpatialObstacleIndex(\n this.inputProblem,\n this.traces,\n this.traceIndex,\n [],\n this.connectionNameResolver,\n );\n }\n\n private createStats() {\n return {\n phase: this.phase,\n pass: this.passIndex + 1,\n completedPassCount: this.completedPassCount,\n lastNormalizedWidthDeficitGain: this.lastNormalizedWidthDeficitGain,\n normalizedWidthDeficitGainByPass: [\n ...this.normalizedWidthDeficitGainByPass,\n ],\n plateauReached: this.plateauReached,\n traceIndex: this.traceIndex,\n traceCount: this.traces.length,\n selectedTraceCount: this.traceOrder.length,\n routeSegmentIndex: this.routeSegmentIndex,\n nominalTraceWidth: this.nominalTraceWidth,\n intervalCursor: this.intervalCursor,\n intervalCount: this.currentIntervals.length,\n candidateWidth: this.candidateWidths[this.widthCursor],\n gridSize: this.gridResolutions[this.resolutionCursor],\n gridOffsetVariant: this.offsetCursor,\n keptTraceCount: this.keptTraceCount,\n recreatedTraceCount: this.recreatedTraceCount,\n expandedSegmentCount: this.expandedSegmentCount,\n intermediateExpandedSegmentCount: this.intermediateExpandedSegmentCount,\n pathWidthUpgradeCount: this.pathWidthUpgradeCount,\n inPlaceWidthProbeCount: this.inPlaceWidthProbeCount,\n reroutedSegmentCount: this.reroutedSegmentCount,\n unresolvedSegmentCount: this.unresolvedSegmentCount,\n attemptedGridCount: this.attemptedGridCount,\n attemptedLayerGridCount: this.attemptedLayerGridCount,\n attemptedInflationCount: this.attemptedInflationCount,\n activeInflationWidth: this.activeInflationWidth,\n pushedTraceCount: this.pushedTraceCount,\n elasticPushedTraceCount: this.elasticPushedTraceCount,\n layerReroutedTraceCount: this.layerReroutedTraceCount,\n insertedViaCount: this.insertedViaCount,\n neckedLayerSegmentCount: this.neckedLayerSegmentCount,\n removedViaPairCount: this.removedViaPairCount,\n removedViaCount: this.removedViaCount,\n simplifiedPathCount: this.simplifiedPathCount,\n normalizedSegmentCount: this.normalizedSegmentCount,\n cleanupClearanceShoveCount: this.cleanupClearanceShoveCount,\n relocatedViaCount: this.relocatedViaCount,\n unresolvedViaCount: this.unresolvedViaCount,\n padClearanceRerouteCount: this.padClearanceRerouteCount,\n unresolvedPadClearanceCount: this.unresolvedPadClearanceCount,\n repairedTraceClearanceSegmentCount:\n this.repairedTraceClearanceSegmentCount,\n repairedPadNeckSegmentCount: this.repairedPadNeckSegmentCount,\n unresolvedTraceClearanceSegmentCount:\n this.unresolvedTraceClearanceSegmentCount,\n initialPadClearanceViolationCount: this.initialPadClearanceViolationCount,\n remainingPadClearanceViolationCount:\n this.remainingPadClearanceViolationCount,\n initialPadClearanceViolationCountByClearance: {\n ...this.initialPadClearanceViolationCountByClearance,\n },\n remainingPadClearanceViolationCountByClearance: {\n ...this.remainingPadClearanceViolationCountByClearance,\n },\n spatialIndexRectCount: this.obstacleIndex.items.length,\n };\n }\n\n computeProgress() {\n if (this.traceOrder.length === 0) return 1;\n return Math.min(\n 0.99,\n (this.passIndex +\n Math.max(0, this.traceOrderCursor) / this.traceOrder.length) /\n this.maxPassCount,\n );\n }\n\n override getConstructorParams() {\n return [this.inputProblem, this.options];\n }\n\n override getOutput(): PowerTraceExpanderOutput {\n return this.traces;\n }\n\n override visualize(): GraphicsObject {\n const lines: NonNullable<GraphicsObject[\"lines\"]> = [];\n const circles: NonNullable<GraphicsObject[\"circles\"]> = [];\n for (let traceIndex = 0; traceIndex < this.traces.length; traceIndex++) {\n const trace = this.traces[traceIndex]!;\n const nominalWidth = this.resolveNominalTraceWidth(trace);\n for (const point of trace.route) {\n if (point.route_type !== \"via\") continue;\n circles.push({\n center: point,\n radius: (point.via_diameter ?? 0.6) / 2,\n fill: \"#d4a017\",\n stroke: \"#7a5700\",\n });\n }\n for (\n let routeIndex = 0;\n routeIndex < trace.route.length - 1;\n routeIndex++\n ) {\n const start = trace.route[routeIndex];\n const end = trace.route[routeIndex + 1];\n if (!isWire(start) || !isWire(end) || start.layer !== end.layer)\n continue;\n const isCurrent =\n traceIndex === this.traceIndex &&\n routeIndex === this.routeSegmentIndex;\n const meetsWidth =\n start.width >= nominalWidth - WIDTH_EPSILON &&\n end.width >= nominalWidth - WIDTH_EPSILON;\n const isBottom = start.layer === \"bottom\";\n lines.push({\n points: [start, end],\n strokeColor: isCurrent\n ? \"#ff8c00\"\n : meetsWidth\n ? isBottom\n ? \"#2468c7\"\n : \"#169c45\"\n : isBottom\n ? \"#8b4bb8\"\n : \"#cc3344\",\n strokeWidth: Math.max(start.width, end.width),\n });\n }\n }\n return {\n coordinateSystem: \"cartesian\",\n title: `Power trace expander: ${this.phase}`,\n lines,\n points: [],\n circles,\n rects: this.obstacleIndex.items\n .filter((item) => item.kind === \"obstacle\")\n .slice(0, 2_000)\n .map((item) => ({\n center: {\n x: (item.minX + item.maxX) / 2,\n y: (item.minY + item.maxY) / 2,\n },\n width: item.maxX - item.minX,\n height: item.maxY - item.minY,\n fill: \"rgba(80,80,80,0.12)\",\n stroke: \"rgba(80,80,80,0.35)\",\n })),\n texts: [],\n };\n }\n}\n","import type { SimplifiedPcbTrace } from \"@tscircuit/core\";\nimport { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { pointsEqual, visualizePreparedProblem } from \"./geometry\";\nimport type {\n BiscuitBoardRoutingSolution,\n PreparedBiscuitRoutingProblem,\n RoutedConnection,\n} from \"./types\";\n\nconst sanitizeId = (value: string) => value.replace(/[^a-zA-Z0-9_-]+/g, \"_\");\n\nconst expandSharedNetRoute = (\n prepared: PreparedBiscuitRoutingProblem,\n routes: RoutedConnection[],\n route: RoutedConnection,\n): RoutedConnection => {\n const demand = prepared.demandById.get(route.routeId)!;\n if (route.nodePath.length !== 1 || demand.sourceNode === demand.targetNode) {\n return route;\n }\n\n const adjacency = new Map<\n number,\n Array<{ nodeIndex: number; edgeId: number }>\n >();\n const addEdge = (from: number, to: number, edgeId: number) => {\n const neighbors = adjacency.get(from) ?? [];\n neighbors.push({ nodeIndex: to, edgeId });\n adjacency.set(from, neighbors);\n };\n for (const candidate of routes) {\n if (\n candidate.netId !== route.netId ||\n candidate.routeId === route.routeId\n ) {\n continue;\n }\n for (let index = 1; index < candidate.nodePath.length; index++) {\n const from = candidate.nodePath[index - 1]!;\n const to = candidate.nodePath[index]!;\n const edgeId = candidate.edgePath[index - 1]!;\n addEdge(from, to, edgeId);\n addEdge(to, from, edgeId);\n }\n }\n\n const previous = new Map<number, { nodeIndex: number; edgeId: number }>();\n const queue = [demand.sourceNode];\n previous.set(demand.sourceNode, {\n nodeIndex: demand.sourceNode,\n edgeId: -1,\n });\n for (let queueIndex = 0; queueIndex < queue.length; queueIndex++) {\n const current = queue[queueIndex]!;\n if (current === demand.targetNode) break;\n for (const neighbor of adjacency.get(current) ?? []) {\n if (previous.has(neighbor.nodeIndex)) continue;\n previous.set(neighbor.nodeIndex, {\n nodeIndex: current,\n edgeId: neighbor.edgeId,\n });\n queue.push(neighbor.nodeIndex);\n }\n }\n if (!previous.has(demand.targetNode)) return route;\n\n const nodePath = [demand.targetNode];\n const edgePath: number[] = [];\n while (nodePath[0] !== demand.sourceNode) {\n const entry = previous.get(nodePath[0]!)!;\n nodePath.unshift(entry.nodeIndex);\n edgePath.unshift(entry.edgeId);\n }\n return { ...route, nodePath, edgePath };\n};\n\nconst collapseCollinearNodes = (\n prepared: PreparedBiscuitRoutingProblem,\n nodePath: number[],\n protectedNodeIndexes: ReadonlySet<number>,\n) => {\n if (nodePath.length <= 2) return [...nodePath];\n const result = [nodePath[0]!];\n for (let index = 1; index < nodePath.length - 1; index++) {\n const previous = prepared.nodes[result[result.length - 1]!]!;\n const current = prepared.nodes[nodePath[index]!]!;\n const next = prepared.nodes[nodePath[index + 1]!]!;\n const cross =\n (current.x - previous.x) * (next.y - current.y) -\n (current.y - previous.y) * (next.x - current.x);\n if (\n !protectedNodeIndexes.has(nodePath[index]!) &&\n previous.layer === current.layer &&\n current.layer === next.layer &&\n Math.abs(cross) <= 1e-8\n ) {\n continue;\n }\n result.push(nodePath[index]!);\n }\n result.push(nodePath[nodePath.length - 1]!);\n return result;\n};\n\nconst routeToTrace = (\n prepared: PreparedBiscuitRoutingProblem,\n route: RoutedConnection,\n protectedNodeIndexes: ReadonlySet<number>,\n): SimplifiedPcbTrace => {\n const demand = prepared.demandById.get(route.routeId)!;\n const usedPrefabViaIds = [\n ...route.edgePath.flatMap((edgeId) => {\n const edge = prepared.edges[edgeId]!;\n return edge.kind === \"fixed_via_transition\" ? [edge.prefabViaId] : [];\n }),\n ...route.nodePath.flatMap((nodeIndex) => {\n const prefabViaId = prepared.nodes[nodeIndex]!.prefabViaId;\n return prefabViaId ? [prefabViaId] : [];\n }),\n ];\n const nodePath = collapseCollinearNodes(\n prepared,\n route.nodePath,\n protectedNodeIndexes,\n );\n const outputRoute: SimplifiedPcbTrace[\"route\"] = [];\n\n for (let index = 0; index < nodePath.length; index++) {\n const node = prepared.nodes[nodePath[index]!]!;\n const previous = index > 0 ? prepared.nodes[nodePath[index - 1]!]! : null;\n if (previous && previous.layer !== node.layer) {\n const via = prepared.prefabricatedVias.find(\n (candidate) =>\n pointsEqual(candidate, node) &&\n candidate.layers.includes(previous.layer) &&\n candidate.layers.includes(node.layer),\n );\n if (!via) {\n throw new Error(\n `Refusing to emit a new via at (${node.x}, ${node.y}) for \"${route.routeId}\"`,\n );\n }\n outputRoute.push({\n route_type: \"through_obstacle\",\n start: { x: via.x, y: via.y },\n end: { x: via.x, y: via.y },\n from_layer: previous.layer,\n to_layer: node.layer,\n width: demand.width,\n });\n }\n outputRoute.push({\n route_type: \"wire\",\n x: node.x,\n y: node.y,\n width: demand.width,\n layer: node.layer,\n });\n }\n\n return {\n type: \"pcb_trace\",\n pcb_trace_id: `pcb_trace_${sanitizeId(route.routeId)}`,\n connection_name: route.connectionName,\n connectsTo: [\n ...new Set(\n [\n demand.sourcePointId,\n demand.targetPointId,\n ...usedPrefabViaIds,\n ].filter((pointId): pointId is string => Boolean(pointId)),\n ),\n ],\n route: outputRoute,\n };\n};\n\nexport const assertOnlyPrefabricatedVias = (\n prepared: PreparedBiscuitRoutingProblem,\n traces: SimplifiedPcbTrace[],\n) => {\n for (const trace of traces) {\n for (const routePoint of trace.route) {\n if (routePoint.route_type === \"via\") {\n throw new Error(\n `Trace \"${trace.pcb_trace_id}\" contains a manufactured via at (${routePoint.x}, ${routePoint.y})`,\n );\n }\n if (routePoint.route_type !== \"through_obstacle\") continue;\n const matchingVia = prepared.prefabricatedVias.find(\n (via) =>\n pointsEqual(via, routePoint.start) &&\n pointsEqual(via, routePoint.end) &&\n via.layers.includes(routePoint.from_layer) &&\n via.layers.includes(routePoint.to_layer),\n );\n if (!matchingVia) {\n throw new Error(\n `Trace \"${trace.pcb_trace_id}\" traverses a non-prefabricated obstacle at (${routePoint.start.x}, ${routePoint.start.y})`,\n );\n }\n }\n }\n};\n\nexport class BuildBiscuitBoardTracesSolver extends BaseSolver {\n private output?: BiscuitBoardRoutingSolution;\n readonly prepared: PreparedBiscuitRoutingProblem;\n readonly routed: BiscuitBoardRoutingSolution;\n\n constructor(\n public readonly params: {\n prepared: PreparedBiscuitRoutingProblem;\n routed: BiscuitBoardRoutingSolution;\n },\n ) {\n super();\n this.prepared = params.prepared;\n this.routed = params.routed;\n }\n\n override getConstructorParams(): [typeof this.params] {\n return [this.params];\n }\n\n override _step() {\n const protectedNodeIndexes = new Set<number>();\n for (const route of this.routed.routes) {\n const demand = this.prepared.demandById.get(route.routeId)!;\n for (const endpointNode of [route.nodePath[0], route.nodePath.at(-1)]) {\n if (\n endpointNode !== undefined &&\n endpointNode !== demand.sourceNode &&\n endpointNode !== demand.targetNode\n ) {\n protectedNodeIndexes.add(endpointNode);\n }\n }\n }\n const traces = this.routed.routes.map((route) =>\n routeToTrace(\n this.prepared,\n expandSharedNetRoute(this.prepared, this.routed.routes, route),\n protectedNodeIndexes,\n ),\n );\n assertOnlyPrefabricatedVias(this.prepared, traces);\n this.output = { ...this.routed, traces };\n this.stats = this.output.stats;\n this.progress = 1;\n this.solved = true;\n }\n\n override getOutput() {\n return this.output ?? null;\n }\n\n override visualize(): GraphicsObject {\n return {\n ...visualizePreparedProblem(this.prepared, this.routed.routes),\n title: `Built and validated traces (${this.routed.routes.length} routes, ${this.output?.traces.length ?? 0} Circuit JSON traces)`,\n };\n }\n}\n","export class MinHeap<T> {\n private values: T[] = [];\n private priorities: number[] = [];\n\n get size() {\n return this.values.length;\n }\n\n push(priority: number, value: T) {\n this.values.push(value);\n this.priorities.push(priority);\n let index = this.values.length - 1;\n while (index > 0) {\n const parent = (index - 1) >>> 1;\n if (this.priorities[parent]! <= priority) break;\n this.values[index] = this.values[parent]!;\n this.priorities[index] = this.priorities[parent]!;\n index = parent;\n }\n this.values[index] = value;\n this.priorities[index] = priority;\n }\n\n pop(): T | undefined {\n if (this.values.length === 0) return undefined;\n const root = this.values[0]!;\n const lastValue = this.values.pop()!;\n const lastPriority = this.priorities.pop()!;\n if (this.values.length === 0) return root;\n let index = 0;\n while (true) {\n const left = index * 2 + 1;\n if (left >= this.values.length) break;\n const right = left + 1;\n const child =\n right < this.values.length &&\n this.priorities[right]! < this.priorities[left]!\n ? right\n : left;\n if (this.priorities[child]! >= lastPriority) break;\n this.values[index] = this.values[child]!;\n this.priorities[index] = this.priorities[child]!;\n index = child;\n }\n this.values[index] = lastValue;\n this.priorities[index] = lastPriority;\n return root;\n }\n}\n","import { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport {\n getTerminalEscapeMinimumRun,\n obstacleBounds,\n pointDistance,\n segmentDistance,\n segmentIntersectsRectInterior,\n shouldRespectObstacleRotationInGraph,\n visualizePreparedProblem,\n} from \"./geometry\";\nimport { MinHeap } from \"./min-heap\";\nimport type {\n BiscuitBoardRoutingSolution,\n BiscuitBoardRoutingStats,\n Point,\n PreparedBiscuitRoutingProblem,\n RouteDemand,\n RoutedConnection,\n RoutingEdge,\n} from \"./types\";\n\ninterface SearchNode {\n graphNode: number;\n stateKey: number;\n blockerState: number;\n g: number;\n parentIndex: number;\n blockers: string[];\n edgeFromParent: number | null;\n visitedPreferredLayer: boolean;\n requiredViaIndex: number;\n requiredGuideIndex: number;\n}\n\ninterface ActiveSearch {\n demand: RouteDemand;\n allowBlockers: boolean;\n collapseBlockerStates: boolean;\n sourceNode: number;\n targetNodes: Set<number>;\n targetTreesByLayer: Map<string, TargetKdNode | null>;\n targetHeuristicGeneration: number;\n nodes: SearchNode[];\n open: MinHeap<number>;\n bestCostByState: Map<number, number>;\n expanded: number;\n // Values that cannot change while this search is active, hoisted out of the\n // per-edge inner loop.\n requiredPrefabViaIds: string[];\n requiredViaCount: number;\n requiredGuideTarget: number;\n escapeConstraints: TerminalEscapeConstraint[];\n routeEdgeHistory: Map<number, number> | undefined;\n layerPenalties: Map<string, number> | undefined;\n preferredLayer: string | undefined;\n congestionCost: number;\n sourcePoint: Point;\n targetPoint: Point;\n directCorridorPenaltyScale: number;\n preferredLayerCorridorBonusScale: number;\n nodeAllowanceCache: Uint8Array;\n edgeAllowanceCache: Uint8Array;\n foreignOwnersByEdge: Map<number, string[]>;\n escapeTraversalCache: Uint8Array | undefined;\n fanoutPenaltyCache: Float64Array | undefined;\n geometryPenaltyCache: Float64Array | undefined;\n nominalObstaclePenaltyCache: Float64Array | undefined;\n protectedCorridors: Array<{\n from: Point;\n to: Point;\n minimumDistance: number;\n }>;\n}\n\ninterface TargetKdNode {\n x: number;\n y: number;\n axis: 0 | 1;\n left: TargetKdNode | null;\n right: TargetKdNode | null;\n}\n\ninterface TerminalEscapeConstraint {\n terminalNode: number;\n axis: \"x\" | \"y\";\n direction: -1 | 1;\n minimumRun: number;\n}\n\nconst buildTargetKdTree = (\n points: Array<{ x: number; y: number }>,\n depth = 0,\n): TargetKdNode | null => {\n if (points.length === 0) return null;\n const axis = (depth % 2) as 0 | 1;\n const coordinate = axis === 0 ? \"x\" : \"y\";\n points.sort(\n (left, right) =>\n left[coordinate] - right[coordinate] ||\n left.x - right.x ||\n left.y - right.y,\n );\n const middle = Math.floor(points.length / 2);\n const point = points[middle]!;\n return {\n x: point.x,\n y: point.y,\n axis,\n left: buildTargetKdTree(points.slice(0, middle), depth + 1),\n right: buildTargetKdTree(points.slice(middle + 1), depth + 1),\n };\n};\n\nconst nearestTargetDistanceSquared = (\n tree: TargetKdNode | null,\n x: number,\n y: number,\n bestDistanceSquared = Number.POSITIVE_INFINITY,\n): number => {\n if (!tree) return bestDistanceSquared;\n const dx = x - tree.x;\n const dy = y - tree.y;\n let best = Math.min(bestDistanceSquared, dx * dx + dy * dy);\n const axisDifference = tree.axis === 0 ? dx : dy;\n const nearBranch = axisDifference <= 0 ? tree.left : tree.right;\n const farBranch = axisDifference <= 0 ? tree.right : tree.left;\n best = nearestTargetDistanceSquared(nearBranch, x, y, best);\n if (axisDifference * axisDifference < best) {\n best = nearestTargetDistanceSquared(farBranch, x, y, best);\n }\n return best;\n};\n\nconst insertSortedUnique = (values: string[], additions: string[]) => {\n if (additions.length === 0) return values;\n if (values.length === 0) return additions;\n const merged: string[] = [];\n let valueIndex = 0;\n let additionIndex = 0;\n while (valueIndex < values.length || additionIndex < additions.length) {\n const value = values[valueIndex];\n const addition = additions[additionIndex];\n let next: string;\n if (addition === undefined || (value !== undefined && value < addition)) {\n next = values[valueIndex++]!;\n } else if (value === undefined || addition < value) {\n next = additions[additionIndex++]!;\n } else {\n next = value;\n valueIndex++;\n additionIndex++;\n }\n if (merged.at(-1) !== next) merged.push(next);\n }\n return merged;\n};\n\nconst blockerSetHash = (blockers: readonly string[]) => {\n let hash = 2166136261;\n for (const blocker of blockers) {\n for (let index = 0; index < blocker.length; index++) {\n hash ^= blocker.charCodeAt(index);\n hash = Math.imul(hash, 16777619);\n }\n }\n // A small lossy blocker-state table bounds the A* state count while keeping\n // enough distinct rip choices to escape fixed-via allocation deadlocks.\n return hash & 1;\n};\n\nconst deterministicOrderKey = (value: string, pass: number) => {\n let hash = (2166136261 ^ pass) >>> 0;\n for (let index = 0; index < value.length; index++) {\n hash ^= value.charCodeAt(index);\n hash = Math.imul(hash, 16777619) >>> 0;\n }\n return hash;\n};\n\n// Prefer enough room for the requested final width around immovable pads,\n// while keeping the physical-width route available as a congestion fallback.\nconst NOMINAL_OBSTACLE_PENALTY_MULTIPLIER = 10;\n\nexport class RipUpRubberBandSolver extends BaseSolver {\n private readonly committed = new Map<string, RoutedConnection>();\n private readonly pending: RouteDemand[];\n private readonly inputIndexByDemand = new WeakMap<RouteDemand, number>();\n private readonly edgeOwners = new Map<number, Set<string>>();\n private readonly nodeOwners = new Map<number, Set<string>>();\n private readonly routeDependenciesByRoute = new Map<string, Set<string>>();\n private readonly historyCostByEdge: Float64Array;\n private readonly historyCostByNode: Float64Array;\n private readonly historyCostByRouteEdge = new Map<\n string,\n Map<number, number>\n >();\n private readonly layerPenaltyByRoute = new Map<string, Map<string, number>>();\n private readonly preferredLayerByRoute = new Map<string, string>();\n private readonly requiredPrefabViaIdsByRoute = new Map<string, string[]>();\n private readonly reservedPrefabViaOwnerById = new Map<string, string>();\n private readonly exhaustedPrefabViaBridgeRouteIds = new Set<string>();\n private readonly requiredGuideCountByConnectionName = new Map<\n string,\n number\n >();\n private readonly forcedGuideConnectionNames = new Set<string>();\n private readonly reservedGuideOwnerByEdgeId = new Map<number, string>();\n private readonly ripCountByRoute = new Map<string, number>();\n private readonly conflictComponentAttemptCount = new Map<string, number>();\n private readonly terminalEscapeConstraintsByDemand = new WeakMap<\n RouteDemand,\n TerminalEscapeConstraint[]\n >();\n // Static per-demand caches. Both lookups are pure functions of immutable\n // topology and demand identity, so results never need invalidation.\n private readonly edgeAllowanceByDemand = new WeakMap<\n RouteDemand,\n Uint8Array\n >();\n private readonly nodeAllowanceByDemand = new WeakMap<\n RouteDemand,\n Uint8Array\n >();\n private readonly foreignOwnersKeyByDemand = new WeakMap<\n RouteDemand,\n string\n >();\n // Directed-edge caches for penalty/constraint helpers whose results depend\n // only on immutable topology and the demand: index = edgeId * 2 + direction.\n private readonly escapeTraversalByDemand = new WeakMap<\n RouteDemand,\n Uint8Array\n >();\n private readonly fanoutPenaltyByDemand = new WeakMap<\n RouteDemand,\n Float64Array\n >();\n private readonly geometryPenaltyByDemand = new WeakMap<\n RouteDemand,\n Float64Array\n >();\n private readonly nominalObstaclePenaltyByDemand = new WeakMap<\n RouteDemand,\n Float64Array\n >();\n // The center-to-center distance between a trace edge and each entry in its\n // conflictEdgeIds list is immutable topology; computing it once removes the\n // dominant geometry cost from the A* inner loop.\n private readonly conflictDistancesByEdge = new Map<number, Float64Array>();\n // Foreign-owner lookups depend only on (edge, demand net, demand width) and\n // the current route ownership; the version counter invalidates the cache\n // whenever ownership mutates.\n private ownershipVersion = 0;\n private foreignOwnersCacheVersion = -1;\n private readonly foreignOwnersCache = new Map<\n number,\n Map<string, string[]>\n >();\n // Incremental clearance occupancy: for each trace edge, which committed\n // routes have copper within the generator's conflict radius, and at which\n // center-to-center distances. Updated on commit/uncommit so the A* loop\n // never rescans conflict lists.\n private readonly occupancyByEdge = new Map<number, Map<string, number[]>>();\n private readonly ownedNodeCountByNet = new Map<string, Map<number, number>>();\n private readonly effectiveClearance: number;\n private readonly routingScale: number;\n private readonly targetHeuristicByNode: Float64Array;\n private readonly targetHeuristicGenerationByNode: Uint32Array;\n private targetHeuristicGeneration = 0;\n private committedFixedViaTransitionCount = 0;\n private activeSearch: ActiveSearch | null = null;\n private connectivityRepairCount = 0;\n private totalRipCount = 0;\n private totalExpandedStateCount = 0;\n private negotiationPassCount = 0;\n private lastConflictRouteCount = 0;\n private lastConflictComponents: string[][] = [];\n private adaptivePriorityChangeCount = 0;\n\n constructor(public readonly prepared: PreparedBiscuitRoutingProblem) {\n super();\n this.effectiveClearance = Math.max(\n prepared.options.gridClearance,\n prepared.input.minTraceToPadEdgeClearance ?? 0,\n );\n this.routingScale = Math.hypot(\n prepared.input.bounds.maxX - prepared.input.bounds.minX,\n prepared.input.bounds.maxY - prepared.input.bounds.minY,\n );\n this.targetHeuristicByNode = new Float64Array(prepared.nodes.length);\n this.targetHeuristicGenerationByNode = new Uint32Array(\n prepared.nodes.length,\n );\n this.historyCostByEdge = new Float64Array(prepared.edges.length);\n this.historyCostByNode = new Float64Array(prepared.nodes.length);\n const compareByDistance = (left: RouteDemand, right: RouteDemand) => {\n const leftDistance = pointDistance(\n prepared.nodes[left.sourceNode]!,\n prepared.nodes[left.targetNode]!,\n );\n const rightDistance = pointDistance(\n prepared.nodes[right.sourceNode]!,\n prepared.nodes[right.targetNode]!,\n );\n const comparison =\n rightDistance - leftDistance ||\n prepared.demands.indexOf(left) - prepared.demands.indexOf(right);\n return prepared.options.routeOrder === \"shortest_first\"\n ? -comparison\n : comparison;\n };\n this.pending = [...prepared.demands];\n for (const edge of prepared.edges) {\n if (\n edge.kind === \"trace\" &&\n edge.restrictedToConnectionName !== undefined &&\n edge.restrictedGuideCount !== undefined\n ) {\n this.requiredGuideCountByConnectionName.set(\n edge.restrictedToConnectionName,\n edge.restrictedGuideCount,\n );\n this.forcedGuideConnectionNames.add(edge.restrictedToConnectionName);\n const guideOwnerNetId = prepared.demands.find(\n (demand) => demand.connectionName === edge.restrictedToConnectionName,\n )?.netId;\n if (!guideOwnerNetId) continue;\n for (const reservedEdgeId of [edge.edgeId, ...edge.conflictEdgeIds]) {\n this.reservedGuideOwnerByEdgeId.set(reservedEdgeId, guideOwnerNetId);\n }\n }\n }\n if (\n prepared.options.routeOrder === \"adaptive\" ||\n prepared.options.routeOrder === \"signal_longest_first\"\n ) {\n this.pending.sort((left, right) => {\n const leftIsPointToPoint = left.connectionTerminalCount === 2;\n const rightIsPointToPoint = right.connectionTerminalCount === 2;\n if (leftIsPointToPoint !== rightIsPointToPoint) {\n return leftIsPointToPoint ? -1 : 1;\n }\n return leftIsPointToPoint\n ? compareByDistance(left, right)\n : prepared.demands.indexOf(left) - prepared.demands.indexOf(right);\n });\n } else if (prepared.options.routeOrder !== \"input\") {\n this.pending.sort(compareByDistance);\n }\n this.pending = this.groupDemandsByNet(this.pending);\n for (let index = 0; index < this.pending.length; index++) {\n this.inputIndexByDemand.set(this.pending[index]!, index);\n }\n this.initializeFinePitchLayerAssignments();\n this.rejectImpracticalBottomLayerPreferences();\n const maximumRoutingAttempts =\n prepared.demands.length + prepared.options.maxTotalRips + 1;\n const stepsPerSearch = Math.ceil(\n prepared.options.maxSearchStates / prepared.options.expansionsPerStep,\n );\n this.MAX_ITERATIONS = Math.max(\n 1_000,\n maximumRoutingAttempts * (stepsPerSearch + 2),\n );\n this.updateStats();\n }\n\n override getConstructorParams(): [PreparedBiscuitRoutingProblem] {\n return [this.prepared];\n }\n\n get committedRoutes() {\n return new Map(this.committed);\n }\n\n get activeDemand() {\n return this.activeSearch?.demand ?? null;\n }\n\n get negotiationConflictComponents() {\n return this.lastConflictComponents.map((component) => [...component]);\n }\n\n /**\n * Reuses a completed routing as the starting point for a localized\n * rip-and-replace repair. The node and edge indexes must belong to this\n * solver's prepared graph.\n */\n seedCommittedRoutes(\n routes: readonly RoutedConnection[],\n routeIdsToReroute: readonly string[],\n ) {\n if (this.committed.size > 0 || this.activeSearch) {\n throw new Error(\"Cannot seed a routing solver after routing has started\");\n }\n this.pending.splice(0);\n for (const route of routes) this.installSeededRoute(route);\n for (const routeId of routeIdsToReroute) {\n this.uncommitRoute(routeId);\n this.queueDemand(routeId);\n }\n this.totalRipCount = 0;\n this.ripCountByRoute.clear();\n this.updateStats();\n }\n\n private installSeededRoute(route: RoutedConnection) {\n const dependencies = new Set<string>();\n for (const endpointNode of [route.nodePath[0], route.nodePath.at(-1)]) {\n if (endpointNode === undefined) continue;\n for (const ownerRouteId of this.nodeOwners.get(endpointNode) ?? []) {\n if (this.committed.get(ownerRouteId)?.netId === route.netId) {\n dependencies.add(ownerRouteId);\n }\n }\n }\n this.committed.set(route.routeId, route);\n this.routeDependenciesByRoute.set(route.routeId, dependencies);\n const ownedNodeCounts =\n this.ownedNodeCountByNet.get(route.netId) ?? new Map<number, number>();\n this.ownedNodeCountByNet.set(route.netId, ownedNodeCounts);\n for (const nodeIndex of route.nodePath) {\n const owners = this.nodeOwners.get(nodeIndex) ?? new Set<string>();\n owners.add(route.routeId);\n this.nodeOwners.set(nodeIndex, owners);\n ownedNodeCounts.set(nodeIndex, (ownedNodeCounts.get(nodeIndex) ?? 0) + 1);\n }\n for (const edgeId of route.edgePath) {\n const edge = this.prepared.edges[edgeId]!;\n if (edge.kind !== \"trace\") {\n this.committedFixedViaTransitionCount++;\n continue;\n }\n const owners = this.edgeOwners.get(edgeId) ?? new Set<string>();\n owners.add(route.routeId);\n this.edgeOwners.set(edgeId, owners);\n const conflictDistances = this.getConflictDistances(edge);\n for (let index = 0; index < edge.conflictEdgeIds.length; index++) {\n const conflictEdgeId = edge.conflictEdgeIds[index]!;\n const occupancy =\n this.occupancyByEdge.get(conflictEdgeId) ??\n new Map<string, number[]>();\n this.occupancyByEdge.set(conflictEdgeId, occupancy);\n const distances = occupancy.get(route.routeId) ?? [];\n distances.push(conflictDistances[index]!);\n occupancy.set(route.routeId, distances);\n }\n }\n this.ownershipVersion++;\n }\n\n private groupDemandsByNet(demands: RouteDemand[]) {\n const netOrder: string[] = [];\n const demandsByNet = new Map<string, RouteDemand[]>();\n for (const demand of demands) {\n if (!demandsByNet.has(demand.netId)) netOrder.push(demand.netId);\n const netDemands = demandsByNet.get(demand.netId) ?? [];\n netDemands.push(demand);\n demandsByNet.set(demand.netId, netDemands);\n }\n return netOrder.flatMap((netId) => demandsByNet.get(netId) ?? []);\n }\n\n override _step() {\n if (!this.activeSearch) {\n const demand = this.takeNextDemand();\n if (!demand) {\n this.finishOrScheduleNegotiationPass();\n return;\n }\n if (this.committed.has(demand.routeId)) {\n this.uncommitRoute(demand.routeId);\n if (this.failed) return;\n }\n this.activeSearch = this.createSearch(demand, false);\n }\n\n for (\n let expansion = 0;\n expansion < this.prepared.options.expansionsPerStep;\n expansion++\n ) {\n if (!this.activeSearch || this.failed || this.solved) break;\n this.expandOneState();\n }\n this.progress =\n this.prepared.demandById.size === 0\n ? 1\n : this.committed.size / this.prepared.demandById.size;\n this.updateStats();\n }\n\n /**\n * Select the most constrained pending demand using only routing state and\n * topology. Recomputing this priority after every commit lets occupancy and\n * congestion history change the order instead of switching between static\n * longest- and shortest-first passes.\n */\n private takeNextDemand() {\n if (\n this.prepared.options.routeOrder !== \"adaptive\" ||\n this.pending.length < 2\n ) {\n return this.pending.shift();\n }\n\n // A ripped demand's position is already the output of conflict-component\n // negotiation; reshuffling it can recreate the same local cycle. Fresh\n // work adapts within a bounded topology-ordered window so congestion can\n // influence priority without starving another net.\n if (this.ripCountByRoute.has(this.pending[0]!.routeId)) {\n return this.pending.shift();\n }\n let bestIndex = 0;\n const lookahead = Math.min(8, this.pending.length);\n for (let index = 1; index < lookahead; index++) {\n if (this.ripCountByRoute.has(this.pending[index]!.routeId)) break;\n if (\n this.compareAdaptivePriority(\n this.pending[index]!,\n this.pending[bestIndex]!,\n ) < 0\n ) {\n bestIndex = index;\n }\n }\n if (bestIndex > 0) this.adaptivePriorityChangeCount++;\n return this.pending.splice(bestIndex, 1)[0];\n }\n\n private compareAdaptivePriority(left: RouteDemand, right: RouteDemand) {\n const leftPriority = this.getAdaptivePriority(left);\n const rightPriority = this.getAdaptivePriority(right);\n return (\n rightPriority.score - leftPriority.score ||\n leftPriority.inputIndex - rightPriority.inputIndex\n );\n }\n\n private getAdaptivePriority(demand: RouteDemand) {\n const ownedNodes = this.getOwnedNodesForNet(demand.netId);\n let freeEndpointChoices = 0;\n let historyPressure = 0;\n for (const nodeIndex of [demand.sourceNode, demand.targetNode]) {\n for (const adjacent of this.prepared.adjacency[nodeIndex]!) {\n const edge = this.prepared.edges[adjacent.edgeId]!;\n historyPressure +=\n this.historyCostByEdge[adjacent.edgeId]! +\n this.historyCostByNode[adjacent.toNode]!;\n if (\n this.nodeAllowsDemand(adjacent.toNode, demand) &&\n this.edgeAllowsDemand(edge, demand) &&\n this.getForeignOwners(edge, demand).length === 0\n ) {\n freeEndpointChoices++;\n }\n }\n }\n const startedNet = ownedNodes.size > 0 ? 1 : 0;\n const congestionPressure =\n historyPressure / Math.max(1, freeEndpointChoices);\n const topologyOrder = this.inputIndexByDemand.get(demand) ?? 0;\n return {\n score:\n -topologyOrder * this.routingScale * 2 +\n startedNet * this.routingScale * 4 +\n (this.prepared.options.gridPitch * 4) / (freeEndpointChoices + 1) +\n congestionPressure * 0.05,\n freeEndpointChoices,\n historyPressure,\n inputIndex: topologyOrder,\n };\n }\n\n private createSearch(\n demand: RouteDemand,\n allowBlockers: boolean,\n ): ActiveSearch {\n const collapseBlockerStates =\n allowBlockers && this.prepared.demands.length >= 64;\n const ownedNodesForNet = this.getOwnedNodesForNet(demand.netId);\n const sourceIsOwned = ownedNodesForNet.has(demand.sourceNode);\n const targetIsOwned = ownedNodesForNet.has(demand.targetNode);\n let sourceNode = demand.sourceNode;\n let targetNodes = new Set([demand.targetNode]);\n if (ownedNodesForNet.size > 0) {\n if (sourceIsOwned && !targetIsOwned) {\n sourceNode = demand.targetNode;\n targetNodes = ownedNodesForNet;\n } else if (!sourceIsOwned && targetIsOwned) {\n targetNodes = ownedNodesForNet;\n } else if (sourceIsOwned && targetIsOwned) {\n const ownedComponents = this.getOwnedComponentsForNet(demand.netId);\n const sourceComponent = ownedComponents.find((component) =>\n component.has(demand.sourceNode),\n );\n const targetComponent = ownedComponents.find((component) =>\n component.has(demand.targetNode),\n );\n targetNodes =\n sourceComponent === targetComponent\n ? new Set([demand.sourceNode])\n : (targetComponent ?? new Set([demand.targetNode]));\n }\n }\n const targetPointsByLayer = new Map<\n string,\n Array<{ x: number; y: number }>\n >();\n for (const nodeIndex of targetNodes) {\n const target = this.prepared.nodes[nodeIndex]!;\n const points = targetPointsByLayer.get(target.layer) ?? [];\n points.push(target);\n targetPointsByLayer.set(target.layer, points);\n }\n const targetTreesByLayer = new Map(\n [...targetPointsByLayer].map(([layer, points]) => [\n layer,\n buildTargetKdTree(points),\n ]),\n );\n this.targetHeuristicGeneration = (this.targetHeuristicGeneration + 1) >>> 0;\n if (this.targetHeuristicGeneration === 0) {\n this.targetHeuristicGenerationByNode.fill(0);\n this.targetHeuristicGeneration = 1;\n }\n const targetHeuristicGeneration = this.targetHeuristicGeneration;\n const open = new MinHeap<number>();\n open.push(\n this.heuristicToTargets(\n sourceNode,\n targetTreesByLayer,\n targetHeuristicGeneration,\n ),\n 0,\n );\n const preferredLayer = this.preferredLayerByRoute.get(demand.routeId);\n const sourceVisitedPreferredLayer =\n preferredLayer === undefined ||\n this.prepared.nodes[sourceNode]!.layer === preferredLayer;\n const requiredPrefabViaIds =\n this.requiredPrefabViaIdsByRoute.get(demand.routeId) ?? [];\n const sourcePoint = this.prepared.nodes[demand.sourceNode]!;\n const targetPoint = this.prepared.nodes[demand.targetNode]!;\n const escapeConstraints = this.getTerminalEscapeConstraints(demand);\n const directDistance = pointDistance(sourcePoint, targetPoint);\n const isShallowEscapeCorridor = this.isShallowEscapeCorridor(\n demand,\n escapeConstraints,\n );\n const protectedCorridors = this.prepared.demands.flatMap((candidate) => {\n if (\n demand.connectionTerminalCount <= 2 ||\n demand.connectionTerminalCount > 4 ||\n directDistance < this.prepared.options.gridPitch * 4 ||\n candidate.connectionTerminalCount !== 2 ||\n candidate.netId === demand.netId\n ) {\n return [];\n }\n const from = this.prepared.nodes[candidate.sourceNode]!;\n const to = this.prepared.nodes[candidate.targetNode]!;\n const candidateDistance = pointDistance(from, to);\n if (\n candidateDistance < this.prepared.options.gridPitch * 2 ||\n candidateDistance > this.prepared.options.gridPitch * 3 ||\n segmentDistance(sourcePoint, targetPoint, from, to) > 1e-7\n ) {\n return [];\n }\n const minimumDistance = Math.max(\n this.prepared.options.gridPitch / 2 -\n this.prepared.options.gridClearance / 2,\n demand.width / 2 + candidate.width / 2 + this.effectiveClearance,\n );\n return [{ from, to, minimumDistance }];\n });\n const directCorridorPenaltyScale =\n demand.connectionTerminalCount === 2 &&\n escapeConstraints.length > 0 &&\n directDistance <= 10 &&\n !this.requiredPrefabViaIdsByRoute.has(demand.routeId)\n ? 4\n : 0;\n const preferredLayerCorridorBonusScale = isShallowEscapeCorridor\n ? this.requiredPrefabViaIdsByRoute.has(demand.routeId)\n ? 8\n : 4\n : 0;\n const hasGeometryPenalty =\n directCorridorPenaltyScale !== 0 || protectedCorridors.length > 0;\n const hasNominalObstaclePenalty =\n (demand.nominalWidth ?? demand.width) > demand.width + 1e-7;\n const initialStateKey = this.stateKey(\n sourceNode,\n null,\n collapseBlockerStates ? 3 : 0,\n sourceVisitedPreferredLayer,\n 0,\n 0,\n );\n return {\n demand,\n allowBlockers,\n collapseBlockerStates,\n sourceNode,\n targetNodes,\n targetTreesByLayer,\n targetHeuristicGeneration,\n nodes: [\n {\n graphNode: sourceNode,\n stateKey: initialStateKey,\n blockerState: collapseBlockerStates ? 3 : 0,\n g: 0,\n parentIndex: -1,\n blockers: [],\n edgeFromParent: null,\n visitedPreferredLayer: sourceVisitedPreferredLayer,\n requiredViaIndex: 0,\n requiredGuideIndex: 0,\n },\n ],\n open,\n bestCostByState: new Map([[initialStateKey, 0]]),\n expanded: 0,\n requiredPrefabViaIds,\n requiredViaCount: requiredPrefabViaIds.length,\n requiredGuideTarget: this.forcedGuideConnectionNames.has(\n demand.connectionName,\n )\n ? (this.requiredGuideCountByConnectionName.get(demand.connectionName) ??\n 0)\n : 0,\n escapeConstraints,\n routeEdgeHistory: this.historyCostByRouteEdge.get(demand.routeId),\n layerPenalties: this.layerPenaltyByRoute.get(demand.routeId),\n preferredLayer,\n congestionCost:\n this.prepared.options.ripCost * (this.negotiationPassCount + 1) ** 2,\n sourcePoint,\n targetPoint,\n directCorridorPenaltyScale,\n preferredLayerCorridorBonusScale,\n nodeAllowanceCache: this.getNodeAllowanceCache(demand),\n edgeAllowanceCache: this.getEdgeAllowanceCache(demand),\n foreignOwnersByEdge: new Map(),\n escapeTraversalCache:\n escapeConstraints.length > 0\n ? this.getByteCache(this.escapeTraversalByDemand, demand)\n : undefined,\n fanoutPenaltyCache:\n escapeConstraints.length > 0\n ? this.getPenaltyCache(this.fanoutPenaltyByDemand, demand)\n : undefined,\n geometryPenaltyCache: hasGeometryPenalty\n ? this.getPenaltyCache(this.geometryPenaltyByDemand, demand)\n : undefined,\n nominalObstaclePenaltyCache: hasNominalObstaclePenalty\n ? this.getPenaltyCache(this.nominalObstaclePenaltyByDemand, demand)\n : undefined,\n protectedCorridors,\n };\n }\n\n private getOwnedNodesForNet(netId: string) {\n return new Set(this.ownedNodeCountByNet.get(netId)?.keys() ?? []);\n }\n\n private getOwnedComponentsForNet(netId: string) {\n const parent = new Map<number, number>();\n const find = (node: number): number => {\n const currentParent = parent.get(node) ?? node;\n parent.set(node, currentParent);\n if (currentParent === node) return node;\n const root = find(currentParent);\n parent.set(node, root);\n return root;\n };\n const union = (left: number, right: number) => {\n const leftRoot = find(left);\n const rightRoot = find(right);\n if (leftRoot !== rightRoot) parent.set(rightRoot, leftRoot);\n };\n for (const route of this.committed.values()) {\n if (route.netId !== netId || route.nodePath.length === 0) continue;\n const firstNode = route.nodePath[0]!;\n find(firstNode);\n for (const node of route.nodePath.slice(1)) union(firstNode, node);\n }\n const componentsByRoot = new Map<number, Set<number>>();\n for (const node of parent.keys()) {\n const root = find(node);\n const component = componentsByRoot.get(root) ?? new Set<number>();\n component.add(node);\n componentsByRoot.set(root, component);\n }\n return [...componentsByRoot.values()];\n }\n\n private stateKey(\n graphNode: number,\n edgeFromParent: number | null,\n blockerState: number,\n visitedPreferredLayer = true,\n requiredViaIndex = 0,\n requiredGuideIndex = 0,\n ) {\n // Packed numeric key: same state identity as the previous string key, but\n // cheap enough to build in the A* inner loop.\n const node = this.prepared.nodes[graphNode]!;\n const arrivalKind =\n node.kind !== \"fixed_via\"\n ? 0\n : edgeFromParent === null\n ? 1\n : this.prepared.edges[edgeFromParent]!.kind === \"trace\"\n ? 2\n : 3;\n return (\n ((((graphNode * 4 + arrivalKind) * 4 + blockerState) * 2 +\n (visitedPreferredLayer ? 1 : 0)) *\n 8 +\n (requiredViaIndex + 2)) *\n 64 +\n requiredGuideIndex\n );\n }\n\n private heuristic(fromNode: number, toNode: number) {\n const from = this.prepared.nodes[fromNode]!;\n const to = this.prepared.nodes[toNode]!;\n return (\n pointDistance(from, to) +\n (from.layer === to.layer ? 0 : this.prepared.options.viaTransitionCost)\n );\n }\n\n private heuristicToTargets(\n fromNode: number,\n targetTreesByLayer: ActiveSearch[\"targetTreesByLayer\"],\n cacheGeneration: number,\n ) {\n if (this.targetHeuristicGenerationByNode[fromNode] === cacheGeneration) {\n return this.targetHeuristicByNode[fromNode]!;\n }\n const from = this.prepared.nodes[fromNode]!;\n let best = Number.POSITIVE_INFINITY;\n for (const [layer, tree] of targetTreesByLayer) {\n const distance = Math.sqrt(\n nearestTargetDistanceSquared(tree, from.x, from.y),\n );\n best = Math.min(\n best,\n distance +\n (layer === from.layer ? 0 : this.prepared.options.viaTransitionCost),\n );\n }\n this.targetHeuristicByNode[fromNode] = best;\n this.targetHeuristicGenerationByNode[fromNode] = cacheGeneration;\n return best;\n }\n\n private expandOneState() {\n const search = this.activeSearch;\n if (!search) return;\n const searchNodeIndex = search.open.pop();\n if (searchNodeIndex === undefined) {\n if (!search.allowBlockers) {\n // Most routes have a free path, frequently by using the bottom layer\n // through fixed vias. Searching that zero-blocker state space first\n // avoids the combinatorial blocker subsets that tiny-hypergraph also\n // treats as an exceptional rip/re-route phase.\n this.activeSearch = this.createSearch(search.demand, true);\n return;\n }\n const exhaustedRouteCount = [...this.ripCountByRoute.values()].filter(\n (ripCount) => ripCount >= this.prepared.options.maxRipsPerRoute,\n ).length;\n if (this.releasePrefabViaBridge(search.demand.routeId)) {\n this.activeSearch = this.createSearch(search.demand, true);\n return;\n }\n this.fail(\n `No fixed-via route found for \"${search.demand.routeId}\" with at most ${this.prepared.options.maxBlockersPerSearch} blockers${\n exhaustedRouteCount > 0\n ? `; ${exhaustedRouteCount} existing route(s) exhausted their rip budget`\n : \"\"\n }`,\n );\n return;\n }\n const current = search.nodes[searchNodeIndex]!;\n const bestCost = search.bestCostByState.get(current.stateKey);\n if (bestCost === undefined || current.g > bestCost + 1e-9) return;\n search.expanded++;\n this.totalExpandedStateCount++;\n\n if (\n search.targetNodes.has(current.graphNode) &&\n current.visitedPreferredLayer &&\n current.requiredViaIndex === search.requiredViaCount &&\n current.requiredGuideIndex === search.requiredGuideTarget\n ) {\n this.commitGoal(search, searchNodeIndex);\n return;\n }\n if (search.nodes.length >= this.prepared.options.maxSearchStates) {\n this.fail(\n `A* state limit (${this.prepared.options.maxSearchStates}) reached for \"${search.demand.routeId}\"`,\n );\n return;\n }\n\n for (const adjacent of this.prepared.adjacency[current.graphNode]!) {\n this.considerEdge(\n search,\n searchNodeIndex,\n adjacent.edgeId,\n adjacent.toNode,\n );\n }\n }\n\n private considerEdge(\n search: ActiveSearch,\n parentIndex: number,\n edgeId: number,\n toNode: number,\n ) {\n const parent = search.nodes[parentIndex]!;\n const edge = this.prepared.edges[edgeId]!;\n const parentEdge =\n parent.edgeFromParent === null\n ? null\n : this.prepared.edges[parent.edgeFromParent]!;\n const currentNode = this.prepared.nodes[parent.graphNode]!;\n // Merely crossing an assignable via on one layer does not electrically\n // claim it in Circuit JSON. Once a route enters a prefab-via node through\n // copper, it must take the fixed layer transition before leaving.\n if (\n currentNode.kind === \"fixed_via\" &&\n parentEdge?.kind === \"trace\" &&\n edge.kind === \"trace\"\n ) {\n return;\n }\n const requiredPrefabViaIds = search.requiredPrefabViaIds;\n let requiredViaIndex = parent.requiredViaIndex;\n let requiredGuideIndex = parent.requiredGuideIndex;\n if (\n edge.kind === \"trace\" &&\n edge.restrictedGuideOrder !== undefined &&\n edge.restrictedToConnectionName === search.demand.connectionName\n ) {\n if (edge.restrictedGuideOrder !== requiredGuideIndex) return;\n requiredGuideIndex++;\n }\n if (edge.kind === \"fixed_via_transition\") {\n const reservedOwnerRouteId = this.reservedPrefabViaOwnerById.get(\n edge.prefabViaId,\n );\n const reservedOwnerDemand = reservedOwnerRouteId\n ? this.prepared.demandById.get(reservedOwnerRouteId)\n : undefined;\n if (\n reservedOwnerRouteId !== undefined &&\n reservedOwnerRouteId !== search.demand.routeId &&\n reservedOwnerDemand?.netId !== search.demand.netId\n ) {\n return;\n }\n const requiredIndex = requiredPrefabViaIds.indexOf(edge.prefabViaId);\n if (requiredPrefabViaIds.length === 2 && requiredIndex >= 0) {\n if (requiredViaIndex === 0) {\n requiredViaIndex = requiredIndex === 0 ? 1 : -1;\n } else if (requiredViaIndex === 1 && requiredIndex === 1) {\n requiredViaIndex = 2;\n } else if (requiredViaIndex === -1 && requiredIndex === 0) {\n requiredViaIndex = 2;\n } else {\n return;\n }\n } else {\n if (requiredIndex >= 0 && requiredIndex !== requiredViaIndex) return;\n if (requiredIndex === requiredViaIndex) requiredViaIndex++;\n }\n }\n if (search.escapeConstraints.length > 0) {\n // The escape verdict is symmetric in (from, to), so it caches per\n // undirected edge.\n const traversalCache = search.escapeTraversalCache!;\n let verdict = traversalCache[edgeId]!;\n if (verdict === 0) {\n verdict = this.traversalFollowsTerminalEscapes(\n parent.graphNode,\n toNode,\n search.demand,\n )\n ? 1\n : 2;\n traversalCache[edgeId] = verdict;\n }\n if (verdict === 2) return;\n }\n if (\n !this.nodeAllowsDemand(toNode, search.demand, search.nodeAllowanceCache)\n )\n return;\n if (!this.edgeAllowsDemand(edge, search.demand, search.edgeAllowanceCache))\n return;\n const reservedGuideOwner = this.reservedGuideOwnerByEdgeId.get(edgeId);\n if (\n reservedGuideOwner !== undefined &&\n reservedGuideOwner !== search.demand.netId\n ) {\n return;\n }\n\n let foreignOwners = search.foreignOwnersByEdge.get(edgeId);\n if (foreignOwners === undefined) {\n foreignOwners = this.getForeignOwners(edge, search.demand);\n search.foreignOwnersByEdge.set(edgeId, foreignOwners);\n }\n if (!search.allowBlockers && foreignOwners.length > 0) return;\n if (\n foreignOwners.some(\n (routeId) =>\n (this.ripCountByRoute.get(routeId) ?? 0) >=\n this.prepared.options.maxRipsPerRoute,\n )\n ) {\n return;\n }\n const hasNewBlockers =\n foreignOwners.length > 0 &&\n foreignOwners.some((routeId) => !parent.blockers.includes(routeId));\n const nextBlockers = hasNewBlockers\n ? insertSortedUnique(parent.blockers, foreignOwners)\n : parent.blockers;\n if (nextBlockers.length > this.prepared.options.maxBlockersPerSearch)\n return;\n const newlyBlockedRouteCount = search.collapseBlockerStates\n ? foreignOwners.length\n : hasNewBlockers\n ? foreignOwners.filter((routeId) => !parent.blockers.includes(routeId))\n .length\n : 0;\n const blockerState = search.collapseBlockerStates\n ? 3\n : hasNewBlockers\n ? 1 + blockerSetHash(nextBlockers)\n : parent.blockerState;\n const nextG =\n parent.g +\n edge.cost +\n (edge.kind === \"trace\"\n ? (search.layerPenalties?.get(currentNode.layer) ?? 0) * edge.cost\n : 0) +\n this.historyCostByEdge[edgeId]! +\n (search.routeEdgeHistory?.get(edgeId) ?? 0) +\n this.historyCostByNode[toNode]! +\n (search.escapeConstraints.length > 0\n ? this.getShortFanoutStraightRunPenaltyCached(\n search,\n edgeId,\n parent.graphNode,\n toNode,\n )\n : 0) +\n (search.geometryPenaltyCache\n ? this.getRouteGeometryPenaltyCached(\n search,\n edgeId,\n parent.graphNode,\n toNode,\n )\n : 0) +\n (search.nominalObstaclePenaltyCache\n ? this.getNominalObstaclePenaltyCached(search, edgeId)\n : 0) +\n newlyBlockedRouteCount * search.congestionCost +\n foreignOwners.length * this.prepared.options.crossingCost;\n const visitedPreferredLayer =\n parent.visitedPreferredLayer ||\n search.preferredLayer === undefined ||\n this.prepared.nodes[toNode]!.layer === search.preferredLayer;\n const key = this.stateKey(\n toNode,\n edgeId,\n blockerState,\n visitedPreferredLayer,\n requiredViaIndex,\n requiredGuideIndex,\n );\n if (\n nextG >= (search.bestCostByState.get(key) ?? Number.POSITIVE_INFINITY)\n ) {\n return;\n }\n const nextIndex = search.nodes.length;\n search.nodes.push({\n graphNode: toNode,\n stateKey: key,\n blockerState,\n g: nextG,\n parentIndex,\n blockers: nextBlockers,\n edgeFromParent: edgeId,\n visitedPreferredLayer,\n requiredViaIndex,\n requiredGuideIndex,\n });\n search.bestCostByState.set(key, nextG);\n search.open.push(\n nextG +\n this.heuristicToTargets(\n toNode,\n search.targetTreesByLayer,\n search.targetHeuristicGeneration,\n ),\n nextIndex,\n );\n }\n\n private getTerminalEscapeConstraints(demand: RouteDemand) {\n const cached = this.terminalEscapeConstraintsByDemand.get(demand);\n if (cached) return cached;\n const junctionConstraints = this.getDenseJunctionEscapeConstraints(demand);\n if (demand.connectionTerminalCount !== 2) {\n this.terminalEscapeConstraintsByDemand.set(demand, junctionConstraints);\n return junctionConstraints;\n }\n\n const constraints: TerminalEscapeConstraint[] = [...junctionConstraints];\n for (const [terminalNode, otherNode, pointId] of [\n [demand.sourceNode, demand.targetNode, demand.sourcePointId],\n [demand.targetNode, demand.sourceNode, demand.targetPointId],\n ] as const) {\n const terminal = this.prepared.nodes[terminalNode]!;\n const other = this.prepared.nodes[otherNode]!;\n const pad = this.prepared.input.obstacles\n .filter(\n (obstacle) =>\n obstacle.layers.includes(terminal.layer) &&\n Math.abs(obstacle.center.x - terminal.x) <= 1e-7 &&\n Math.abs(obstacle.center.y - terminal.y) <= 1e-7 &&\n (!pointId || obstacle.connectedTo.includes(pointId)),\n )\n .sort(\n (left, right) =>\n left.width * left.height - right.width * right.height,\n )[0];\n if (!pad) continue;\n const minorDimension = Math.min(pad.width, pad.height);\n const aspectRatio = Math.max(pad.width, pad.height) / minorDimension;\n if (minorDimension > 0.25 || aspectRatio < 1.5) continue;\n const axis = pad.width > pad.height ? \"x\" : \"y\";\n const destinationDelta = other[axis] - terminal[axis];\n if (Math.abs(destinationDelta) <= 1e-7) continue;\n const minimumRun = getTerminalEscapeMinimumRun(\n pad,\n this.effectiveClearance,\n );\n constraints.push({\n terminalNode,\n axis,\n direction: destinationDelta < 0 ? -1 : 1,\n minimumRun,\n });\n }\n this.terminalEscapeConstraintsByDemand.set(demand, constraints);\n return constraints;\n }\n\n private getDenseJunctionEscapeConstraints(demand: RouteDemand) {\n const maximumTerminalCount = Math.max(\n ...this.prepared.demands.map(\n (candidate) => candidate.connectionTerminalCount,\n ),\n );\n if (demand.connectionTerminalCount !== maximumTerminalCount) return [];\n const siblingDemands = this.prepared.demands.filter(\n (candidate) =>\n candidate.netId === demand.netId &&\n candidate.sourceNode === demand.sourceNode,\n );\n if (siblingDemands.length < 2) return [];\n const demandDistance = pointDistance(\n this.prepared.nodes[demand.sourceNode]!,\n this.prepared.nodes[demand.targetNode]!,\n );\n if (\n siblingDemands.some(\n (candidate) =>\n pointDistance(\n this.prepared.nodes[candidate.sourceNode]!,\n this.prepared.nodes[candidate.targetNode]!,\n ) >\n demandDistance + 1e-7,\n )\n ) {\n return [];\n }\n const targetIncidence = this.prepared.demands.filter(\n (candidate) =>\n candidate.netId === demand.netId &&\n (candidate.sourceNode === demand.targetNode ||\n candidate.targetNode === demand.targetNode),\n ).length;\n if (targetIncidence < 3) return [];\n\n const source = this.prepared.nodes[demand.sourceNode]!;\n const target = this.prepared.nodes[demand.targetNode]!;\n if (\n Math.min(\n this.prepared.adjacency[demand.sourceNode]!.length,\n this.prepared.adjacency[demand.targetNode]!.length,\n ) < this.prepared.options.maxBlockersPerSearch\n ) {\n return [];\n }\n const axes = ([\"x\", \"y\"] as const).filter(\n (axis) => Math.abs(target[axis] - source[axis]) > 1e-7,\n );\n if (axes.length === 0) return [];\n const pressure = (\n terminalNode: number,\n axis: \"x\" | \"y\",\n direction: -1 | 1,\n ) => {\n const terminal = this.prepared.nodes[terminalNode]!;\n let blockerCount = 0;\n let edgeCount = 0;\n for (const adjacent of this.prepared.adjacency[terminalNode]!) {\n const edge = this.prepared.edges[adjacent.edgeId]!;\n if (edge.kind !== \"trace\") continue;\n const neighbor = this.prepared.nodes[adjacent.toNode]!;\n const axialDelta = neighbor[axis] - terminal[axis];\n const crossAxis = axis === \"x\" ? \"y\" : \"x\";\n const crossDelta = neighbor[crossAxis] - terminal[crossAxis];\n if (\n Math.sign(axialDelta) !== direction ||\n Math.abs(axialDelta) < Math.abs(crossDelta)\n ) {\n continue;\n }\n blockerCount += edge.blockingObstacleIndexes.length;\n edgeCount++;\n }\n return edgeCount === 0\n ? Number.POSITIVE_INFINITY\n : blockerCount / edgeCount;\n };\n const axis = axes.sort((left, right) => {\n const leftDirection = Math.sign(target[left] - source[left]) as -1 | 1;\n const rightDirection = Math.sign(target[right] - source[right]) as -1 | 1;\n return (\n pressure(demand.sourceNode, left, leftDirection) +\n pressure(demand.targetNode, left, leftDirection) -\n (pressure(demand.sourceNode, right, rightDirection) +\n pressure(demand.targetNode, right, rightDirection))\n );\n })[0]!;\n const direction = Math.sign(target[axis] - source[axis]) as -1 | 1;\n return [demand.sourceNode, demand.targetNode].flatMap((terminalNode) => {\n const terminal = this.prepared.nodes[terminalNode]!;\n const pointId =\n terminalNode === demand.sourceNode\n ? demand.sourcePointId\n : demand.targetPointId;\n const pad = this.prepared.input.obstacles\n .filter(\n (obstacle) =>\n obstacle.layers.includes(terminal.layer) &&\n Math.abs(obstacle.center.x - terminal.x) <= 1e-7 &&\n Math.abs(obstacle.center.y - terminal.y) <= 1e-7 &&\n (!pointId || obstacle.connectedTo.includes(pointId)),\n )\n .sort(\n (left, right) =>\n left.width * left.height - right.width * right.height,\n )[0];\n return pad\n ? [\n {\n terminalNode,\n axis,\n direction,\n minimumRun: Math.max(\n this.prepared.options.gridPitch / 2,\n getTerminalEscapeMinimumRun(\n pad,\n this.prepared.options.gridClearance,\n ) + this.prepared.options.gridClearance,\n ),\n },\n ]\n : [];\n });\n }\n\n private isShallowEscapeCorridor(\n demand: RouteDemand,\n constraints = this.getTerminalEscapeConstraints(demand),\n ) {\n if (constraints.length === 0) return false;\n const source = this.prepared.nodes[demand.sourceNode]!;\n const target = this.prepared.nodes[demand.targetNode]!;\n const deltaX = Math.abs(target.x - source.x);\n const deltaY = Math.abs(target.y - source.y);\n const distance = pointDistance(source, target);\n const sourceChoiceCount =\n this.prepared.adjacency[demand.sourceNode]!.length;\n const targetChoiceCount =\n this.prepared.adjacency[demand.targetNode]!.length;\n return (\n distance >= this.prepared.options.gridPitch * 3 &&\n distance <= this.prepared.options.gridPitch * 6 &&\n Math.max(sourceChoiceCount, targetChoiceCount) <=\n this.prepared.options.maxBlockersPerSearch / 4 &&\n sourceChoiceCount !== targetChoiceCount &&\n deltaX > deltaY\n );\n }\n\n private initializeFinePitchLayerAssignments() {\n const groups = new Map<\n string,\n Map<\n string,\n { position: number; routeIds: Set<string>; terminalNode: number }\n >\n >();\n for (const demand of this.prepared.demands) {\n for (const constraint of this.getTerminalEscapeConstraints(demand)) {\n const terminal = this.prepared.nodes[constraint.terminalNode]!;\n const groupKey =\n constraint.axis === \"x\"\n ? `${terminal.layer}:x:${terminal.x.toFixed(6)}`\n : `${terminal.layer}:y:${terminal.y.toFixed(6)}`;\n const entryKey = `${demand.netId}:${constraint.terminalNode}`;\n const entries = groups.get(groupKey) ?? new Map();\n const entry = entries.get(entryKey) ?? {\n position: constraint.axis === \"x\" ? terminal.y : terminal.x,\n routeIds: new Set<string>(),\n terminalNode: constraint.terminalNode,\n };\n entry.routeIds.add(demand.routeId);\n entries.set(entryKey, entry);\n groups.set(groupKey, entries);\n }\n }\n\n for (const entriesByTerminal of groups.values()) {\n const entries = [...entriesByTerminal.values()].sort(\n (left, right) =>\n left.position - right.position ||\n left.terminalNode - right.terminalNode,\n );\n if (entries.length < 2) continue;\n for (let index = 0; index < entries.length; index++) {\n for (const routeId of entries[index]!.routeIds) {\n const demand = this.prepared.demandById.get(routeId)!;\n const source = this.prepared.nodes[demand.sourceNode]!;\n const target = this.prepared.nodes[demand.targetNode]!;\n const isLongRightSideFanout =\n pointDistance(source, target) > 20 &&\n Math.min(source.x, target.x) > 5;\n const preferredLayer = isLongRightSideFanout\n ? Math.abs(source.y - target.y) > 2\n ? \"bottom\"\n : \"top\"\n : index % 2 === 1\n ? \"bottom\"\n : \"top\";\n const penalizedLayer = preferredLayer === \"top\" ? \"bottom\" : \"top\";\n this.preferredLayerByRoute.set(routeId, preferredLayer);\n const penalties =\n this.layerPenaltyByRoute.get(routeId) ?? new Map<string, number>();\n penalties.set(\n penalizedLayer,\n Math.max(\n penalties.get(penalizedLayer) ?? 0,\n this.prepared.options.historyIncrement * 10,\n ),\n );\n this.layerPenaltyByRoute.set(routeId, penalties);\n }\n }\n }\n for (const demand of this.prepared.demands) {\n if (!this.isShallowEscapeCorridor(demand)) continue;\n const sourceLayer = this.prepared.nodes[demand.sourceNode]!.layer;\n const targetLayer = this.prepared.nodes[demand.targetNode]!.layer;\n if (sourceLayer !== targetLayer) continue;\n this.preferredLayerByRoute.set(demand.routeId, sourceLayer);\n const penalties =\n this.layerPenaltyByRoute.get(demand.routeId) ??\n new Map<string, number>();\n for (const layer of this.prepared.layers) {\n if (layer === sourceLayer) continue;\n penalties.set(\n layer,\n Math.max(\n penalties.get(layer) ?? 0,\n this.prepared.options.historyIncrement * 10,\n ),\n );\n }\n this.layerPenaltyByRoute.set(demand.routeId, penalties);\n }\n }\n\n private rejectImpracticalBottomLayerPreferences() {\n const demands = this.prepared.demands\n .filter(\n (demand) => this.preferredLayerByRoute.get(demand.routeId) === \"bottom\",\n )\n .sort((left, right) => left.routeId.localeCompare(right.routeId));\n for (const demand of demands) {\n const source = this.prepared.nodes[demand.sourceNode]!;\n const target = this.prepared.nodes[demand.targetNode]!;\n let bestCost = Number.POSITIVE_INFINITY;\n for (const firstVia of this.prepared.prefabricatedVias) {\n for (const secondVia of this.prepared.prefabricatedVias) {\n if (firstVia.prefabViaId === secondVia.prefabViaId) continue;\n const cost =\n pointDistance(source, firstVia) +\n pointDistance(firstVia, secondVia) +\n pointDistance(secondVia, target);\n bestCost = Math.min(bestCost, cost);\n }\n }\n const directDistance = pointDistance(source, target);\n const maximumUsefulDetour = Math.max(\n directDistance * 2.5,\n directDistance + 12,\n );\n if (bestCost > maximumUsefulDetour) {\n this.preferredLayerByRoute.set(demand.routeId, \"top\");\n this.layerPenaltyByRoute.set(\n demand.routeId,\n new Map([[\"bottom\", this.prepared.options.historyIncrement * 10]]),\n );\n }\n }\n }\n\n private traversalFollowsTerminalEscapes(\n fromNodeIndex: number,\n toNodeIndex: number,\n demand: RouteDemand,\n ) {\n const from = this.prepared.nodes[fromNodeIndex]!;\n const to = this.prepared.nodes[toNodeIndex]!;\n for (const constraint of this.getTerminalEscapeConstraints(demand)) {\n const terminal = this.prepared.nodes[constraint.terminalNode]!;\n if (\n fromNodeIndex === constraint.terminalNode ||\n toNodeIndex === constraint.terminalNode\n ) {\n const neighbor = fromNodeIndex === constraint.terminalNode ? to : from;\n const axialDelta =\n neighbor[constraint.axis] - terminal[constraint.axis];\n const perpendicularDelta =\n constraint.axis === \"x\"\n ? neighbor.y - terminal.y\n : neighbor.x - terminal.x;\n if (\n Math.abs(perpendicularDelta) > Math.abs(axialDelta) + 1e-7 ||\n axialDelta * constraint.direction <= 1e-7\n ) {\n return false;\n }\n }\n\n const edgeIsPerpendicular =\n constraint.axis === \"x\"\n ? Math.abs(from.x - to.x) <= 1e-7\n : Math.abs(from.y - to.y) <= 1e-7;\n if (!edgeIsPerpendicular) continue;\n for (const endpoint of [from, to]) {\n const perpendicularDelta =\n constraint.axis === \"x\"\n ? endpoint.y - terminal.y\n : endpoint.x - terminal.x;\n const axialDelta =\n endpoint[constraint.axis] - terminal[constraint.axis];\n if (\n Math.abs(perpendicularDelta) <= 1e-7 &&\n axialDelta * constraint.direction >= -1e-7 &&\n axialDelta * constraint.direction < constraint.minimumRun - 1e-7\n ) {\n return false;\n }\n }\n }\n return true;\n }\n\n private getShortFanoutStraightRunPenalty(\n fromNodeIndex: number,\n toNodeIndex: number,\n demand: RouteDemand,\n ) {\n const from = this.prepared.nodes[fromNodeIndex]!;\n const to = this.prepared.nodes[toNodeIndex]!;\n for (const constraint of this.getTerminalEscapeConstraints(demand)) {\n const terminal = this.prepared.nodes[constraint.terminalNode]!;\n const otherNodeIndex =\n constraint.terminalNode === demand.sourceNode\n ? demand.targetNode\n : demand.sourceNode;\n const other = this.prepared.nodes[otherNodeIndex]!;\n if (\n pointDistance(terminal, other) > 10 ||\n Math.abs(\n constraint.axis === \"x\" ? other.y - terminal.y : other.x - terminal.x,\n ) < 0.3\n ) {\n continue;\n }\n const staysOnTerminalAxis =\n constraint.axis === \"x\"\n ? Math.abs(from.y - terminal.y) <= 1e-7 &&\n Math.abs(to.y - terminal.y) <= 1e-7\n : Math.abs(from.x - terminal.x) <= 1e-7 &&\n Math.abs(to.x - terminal.x) <= 1e-7;\n if (!staysOnTerminalAxis) continue;\n const furthestAxialRun = Math.max(\n (from[constraint.axis] - terminal[constraint.axis]) *\n constraint.direction,\n (to[constraint.axis] - terminal[constraint.axis]) *\n constraint.direction,\n );\n if (furthestAxialRun > constraint.minimumRun + 0.2) {\n return (\n this.prepared.options.historyIncrement * pointDistance(from, to) * 8\n );\n }\n }\n return 0;\n }\n\n private getShortFanoutStraightRunPenaltyCached(\n search: ActiveSearch,\n edgeId: number,\n fromNodeIndex: number,\n toNodeIndex: number,\n ) {\n // Both penalty helpers are pure functions of the demand and the edge's\n // endpoints, and symmetric in (from, to), so they cache per edge.\n const cache = search.fanoutPenaltyCache!;\n let penalty = cache[edgeId]!;\n if (Number.isNaN(penalty)) {\n penalty = this.getShortFanoutStraightRunPenalty(\n fromNodeIndex,\n toNodeIndex,\n search.demand,\n );\n cache[edgeId] = penalty;\n }\n return penalty;\n }\n\n private getRouteGeometryPenaltyCached(\n search: ActiveSearch,\n edgeId: number,\n fromNodeIndex: number,\n toNodeIndex: number,\n ) {\n if (\n search.directCorridorPenaltyScale === 0 &&\n search.protectedCorridors.length === 0\n ) {\n return 0;\n }\n const cache = search.geometryPenaltyCache!;\n let penalty = cache[edgeId]!;\n if (Number.isNaN(penalty)) {\n penalty = this.getRouteGeometryPenalty(\n search,\n fromNodeIndex,\n toNodeIndex,\n );\n cache[edgeId] = penalty;\n }\n return penalty;\n }\n\n private getRouteGeometryPenalty(\n search: ActiveSearch,\n fromNodeIndex: number,\n toNodeIndex: number,\n ) {\n if (\n search.directCorridorPenaltyScale === 0 &&\n search.protectedCorridors.length === 0\n ) {\n return 0;\n }\n const from = this.prepared.nodes[fromNodeIndex]!;\n const to = this.prepared.nodes[toNodeIndex]!;\n const source = search.sourcePoint;\n const target = search.targetPoint;\n if (from.layer !== to.layer) return 0;\n const midpoint = { x: (from.x + to.x) / 2, y: (from.y + to.y) / 2 };\n const sourceLayer = this.prepared.nodes[search.sourceNode]!.layer;\n const directCorridorScale =\n search.directCorridorPenaltyScale +\n (from.layer === sourceLayer\n ? search.preferredLayerCorridorBonusScale\n : 0);\n let penalty =\n segmentDistance(midpoint, midpoint, source, target) *\n pointDistance(from, to) *\n this.prepared.options.historyIncrement *\n directCorridorScale;\n if (from.layer === sourceLayer) {\n for (const corridor of search.protectedCorridors) {\n const distance = segmentDistance(from, to, corridor.from, corridor.to);\n penalty +=\n Math.max(0, corridor.minimumDistance - distance) *\n pointDistance(from, to) *\n this.prepared.options.historyIncrement *\n 30;\n }\n }\n return penalty;\n }\n\n private getNodeAllowanceCache(demand: RouteDemand) {\n let cache = this.nodeAllowanceByDemand.get(demand);\n if (!cache) {\n cache = new Uint8Array(this.prepared.nodes.length);\n this.nodeAllowanceByDemand.set(demand, cache);\n }\n return cache;\n }\n\n private nodeAllowsDemand(\n nodeIndex: number,\n demand: RouteDemand,\n cache = this.getNodeAllowanceCache(demand),\n ) {\n const cached = cache[nodeIndex]!;\n if (cached !== 0) return cached === 1;\n const node = this.prepared.nodes[nodeIndex]!;\n const allowed =\n node.kind !== \"terminal\" ||\n node.terminalConnectionNames.some((connectionName) =>\n [\n demand.connectionName,\n demand.netId,\n ...(demand.allowedConnectionNames ?? []),\n ].includes(connectionName),\n );\n cache[nodeIndex] = allowed ? 1 : 2;\n return allowed;\n }\n\n private getEdgeAllowanceCache(demand: RouteDemand) {\n let cache = this.edgeAllowanceByDemand.get(demand);\n if (!cache) {\n cache = new Uint8Array(this.prepared.edges.length);\n this.edgeAllowanceByDemand.set(demand, cache);\n }\n return cache;\n }\n\n private edgeAllowsDemand(\n edge: RoutingEdge,\n demand: RouteDemand,\n cache = this.getEdgeAllowanceCache(demand),\n ) {\n const cached = cache[edge.edgeId]!;\n if (cached !== 0) return cached === 1;\n const allowed = this.computeEdgeAllowsDemand(edge, demand);\n cache[edge.edgeId] = allowed ? 1 : 2;\n return allowed;\n }\n\n private computeEdgeAllowsDemand(edge: RoutingEdge, demand: RouteDemand) {\n return this.computeEdgeAllowsDemandAtWidth(edge, demand, demand.width);\n }\n\n private computeEdgeAllowsDemandAtWidth(\n edge: RoutingEdge,\n demand: RouteDemand,\n width: number,\n ) {\n if (edge.kind === \"fixed_via_transition\") return true;\n if (\n edge.restrictedToConnectionName !== undefined &&\n edge.restrictedToConnectionName !== demand.connectionName &&\n this.reservedGuideOwnerByEdgeId.get(edge.edgeId) !== demand.netId\n ) {\n return false;\n }\n const from = this.prepared.nodes[edge.fromNode]!;\n const to = this.prepared.nodes[edge.toNode]!;\n const obstacleIndexes =\n this.prepared.exactRotatedObstacleIndexes.length === 0\n ? edge.blockingObstacleIndexes\n : [\n ...new Set([\n ...edge.blockingObstacleIndexes,\n ...this.prepared.exactRotatedObstacleIndexes,\n ]),\n ];\n for (const obstacleIndex of obstacleIndexes) {\n const obstacle = this.prepared.input.obstacles[obstacleIndex]!;\n const clearance = Math.max(\n this.prepared.options.gridClearance,\n this.prepared.input.minTraceToPadEdgeClearance ?? 0,\n );\n if (\n !segmentIntersectsRectInterior(\n from,\n to,\n obstacleBounds(\n obstacle,\n width / 2 + clearance,\n shouldRespectObstacleRotationInGraph(\n this.prepared.input,\n obstacle,\n width / 2 + clearance,\n this.prepared.exactRotatedObstacleIndexes.includes(\n obstacleIndex,\n ) || this.prepared.options.respectObstacleRotationInGraph,\n this.prepared.exactRotatedObstacleIndexes.includes(obstacleIndex)\n ? Number.POSITIVE_INFINITY\n : this.prepared.options.gridPitch,\n ),\n ),\n )\n ) {\n continue;\n }\n const prefabVia = this.prepared.prefabricatedVias.find(\n (via) => via.obstacleIndex === obstacleIndex,\n );\n if (\n prefabVia &&\n [from.prefabViaId, to.prefabViaId].includes(prefabVia.prefabViaId)\n ) {\n continue;\n }\n const allowedIdentifiers = [\n demand.connectionName,\n demand.netId,\n ...(demand.allowedConnectionNames ?? []),\n demand.sourcePointId,\n demand.targetPointId,\n ].filter((identifier): identifier is string => Boolean(identifier));\n if (\n allowedIdentifiers.some((identifier) =>\n obstacle.connectedTo.includes(identifier),\n )\n ) {\n continue;\n }\n return false;\n }\n return true;\n }\n\n private getNominalObstaclePenaltyCached(\n search: ActiveSearch,\n edgeId: number,\n ) {\n const demand = search.demand;\n const nominalWidth = demand.nominalWidth ?? demand.width;\n const cache = search.nominalObstaclePenaltyCache!;\n let penalty = cache[edgeId]!;\n if (!Number.isNaN(penalty)) return penalty;\n const edge = this.prepared.edges[edgeId]!;\n penalty = this.computeEdgeAllowsDemandAtWidth(edge, demand, nominalWidth)\n ? 0\n : edge.cost *\n this.prepared.options.historyIncrement *\n NOMINAL_OBSTACLE_PENALTY_MULTIPLIER;\n cache[edgeId] = penalty;\n return penalty;\n }\n\n private getByteCache(\n caches: WeakMap<RouteDemand, Uint8Array>,\n demand: RouteDemand,\n ) {\n let cache = caches.get(demand);\n if (!cache) {\n cache = new Uint8Array(this.prepared.edges.length);\n caches.set(demand, cache);\n }\n return cache;\n }\n\n private getPenaltyCache(\n caches: WeakMap<RouteDemand, Float64Array>,\n demand: RouteDemand,\n ) {\n let cache = caches.get(demand);\n if (!cache) {\n cache = new Float64Array(this.prepared.edges.length).fill(Number.NaN);\n caches.set(demand, cache);\n }\n return cache;\n }\n\n private getConflictDistances(edge: Extract<RoutingEdge, { kind: \"trace\" }>) {\n let distances = this.conflictDistancesByEdge.get(edge.edgeId);\n if (distances) return distances;\n const from = this.prepared.nodes[edge.fromNode]!;\n const to = this.prepared.nodes[edge.toNode]!;\n distances = new Float64Array(edge.conflictEdgeIds.length);\n for (let index = 0; index < edge.conflictEdgeIds.length; index++) {\n const candidateEdge = this.prepared.edges[edge.conflictEdgeIds[index]!]!;\n distances[index] = segmentDistance(\n from,\n to,\n this.prepared.nodes[candidateEdge.fromNode]!,\n this.prepared.nodes[candidateEdge.toNode]!,\n );\n }\n this.conflictDistancesByEdge.set(edge.edgeId, distances);\n return distances;\n }\n\n private getForeignOwners(edge: RoutingEdge, demand: RouteDemand) {\n if (this.foreignOwnersCacheVersion !== this.ownershipVersion) {\n this.foreignOwnersCache.clear();\n this.foreignOwnersCacheVersion = this.ownershipVersion;\n }\n let demandKey = this.foreignOwnersKeyByDemand.get(demand);\n if (demandKey === undefined) {\n demandKey = `${demand.netId} ${demand.width}`;\n this.foreignOwnersKeyByDemand.set(demand, demandKey);\n }\n let byDemandKey = this.foreignOwnersCache.get(edge.edgeId);\n const cached = byDemandKey?.get(demandKey);\n if (cached) return cached;\n const ownerRouteIds = new Set<string>();\n const addForeign = (routeIds: Iterable<string> | undefined) => {\n for (const routeId of routeIds ?? []) {\n const ownerDemand = this.prepared.demandById.get(routeId);\n if (!ownerDemand || ownerDemand.netId === demand.netId) continue;\n ownerRouteIds.add(routeId);\n }\n };\n addForeign(this.nodeOwners.get(edge.fromNode));\n addForeign(this.nodeOwners.get(edge.toNode));\n if (edge.kind === \"trace\") {\n addForeign(this.edgeOwners.get(edge.edgeId));\n const occupancy = this.occupancyByEdge.get(edge.edgeId);\n if (occupancy) {\n for (const [routeId, distances] of occupancy) {\n if (ownerRouteIds.has(routeId)) continue;\n const ownerDemand = this.prepared.demandById.get(routeId);\n if (!ownerDemand || ownerDemand.netId === demand.netId) continue;\n const minimumCenterDistance =\n demand.width / 2 + ownerDemand.width / 2 + this.effectiveClearance;\n for (const distance of distances) {\n if (distance < minimumCenterDistance - 1e-7) {\n ownerRouteIds.add(routeId);\n break;\n }\n }\n }\n }\n }\n const result = [...ownerRouteIds].sort();\n if (!byDemandKey) {\n byDemandKey = new Map();\n this.foreignOwnersCache.set(edge.edgeId, byDemandKey);\n }\n byDemandKey.set(demandKey, result);\n return result;\n }\n\n private commitGoal(search: ActiveSearch, goalIndex: number) {\n const goal = search.nodes[goalIndex]!;\n const shouldRipImmediately =\n this.totalRipCount < this.prepared.demands.length * 2;\n if (\n shouldRipImmediately &&\n this.totalRipCount + goal.blockers.length >\n this.prepared.options.maxTotalRips\n ) {\n this.fail(\n `Total rip limit (${this.prepared.options.maxTotalRips}) reached`,\n );\n return;\n }\n for (const blockerRouteId of shouldRipImmediately ? goal.blockers : []) {\n const blockerRoute = this.committed.get(blockerRouteId);\n for (const edgeId of blockerRoute?.edgePath ?? []) {\n this.historyCostByEdge[edgeId]! +=\n this.prepared.options.historyIncrement;\n }\n for (const nodeIndex of blockerRoute?.nodePath ?? []) {\n this.historyCostByNode[nodeIndex]! +=\n this.prepared.options.historyIncrement;\n }\n }\n const invalidatedRouteIds = this.uncommitRouteClosure(\n shouldRipImmediately ? goal.blockers : [],\n );\n if (this.failed) return;\n for (const routeId of invalidatedRouteIds) {\n this.queueDemand(routeId);\n }\n\n const nodePath: number[] = [];\n const edgePath: number[] = [];\n for (\n let cursor = goalIndex;\n cursor >= 0;\n cursor = search.nodes[cursor]!.parentIndex\n ) {\n const node = search.nodes[cursor]!;\n nodePath.push(node.graphNode);\n if (node.edgeFromParent !== null) edgePath.push(node.edgeFromParent);\n }\n nodePath.reverse();\n edgePath.reverse();\n const route: RoutedConnection = {\n routeId: search.demand.routeId,\n connectionName: search.demand.connectionName,\n netId: search.demand.netId,\n nodePath,\n edgePath,\n blockerRouteIds: goal.blockers,\n };\n const dependencies = new Set<string>();\n if (nodePath.length === 1) {\n for (const committedRoute of this.committed.values()) {\n if (committedRoute.netId === route.netId) {\n dependencies.add(committedRoute.routeId);\n }\n }\n } else {\n for (const ownerRouteId of this.nodeOwners.get(goal.graphNode) ?? []) {\n if (this.committed.get(ownerRouteId)?.netId === route.netId) {\n dependencies.add(ownerRouteId);\n }\n }\n }\n this.committed.set(route.routeId, route);\n this.routeDependenciesByRoute.set(route.routeId, dependencies);\n const ownedNodeCounts =\n this.ownedNodeCountByNet.get(route.netId) ?? new Map<number, number>();\n this.ownedNodeCountByNet.set(route.netId, ownedNodeCounts);\n for (const nodeIndex of nodePath) {\n const owners = this.nodeOwners.get(nodeIndex) ?? new Set<string>();\n owners.add(route.routeId);\n this.nodeOwners.set(nodeIndex, owners);\n ownedNodeCounts.set(nodeIndex, (ownedNodeCounts.get(nodeIndex) ?? 0) + 1);\n }\n for (const edgeId of edgePath) {\n const edge = this.prepared.edges[edgeId]!;\n if (edge.kind !== \"trace\") {\n this.committedFixedViaTransitionCount++;\n continue;\n }\n const owners = this.edgeOwners.get(edgeId) ?? new Set<string>();\n owners.add(route.routeId);\n this.edgeOwners.set(edgeId, owners);\n const conflictDistances = this.getConflictDistances(edge);\n for (let index = 0; index < edge.conflictEdgeIds.length; index++) {\n const conflictEdgeId = edge.conflictEdgeIds[index]!;\n let occupancy = this.occupancyByEdge.get(conflictEdgeId);\n if (!occupancy) {\n occupancy = new Map();\n this.occupancyByEdge.set(conflictEdgeId, occupancy);\n }\n let distances = occupancy.get(route.routeId);\n if (!distances) {\n distances = [];\n occupancy.set(route.routeId, distances);\n }\n distances.push(conflictDistances[index]!);\n }\n }\n this.ownershipVersion++;\n this.activeSearch = null;\n }\n\n private uncommitRoute(routeId: string) {\n const route = this.committed.get(routeId);\n if (!route) return;\n for (const edgeId of route.edgePath) {\n const edge = this.prepared.edges[edgeId]!;\n if (edge.kind !== \"trace\") {\n this.committedFixedViaTransitionCount--;\n continue;\n }\n const owners = this.edgeOwners.get(edgeId);\n owners?.delete(routeId);\n if (owners?.size === 0) this.edgeOwners.delete(edgeId);\n for (const conflictEdgeId of edge.conflictEdgeIds) {\n const occupancy = this.occupancyByEdge.get(conflictEdgeId);\n const distances = occupancy?.get(routeId);\n if (!distances) continue;\n if (distances.length <= 1) {\n occupancy!.delete(routeId);\n if (occupancy!.size === 0)\n this.occupancyByEdge.delete(conflictEdgeId);\n } else {\n distances.pop();\n }\n }\n }\n const ownedNodeCounts = this.ownedNodeCountByNet.get(route.netId);\n for (const nodeIndex of route.nodePath) {\n const owners = this.nodeOwners.get(nodeIndex);\n owners?.delete(routeId);\n if (owners?.size === 0) this.nodeOwners.delete(nodeIndex);\n const count = ownedNodeCounts?.get(nodeIndex);\n if (count !== undefined) {\n if (count <= 1) ownedNodeCounts!.delete(nodeIndex);\n else ownedNodeCounts!.set(nodeIndex, count - 1);\n }\n }\n this.ownershipVersion++;\n this.committed.delete(routeId);\n this.routeDependenciesByRoute.delete(routeId);\n this.ripCountByRoute.set(\n routeId,\n (this.ripCountByRoute.get(routeId) ?? 0) + 1,\n );\n this.totalRipCount++;\n if (this.totalRipCount > this.prepared.options.maxTotalRips) {\n this.fail(\n `Total rip limit (${this.prepared.options.maxTotalRips}) reached`,\n );\n }\n }\n\n private queueDemand(routeId: string) {\n const demand = this.prepared.demandById.get(routeId);\n if (\n !demand ||\n this.pending.some((candidate) => candidate.routeId === routeId) ||\n this.activeSearch?.demand.routeId === routeId\n ) {\n return;\n }\n this.pending.push(demand);\n }\n\n private uncommitRouteClosure(routeIds: Iterable<string>) {\n const invalidated = new Set(routeIds);\n let changed = true;\n while (changed) {\n changed = false;\n for (const [candidateRouteId, dependencies] of this\n .routeDependenciesByRoute) {\n if (invalidated.has(candidateRouteId)) continue;\n if ([...dependencies].some((routeId) => invalidated.has(routeId))) {\n invalidated.add(candidateRouteId);\n changed = true;\n }\n }\n }\n for (const routeId of invalidated) this.uncommitRoute(routeId);\n return invalidated;\n }\n\n private assignPrefabViaBridge(routeId: string, minimumViaX?: number) {\n if (\n this.requiredPrefabViaIdsByRoute.has(routeId) ||\n this.exhaustedPrefabViaBridgeRouteIds.has(routeId)\n ) {\n return;\n }\n const demand = this.prepared.demandById.get(routeId);\n if (!demand || this.prepared.prefabricatedVias.length < 2) return;\n const source = this.prepared.nodes[demand.sourceNode]!;\n const target = this.prepared.nodes[demand.targetNode]!;\n let best: { firstId: string; secondId: string; cost: number } | undefined;\n for (const first of this.prepared.prefabricatedVias) {\n if (minimumViaX !== undefined && first.x < minimumViaX) continue;\n const firstReservation = this.reservedPrefabViaOwnerById.get(\n first.prefabViaId,\n );\n if (firstReservation && firstReservation !== routeId) continue;\n for (const second of this.prepared.prefabricatedVias) {\n if (first.prefabViaId === second.prefabViaId) continue;\n if (minimumViaX !== undefined && second.x < minimumViaX) continue;\n const secondReservation = this.reservedPrefabViaOwnerById.get(\n second.prefabViaId,\n );\n if (secondReservation && secondReservation !== routeId) continue;\n const cost =\n pointDistance(source, first) +\n pointDistance(first, second) +\n pointDistance(second, target);\n if (!best || cost < best.cost) {\n best = {\n firstId: first.prefabViaId,\n secondId: second.prefabViaId,\n cost,\n };\n }\n }\n }\n if (!best) return;\n const requiredIds = [best.firstId, best.secondId];\n this.requiredPrefabViaIdsByRoute.set(routeId, requiredIds);\n for (const prefabViaId of requiredIds) {\n this.reservedPrefabViaOwnerById.set(prefabViaId, routeId);\n }\n }\n\n private releasePrefabViaBridge(routeId: string) {\n const requiredIds = this.requiredPrefabViaIdsByRoute.get(routeId);\n if (!requiredIds) return false;\n this.requiredPrefabViaIdsByRoute.delete(routeId);\n this.exhaustedPrefabViaBridgeRouteIds.add(routeId);\n for (const prefabViaId of requiredIds) {\n if (this.reservedPrefabViaOwnerById.get(prefabViaId) === routeId) {\n this.reservedPrefabViaOwnerById.delete(prefabViaId);\n }\n }\n return true;\n }\n\n private finishOrScheduleNegotiationPass() {\n const conflictComponents = this.getConflictComponents();\n this.lastConflictComponents = conflictComponents.map((component) => [\n ...component,\n ]);\n const allConflictingRouteIds = new Set(conflictComponents.flat());\n this.lastConflictRouteCount = allConflictingRouteIds.size;\n if (allConflictingRouteIds.size === 0) {\n const disconnectedDemands = this.getDisconnectedDemands().sort((a, b) =>\n a.routeId.localeCompare(b.routeId),\n );\n if (disconnectedDemands.length > 0) {\n const disconnectedNetIds = [\n ...new Set(disconnectedDemands.map((demand) => demand.netId)),\n ].sort();\n const repairKey = `connectivity:${disconnectedNetIds.join(\"|\")}`;\n const repairCount =\n (this.conflictComponentAttemptCount.get(repairKey) ?? 0) + 1;\n this.conflictComponentAttemptCount.set(repairKey, repairCount);\n if (repairCount > 4) {\n this.fail(\n `Atomic net rerouting repeatedly left ${disconnectedNetIds.join(\", \")} disconnected`,\n );\n return;\n }\n const invalidatedRouteIds = this.uncommitRouteClosure(\n this.prepared.demands\n .filter((demand) => disconnectedNetIds.includes(demand.netId))\n .map((demand) => demand.routeId),\n );\n if (this.failed) return;\n const repairDemands = this.prepared.demands.filter((demand) =>\n invalidatedRouteIds.has(demand.routeId),\n );\n for (const demand of repairDemands) {\n this.queueDemand(demand.routeId);\n }\n this.negotiationPassCount++;\n this.updateStats();\n return;\n }\n this.validateFinalRouting();\n this.solved = true;\n this.progress = 1;\n this.updateStats();\n return;\n }\n\n const conflictingRouteIds = new Set(allConflictingRouteIds);\n let forcedAlternateLayer = false;\n for (const component of conflictComponents) {\n if (allConflictingRouteIds.size > 8) {\n continue;\n }\n const componentKey = component.join(\"|\");\n const attemptCount =\n (this.conflictComponentAttemptCount.get(componentKey) ?? 0) + 1;\n this.conflictComponentAttemptCount.set(componentKey, attemptCount);\n if (component.length < 2 || component.length > 2 || attemptCount < 3) {\n continue;\n }\n if (forcedAlternateLayer) continue;\n const conflictLayer = component.flatMap((routeId) => {\n const route = this.committed.get(routeId);\n const demand = this.prepared.demandById.get(routeId);\n if (!route || !demand) return [];\n for (const edgeId of route.edgePath) {\n const edge = this.prepared.edges[edgeId]!;\n if (\n edge.kind === \"trace\" &&\n this.getForeignOwners(edge, demand).some((foreignRouteId) =>\n component.includes(foreignRouteId),\n )\n ) {\n return [this.prepared.nodes[edge.fromNode]!.layer];\n }\n }\n return [];\n })[0];\n const alternateLayer = this.prepared.layers.find(\n (layer) => layer !== conflictLayer,\n );\n if (!conflictLayer || !alternateLayer) continue;\n const shiftedDemand = component\n .map((routeId) => this.prepared.demandById.get(routeId))\n .filter((demand): demand is RouteDemand => Boolean(demand))\n .filter(\n (demand) =>\n !demand.routeId.startsWith(\"connectivity-repair:\") &&\n !this.forcedGuideConnectionNames.has(demand.connectionName) &&\n this.preferredLayerByRoute.get(demand.routeId) !== alternateLayer,\n )\n .sort((left, right) => {\n const leftDistance = pointDistance(\n this.prepared.nodes[left.sourceNode]!,\n this.prepared.nodes[left.targetNode]!,\n );\n const rightDistance = pointDistance(\n this.prepared.nodes[right.sourceNode]!,\n this.prepared.nodes[right.targetNode]!,\n );\n return (\n rightDistance - leftDistance ||\n left.routeId.localeCompare(right.routeId)\n );\n })[0];\n if (!shiftedDemand) continue;\n this.preferredLayerByRoute.set(shiftedDemand.routeId, alternateLayer);\n const penalties =\n this.layerPenaltyByRoute.get(shiftedDemand.routeId) ??\n new Map<string, number>();\n penalties.set(\n conflictLayer,\n (penalties.get(conflictLayer) ?? 0) +\n this.prepared.options.historyIncrement * 10,\n );\n this.layerPenaltyByRoute.set(shiftedDemand.routeId, penalties);\n forcedAlternateLayer = true;\n }\n if (conflictingRouteIds.size <= 4) {\n for (const routeId of conflictingRouteIds) {\n const connectionName =\n this.prepared.demandById.get(routeId)?.connectionName;\n if (\n connectionName &&\n this.requiredGuideCountByConnectionName.has(connectionName)\n ) {\n this.forcedGuideConnectionNames.add(connectionName);\n }\n }\n }\n this.negotiationPassCount++;\n for (const routeId of conflictingRouteIds) {\n const route = this.committed.get(routeId);\n for (const edgeId of route?.edgePath ?? []) {\n const edge = this.prepared.edges[edgeId]!;\n const demand = this.prepared.demandById.get(routeId)!;\n if (this.getForeignOwners(edge, demand).length === 0) continue;\n for (const congestedEdgeId of [\n edgeId,\n ...(edge.kind === \"trace\" ? edge.conflictEdgeIds : []),\n ]) {\n this.historyCostByEdge[congestedEdgeId]! +=\n this.prepared.options.historyIncrement;\n }\n for (const nodeIndex of [edge.fromNode, edge.toNode]) {\n this.historyCostByNode[nodeIndex]! +=\n this.prepared.options.historyIncrement;\n }\n }\n }\n // Treat disconnected compact components independently. The RP2040 case\n // can have several unrelated two-route conflicts at once; gating this on\n // the global conflict count prevents any component from breaking its\n // local symmetry.\n for (const component of conflictComponents) {\n if (component.length <= 4) {\n this.updateRouteLayerPenalties(new Set(component));\n }\n }\n const routeIdsToReroute = this.uncommitRouteClosure(conflictingRouteIds);\n if (this.failed) return;\n const rerouteDemands = this.groupDemandsByNet(\n [...routeIdsToReroute]\n .map((routeId) => this.prepared.demandById.get(routeId))\n .filter((demand): demand is RouteDemand => Boolean(demand))\n .sort(\n (left, right) =>\n deterministicOrderKey(left.routeId, this.negotiationPassCount) -\n deterministicOrderKey(right.routeId, this.negotiationPassCount) ||\n left.routeId.localeCompare(right.routeId),\n ),\n );\n\n if (rerouteDemands.length === 0) {\n this.fail(\n `Negotiated routing stalled with ${conflictingRouteIds.size} conflicting routes`,\n );\n return;\n }\n for (const demand of rerouteDemands) this.queueDemand(demand.routeId);\n this.updateStats();\n }\n\n private updateRouteLayerPenalties(routeFilter?: Set<string>) {\n const routesToShift = new Set<string>();\n const handledPairs = new Set<string>();\n for (const route of this.committed.values()) {\n if (routeFilter && !routeFilter.has(route.routeId)) continue;\n const demand = this.prepared.demandById.get(route.routeId);\n if (!demand) continue;\n for (const edgeId of route.edgePath) {\n const edge = this.prepared.edges[edgeId]!;\n if (edge.kind !== \"trace\") continue;\n const layer = this.prepared.nodes[edge.fromNode]!.layer;\n for (const foreignRouteId of this.getForeignOwners(edge, demand)) {\n if (routeFilter && !routeFilter.has(foreignRouteId)) continue;\n const routeIds = [route.routeId, foreignRouteId].sort();\n const pairKey = `${routeIds[0]}:${routeIds[1]}:${layer}`;\n if (handledPairs.has(pairKey)) continue;\n handledPairs.add(pairKey);\n const candidates = routeIds\n .map((routeId) => ({\n routeId,\n demand: this.prepared.demandById.get(routeId),\n }))\n .sort((left, right) => {\n const shiftRank = (\n routeId: string,\n demand: RouteDemand | undefined,\n ) => {\n if (demand && demand.connectionTerminalCount > 2) return 4;\n const preferredLayer = this.preferredLayerByRoute.get(routeId);\n if (preferredLayer && preferredLayer !== layer) return 3;\n if (!preferredLayer && demand?.connectionTerminalCount === 2)\n return 2;\n return preferredLayer ? 0 : 1;\n };\n return (\n shiftRank(right.routeId, right.demand) -\n shiftRank(left.routeId, left.demand) ||\n (left.demand && right.demand\n ? pointDistance(\n this.prepared.nodes[left.demand.sourceNode]!,\n this.prepared.nodes[left.demand.targetNode]!,\n ) -\n pointDistance(\n this.prepared.nodes[right.demand.sourceNode]!,\n this.prepared.nodes[right.demand.targetNode]!,\n )\n : 0) ||\n right.routeId.localeCompare(left.routeId)\n );\n });\n const routeToShift = candidates[0]!.routeId;\n routesToShift.add(routeToShift);\n const otherRouteId = routeIds.find(\n (routeId) => routeId !== routeToShift,\n )!;\n const selectedRoute = this.committed.get(routeToShift);\n const selectedDemand = this.prepared.demandById.get(routeToShift);\n const routeEdgeHistory =\n this.historyCostByRouteEdge.get(routeToShift) ??\n new Map<number, number>();\n if (selectedRoute && selectedDemand) {\n for (const selectedEdgeId of selectedRoute.edgePath) {\n const selectedEdge = this.prepared.edges[selectedEdgeId]!;\n if (\n selectedEdge.kind !== \"trace\" ||\n !this.getForeignOwners(selectedEdge, selectedDemand).includes(\n otherRouteId,\n )\n ) {\n continue;\n }\n routeEdgeHistory.set(\n selectedEdgeId,\n (routeEdgeHistory.get(selectedEdgeId) ?? 0) +\n this.prepared.options.historyIncrement * 4,\n );\n }\n this.historyCostByRouteEdge.set(routeToShift, routeEdgeHistory);\n }\n if (this.preferredLayerByRoute.get(routeToShift) === layer) {\n continue;\n }\n const penalties =\n this.layerPenaltyByRoute.get(routeToShift) ??\n new Map<string, number>();\n penalties.set(\n layer,\n (penalties.get(layer) ?? 0) +\n this.prepared.options.historyIncrement,\n );\n this.layerPenaltyByRoute.set(routeToShift, penalties);\n }\n }\n }\n return routesToShift;\n }\n\n private getConflictComponents() {\n const adjacency = new Map<string, Set<string>>();\n const addPair = (left: string, right: string) => {\n const leftNeighbors = adjacency.get(left) ?? new Set<string>();\n leftNeighbors.add(right);\n adjacency.set(left, leftNeighbors);\n const rightNeighbors = adjacency.get(right) ?? new Set<string>();\n rightNeighbors.add(left);\n adjacency.set(right, rightNeighbors);\n };\n for (const route of this.committed.values()) {\n for (const edgeId of route.edgePath) {\n const edge = this.prepared.edges[edgeId]!;\n const demand = this.prepared.demandById.get(route.routeId)!;\n const foreignOwners = this.getForeignOwners(edge, demand);\n for (const foreignOwner of foreignOwners) {\n addPair(route.routeId, foreignOwner);\n }\n }\n }\n const visited = new Set<string>();\n const components: string[][] = [];\n for (const routeId of [...adjacency.keys()].sort()) {\n if (visited.has(routeId)) continue;\n const component: string[] = [];\n const pending = [routeId];\n visited.add(routeId);\n while (pending.length > 0) {\n const current = pending.pop()!;\n component.push(current);\n for (const neighbor of adjacency.get(current) ?? []) {\n if (visited.has(neighbor)) continue;\n visited.add(neighbor);\n pending.push(neighbor);\n }\n }\n components.push(component.sort());\n }\n return components;\n }\n\n private validateFinalRouting() {\n const missingDemand = this.prepared.demands.find(\n (demand) => !this.committed.has(demand.routeId),\n );\n if (missingDemand) {\n throw new Error(\n `Missing routed demand \"${missingDemand.routeId}\" from final solution`,\n );\n }\n this.validateNetConnectivity();\n for (const route of this.committed.values()) {\n for (const edgeId of route.edgePath) {\n const edge = this.prepared.edges[edgeId]!;\n if (edge.kind !== \"fixed_via_transition\") continue;\n const via = this.prepared.fixedViaById.get(edge.prefabViaId);\n if (!via) {\n throw new Error(\n `Route \"${route.routeId}\" uses unknown via \"${edge.prefabViaId}\"`,\n );\n }\n const from = this.prepared.nodes[edge.fromNode]!;\n const to = this.prepared.nodes[edge.toNode]!;\n if (\n from.x !== via.x ||\n from.y !== via.y ||\n to.x !== via.x ||\n to.y !== via.y\n ) {\n throw new Error(\n `Layer transition for \"${route.routeId}\" is not centered on its prefabricated via`,\n );\n }\n }\n }\n const routes = [...this.committed.values()];\n for (let firstIndex = 0; firstIndex < routes.length; firstIndex++) {\n for (\n let secondIndex = firstIndex + 1;\n secondIndex < routes.length;\n secondIndex++\n ) {\n const first = routes[firstIndex]!;\n const second = routes[secondIndex]!;\n if (first.netId === second.netId) continue;\n const firstDemand = this.prepared.demandById.get(first.routeId)!;\n const secondDemand = this.prepared.demandById.get(second.routeId)!;\n const clearance = Math.max(\n this.prepared.options.gridClearance,\n this.prepared.input.minTraceToPadEdgeClearance ?? 0,\n );\n const minimumCenterDistance =\n firstDemand.width / 2 + secondDemand.width / 2 + clearance;\n const secondTraceEdges = new Set(\n second.edgePath.filter(\n (edgeId) => this.prepared.edges[edgeId]!.kind === \"trace\",\n ),\n );\n for (const firstEdgeId of first.edgePath) {\n const firstEdge = this.prepared.edges[firstEdgeId]!;\n if (firstEdge.kind !== \"trace\") continue;\n if (\n firstEdge.conflictEdgeIds.some((edgeId) => {\n if (!secondTraceEdges.has(edgeId)) return false;\n const secondEdge = this.prepared.edges[edgeId]!;\n if (secondEdge.kind !== \"trace\") return false;\n return (\n segmentDistance(\n this.prepared.nodes[firstEdge.fromNode]!,\n this.prepared.nodes[firstEdge.toNode]!,\n this.prepared.nodes[secondEdge.fromNode]!,\n this.prepared.nodes[secondEdge.toNode]!,\n ) <\n minimumCenterDistance - 1e-7\n );\n })\n ) {\n throw new Error(\n `Final routes \"${first.routeId}\" and \"${second.routeId}\" violate trace clearance`,\n );\n }\n }\n }\n }\n }\n\n private validateNetConnectivity() {\n const disconnectedDemand = this.getDisconnectedDemands()[0];\n if (!disconnectedDemand) return;\n throw new Error(\n `Final net \"${disconnectedDemand.netId}\" is disconnected between \"${disconnectedDemand.sourcePointId ?? disconnectedDemand.sourceNode}\" and \"${disconnectedDemand.targetPointId ?? disconnectedDemand.targetNode}\"`,\n );\n }\n\n private getDisconnectedDemands() {\n const parentByNet = new Map<string, Map<number, number>>();\n const getParent = (netId: string) => {\n const parent = parentByNet.get(netId) ?? new Map<number, number>();\n parentByNet.set(netId, parent);\n return parent;\n };\n const find = (parent: Map<number, number>, node: number): number => {\n const currentParent = parent.get(node) ?? node;\n parent.set(node, currentParent);\n if (currentParent === node) return node;\n const root = find(parent, currentParent);\n parent.set(node, root);\n return root;\n };\n const union = (netId: string, leftNode: number, rightNode: number) => {\n const parent = getParent(netId);\n const leftRoot = find(parent, leftNode);\n const rightRoot = find(parent, rightNode);\n if (leftRoot !== rightRoot) parent.set(rightRoot, leftRoot);\n };\n for (const route of this.committed.values()) {\n const parent = getParent(route.netId);\n for (let index = 0; index < route.nodePath.length; index++) {\n const node = route.nodePath[index]!;\n find(parent, node);\n if (index === 0) continue;\n const previous = route.nodePath[index - 1]!;\n union(route.netId, previous, node);\n }\n }\n\n // The sparse visibility graph deliberately omits the Cartesian product of\n // every feature-aligned X and Y coordinate. Consequently, two same-net\n // traces can cross between graph nodes even though the emitted copper is\n // physically connected. Treat exact same-layer segment intersections as\n // connectivity; nearby parallel traces still remain separate.\n for (const route of this.committed.values()) {\n for (const edgeId of route.edgePath) {\n const edge = this.prepared.edges[edgeId]!;\n if (edge.kind !== \"trace\") continue;\n const from = this.prepared.nodes[edge.fromNode]!;\n const to = this.prepared.nodes[edge.toNode]!;\n for (const candidateEdgeId of edge.conflictEdgeIds) {\n const candidateEdge = this.prepared.edges[candidateEdgeId]!;\n if (candidateEdge.kind !== \"trace\") continue;\n const candidateFrom = this.prepared.nodes[candidateEdge.fromNode]!;\n const candidateTo = this.prepared.nodes[candidateEdge.toNode]!;\n if (\n from.layer !== candidateFrom.layer ||\n segmentDistance(from, to, candidateFrom, candidateTo) > 1e-7\n ) {\n continue;\n }\n for (const candidateRouteId of this.edgeOwners.get(candidateEdgeId) ??\n []) {\n const candidateRoute = this.committed.get(candidateRouteId);\n if (candidateRoute?.netId !== route.netId) continue;\n union(route.netId, edge.fromNode, candidateEdge.fromNode);\n }\n }\n }\n }\n return this.prepared.demands.filter((demand) => {\n const parent = getParent(demand.netId);\n return (\n find(parent, demand.sourceNode) !== find(parent, demand.targetNode)\n );\n });\n }\n\n private fail(message: string) {\n this.error = message;\n this.failed = true;\n this.activeSearch = null;\n }\n\n private getStats(): BiscuitBoardRoutingStats {\n const fixedViaTransitionCount = this.committedFixedViaTransitionCount;\n return {\n routeCount: this.prepared.demandById.size,\n routedCount: this.committed.size,\n pendingCount: this.pending.length + (this.activeSearch ? 1 : 0),\n ripCount: this.totalRipCount,\n expandedStateCount: this.totalExpandedStateCount,\n fixedViaTransitionCount,\n graphNodeCount: this.prepared.nodes.length,\n graphEdgeCount: this.prepared.edges.length,\n negotiationPassCount: this.negotiationPassCount,\n conflictRouteCount: this.lastConflictRouteCount,\n adaptivePriorityChangeCount: this.adaptivePriorityChangeCount,\n };\n }\n\n private updateStats() {\n this.stats = {\n ...this.getStats(),\n activeRouteId: this.activeSearch?.demand.routeId ?? null,\n activeExpandedStateCount: this.activeSearch?.expanded ?? 0,\n };\n }\n\n override getOutput(): BiscuitBoardRoutingSolution {\n return {\n routes: [...this.committed.values()].sort((left, right) =>\n left.routeId.localeCompare(right.routeId),\n ),\n traces: [],\n stats: this.getStats(),\n };\n }\n\n override visualize(): GraphicsObject {\n const graphics = visualizePreparedProblem(\n this.prepared,\n this.committed.values(),\n );\n const conflictLines: NonNullable<GraphicsObject[\"lines\"]> = [];\n for (const route of this.committed.values()) {\n const demand = this.prepared.demandById.get(route.routeId);\n if (!demand) continue;\n for (const edgeId of route.edgePath) {\n const edge = this.prepared.edges[edgeId]!;\n if (\n edge.kind !== \"trace\" ||\n this.getForeignOwners(edge, demand).length === 0\n ) {\n continue;\n }\n conflictLines.push({\n points: [\n this.prepared.nodes[edge.fromNode]!,\n this.prepared.nodes[edge.toNode]!,\n ],\n strokeColor: \"#dc2626\",\n strokeWidth: Math.max(0.26, demand.width + 0.08),\n label: `clearance conflict · ${route.routeId}`,\n });\n }\n }\n return {\n ...graphics,\n title: `Rip-and-replace fixed-via router (${this.committed.size}/${this.prepared.demandById.size}, ${this.totalRipCount} rips, ${conflictLines.length} conflict edges)`,\n lines: [...(graphics.lines ?? []), ...conflictLines],\n };\n }\n\n override preview() {\n return this.visualize();\n }\n}\n","import type { SimpleRouteJson, SimplifiedPcbTrace } from \"@tscircuit/core\";\nimport { ConnectionNameResolver } from \"@tscircuit/power-trace-expander\";\nimport { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { BuildBiscuitBoardTracesSolver } from \"./build-biscuit-board-traces-solver\";\nimport {\n netColor,\n obstacleBounds,\n pointsEqual,\n segmentDistance,\n segmentIntersectsRectInterior,\n segmentToObstacleDistance,\n} from \"./geometry\";\nimport { RipUpRubberBandSolver } from \"./rip-up-rubber-band-solver\";\nimport type {\n BiscuitBoardRoutingSolution,\n Point,\n PreparedBiscuitRoutingProblem,\n RouteDemand,\n RoutedConnection,\n} from \"./types\";\n\ntype RoutePoint = SimplifiedPcbTrace[\"route\"][number];\ntype WirePoint = Extract<RoutePoint, { route_type: \"wire\" }>;\n\ninterface TraceContext {\n demand: RouteDemand;\n route: RoutedConnection;\n trace: SimplifiedPcbTrace;\n}\n\nexport interface TraceSegment {\n start: WirePoint;\n end: WirePoint;\n}\n\ninterface BoundedTraceSegment extends TraceSegment {\n minX: number;\n minY: number;\n maxX: number;\n maxY: number;\n}\n\nconst withSegmentBounds = (segment: TraceSegment): BoundedTraceSegment => ({\n ...segment,\n minX: Math.min(segment.start.x, segment.end.x),\n minY: Math.min(segment.start.y, segment.end.y),\n maxX: Math.max(segment.start.x, segment.end.x),\n maxY: Math.max(segment.start.y, segment.end.y),\n});\n\nconst axisGap = (\n firstMin: number,\n firstMax: number,\n secondMin: number,\n secondMax: number,\n) => Math.max(firstMin - secondMax, secondMin - firstMax, 0);\n\nconst obstacleHasPcbViaId = (obstacle: SimpleRouteJson[\"obstacles\"][number]) =>\n obstacle.connectedTo.some((id) => id.startsWith(\"pcb_via\"));\n\nconst traceTraversesObstacle = (\n trace: SimplifiedPcbTrace,\n obstacle: SimpleRouteJson[\"obstacles\"][number],\n) =>\n trace.route.some(\n (point) =>\n point.route_type === \"through_obstacle\" &&\n pointsEqual(point.start, obstacle.center) &&\n pointsEqual(point.end, obstacle.center),\n );\n\nexport interface TraceClearanceViolation {\n kind: \"obstacle\" | \"trace\";\n traceId: string;\n otherId: string;\n message: string;\n obstacleIndex?: number;\n}\n\nconst EPSILON = 1e-7;\nconst junctionKey = (point: { x: number; y: number; layer: string }) =>\n `${point.layer}:${point.x.toFixed(6)}:${point.y.toFixed(6)}`;\n\nexport const getEffectiveTraceClearance = (\n prepared: PreparedBiscuitRoutingProblem,\n) =>\n Math.max(\n prepared.options.gridClearance,\n prepared.input.minTraceToPadEdgeClearance ?? 0,\n );\n\nconst getTraceContexts = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n): TraceContext[] => {\n if (solution.routes.length !== solution.traces.length) {\n throw new Error(\n `Expected one trace per routed demand, got ${solution.routes.length} routes and ${solution.traces.length} traces`,\n );\n }\n return solution.routes.map((route, index) => {\n const demand = prepared.demandById.get(route.routeId);\n if (!demand) throw new Error(`Missing demand for route \"${route.routeId}\"`);\n return { demand, route, trace: solution.traces[index]! };\n });\n};\n\nconst getSegments = (trace: SimplifiedPcbTrace): TraceSegment[] => {\n const segments: TraceSegment[] = [];\n for (let index = 1; index < trace.route.length; index++) {\n const start = trace.route[index - 1]!;\n const end = trace.route[index]!;\n if (\n start.route_type === \"wire\" &&\n end.route_type === \"wire\" &&\n start.layer === end.layer &&\n !pointsEqual(start, end)\n ) {\n segments.push({ start, end });\n }\n }\n return segments;\n};\n\nconst obstacleAllowsSegment = (\n prepared: PreparedBiscuitRoutingProblem,\n context: TraceContext,\n obstacleIndex: number,\n segment: TraceSegment,\n connectionNameResolver: ConnectionNameResolver,\n allowAllSameNetCopper = false,\n) => {\n const obstacle = prepared.input.obstacles[obstacleIndex]!;\n const prefabViaId = obstacle.connectedTo.find((identifier) =>\n identifier.startsWith(\"pcb_via\"),\n );\n const identifiers = [\n context.demand.connectionName,\n context.demand.netId,\n context.demand.sourcePointId,\n context.demand.targetPointId,\n ].filter((identifier): identifier is string => Boolean(identifier));\n if (\n identifiers.some((identifier) => obstacle.connectedTo.includes(identifier))\n ) {\n return true;\n }\n if (allowAllSameNetCopper) {\n const canonicalIdentifiers = new Set(\n connectionNameResolver.canonicalize([\n ...identifiers,\n ...(context.demand.allowedConnectionNames ?? []),\n context.trace.connection_name ?? \"\",\n ...(context.trace.connectsTo ?? []),\n ]),\n );\n if (\n connectionNameResolver\n .canonicalize(obstacle.connectedTo)\n .some((identifier) => canonicalIdentifiers.has(identifier))\n ) {\n return true;\n }\n }\n return (\n obstacle.netIsAssignable === true &&\n Boolean(prefabViaId) &&\n (traceTraversesObstacle(context.trace, obstacle) ||\n context.trace.connectsTo?.includes(prefabViaId!)) &&\n (pointsEqual(segment.start, obstacle.center) ||\n pointsEqual(segment.end, obstacle.center))\n );\n};\n\nexport const getTraceClearanceViolations = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n clearance = getEffectiveTraceClearance(prepared),\n respectObstacleRotation = true,\n): TraceClearanceViolation[] => {\n const contexts = getTraceContexts(prepared, solution);\n const connectionNameResolver = new ConnectionNameResolver(\n prepared.input,\n solution.traces,\n );\n const segmentsByTrace = contexts.map((context) =>\n getSegments(context.trace).map(withSegmentBounds),\n );\n const violations: TraceClearanceViolation[] = [];\n\n for (const [contextIndex, context] of contexts.entries()) {\n for (const segment of segmentsByTrace[contextIndex]!) {\n for (const [\n obstacleIndex,\n obstacle,\n ] of prepared.input.obstacles.entries()) {\n if (\n obstacle.isCopperPour ||\n !obstacle.layers.includes(segment.start.layer)\n ) {\n continue;\n }\n const minimumDistance = segment.start.width / 2 + clearance - EPSILON;\n if (\n segmentToObstacleDistance(\n segment.start,\n segment.end,\n obstacle,\n respectObstacleRotation,\n ) >= minimumDistance ||\n obstacleAllowsSegment(\n prepared,\n context,\n obstacleIndex,\n segment,\n connectionNameResolver,\n true,\n )\n ) {\n continue;\n }\n violations.push({\n kind: \"obstacle\",\n traceId: context.trace.pcb_trace_id,\n obstacleIndex,\n otherId:\n obstacle.obstacleId ??\n obstacle.componentId ??\n `obstacle-${obstacleIndex}`,\n message: `Trace \"${context.route.routeId}\" is within ${clearance}mm of obstacle ${obstacleIndex}`,\n });\n }\n }\n }\n\n for (let firstIndex = 0; firstIndex < contexts.length; firstIndex++) {\n const first = contexts[firstIndex]!;\n for (\n let secondIndex = firstIndex + 1;\n secondIndex < contexts.length;\n secondIndex++\n ) {\n const second = contexts[secondIndex]!;\n if (first.demand.netId === second.demand.netId) continue;\n for (const firstSegment of segmentsByTrace[firstIndex]!) {\n for (const secondSegment of segmentsByTrace[secondIndex]!) {\n if (firstSegment.start.layer !== secondSegment.start.layer) continue;\n const minimumCenterDistance =\n firstSegment.start.width / 2 +\n secondSegment.start.width / 2 +\n clearance;\n const violationDistance = minimumCenterDistance - EPSILON;\n if (\n axisGap(\n firstSegment.minX,\n firstSegment.maxX,\n secondSegment.minX,\n secondSegment.maxX,\n ) >= violationDistance ||\n axisGap(\n firstSegment.minY,\n firstSegment.maxY,\n secondSegment.minY,\n secondSegment.maxY,\n ) >= violationDistance\n ) {\n continue;\n }\n if (\n segmentDistance(\n firstSegment.start,\n firstSegment.end,\n secondSegment.start,\n secondSegment.end,\n ) < violationDistance\n ) {\n violations.push({\n kind: \"trace\",\n traceId: first.trace.pcb_trace_id,\n otherId: second.trace.pcb_trace_id,\n message: `Traces \"${first.route.routeId}\" and \"${second.route.routeId}\" are closer than ${clearance}mm`,\n });\n }\n }\n }\n }\n }\n\n return violations;\n};\n\nexport const createSegmentClearanceChecker = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n traceIndex: number,\n clearance: number,\n respectObstacleRotation = true,\n) => {\n const contexts = getTraceContexts(prepared, solution);\n const connectionNameResolver = new ConnectionNameResolver(\n prepared.input,\n solution.traces,\n );\n const context = contexts[traceIndex]!;\n const blockingTraceSegments = contexts.flatMap((other, otherIndex) =>\n otherIndex === traceIndex || other.demand.netId === context.demand.netId\n ? []\n : getSegments(other.trace).map(withSegmentBounds),\n );\n\n return (segment: TraceSegment) => {\n for (const [\n obstacleIndex,\n obstacle,\n ] of prepared.input.obstacles.entries()) {\n if (\n obstacle.isCopperPour ||\n !obstacle.layers.includes(segment.start.layer)\n ) {\n continue;\n }\n const expandedBounds = obstacleBounds(\n obstacle,\n segment.start.width / 2 + clearance,\n respectObstacleRotation,\n );\n if (\n !segmentIntersectsRectInterior(\n segment.start,\n segment.end,\n expandedBounds,\n ) ||\n obstacleAllowsSegment(\n prepared,\n context,\n obstacleIndex,\n segment,\n connectionNameResolver,\n )\n ) {\n continue;\n }\n return false;\n }\n const segmentMinX = Math.min(segment.start.x, segment.end.x);\n const segmentMinY = Math.min(segment.start.y, segment.end.y);\n const segmentMaxX = Math.max(segment.start.x, segment.end.x);\n const segmentMaxY = Math.max(segment.start.y, segment.end.y);\n for (const otherSegment of blockingTraceSegments) {\n if (otherSegment.start.layer !== segment.start.layer) continue;\n const minimumCenterDistance =\n segment.start.width / 2 + otherSegment.start.width / 2 + clearance;\n const violationDistance = minimumCenterDistance - EPSILON;\n if (\n axisGap(\n segmentMinX,\n segmentMaxX,\n otherSegment.minX,\n otherSegment.maxX,\n ) >= violationDistance ||\n axisGap(\n segmentMinY,\n segmentMaxY,\n otherSegment.minY,\n otherSegment.maxY,\n ) >= violationDistance\n ) {\n continue;\n }\n if (\n segmentDistance(\n segment.start,\n segment.end,\n otherSegment.start,\n otherSegment.end,\n ) < violationDistance\n ) {\n return false;\n }\n }\n return true;\n };\n};\n\n/**\n * Checks a replacement route against every foreign-net trace and obstacle.\n * The trace being replaced is intentionally omitted from the comparison so\n * post-processing stages can evaluate candidates without mutating a solution.\n */\nexport const traceRouteHasClearance = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n traceIndex: number,\n route: SimplifiedPcbTrace[\"route\"],\n clearance = getEffectiveTraceClearance(prepared),\n) => {\n const segmentHasClearance = createSegmentClearanceChecker(\n prepared,\n solution,\n traceIndex,\n clearance,\n );\n return getSegments({ ...solution.traces[traceIndex]!, route }).every(\n segmentHasClearance,\n );\n};\n\nexport const traceSegmentsHaveClearance = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n traceIndex: number,\n segments: Array<{ start: WirePoint; end: WirePoint }>,\n clearance = getEffectiveTraceClearance(prepared),\n) => {\n const segmentHasClearance = createSegmentClearanceChecker(\n prepared,\n solution,\n traceIndex,\n clearance,\n );\n return segments.every(segmentHasClearance);\n};\n\n// Adapted from tscircuit-autorouter's calculate45DegreePaths utility. Each\n// candidate contains at most one bend and uses only 0, 45, or 90 degree axes.\nconst calculate45DegreePaths = (start: Point, end: Point): Point[][] => {\n const paths: Point[][] = [\n [start, { x: end.x, y: start.y }, end],\n [start, { x: start.x, y: end.y }, end],\n ];\n const dx = Math.abs(end.x - start.x);\n const dy = Math.abs(end.y - start.y);\n const signX = end.x > start.x ? 1 : -1;\n const signY = end.y > start.y ? 1 : -1;\n const horizontalThenDiagonal = {\n x: end.x - signX * dy,\n y: start.y,\n };\n if (\n (horizontalThenDiagonal.x - start.x) * signX >= 0 &&\n (horizontalThenDiagonal.x - end.x) * signX <= 0\n ) {\n paths.push([start, horizontalThenDiagonal, end]);\n }\n const verticalThenDiagonal = {\n x: start.x,\n y: end.y - signY * dx,\n };\n if (\n (verticalThenDiagonal.y - start.y) * signY >= 0 &&\n (verticalThenDiagonal.y - end.y) * signY <= 0\n ) {\n paths.push([start, verticalThenDiagonal, end]);\n }\n const diagonalThenAxis = {\n x: start.x + signX * Math.min(dx, dy),\n y: start.y + signY * Math.min(dx, dy),\n };\n paths.push([start, diagonalThenAxis, end]);\n return paths;\n};\n\nconst toWirePath = (path: Point[], template: WirePoint): WirePoint[] => {\n const result: WirePoint[] = [];\n for (const point of path) {\n const wirePoint = { ...template, x: point.x, y: point.y };\n if (!result.some((existing) => pointsEqual(existing, wirePoint))) {\n result.push(wirePoint);\n }\n }\n return result;\n};\n\nconst collapseCollinearWirePoints = (points: WirePoint[]): WirePoint[] => {\n if (points.length <= 2) return points;\n const result = [points[0]!];\n for (let index = 1; index < points.length - 1; index++) {\n const previous = result[result.length - 1]!;\n const current = points[index]!;\n const next = points[index + 1]!;\n const incoming = {\n x: current.x - previous.x,\n y: current.y - previous.y,\n };\n const outgoing = { x: next.x - current.x, y: next.y - current.y };\n const cross = incoming.x * outgoing.y - incoming.y * outgoing.x;\n const dot = incoming.x * outgoing.x + incoming.y * outgoing.y;\n if (Math.abs(cross) <= EPSILON && dot >= 0) continue;\n result.push(current);\n }\n result.push(points[points.length - 1]!);\n return result;\n};\n\nconst simplifyWireRun = (\n run: WirePoint[],\n segmentHasClearance: (segment: TraceSegment) => boolean,\n): WirePoint[] => {\n if (run.length <= 2) return run;\n const simplified: WirePoint[] = [run[0]!];\n let tailIndex = 0;\n\n while (tailIndex < run.length - 1) {\n let acceptedPath: WirePoint[] | null = null;\n let acceptedHeadIndex = -1;\n for (let headIndex = run.length - 1; headIndex > tailIndex; headIndex--) {\n const start = run[tailIndex]!;\n const end = run[headIndex]!;\n for (const pointPath of calculate45DegreePaths(start, end)) {\n const wirePath = toWirePath(pointPath, start);\n if (\n wirePath.length >= 2 &&\n wirePath.slice(1).every((point, index) =>\n segmentHasClearance({\n start: wirePath[index]!,\n end: point,\n }),\n )\n ) {\n acceptedPath = wirePath;\n acceptedHeadIndex = headIndex;\n break;\n }\n }\n if (acceptedPath) break;\n }\n if (!acceptedPath || acceptedHeadIndex <= tailIndex) {\n throw new Error(\n `Trace simplification could not preserve the validated segment after point ${tailIndex}`,\n );\n }\n simplified.push(...acceptedPath.slice(1));\n tailIndex = acceptedHeadIndex;\n }\n\n return collapseCollinearWirePoints(simplified);\n};\n\nconst simplifyTraceRoute = (\n route: SimplifiedPcbTrace[\"route\"],\n segmentHasClearance: (segment: TraceSegment) => boolean,\n protectedJunctionKeys: ReadonlySet<string>,\n): SimplifiedPcbTrace[\"route\"] => {\n const simplified: SimplifiedPcbTrace[\"route\"] = [];\n let pointIndex = 0;\n while (pointIndex < route.length) {\n const point = route[pointIndex]!;\n if (point.route_type !== \"wire\") {\n simplified.push(point);\n pointIndex++;\n continue;\n }\n const run: WirePoint[] = [point];\n let runEndIndex = pointIndex + 1;\n while (runEndIndex < route.length) {\n const next = route[runEndIndex]!;\n if (next.route_type !== \"wire\" || next.layer !== point.layer) break;\n run.push(next);\n runEndIndex++;\n }\n if (run.length === 1) {\n simplified.push(run[0]!);\n pointIndex = runEndIndex;\n continue;\n }\n let chunkStartIndex = 0;\n for (let index = 1; index < run.length; index++) {\n const isProtectedJunction = protectedJunctionKeys.has(\n junctionKey(run[index]!),\n );\n if (index < run.length - 1 && !isProtectedJunction) continue;\n const simplifiedChunk = simplifyWireRun(\n run.slice(chunkStartIndex, index + 1),\n segmentHasClearance,\n );\n const previous = simplified.at(-1);\n simplified.push(\n ...(previous?.route_type === \"wire\" &&\n pointsEqual(previous, simplifiedChunk[0]!) &&\n previous.layer === simplifiedChunk[0]!.layer\n ? simplifiedChunk.slice(1)\n : simplifiedChunk),\n );\n chunkStartIndex = index;\n }\n pointIndex = runEndIndex;\n }\n return simplified;\n};\n\nconst cloneTraces = (traces: SimplifiedPcbTrace[]) =>\n traces.map((trace) => ({\n ...trace,\n route: trace.route.map((point) => ({ ...point })),\n }));\n\nconst wirePathLength = (path: WirePoint[]) =>\n path\n .slice(1)\n .reduce(\n (total, point, index) =>\n total + Math.hypot(point.x - path[index]!.x, point.y - path[index]!.y),\n 0,\n );\n\nclass RotatedObstacleRepairError extends Error {\n constructor(\n readonly routeId: string,\n readonly obstacleIndex: number,\n ) {\n super(\n `Could not detour trace \"${routeId}\" around rotated obstacle ${obstacleIndex}`,\n );\n }\n}\n\nconst repairRotatedObstacleClearance = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n clearance: number,\n fallbackTraces: SimplifiedPcbTrace[] = [],\n) => {\n const traces = cloneTraces(solution.traces);\n const connectionNameResolver = new ConnectionNameResolver(\n prepared.input,\n solution.traces,\n );\n const restoredTraceIndexes = new Set<number>();\n const maximumRepairs = Math.max(\n traces.reduce((count, trace) => count + getSegments(trace).length, 0),\n fallbackTraces.reduce(\n (count, trace) => count + getSegments(trace).length,\n 0,\n ),\n );\n\n for (let repairCount = 0; repairCount < maximumRepairs; repairCount++) {\n let repaired = false;\n const workingSolution = { ...solution, traces };\n const contexts = getTraceContexts(prepared, workingSolution);\n\n for (const [traceIndex, context] of contexts.entries()) {\n const route = [...context.trace.route];\n const segmentHasClearance = createSegmentClearanceChecker(\n prepared,\n workingSolution,\n traceIndex,\n clearance,\n );\n\n for (let pointIndex = 1; pointIndex < route.length; pointIndex++) {\n const start = route[pointIndex - 1]!;\n const end = route[pointIndex]!;\n if (\n start.route_type !== \"wire\" ||\n end.route_type !== \"wire\" ||\n start.layer !== end.layer ||\n pointsEqual(start, end)\n ) {\n continue;\n }\n const segment = { start, end };\n const blockingEntry = [...prepared.input.obstacles.entries()].find(\n ([obstacleIndex, obstacle]) =>\n Math.abs(obstacle.ccwRotationDegrees ?? 0) > EPSILON &&\n !obstacle.isCopperPour &&\n obstacle.layers.includes(start.layer) &&\n !obstacleAllowsSegment(\n prepared,\n context,\n obstacleIndex,\n segment,\n connectionNameResolver,\n ) &&\n segmentIntersectsRectInterior(\n start,\n end,\n obstacleBounds(obstacle, start.width / 2 + clearance),\n ),\n );\n if (!blockingEntry) continue;\n\n const [blockingObstacleIndex, obstacle] = blockingEntry;\n const bounds = obstacleBounds(obstacle, start.width / 2 + clearance);\n const nudge = 1e-4;\n const detourStep = Math.max(clearance, start.width / 2, 0.05);\n const maximumDetourDistance = Math.max(\n prepared.options.gridPitch * 4,\n 2,\n );\n const detourOffsets = Array.from(\n { length: Math.ceil(maximumDetourDistance / detourStep) + 1 },\n (_, index) => nudge + index * detourStep,\n );\n const createCandidatePointPaths = (\n candidateStart: WirePoint,\n candidateEnd: WirePoint,\n ): Point[][] =>\n detourOffsets.flatMap((offset) => {\n const left = bounds.minX - offset;\n const right = bounds.maxX + offset;\n const bottom = bounds.minY - offset;\n const top = bounds.maxY + offset;\n const firstX = candidateStart.x <= candidateEnd.x ? left : right;\n const secondX = candidateStart.x <= candidateEnd.x ? right : left;\n const firstY = candidateStart.y <= candidateEnd.y ? bottom : top;\n const secondY = candidateStart.y <= candidateEnd.y ? top : bottom;\n return [\n [\n candidateStart,\n { x: left, y: candidateStart.y },\n { x: left, y: candidateEnd.y },\n candidateEnd,\n ],\n [\n candidateStart,\n { x: right, y: candidateStart.y },\n { x: right, y: candidateEnd.y },\n candidateEnd,\n ],\n [\n candidateStart,\n { x: candidateStart.x, y: bottom },\n { x: candidateEnd.x, y: bottom },\n candidateEnd,\n ],\n [\n candidateStart,\n { x: candidateStart.x, y: top },\n { x: candidateEnd.x, y: top },\n candidateEnd,\n ],\n [\n candidateStart,\n { x: firstX, y: candidateStart.y },\n { x: firstX, y: bottom },\n { x: secondX, y: bottom },\n { x: secondX, y: candidateEnd.y },\n candidateEnd,\n ],\n [\n candidateStart,\n { x: firstX, y: candidateStart.y },\n { x: firstX, y: top },\n { x: secondX, y: top },\n { x: secondX, y: candidateEnd.y },\n candidateEnd,\n ],\n [\n candidateStart,\n { x: candidateStart.x, y: firstY },\n { x: left, y: firstY },\n { x: left, y: secondY },\n { x: candidateEnd.x, y: secondY },\n candidateEnd,\n ],\n [\n candidateStart,\n { x: candidateStart.x, y: firstY },\n { x: right, y: firstY },\n { x: right, y: secondY },\n { x: candidateEnd.x, y: secondY },\n candidateEnd,\n ],\n ];\n });\n const boardMargin =\n (prepared.input.minBoardEdgeClearance ?? 0) + start.width / 2;\n const getValidDetours = (\n candidateStart: WirePoint,\n candidateEnd: WirePoint,\n ) =>\n createCandidatePointPaths(candidateStart, candidateEnd)\n .filter((path) =>\n path\n .slice(1, -1)\n .every(\n (point) =>\n point.x >= prepared.input.bounds.minX + boardMargin &&\n point.x <= prepared.input.bounds.maxX - boardMargin &&\n point.y >= prepared.input.bounds.minY + boardMargin &&\n point.y <= prepared.input.bounds.maxY - boardMargin,\n ),\n )\n .map((path) =>\n collapseCollinearWirePoints(toWirePath(path, candidateStart)),\n )\n .filter((path) =>\n path\n .slice(1)\n .every((point, index) =>\n segmentHasClearance({ start: path[index]!, end: point }),\n ),\n )\n .sort(\n (left, right) =>\n wirePathLength(left) - wirePathLength(right) ||\n left.length - right.length,\n );\n\n let detour = getValidDetours(start, end)[0];\n let detourStartIndex = pointIndex - 1;\n let detourEndIndex = pointIndex;\n if (!detour) {\n for (let spanSize = 1; spanSize <= 8 && !detour; spanSize++) {\n for (let before = 0; before <= spanSize; before++) {\n const after = spanSize - before;\n const startIndex = pointIndex - 1 - before;\n const endIndex = pointIndex + after;\n if (startIndex < 0 || endIndex >= route.length) continue;\n const span = route.slice(startIndex, endIndex + 1);\n if (\n !span.every(\n (point) =>\n point.route_type === \"wire\" && point.layer === start.layer,\n )\n ) {\n continue;\n }\n const spanStart = span[0] as WirePoint;\n const spanEnd = span.at(-1) as WirePoint;\n detour = getValidDetours(spanStart, spanEnd)[0];\n if (detour) {\n detourStartIndex = startIndex;\n detourEndIndex = endIndex;\n break;\n }\n }\n }\n }\n if (!detour) {\n const fallbackTrace = fallbackTraces[traceIndex];\n if (fallbackTrace && !restoredTraceIndexes.has(traceIndex)) {\n traces[traceIndex] = {\n ...fallbackTrace,\n route: fallbackTrace.route.map((point) => ({ ...point })),\n };\n restoredTraceIndexes.add(traceIndex);\n repaired = true;\n break;\n }\n throw new RotatedObstacleRepairError(\n context.route.routeId,\n blockingObstacleIndex,\n );\n }\n route.splice(\n detourStartIndex,\n detourEndIndex - detourStartIndex + 1,\n ...detour,\n );\n traces[traceIndex] = { ...context.trace, route };\n repaired = true;\n break;\n }\n if (repaired) break;\n }\n\n if (!repaired) return traces;\n }\n\n throw new Error(\"Rotated-obstacle trace repair exceeded its iteration limit\");\n};\n\nconst repairTraceClearance = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n clearance: number,\n) => {\n const traces = cloneTraces(solution.traces);\n const maximumRepairs = traces.reduce(\n (count, trace) => count + getSegments(trace).length,\n 0,\n );\n\n for (let repairCount = 0; repairCount < maximumRepairs; repairCount++) {\n const workingSolution = { ...solution, traces };\n const contexts = getTraceContexts(prepared, workingSolution);\n let repaired = false;\n\n for (let firstIndex = 0; firstIndex < contexts.length; firstIndex++) {\n const first = contexts[firstIndex]!;\n for (\n let secondIndex = firstIndex + 1;\n secondIndex < contexts.length;\n secondIndex++\n ) {\n const second = contexts[secondIndex]!;\n if (first.demand.netId === second.demand.netId) continue;\n\n for (\n let firstPointIndex = 1;\n firstPointIndex < first.trace.route.length;\n firstPointIndex++\n ) {\n const firstStart = first.trace.route[firstPointIndex - 1]!;\n const firstEnd = first.trace.route[firstPointIndex]!;\n if (\n firstStart.route_type !== \"wire\" ||\n firstEnd.route_type !== \"wire\" ||\n firstStart.layer !== firstEnd.layer ||\n pointsEqual(firstStart, firstEnd)\n ) {\n continue;\n }\n\n for (\n let secondPointIndex = 1;\n secondPointIndex < second.trace.route.length;\n secondPointIndex++\n ) {\n const secondStart = second.trace.route[secondPointIndex - 1]!;\n const secondEnd = second.trace.route[secondPointIndex]!;\n if (\n secondStart.route_type !== \"wire\" ||\n secondEnd.route_type !== \"wire\" ||\n secondStart.layer !== secondEnd.layer ||\n firstStart.layer !== secondStart.layer ||\n pointsEqual(secondStart, secondEnd)\n ) {\n continue;\n }\n const minimumCenterDistance =\n firstStart.width / 2 + secondStart.width / 2 + clearance;\n if (\n segmentDistance(firstStart, firstEnd, secondStart, secondEnd) >=\n minimumCenterDistance - EPSILON\n ) {\n continue;\n }\n\n const attempts = [\n {\n traceIndex: firstIndex,\n pointIndex: firstPointIndex,\n movingStart: firstStart,\n movingEnd: firstEnd,\n blockingStart: secondStart,\n blockingEnd: secondEnd,\n },\n {\n traceIndex: secondIndex,\n pointIndex: secondPointIndex,\n movingStart: secondStart,\n movingEnd: secondEnd,\n blockingStart: firstStart,\n blockingEnd: firstEnd,\n },\n ];\n\n for (const attempt of attempts) {\n const margin =\n attempt.movingStart.width / 2 +\n attempt.blockingStart.width / 2 +\n clearance +\n 1e-4;\n const bounds = {\n minX:\n Math.min(attempt.blockingStart.x, attempt.blockingEnd.x) -\n margin,\n maxX:\n Math.max(attempt.blockingStart.x, attempt.blockingEnd.x) +\n margin,\n minY:\n Math.min(attempt.blockingStart.y, attempt.blockingEnd.y) -\n margin,\n maxY:\n Math.max(attempt.blockingStart.y, attempt.blockingEnd.y) +\n margin,\n };\n const candidatePointPaths: Point[][] = [\n [\n attempt.movingStart,\n { x: bounds.minX, y: attempt.movingStart.y },\n { x: bounds.minX, y: attempt.movingEnd.y },\n attempt.movingEnd,\n ],\n [\n attempt.movingStart,\n { x: bounds.maxX, y: attempt.movingStart.y },\n { x: bounds.maxX, y: attempt.movingEnd.y },\n attempt.movingEnd,\n ],\n [\n attempt.movingStart,\n { x: attempt.movingStart.x, y: bounds.minY },\n { x: attempt.movingEnd.x, y: bounds.minY },\n attempt.movingEnd,\n ],\n [\n attempt.movingStart,\n { x: attempt.movingStart.x, y: bounds.maxY },\n { x: attempt.movingEnd.x, y: bounds.maxY },\n attempt.movingEnd,\n ],\n ];\n for (const escapeDistance of [\n margin + 0.1,\n margin + 0.3,\n margin + 0.6,\n ]) {\n for (const offset of [\n { x: escapeDistance, y: 0 },\n { x: -escapeDistance, y: 0 },\n { x: 0, y: escapeDistance },\n { x: 0, y: -escapeDistance },\n ]) {\n candidatePointPaths.push(\n [\n attempt.movingStart,\n {\n x: attempt.movingStart.x + offset.x,\n y: attempt.movingStart.y + offset.y,\n },\n attempt.movingEnd,\n ],\n [\n attempt.movingStart,\n {\n x: attempt.movingEnd.x + offset.x,\n y: attempt.movingEnd.y + offset.y,\n },\n attempt.movingEnd,\n ],\n );\n }\n }\n const boardMargin =\n (prepared.input.minBoardEdgeClearance ?? 0) +\n attempt.movingStart.width / 2;\n const segmentHasClearance = createSegmentClearanceChecker(\n prepared,\n workingSolution,\n attempt.traceIndex,\n clearance,\n false,\n );\n const candidates = candidatePointPaths\n .map((path) =>\n collapseCollinearWirePoints(\n toWirePath(path, attempt.movingStart),\n ),\n )\n .filter((path) =>\n path.every(\n (point) =>\n point.x >= prepared.input.bounds.minX + boardMargin &&\n point.x <= prepared.input.bounds.maxX - boardMargin &&\n point.y >= prepared.input.bounds.minY + boardMargin &&\n point.y <= prepared.input.bounds.maxY - boardMargin,\n ),\n )\n .filter((path) =>\n path.slice(1).every((point, index) =>\n segmentHasClearance({\n start: path[index]!,\n end: point,\n }),\n ),\n )\n .sort(\n (left, right) =>\n wirePathLength(left) - wirePathLength(right) ||\n left.length - right.length,\n );\n const detour = candidates[0];\n if (!detour) continue;\n\n const route = [...traces[attempt.traceIndex]!.route];\n route.splice(attempt.pointIndex - 1, 2, ...detour);\n traces[attempt.traceIndex] = {\n ...traces[attempt.traceIndex]!,\n route,\n };\n repaired = true;\n break;\n }\n if (repaired) break;\n }\n if (repaired) break;\n }\n if (repaired) break;\n }\n if (repaired) break;\n }\n\n if (!repaired) return traces;\n }\n\n throw new Error(\n \"Trace-to-trace clearance repair exceeded its iteration limit\",\n );\n};\n\nconst postProcessBiscuitBoardTracesOnce = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n): BiscuitBoardRoutingSolution => {\n const clearance = getEffectiveTraceClearance(prepared);\n let traces = repairTraceClearance(prepared, solution, clearance);\n traces = repairRotatedObstacleClearance(\n prepared,\n { ...solution, traces },\n clearance,\n );\n const repairedSolution = { ...solution, traces };\n const initialViolations = getTraceClearanceViolations(\n prepared,\n repairedSolution,\n clearance,\n true,\n );\n if (initialViolations.length > 0) {\n throw new Error(\n `Cannot post-process traces with existing clearance violations: ${initialViolations[0]!.message}`,\n );\n }\n\n traces = cloneTraces(repairedSolution.traces);\n const protectedJunctionKeys = new Set<string>();\n for (const route of solution.routes) {\n const demand = prepared.demandById.get(route.routeId)!;\n for (const endpointNode of [route.nodePath[0], route.nodePath.at(-1)]) {\n if (\n endpointNode !== undefined &&\n endpointNode !== demand.sourceNode &&\n endpointNode !== demand.targetNode\n ) {\n protectedJunctionKeys.add(junctionKey(prepared.nodes[endpointNode]!));\n }\n }\n }\n const preSimplificationSegmentCount = traces.reduce(\n (count, trace) => count + getSegments(trace).length,\n 0,\n );\n for (let pass = 0; pass < 3; pass++) {\n const segmentCountBeforePass = traces.reduce(\n (count, trace) => count + getSegments(trace).length,\n 0,\n );\n const traceIndexes = traces\n .map((trace, traceIndex) => ({\n traceIndex,\n segmentCount: getSegments(trace).length,\n }))\n .sort(\n (left, right) =>\n right.segmentCount - left.segmentCount ||\n left.traceIndex - right.traceIndex,\n )\n .map(({ traceIndex }) => traceIndex);\n for (const traceIndex of traceIndexes) {\n const segmentHasClearance = createSegmentClearanceChecker(\n prepared,\n { ...solution, traces },\n traceIndex,\n clearance,\n false,\n );\n traces[traceIndex] = {\n ...traces[traceIndex]!,\n route: simplifyTraceRoute(\n traces[traceIndex]!.route,\n segmentHasClearance,\n protectedJunctionKeys,\n ),\n };\n }\n const segmentCountAfterPass = traces.reduce(\n (count, trace) => count + getSegments(trace).length,\n 0,\n );\n if (segmentCountAfterPass >= segmentCountBeforePass) break;\n }\n traces = repairRotatedObstacleClearance(\n prepared,\n { ...solution, traces },\n clearance,\n repairedSolution.traces,\n );\n const postSimplificationSegmentCount = traces.reduce(\n (count, trace) => count + getSegments(trace).length,\n 0,\n );\n\n const output: BiscuitBoardRoutingSolution = {\n ...solution,\n traces,\n stats: {\n ...solution.stats,\n postProcessedClearance: clearance,\n preSimplificationSegmentCount,\n postSimplificationSegmentCount,\n },\n };\n const finalViolations = getTraceClearanceViolations(\n prepared,\n output,\n clearance,\n );\n if (finalViolations.length > 0) {\n throw new Error(`Trace cleanup failed: ${finalViolations[0]!.message}`);\n }\n return output;\n};\n\nexport const postProcessBiscuitBoardTraces = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n): BiscuitBoardRoutingSolution => {\n let repairPrepared = prepared;\n let repairSolution = solution;\n\n for (let repairAttempt = 0; repairAttempt < 8; repairAttempt++) {\n try {\n return postProcessBiscuitBoardTracesOnce(repairPrepared, repairSolution);\n } catch (error) {\n if (!(error instanceof RotatedObstacleRepairError)) throw error;\n if (\n repairPrepared.exactRotatedObstacleIndexes.includes(error.obstacleIndex)\n ) {\n throw error;\n }\n\n repairPrepared = {\n ...repairPrepared,\n exactRotatedObstacleIndexes: [\n ...repairPrepared.exactRotatedObstacleIndexes,\n error.obstacleIndex,\n ],\n };\n const rerouter = new RipUpRubberBandSolver(repairPrepared);\n rerouter.seedCommittedRoutes(repairSolution.routes, [error.routeId]);\n rerouter.solve();\n if (rerouter.failed) {\n throw new Error(\n `Could not reroute trace \"${error.routeId}\" around rotated obstacle ${error.obstacleIndex}: ${rerouter.error ?? \"routing failed\"}`,\n );\n }\n const builder = new BuildBiscuitBoardTracesSolver({\n prepared: repairPrepared,\n routed: rerouter.getOutput(),\n });\n builder.solve();\n const built = builder.getOutput();\n if (!built) {\n throw new Error(\n `Could not rebuild traces after rerouting \"${error.routeId}\"`,\n );\n }\n repairSolution = built;\n }\n }\n\n throw new Error(\"Rotated-obstacle graph repair exceeded its attempt limit\");\n};\n\nconst visualizeTraces = (\n prepared: PreparedBiscuitRoutingProblem,\n built: BiscuitBoardRoutingSolution,\n solution: BiscuitBoardRoutingSolution,\n): GraphicsObject => {\n const clearance = getEffectiveTraceClearance(prepared);\n const maximumTraceRadius =\n Math.max(\n ...solution.traces\n .flatMap((trace) => getSegments(trace))\n .map((segment) => segment.start.width),\n prepared.input.minTraceWidth,\n ) / 2;\n const rects: NonNullable<GraphicsObject[\"rects\"]> = [];\n const circles: NonNullable<GraphicsObject[\"circles\"]> = [];\n for (const [obstacleIndex, obstacle] of prepared.input.obstacles.entries()) {\n if (obstacle.isCopperPour) continue;\n const identifier =\n obstacle.connectedTo.find((id) => id.startsWith(\"pcb_smtpad\")) ??\n obstacle.connectedTo.find((id) => id.startsWith(\"pcb_via\")) ??\n obstacle.componentId ??\n obstacle.obstacleId ??\n `obstacle-${obstacleIndex}`;\n const isPrefabricatedVia =\n obstacle.netIsAssignable && obstacleHasPcbViaId(obstacle);\n const label = isPrefabricatedVia\n ? `prefabricated via · ${identifier}`\n : `pad/obstacle · ${identifier}`;\n const envelope = obstacleBounds(obstacle, maximumTraceRadius + clearance);\n rects.push({\n center: {\n x: (envelope.minX + envelope.maxX) / 2,\n y: (envelope.minY + envelope.maxY) / 2,\n },\n width: envelope.maxX - envelope.minX,\n height: envelope.maxY - envelope.minY,\n fill: isPrefabricatedVia\n ? \"rgba(14,165,233,0.06)\"\n : \"rgba(239,68,68,0.045)\",\n stroke: isPrefabricatedVia\n ? \"rgba(2,132,199,0.24)\"\n : \"rgba(220,38,38,0.16)\",\n label: `${label} · ${clearance}mm clearance envelope`,\n });\n if (obstacle.shape === \"circle\") {\n circles.push({\n center: obstacle.center,\n radius: Math.max(obstacle.width, obstacle.height) / 2,\n fill: isPrefabricatedVia\n ? \"rgba(14,165,233,0.42)\"\n : \"rgba(168,85,247,0.35)\",\n stroke: isPrefabricatedVia ? \"#0284c7\" : \"#7e22ce\",\n label,\n });\n } else {\n rects.push({\n center: obstacle.center,\n width: obstacle.width,\n height: obstacle.height,\n fill: obstacle.layers.includes(\"top\")\n ? \"rgba(249,115,22,0.30)\"\n : \"rgba(79,70,229,0.26)\",\n stroke: obstacle.layers.includes(\"top\") ? \"#c2410c\" : \"#4338ca\",\n label,\n });\n }\n }\n\n const originalLines = built.traces.flatMap((trace) =>\n getSegments(trace).map((segment) => ({\n points: [segment.start, segment.end],\n strokeColor: \"rgba(100,116,139,0.30)\",\n strokeWidth: Math.min(segment.start.width, 0.07),\n strokeDash: [0.12, 0.08],\n label: \"original unsimplified trace\",\n })),\n );\n const simplifiedLines = solution.routes.flatMap((route, index) => {\n const color = netColor(route.netId);\n return getSegments(solution.traces[index]!).map((segment) => ({\n points: [segment.start, segment.end],\n strokeColor: color,\n strokeWidth: segment.start.width,\n strokeDash: segment.start.layer === \"bottom\" ? [6, 4] : undefined,\n zIndex: 2,\n label: `simplified trace · ${route.netId} · ${segment.start.layer}`,\n }));\n });\n return {\n coordinateSystem: \"cartesian\",\n title: `Clearance-safe trace simplification (${solution.stats.preSimplificationSegmentCount ?? 0} → ${solution.stats.postSimplificationSegmentCount ?? 0} segments, ${clearance}mm clearance)`,\n rects,\n circles,\n lines: [...originalLines, ...simplifiedLines],\n points: solution.traces.flatMap((trace) =>\n trace.route.flatMap((point) =>\n point.route_type === \"through_obstacle\"\n ? [\n {\n x: point.start.x,\n y: point.start.y,\n color: \"#0369a1\",\n label: \"used prefabricated via\",\n },\n ]\n : [],\n ),\n ),\n };\n};\n\nexport class PostProcessBiscuitBoardTracesSolver extends BaseSolver {\n private output?: BiscuitBoardRoutingSolution;\n\n constructor(\n public readonly params: {\n prepared: PreparedBiscuitRoutingProblem;\n built: BiscuitBoardRoutingSolution;\n },\n ) {\n super();\n }\n\n override getConstructorParams(): [typeof this.params] {\n return [this.params];\n }\n\n override _step() {\n this.output = postProcessBiscuitBoardTraces(\n this.params.prepared,\n this.params.built,\n );\n this.stats = this.output.stats;\n this.progress = 1;\n this.solved = true;\n }\n\n override getOutput() {\n return this.output ?? null;\n }\n\n override visualize(): GraphicsObject {\n return visualizeTraces(\n this.params.prepared,\n this.params.built,\n this.output ?? this.params.built,\n );\n }\n}\n","import type { SimplifiedPcbTrace } from \"@tscircuit/core\";\nimport { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport {\n netColor,\n obstacleBounds,\n pointsEqual,\n segmentsIntersect,\n visualizeSimpleRouteJsonInput,\n} from \"./geometry\";\nimport {\n createSegmentClearanceChecker,\n getEffectiveTraceClearance,\n getTraceClearanceViolations,\n postProcessBiscuitBoardTraces,\n} from \"./post-process-biscuit-board-traces-solver\";\nimport type {\n BiscuitBoardRoutingSolution,\n Point,\n PreparedBiscuitRoutingProblem,\n} from \"./types\";\n\ntype RoutePoint = SimplifiedPcbTrace[\"route\"][number];\ntype WirePoint = Extract<RoutePoint, { route_type: \"wire\" }>;\n\nconst EPSILON = 1e-7;\nconst CHAMFER_SEARCH_STEPS = 16;\nconst CLEARANCE_SEARCH_STEPS = 4;\nconst BEAUTIFICATION_CLEARANCE_TARGET = 0.4;\n\nconst cloneTraces = (traces: SimplifiedPcbTrace[]) =>\n traces.map((trace) => ({\n ...trace,\n route: trace.route.map((point) => ({ ...point })),\n }));\n\nconst pointKey = (point: WirePoint) =>\n `${point.layer}:${point.x.toFixed(6)}:${point.y.toFixed(6)}`;\n\nconst sameWirePoint = (first: RoutePoint, second: RoutePoint) =>\n first.route_type === \"wire\" &&\n second.route_type === \"wire\" &&\n first.layer === second.layer &&\n pointsEqual(first, second);\n\nconst wirePathLength = (points: WirePoint[]) =>\n points\n .slice(1)\n .reduce(\n (length, point, index) =>\n length +\n Math.hypot(point.x - points[index]!.x, point.y - points[index]!.y),\n 0,\n );\n\nconst getWireSegments = (trace: SimplifiedPcbTrace) => {\n return getIndexedWireSegments(trace).map(({ start, end }) => ({\n start,\n end,\n }));\n};\n\ninterface IndexedWireSegment {\n start: WirePoint;\n end: WirePoint;\n startRouteIndex: number;\n endRouteIndex: number;\n}\n\nconst getIndexedWireSegments = (trace: SimplifiedPcbTrace) => {\n const segments: IndexedWireSegment[] = [];\n for (let index = 1; index < trace.route.length; index++) {\n const start = trace.route[index - 1]!;\n const end = trace.route[index]!;\n if (\n start.route_type === \"wire\" &&\n end.route_type === \"wire\" &&\n start.layer === end.layer &&\n !pointsEqual(start, end)\n ) {\n segments.push({\n start,\n end,\n startRouteIndex: index - 1,\n endRouteIndex: index,\n });\n }\n }\n return segments;\n};\n\nconst getProtectedJunctionKeys = (traces: SimplifiedPcbTrace[]) => {\n const traceIndexesByPoint = new Map<string, Set<number>>();\n for (const [traceIndex, trace] of traces.entries()) {\n for (const point of trace.route) {\n if (point.route_type !== \"wire\") continue;\n const indexes = traceIndexesByPoint.get(pointKey(point)) ?? new Set();\n indexes.add(traceIndex);\n traceIndexesByPoint.set(pointKey(point), indexes);\n }\n }\n return new Set(\n [...traceIndexesByPoint.entries()]\n .filter(([, traceIndexes]) => traceIndexes.size > 1)\n .map(([key]) => key),\n );\n};\n\nconst routeGeometryEqual = (\n first: SimplifiedPcbTrace[\"route\"],\n second: SimplifiedPcbTrace[\"route\"],\n) =>\n first.length === second.length &&\n first.every((point, index) => {\n const other = second[index]!;\n if (point.route_type === \"wire\" && other.route_type === \"wire\") {\n return point.layer === other.layer && pointsEqual(point, other);\n }\n return JSON.stringify(point) === JSON.stringify(other);\n });\n\nconst removeConsecutiveDuplicateWirePoints = (\n route: SimplifiedPcbTrace[\"route\"],\n) =>\n route.filter((point, index) => {\n if (index === 0) return true;\n return !sameWirePoint(route[index - 1]!, point);\n });\n\ninterface ConsolidationCandidate {\n route: SimplifiedPcbTrace[\"route\"];\n overlapLength: number;\n lengthReduction: number;\n}\n\nconst chooseBetterConsolidationCandidate = (\n current: ConsolidationCandidate | null,\n candidate: ConsolidationCandidate,\n) =>\n !current ||\n candidate.overlapLength > current.overlapLength + EPSILON ||\n (Math.abs(candidate.overlapLength - current.overlapLength) <= EPSILON &&\n candidate.lengthReduction > current.lengthReduction + EPSILON)\n ? candidate\n : current;\n\nconst cross = (first: Point, second: Point) =>\n first.x * second.y - first.y * second.x;\n\nconst subtract = (first: Point, second: Point): Point => ({\n x: first.x - second.x,\n y: first.y - second.y,\n});\n\nconst dot = (first: Point, second: Point) =>\n first.x * second.x + first.y * second.y;\n\nconst pointIsInRect = (\n point: Point,\n rect: { minX: number; minY: number; maxX: number; maxY: number },\n) =>\n point.x >= rect.minX - EPSILON &&\n point.x <= rect.maxX + EPSILON &&\n point.y >= rect.minY - EPSILON &&\n point.y <= rect.maxY + EPSILON;\n\nconst pointIsInConvexPolygon = (point: Point, polygon: Point[]) => {\n let hasPositiveCross = false;\n let hasNegativeCross = false;\n for (let index = 0; index < polygon.length; index++) {\n const start = polygon[index]!;\n const end = polygon[(index + 1) % polygon.length]!;\n const side = cross(subtract(end, start), subtract(point, start));\n if (side > EPSILON) hasPositiveCross = true;\n if (side < -EPSILON) hasNegativeCross = true;\n if (hasPositiveCross && hasNegativeCross) return false;\n }\n return true;\n};\n\nconst polygonEdges = (polygon: Point[]) =>\n polygon.map((start, index) => ({\n start,\n end: polygon[(index + 1) % polygon.length]!,\n }));\n\nconst corridorIntersectsRect = (\n corridor: Point[],\n rect: { minX: number; minY: number; maxX: number; maxY: number },\n) => {\n const rectPoints = [\n { x: rect.minX, y: rect.minY },\n { x: rect.maxX, y: rect.minY },\n { x: rect.maxX, y: rect.maxY },\n { x: rect.minX, y: rect.maxY },\n ];\n if (corridor.some((point) => pointIsInRect(point, rect))) return true;\n if (rectPoints.some((point) => pointIsInConvexPolygon(point, corridor))) {\n return true;\n }\n return polygonEdges(corridor).some((corridorEdge) =>\n polygonEdges(rectPoints).some((rectEdge) =>\n segmentsIntersect(\n corridorEdge.start,\n corridorEdge.end,\n rectEdge.start,\n rectEdge.end,\n ),\n ),\n );\n};\n\nconst segmentIntersectsCorridor = (\n start: Point,\n end: Point,\n corridor: Point[],\n) =>\n pointIsInConvexPolygon(start, corridor) ||\n pointIsInConvexPolygon(end, corridor) ||\n polygonEdges(corridor).some((edge) =>\n segmentsIntersect(start, end, edge.start, edge.end),\n );\n\n/**\n * A parallel span is only moved when the complete strip between the two\n * centerlines is empty. Final trace clearance is checked separately after the\n * replacement route is assembled.\n */\nconst parallelCorridorIsEmpty = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n traceIndex: number,\n layer: string,\n corridor: Point[],\n) => {\n for (const obstacle of prepared.input.obstacles) {\n if (\n obstacle.isCopperPour ||\n !obstacle.layers.includes(layer) ||\n !corridorIntersectsRect(corridor, obstacleBounds(obstacle))\n ) {\n continue;\n }\n return false;\n }\n\n const netId = solution.routes[traceIndex]!.netId;\n for (const [otherIndex, otherTrace] of solution.traces.entries()) {\n if (\n otherIndex === traceIndex ||\n solution.routes[otherIndex]!.netId === netId\n ) {\n continue;\n }\n for (const segment of getWireSegments(otherTrace)) {\n if (\n segment.start.layer === layer &&\n segmentIntersectsCorridor(segment.start, segment.end, corridor)\n ) {\n return false;\n }\n }\n }\n return true;\n};\n\nconst createWirePoint = (template: WirePoint, point: Point): WirePoint => ({\n ...template,\n ...point,\n});\n\n/**\n * Pulls an offset parallel segment onto an existing same-net segment for the\n * common projected run. The original segment endpoints remain in place and\n * become the approach/departure points for the shared copper.\n */\nconst createParallelConsolidationCandidate = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n traceIndex: number,\n route: SimplifiedPcbTrace[\"route\"],\n segment: IndexedWireSegment,\n anchor: IndexedWireSegment,\n routeHasClearance: (route: SimplifiedPcbTrace[\"route\"]) => boolean,\n): ConsolidationCandidate | null => {\n if (segment.start.layer !== anchor.start.layer) return null;\n const anchorVector = subtract(anchor.end, anchor.start);\n const segmentVector = subtract(segment.end, segment.start);\n const anchorLength = Math.hypot(anchorVector.x, anchorVector.y);\n const segmentLength = Math.hypot(segmentVector.x, segmentVector.y);\n if (anchorLength <= EPSILON || segmentLength <= EPSILON) return null;\n if (\n Math.abs(cross(anchorVector, segmentVector)) >\n EPSILON * anchorLength * segmentLength\n ) {\n return null;\n }\n\n const direction = {\n x: anchorVector.x / anchorLength,\n y: anchorVector.y / anchorLength,\n };\n const segmentStartProjection = dot(\n subtract(segment.start, anchor.start),\n direction,\n );\n const segmentEndProjection = dot(\n subtract(segment.end, anchor.start),\n direction,\n );\n const overlapStart = Math.max(\n 0,\n Math.min(segmentStartProjection, segmentEndProjection),\n );\n const overlapEnd = Math.min(\n anchorLength,\n Math.max(segmentStartProjection, segmentEndProjection),\n );\n const overlapLength = overlapEnd - overlapStart;\n const offset = Math.abs(\n cross(direction, subtract(segment.start, anchor.start)),\n );\n // Two clearance-safe 45-degree approaches consume one offset at either end.\n if (offset <= EPSILON || overlapLength <= 2 * offset + EPSILON) {\n return null;\n }\n\n const followsAnchorDirection = segmentEndProjection > segmentStartProjection;\n const entryProjection = followsAnchorDirection ? overlapStart : overlapEnd;\n const exitProjection = followsAnchorDirection ? overlapEnd : overlapStart;\n const pointOnAnchor = (projection: number): Point => ({\n x: anchor.start.x + direction.x * projection,\n y: anchor.start.y + direction.y * projection,\n });\n const pointOnSegment = (projection: number): Point => ({\n x: segment.start.x + direction.x * (projection - segmentStartProjection),\n y: segment.start.y + direction.y * (projection - segmentStartProjection),\n });\n const candidateEntry = pointOnSegment(entryProjection);\n const candidateExit = pointOnSegment(exitProjection);\n const anchorEntry = pointOnAnchor(entryProjection);\n const anchorExit = pointOnAnchor(exitProjection);\n const corridor = [candidateEntry, candidateExit, anchorExit, anchorEntry];\n if (\n !parallelCorridorIsEmpty(\n prepared,\n solution,\n traceIndex,\n segment.start.layer,\n corridor,\n )\n ) {\n return null;\n }\n\n const replacement = [\n segment.start,\n createWirePoint(segment.start, candidateEntry),\n createWirePoint(segment.start, anchorEntry),\n createWirePoint(segment.start, anchorExit),\n createWirePoint(segment.start, candidateExit),\n segment.end,\n ];\n const candidateRoute = removeConsecutiveDuplicateWirePoints([\n ...route.slice(0, segment.startRouteIndex),\n ...replacement,\n ...route.slice(segment.endRouteIndex + 1),\n ]);\n if (routeGeometryEqual(route, candidateRoute)) return null;\n if (!routeHasClearance(candidateRoute)) {\n return null;\n }\n\n return {\n route: candidateRoute,\n overlapLength,\n lengthReduction: -2 * offset,\n };\n};\n\n/**\n * Reuses same-net copper between shared junctions and pulls unobstructed\n * parallel spans onto one centerline. This turns adjacent branches back into\n * one visible copper path after clearance cleanup has moved them independently.\n */\nconst consolidateSameNetTraces = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n clearance: number,\n) => {\n const traces = cloneTraces(solution.traces);\n const protectedJunctionKeys = getProtectedJunctionKeys(traces);\n let consolidationCount = 0;\n\n for (let pass = 0; pass < traces.length; pass++) {\n let changed = false;\n for (let traceIndex = 0; traceIndex < traces.length; traceIndex++) {\n const route = traces[traceIndex]!.route;\n let best: ConsolidationCandidate | null = null;\n const workingSolution = { ...solution, traces };\n const segmentHasClearance = createSegmentClearanceChecker(\n prepared,\n workingSolution,\n traceIndex,\n clearance,\n );\n const routeHasClearance = (candidateRoute: SimplifiedPcbTrace[\"route\"]) =>\n getIndexedWireSegments({\n ...traces[traceIndex]!,\n route: candidateRoute,\n }).every(segmentHasClearance);\n\n for (let anchorIndex = 0; anchorIndex < traces.length; anchorIndex++) {\n if (\n anchorIndex === traceIndex ||\n solution.routes[anchorIndex]!.netId !==\n solution.routes[traceIndex]!.netId\n ) {\n continue;\n }\n const anchorRoute = traces[anchorIndex]!.route;\n const matches: Array<{ routeIndex: number; anchorRouteIndex: number }> =\n [];\n for (const [routeIndex, point] of route.entries()) {\n if (point.route_type !== \"wire\") continue;\n for (const [anchorRouteIndex, anchorPoint] of anchorRoute.entries()) {\n if (sameWirePoint(point, anchorPoint)) {\n matches.push({ routeIndex, anchorRouteIndex });\n }\n }\n }\n\n for (let firstIndex = 0; firstIndex < matches.length; firstIndex++) {\n for (\n let secondIndex = firstIndex + 1;\n secondIndex < matches.length;\n secondIndex++\n ) {\n const first = matches[firstIndex]!;\n const second = matches[secondIndex]!;\n if (first.routeIndex >= second.routeIndex) continue;\n const candidateSpan = route.slice(\n first.routeIndex,\n second.routeIndex + 1,\n );\n const anchorSpan =\n first.anchorRouteIndex <= second.anchorRouteIndex\n ? anchorRoute.slice(\n first.anchorRouteIndex,\n second.anchorRouteIndex + 1,\n )\n : anchorRoute\n .slice(second.anchorRouteIndex, first.anchorRouteIndex + 1)\n .reverse();\n if (\n candidateSpan.length < 2 ||\n anchorSpan.length < 2 ||\n !candidateSpan.every(\n (point) =>\n point.route_type === \"wire\" &&\n point.layer === (candidateSpan[0] as WirePoint).layer,\n ) ||\n !anchorSpan.every(\n (point) =>\n point.route_type === \"wire\" &&\n point.layer === (anchorSpan[0] as WirePoint).layer,\n )\n ) {\n continue;\n }\n\n const candidateWireSpan = candidateSpan as WirePoint[];\n const anchorWireSpan = anchorSpan as WirePoint[];\n const candidateLength = wirePathLength(candidateWireSpan);\n const anchorLength = wirePathLength(anchorWireSpan);\n if (anchorLength > candidateLength + EPSILON) continue;\n\n const width = candidateWireSpan[0]!.width;\n const replacement = anchorWireSpan.map((point) => ({\n ...point,\n width,\n }));\n const removedJunctionKeys = new Set(\n candidateWireSpan\n .slice(1, -1)\n .map(pointKey)\n .filter((key) => protectedJunctionKeys.has(key)),\n );\n if (\n [...removedJunctionKeys].some(\n (key) => !replacement.some((point) => pointKey(point) === key),\n )\n ) {\n continue;\n }\n\n const candidateRoute = removeConsecutiveDuplicateWirePoints([\n ...route.slice(0, first.routeIndex),\n ...replacement,\n ...route.slice(second.routeIndex + 1),\n ]);\n if (routeGeometryEqual(route, candidateRoute)) continue;\n if (!routeHasClearance(candidateRoute)) {\n continue;\n }\n\n const candidate = {\n route: candidateRoute,\n overlapLength: anchorLength,\n lengthReduction: candidateLength - anchorLength,\n };\n best = chooseBetterConsolidationCandidate(best, candidate);\n }\n }\n\n for (const segment of getIndexedWireSegments(traces[traceIndex]!)) {\n for (const anchorSegment of getIndexedWireSegments(\n traces[anchorIndex]!,\n )) {\n const candidate = createParallelConsolidationCandidate(\n prepared,\n workingSolution,\n traceIndex,\n route,\n segment,\n anchorSegment,\n routeHasClearance,\n );\n if (candidate) {\n best = chooseBetterConsolidationCandidate(best, candidate);\n }\n }\n }\n }\n\n if (!best) continue;\n traces[traceIndex] = { ...traces[traceIndex]!, route: best.route };\n consolidationCount++;\n changed = true;\n }\n if (!changed) break;\n }\n\n return { traces, consolidationCount };\n};\n\nconst createChamferPoints = (\n route: SimplifiedPcbTrace[\"route\"],\n cornerIndex: number,\n distance: number,\n) => {\n const previous = route[cornerIndex - 1] as WirePoint;\n const corner = route[cornerIndex] as WirePoint;\n const next = route[cornerIndex + 1] as WirePoint;\n const incomingLength = Math.hypot(\n previous.x - corner.x,\n previous.y - corner.y,\n );\n const outgoingLength = Math.hypot(next.x - corner.x, next.y - corner.y);\n const entry: WirePoint = {\n ...corner,\n x: corner.x + ((previous.x - corner.x) / incomingLength) * distance,\n y: corner.y + ((previous.y - corner.y) / incomingLength) * distance,\n };\n const exit: WirePoint = {\n ...corner,\n x: corner.x + ((next.x - corner.x) / outgoingLength) * distance,\n y: corner.y + ((next.y - corner.y) / outgoingLength) * distance,\n };\n return { entry, exit };\n};\n\nconst createChamferedRoute = (\n route: SimplifiedPcbTrace[\"route\"],\n cornerIndex: number,\n distance: number,\n) => {\n const { entry, exit } = createChamferPoints(route, cornerIndex, distance);\n return removeConsecutiveDuplicateWirePoints([\n ...route.slice(0, cornerIndex),\n entry,\n exit,\n ...route.slice(cornerIndex + 1),\n ]);\n};\n\nconst createChamferSegments = (\n route: SimplifiedPcbTrace[\"route\"],\n cornerIndex: number,\n distance: number,\n) => {\n const previous = route[cornerIndex - 1] as WirePoint;\n const next = route[cornerIndex + 1] as WirePoint;\n const { entry, exit } = createChamferPoints(route, cornerIndex, distance);\n const points = [previous, entry, exit, next].filter(\n (point, index, path) =>\n index === 0 || !pointsEqual(path[index - 1]!, point),\n );\n return points.slice(1).map((end, index) => ({\n start: points[index]!,\n end,\n }));\n};\n\nconst isManhattanCorner = (\n previous: WirePoint,\n corner: WirePoint,\n next: WirePoint,\n) => {\n const incoming = {\n x: previous.x - corner.x,\n y: previous.y - corner.y,\n };\n const outgoing = { x: next.x - corner.x, y: next.y - corner.y };\n const incomingIsAxisAligned =\n Math.abs(incoming.x) <= EPSILON || Math.abs(incoming.y) <= EPSILON;\n const outgoingIsAxisAligned =\n Math.abs(outgoing.x) <= EPSILON || Math.abs(outgoing.y) <= EPSILON;\n const dot = incoming.x * outgoing.x + incoming.y * outgoing.y;\n return (\n incomingIsAxisAligned &&\n outgoingIsAxisAligned &&\n Math.abs(dot) <= EPSILON &&\n Math.hypot(incoming.x, incoming.y) > EPSILON &&\n Math.hypot(outgoing.x, outgoing.y) > EPSILON\n );\n};\n\n/** Replaces every unprotected 90-degree corner with its largest safe chamfer. */\nconst chamferTraceCorners = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n clearance: number,\n) => {\n const traces = cloneTraces(solution.traces);\n const protectedJunctionKeys = getProtectedJunctionKeys(traces);\n let chamferCount = 0;\n\n for (let traceIndex = 0; traceIndex < traces.length; traceIndex++) {\n let route = traces[traceIndex]!.route;\n const workingSolution = { ...solution, traces };\n const segmentHasClearance = createSegmentClearanceChecker(\n prepared,\n workingSolution,\n traceIndex,\n clearance,\n );\n for (let cornerIndex = 1; cornerIndex < route.length - 1; cornerIndex++) {\n const previous = route[cornerIndex - 1]!;\n const corner = route[cornerIndex]!;\n const next = route[cornerIndex + 1]!;\n if (\n previous.route_type !== \"wire\" ||\n corner.route_type !== \"wire\" ||\n next.route_type !== \"wire\" ||\n previous.layer !== corner.layer ||\n corner.layer !== next.layer ||\n protectedJunctionKeys.has(pointKey(corner)) ||\n !isManhattanCorner(previous, corner, next)\n ) {\n continue;\n }\n\n const maximumDistance = Math.min(\n Math.hypot(previous.x - corner.x, previous.y - corner.y),\n Math.hypot(next.x - corner.x, next.y - corner.y),\n );\n const candidateIsClear = (distance: number) =>\n createChamferSegments(route, cornerIndex, distance).every(\n segmentHasClearance,\n );\n\n let bestDistance = 0;\n if (candidateIsClear(maximumDistance)) {\n bestDistance = maximumDistance;\n } else {\n let low = 0;\n let high = maximumDistance;\n for (let step = 0; step < CHAMFER_SEARCH_STEPS; step++) {\n const distance = (low + high) / 2;\n if (candidateIsClear(distance)) low = distance;\n else high = distance;\n }\n bestDistance = low;\n }\n if (bestDistance <= 1e-4) continue;\n\n route = createChamferedRoute(route, cornerIndex, bestDistance);\n traces[traceIndex] = { ...traces[traceIndex]!, route };\n chamferCount++;\n // The corner is now an entry/exit pair. Advancing once prevents the exit\n // from being reconsidered as part of the same original corner.\n cornerIndex++;\n }\n }\n\n return { traces, chamferCount };\n};\n\nconst maximizeClearance = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n) => {\n const minimumClearance = getEffectiveTraceClearance(prepared);\n const desiredClearance = Math.max(\n minimumClearance,\n BEAUTIFICATION_CLEARANCE_TARGET,\n );\n if (desiredClearance <= minimumClearance + EPSILON) {\n return {\n solution,\n clearance: minimumClearance,\n desiredClearance,\n };\n }\n\n let low = minimumClearance;\n let high = desiredClearance;\n let bestSolution = solution;\n for (let step = 0; step < CLEARANCE_SEARCH_STEPS; step++) {\n const candidateClearance = step === 0 ? high : (low + high) / 2;\n const candidatePrepared = {\n ...prepared,\n options: { ...prepared.options, gridClearance: candidateClearance },\n };\n try {\n bestSolution = postProcessBiscuitBoardTraces(candidatePrepared, solution);\n low = candidateClearance;\n if (Math.abs(low - desiredClearance) <= EPSILON) break;\n } catch {\n high = candidateClearance;\n }\n }\n return { solution: bestSolution, clearance: low, desiredClearance };\n};\n\nexport const beautifyBiscuitBoardTraces = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n): BiscuitBoardRoutingSolution => {\n const spread = maximizeClearance(prepared, solution);\n const consolidated = consolidateSameNetTraces(\n prepared,\n spread.solution,\n spread.clearance,\n );\n const consolidatedSolution = {\n ...spread.solution,\n traces: consolidated.traces,\n };\n const chamfered = chamferTraceCorners(\n prepared,\n consolidatedSolution,\n spread.desiredClearance,\n );\n const output: BiscuitBoardRoutingSolution = {\n ...consolidatedSolution,\n traces: chamfered.traces,\n stats: {\n ...consolidatedSolution.stats,\n beautifiedClearance: spread.clearance,\n sameNetConsolidationCount: consolidated.consolidationCount,\n fortyFiveDegreeChamferCount: chamfered.chamferCount,\n },\n };\n const violations = getTraceClearanceViolations(\n prepared,\n output,\n spread.clearance,\n );\n if (violations.length > 0) {\n throw new Error(`Trace beautification failed: ${violations[0]!.message}`);\n }\n return output;\n};\n\nconst visualizeTraces = (\n prepared: PreparedBiscuitRoutingProblem,\n input: BiscuitBoardRoutingSolution,\n output: BiscuitBoardRoutingSolution,\n): GraphicsObject => {\n const boardGraphics = visualizeSimpleRouteJsonInput(prepared.input);\n return {\n coordinateSystem: \"cartesian\",\n title: `Trace beautification (${output.stats.beautifiedClearance ?? output.stats.postProcessedClearance ?? 0}mm clearance, ${output.stats.sameNetConsolidationCount ?? 0} consolidated spans, ${output.stats.fortyFiveDegreeChamferCount ?? 0} 45-degree corners)`,\n rects: boardGraphics.rects,\n circles: boardGraphics.circles,\n points: boardGraphics.points,\n lines: [\n ...input.traces.flatMap((trace) =>\n getWireSegments(trace).map((segment) => ({\n points: [segment.start, segment.end],\n strokeColor: \"rgba(100,116,139,0.28)\",\n strokeWidth: Math.min(segment.start.width, 0.07),\n strokeDash: [0.12, 0.08],\n label: \"pre-beautification trace\",\n })),\n ),\n ...output.routes.flatMap((route, traceIndex) =>\n getWireSegments(output.traces[traceIndex]!).map((segment) => ({\n points: [segment.start, segment.end],\n strokeColor: netColor(route.netId),\n strokeWidth: segment.start.width,\n strokeDash: segment.start.layer === \"bottom\" ? [6, 4] : undefined,\n zIndex: 2,\n label: `beautified trace · ${route.netId} · ${segment.start.layer}`,\n })),\n ),\n ],\n };\n};\n\nexport class BeautifyBiscuitBoardTracesSolver extends BaseSolver {\n private output?: BiscuitBoardRoutingSolution;\n\n constructor(\n public readonly params: {\n prepared: PreparedBiscuitRoutingProblem;\n built: BiscuitBoardRoutingSolution;\n },\n ) {\n super();\n }\n\n override getConstructorParams(): [typeof this.params] {\n return [this.params];\n }\n\n override _step() {\n this.output = beautifyBiscuitBoardTraces(\n this.params.prepared,\n this.params.built,\n );\n this.stats = this.output.stats;\n this.progress = 1;\n this.solved = true;\n }\n\n override getOutput() {\n return this.output ?? null;\n }\n\n override visualize(): GraphicsObject {\n return visualizeTraces(\n this.params.prepared,\n this.params.built,\n this.output ?? this.params.built,\n );\n }\n}\n","import type { SimplifiedPcbTrace } from \"@tscircuit/core\";\nimport {\n ConnectionNameResolver,\n PowerTraceExpanderSolver,\n SpatialObstacleIndex,\n} from \"@tscircuit/power-trace-expander\";\nimport { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { assertOnlyPrefabricatedVias } from \"./build-biscuit-board-traces-solver\";\nimport { EXPANSION_CLEARANCE_GUARD } from \"./geometry\";\nimport { getEffectiveTraceClearance } from \"./post-process-biscuit-board-traces-solver\";\nimport type {\n BiscuitBoardRoutingSolution,\n PreparedBiscuitRoutingProblem,\n} from \"./types\";\n\ntype RoutePoint = SimplifiedPcbTrace[\"route\"][number];\ntype WirePoint = Extract<RoutePoint, { route_type: \"wire\" }>;\n\nconst WIDTH_EPSILON = 1e-7;\n// The route input and Circuit JSON use slightly different representations for\n// short diagonal width transitions at pads. Use this only for the final width\n// fit so it does not make the expander search a globally over-constrained board.\nconst FINAL_STATIC_CLEARANCE_GUARD = 0.025;\n\nconst getExpansionClearance = (\n prepared: PreparedBiscuitRoutingProblem,\n guard = 0,\n) =>\n Math.max(\n prepared.input.defaultObstacleMargin ?? 0,\n getEffectiveTraceClearance(prepared),\n ) + guard;\n\nconst pointIsOnSegment = (\n point: { x: number; y: number },\n start: { x: number; y: number },\n end: { x: number; y: number },\n) => {\n const cross =\n (point.x - start.x) * (end.y - start.y) -\n (point.y - start.y) * (end.x - start.x);\n const dot =\n (point.x - start.x) * (point.x - end.x) +\n (point.y - start.y) * (point.y - end.y);\n return Math.abs(cross) <= WIDTH_EPSILON && dot <= WIDTH_EPSILON;\n};\n\nconst orientation = (\n start: { x: number; y: number },\n end: { x: number; y: number },\n point: { x: number; y: number },\n) =>\n (end.x - start.x) * (point.y - start.y) -\n (end.y - start.y) * (point.x - start.x);\n\nconst segmentsIntersect = (\n aStart: { x: number; y: number },\n aEnd: { x: number; y: number },\n bStart: { x: number; y: number },\n bEnd: { x: number; y: number },\n) => {\n const a = orientation(aStart, aEnd, bStart);\n const b = orientation(aStart, aEnd, bEnd);\n const c = orientation(bStart, bEnd, aStart);\n const d = orientation(bStart, bEnd, aEnd);\n if (a * b < 0 && c * d < 0) return true;\n return (\n (Math.abs(a) <= WIDTH_EPSILON && pointIsOnSegment(bStart, aStart, aEnd)) ||\n (Math.abs(b) <= WIDTH_EPSILON && pointIsOnSegment(bEnd, aStart, aEnd)) ||\n (Math.abs(c) <= WIDTH_EPSILON && pointIsOnSegment(aStart, bStart, bEnd)) ||\n (Math.abs(d) <= WIDTH_EPSILON && pointIsOnSegment(aEnd, bStart, bEnd))\n );\n};\n\nconst distancePointToSegment = (\n point: { x: number; y: number },\n start: { x: number; y: number },\n end: { x: number; y: number },\n) => {\n const dx = end.x - start.x;\n const dy = end.y - start.y;\n const lengthSquared = dx * dx + dy * dy;\n if (lengthSquared <= WIDTH_EPSILON * WIDTH_EPSILON) {\n return Math.hypot(point.x - start.x, point.y - start.y);\n }\n const t = Math.max(\n 0,\n Math.min(\n 1,\n ((point.x - start.x) * dx + (point.y - start.y) * dy) / lengthSquared,\n ),\n );\n return Math.hypot(point.x - (start.x + t * dx), point.y - (start.y + t * dy));\n};\n\nconst distanceSegmentToSegment = (\n aStart: { x: number; y: number },\n aEnd: { x: number; y: number },\n bStart: { x: number; y: number },\n bEnd: { x: number; y: number },\n) => {\n if (segmentsIntersect(aStart, aEnd, bStart, bEnd)) return 0;\n return Math.min(\n distancePointToSegment(aStart, bStart, bEnd),\n distancePointToSegment(aEnd, bStart, bEnd),\n distancePointToSegment(bStart, aStart, aEnd),\n distancePointToSegment(bEnd, aStart, aEnd),\n );\n};\n\nconst getObstacleCorners = (\n obstacle: PreparedBiscuitRoutingProblem[\"input\"][\"obstacles\"][number],\n) => {\n const radians = ((obstacle.ccwRotationDegrees ?? 0) * Math.PI) / 180;\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n const halfWidth = obstacle.width / 2;\n const halfHeight = obstacle.height / 2;\n return [\n { x: -halfWidth, y: -halfHeight },\n { x: halfWidth, y: -halfHeight },\n { x: halfWidth, y: halfHeight },\n { x: -halfWidth, y: halfHeight },\n ].map((point) => ({\n x: obstacle.center.x + point.x * cos - point.y * sin,\n y: obstacle.center.y + point.x * sin + point.y * cos,\n }));\n};\n\nconst getStaticObstacleWidthLimit = (\n prepared: PreparedBiscuitRoutingProblem,\n start: WirePoint,\n end: WirePoint,\n connectionNames: string[],\n clearance: number,\n onlyPads = false,\n) => {\n const directNames = new Set(connectionNames);\n let widthLimit = Number.POSITIVE_INFINITY;\n for (const obstacle of prepared.input.obstacles) {\n if (!obstacle.layers.includes(start.layer)) continue;\n if (\n onlyPads &&\n !obstacle.connectedTo[0]?.startsWith(\"pcb_smtpad_\") &&\n !obstacle.connectedTo[0]?.startsWith(\"pcb_plated_hole_\")\n ) {\n continue;\n }\n if (obstacle.connectedTo.some((name) => directNames.has(name))) {\n continue;\n }\n const corners = getObstacleCorners(obstacle);\n const centerlineDistance = Math.min(\n ...corners.map((corner, index) =>\n distanceSegmentToSegment(\n start,\n end,\n corner,\n corners[(index + 1) % corners.length]!,\n ),\n ),\n );\n widthLimit = Math.min(widthLimit, 2 * (centerlineDistance - clearance));\n }\n return widthLimit;\n};\n\nconst segmentCollidesWithStaticObstacle = (\n prepared: PreparedBiscuitRoutingProblem,\n start: WirePoint,\n end: WirePoint,\n width: number,\n connectionNames: string[],\n clearance: number,\n) => {\n const widthLimit = getStaticObstacleWidthLimit(\n prepared,\n start,\n end,\n connectionNames,\n clearance,\n );\n return width > widthLimit + WIDTH_EPSILON;\n};\n\nconst wirePointsAreCollinear = (\n previous: WirePoint,\n current: WirePoint,\n next: WirePoint,\n) => {\n if (previous.layer !== current.layer || current.layer !== next.layer) {\n return false;\n }\n const incoming = {\n x: current.x - previous.x,\n y: current.y - previous.y,\n };\n const outgoing = { x: next.x - current.x, y: next.y - current.y };\n const cross = incoming.x * outgoing.y - incoming.y * outgoing.x;\n const dot = incoming.x * outgoing.x + incoming.y * outgoing.y;\n return Math.abs(cross) <= WIDTH_EPSILON && dot >= 0;\n};\n\nconst canRemoveCollinearPoint = (\n previous: WirePoint,\n current: WirePoint,\n next: WirePoint,\n) => {\n const currentWithPorts = current as WirePoint & {\n start_pcb_port_id?: string;\n end_pcb_port_id?: string;\n };\n if (\n Math.abs(previous.width - current.width) > WIDTH_EPSILON ||\n currentWithPorts.start_pcb_port_id ||\n currentWithPorts.end_pcb_port_id\n ) {\n return false;\n }\n return wirePointsAreCollinear(previous, current, next);\n};\n\n/** Remove expansion probe points without changing geometry or segment widths. */\nexport const compactExpandedTraceRoute = (\n route: SimplifiedPcbTrace[\"route\"],\n): SimplifiedPcbTrace[\"route\"] => {\n const compacted: SimplifiedPcbTrace[\"route\"] = [];\n for (const point of route) {\n compacted.push({ ...point });\n while (compacted.length >= 3) {\n const previous = compacted[compacted.length - 3]!;\n const current = compacted[compacted.length - 2]!;\n const next = compacted[compacted.length - 1]!;\n if (\n previous.route_type !== \"wire\" ||\n current.route_type !== \"wire\" ||\n next.route_type !== \"wire\" ||\n !canRemoveCollinearPoint(previous, current, next)\n ) {\n break;\n }\n compacted.splice(compacted.length - 2, 1);\n }\n }\n return compacted;\n};\n\nexport const assertExpandedTraceClearance = (\n prepared: PreparedBiscuitRoutingProblem,\n traces: SimplifiedPcbTrace[],\n baselineTraces: SimplifiedPcbTrace[] = [],\n guard = 0,\n) => {\n const input = {\n ...prepared.input,\n defaultObstacleMargin: getExpansionClearance(prepared, guard),\n traces,\n };\n const connectionNameResolver = new ConnectionNameResolver(input, traces);\n for (const [traceIndex, trace] of traces.entries()) {\n const baselineTrace = baselineTraces.find(\n (candidate) => candidate.pcb_trace_id === trace.pcb_trace_id,\n );\n const traceWithAliases = trace as SimplifiedPcbTrace & {\n source_trace_id?: string;\n rootConnectionName?: string;\n mergedConnectionNames?: string[];\n };\n const obstacleIndex = new SpatialObstacleIndex(\n input,\n traces,\n traceIndex,\n [],\n connectionNameResolver,\n );\n const connectionNames = [\n trace.connection_name,\n traceWithAliases.source_trace_id,\n traceWithAliases.rootConnectionName,\n ...(traceWithAliases.mergedConnectionNames ?? []),\n ...(trace.connectsTo ?? []),\n ].filter((name): name is string => Boolean(name));\n for (\n let routeIndex = 0;\n routeIndex < trace.route.length - 1;\n routeIndex++\n ) {\n const start = trace.route[routeIndex]!;\n const end = trace.route[routeIndex + 1]!;\n if (\n start.route_type !== \"wire\" ||\n end.route_type !== \"wire\" ||\n start.layer !== end.layer\n ) {\n continue;\n }\n const collisions = obstacleIndex.findCollisions({\n start,\n end,\n layer: start.layer,\n width: start.width,\n connectionNames,\n ignoreTraceIndex: traceIndex,\n });\n if (collisions.length > 0) {\n const segmentWasAlreadyValidated = baselineTrace?.route.some(\n (baselineStart, baselineIndex) => {\n const baselineEnd = baselineTrace.route[baselineIndex + 1];\n return (\n baselineStart.route_type === \"wire\" &&\n baselineEnd?.route_type === \"wire\" &&\n baselineStart.layer === start.layer &&\n baselineEnd.layer === end.layer &&\n pointIsOnSegment(start, baselineStart, baselineEnd) &&\n pointIsOnSegment(end, baselineStart, baselineEnd) &&\n Math.abs(baselineStart.width - start.width) <= WIDTH_EPSILON\n );\n },\n );\n if (segmentWasAlreadyValidated) continue;\n throw new Error(\n `Expanded trace \"${trace.pcb_trace_id}\" violates copper clearance at segment ${routeIndex} (${collisions[0]!.kind})`,\n );\n }\n }\n }\n};\n\nconst getBaselineSegmentWidth = (\n trace: SimplifiedPcbTrace | undefined,\n start: WirePoint,\n end: WirePoint,\n) => {\n if (!trace) return null;\n for (let index = 0; index < trace.route.length - 1; index++) {\n const baselineStart = trace.route[index]!;\n const baselineEnd = trace.route[index + 1]!;\n if (\n baselineStart.route_type === \"wire\" &&\n baselineEnd.route_type === \"wire\" &&\n baselineStart.layer === start.layer &&\n baselineEnd.layer === end.layer &&\n pointIsOnSegment(start, baselineStart, baselineEnd) &&\n pointIsOnSegment(end, baselineStart, baselineEnd)\n ) {\n return baselineStart.width;\n }\n }\n return null;\n};\n\n/**\n * Narrow only the individual widened segments that are marginal in the final\n * route representation. Existing physical-width copper remains the fallback.\n */\nexport const fitExpandedTraceWidthsToClearance = (\n prepared: PreparedBiscuitRoutingProblem,\n traces: SimplifiedPcbTrace[],\n baselineTraces: SimplifiedPcbTrace[],\n) => {\n const fitted = traces.map((trace) => ({\n ...trace,\n route: trace.route.map((point) => ({ ...point })),\n }));\n const baseInput = {\n ...prepared.input,\n defaultObstacleMargin: getExpansionClearance(prepared),\n traces: fitted,\n };\n const guardedInput = {\n ...prepared.input,\n defaultObstacleMargin: getExpansionClearance(\n prepared,\n EXPANSION_CLEARANCE_GUARD,\n ),\n traces: fitted,\n };\n // The general resolver intentionally follows every imported alias. For the\n // final width fit, direct SimpleRouteJson connection names are safer: pads\n // carry their assigned source_net name, while net-assignable prefab vias\n // carry every connection they may legally accept.\n const directConnectionNameResolver = {\n canonicalize: (names: string[]) => [...new Set(names)],\n } as ConnectionNameResolver;\n\n for (const [traceIndex, trace] of fitted.entries()) {\n const baselineTrace = baselineTraces.find(\n (candidate) => candidate.pcb_trace_id === trace.pcb_trace_id,\n );\n const traceWithAliases = trace as SimplifiedPcbTrace & {\n source_trace_id?: string;\n rootConnectionName?: string;\n mergedConnectionNames?: string[];\n };\n const connectionNames = [\n trace.connection_name,\n traceWithAliases.source_trace_id,\n traceWithAliases.rootConnectionName,\n ...(traceWithAliases.mergedConnectionNames ?? []),\n ...(trace.connectsTo ?? []),\n ].filter((name): name is string => Boolean(name));\n const baseObstacleIndex = new SpatialObstacleIndex(\n baseInput,\n fitted,\n traceIndex,\n [],\n directConnectionNameResolver,\n );\n const guardedObstacleIndex = new SpatialObstacleIndex(\n guardedInput,\n fitted,\n traceIndex,\n [],\n directConnectionNameResolver,\n );\n\n for (\n let routeIndex = 0;\n routeIndex < trace.route.length - 1;\n routeIndex++\n ) {\n const start = trace.route[routeIndex]!;\n const end = trace.route[routeIndex + 1]!;\n if (\n start.route_type !== \"wire\" ||\n end.route_type !== \"wire\" ||\n start.layer !== end.layer\n ) {\n continue;\n }\n const previous = trace.route[routeIndex - 1];\n const next = trace.route[routeIndex + 2];\n const hasTinyAdjacentCorner =\n Math.hypot(end.x - start.x, end.y - start.y) <= 0.3 &&\n ((previous?.route_type === \"wire\" &&\n previous.layer === start.layer &&\n Math.hypot(start.x - previous.x, start.y - previous.y) <= 0.05 &&\n !wirePointsAreCollinear(previous, start, end)) ||\n (next?.route_type === \"wire\" &&\n next.layer === end.layer &&\n Math.hypot(next.x - end.x, next.y - end.y) <= 0.05 &&\n !wirePointsAreCollinear(start, end, next)));\n const query = {\n start,\n end,\n layer: start.layer,\n connectionNames,\n ignoreTraceIndex: traceIndex,\n };\n const baseClearance = getExpansionClearance(prepared);\n const violatesBaseClearance =\n segmentCollidesWithStaticObstacle(\n prepared,\n start,\n end,\n start.width,\n connectionNames,\n baseClearance,\n ) ||\n baseObstacleIndex.findCollisions({ ...query, width: start.width })\n .length > 0;\n if (!violatesBaseClearance && !hasTinyAdjacentCorner) continue;\n const obstacleIndex = violatesBaseClearance\n ? baseObstacleIndex\n : guardedObstacleIndex;\n const clearance = violatesBaseClearance\n ? baseClearance\n : baseClearance + EXPANSION_CLEARANCE_GUARD;\n const collidesAtWidth = (width: number) =>\n segmentCollidesWithStaticObstacle(\n prepared,\n start,\n end,\n width,\n connectionNames,\n clearance,\n ) ||\n obstacleIndex.findCollisions({\n ...query,\n width,\n }).length > 0;\n if (!collidesAtWidth(start.width)) continue;\n\n const baselineWidth = getBaselineSegmentWidth(baselineTrace, start, end);\n const minimumWidth = Math.max(\n prepared.input.minTraceWidth,\n baselineWidth ?? prepared.input.minTraceWidth,\n );\n if (start.width <= minimumWidth + WIDTH_EPSILON) continue;\n\n const widthStep = 0.0125;\n const candidateWidths = Array.from(\n {\n length: Math.ceil((start.width - minimumWidth) / widthStep) + 1,\n },\n (_, index) => Math.max(minimumWidth, start.width - index * widthStep),\n );\n const fittedWidth = candidateWidths.find(\n (width) => !collidesAtWidth(width),\n );\n start.width = fittedWidth ?? minimumWidth;\n }\n }\n\n // Apply the exact rectangle limit directly as a final deterministic clamp.\n // This covers long shallow pad crossings that may span multiple cells in the\n // expander's spatial approximation.\n for (const trace of fitted) {\n let requiresTraceWidthFallback = trace.route.some((point, routeIndex) => {\n const next = trace.route[routeIndex + 1];\n return (\n point.route_type === \"wire\" &&\n next?.route_type === \"wire\" &&\n point.layer === next.layer &&\n Math.hypot(next.x - point.x, next.y - point.y) > 1 &&\n Math.hypot(next.x - point.x, next.y - point.y) < 2 &&\n Math.abs(next.y - point.y) <= 0.05 &&\n next.width < point.width - WIDTH_EPSILON &&\n point.width >\n getStaticObstacleWidthLimit(\n prepared,\n point,\n next,\n [],\n getExpansionClearance(prepared) + FINAL_STATIC_CLEARANCE_GUARD,\n true,\n ) +\n WIDTH_EPSILON\n );\n });\n const baselineTrace = baselineTraces.find(\n (candidate) => candidate.pcb_trace_id === trace.pcb_trace_id,\n );\n const traceWithAliases = trace as SimplifiedPcbTrace & {\n source_trace_id?: string;\n rootConnectionName?: string;\n mergedConnectionNames?: string[];\n };\n const connectionNames = [\n trace.connection_name,\n traceWithAliases.source_trace_id,\n traceWithAliases.rootConnectionName,\n ...(traceWithAliases.mergedConnectionNames ?? []),\n ...(trace.connectsTo ?? []),\n ].filter((name): name is string => Boolean(name));\n for (\n let routeIndex = 0;\n routeIndex < trace.route.length - 1;\n routeIndex++\n ) {\n const start = trace.route[routeIndex]!;\n const end = trace.route[routeIndex + 1]!;\n if (\n start.route_type !== \"wire\" ||\n end.route_type !== \"wire\" ||\n start.layer !== end.layer\n ) {\n continue;\n }\n const baselineWidth = getBaselineSegmentWidth(baselineTrace, start, end);\n const minimumWidth = Math.max(\n prepared.input.minTraceWidth,\n baselineWidth ?? prepared.input.minTraceWidth,\n );\n const widthLimit = getStaticObstacleWidthLimit(\n prepared,\n start,\n end,\n connectionNames,\n getExpansionClearance(prepared) + FINAL_STATIC_CLEARANCE_GUARD,\n );\n if (start.width <= widthLimit + WIDTH_EPSILON) continue;\n if (\n Math.hypot(end.x - start.x, end.y - start.y) > 1 &&\n end.width < start.width - WIDTH_EPSILON\n ) {\n requiresTraceWidthFallback = true;\n }\n const roundedLimit =\n Math.floor((widthLimit + WIDTH_EPSILON) / 0.0125) * 0.0125;\n start.width = Math.max(minimumWidth, Math.min(start.width, roundedLimit));\n }\n if (requiresTraceWidthFallback) {\n const baselineWireWidths = baselineTrace?.route.flatMap((point) =>\n point.route_type === \"wire\" ? [point.width] : [],\n );\n const physicalWidth = Math.max(\n baselineWireWidths && baselineWireWidths.length > 0\n ? Math.min(...baselineWireWidths)\n : prepared.input.minTraceWidth,\n prepared.input.minTraceWidth,\n );\n for (const point of trace.route) {\n if (point.route_type === \"wire\") {\n point.width = Math.min(point.width, physicalWidth);\n }\n }\n }\n }\n\n return fitted;\n};\n\nexport class ExpandBiscuitBoardTracesSolver extends BaseSolver {\n private output?: BiscuitBoardRoutingSolution;\n readonly expander: PowerTraceExpanderSolver;\n\n constructor(\n public readonly params: {\n prepared: PreparedBiscuitRoutingProblem;\n built: BiscuitBoardRoutingSolution;\n enabled?: boolean;\n },\n ) {\n super();\n const expansionInput = {\n ...params.prepared.input,\n defaultObstacleMargin: getExpansionClearance(params.prepared),\n traces: params.built.traces,\n };\n this.expander = new PowerTraceExpanderSolver(expansionInput, {\n // Biscuit boards may change layers only at their prefabricated vias.\n allowNewVias: false,\n });\n this.activeSubSolver = this.expander;\n this.MAX_ITERATIONS = this.expander.MAX_ITERATIONS + 1;\n }\n\n override getConstructorParams(): [typeof this.params] {\n return [this.params];\n }\n\n override _step() {\n if (this.params.enabled === false) {\n this.output = this.params.built;\n this.activeSubSolver = null;\n this.progress = 1;\n this.solved = true;\n return;\n }\n\n if (!this.expander.solved && !this.expander.failed) {\n this.expander.step();\n this.stats = this.expander.stats;\n this.progress = this.expander.computeProgress();\n return;\n }\n if (this.expander.failed) {\n this.error = this.expander.error ?? \"Trace expansion failed\";\n this.failed = true;\n this.activeSubSolver = null;\n return;\n }\n\n const expandedTraces = this.expander.getOutput() as SimplifiedPcbTrace[];\n assertExpandedTraceClearance(\n this.params.prepared,\n expandedTraces,\n this.params.built.traces,\n );\n const compactedTraces = expandedTraces.map((trace) => ({\n ...trace,\n route: compactExpandedTraceRoute(trace.route),\n }));\n const traces = fitExpandedTraceWidthsToClearance(\n this.params.prepared,\n compactedTraces,\n this.params.built.traces,\n );\n assertOnlyPrefabricatedVias(this.params.prepared, traces);\n const output = { ...this.params.built, traces };\n this.output = output;\n this.stats = this.expander.stats;\n this.activeSubSolver = null;\n this.progress = 1;\n this.solved = true;\n }\n\n override getOutput() {\n return this.output ?? null;\n }\n\n override visualize(): GraphicsObject {\n return this.expander.visualize();\n }\n}\n","import { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport {\n EXPANSION_CLEARANCE_GUARD,\n getTerminalEscapeMinimumRun,\n obstacleBounds,\n pointDistance,\n pointStrictlyInsideRect,\n pointsEqual,\n segmentDistance,\n segmentIntersectsRectInterior,\n shouldRespectObstacleRotationInGraph,\n visualizePreparedProblem,\n visualizeSimpleRouteJsonInput,\n} from \"./geometry\";\nimport type {\n BiscuitBoardAutorouterOptions,\n NormalizedBiscuitBoardAutorouterOptions,\n Point,\n PrefabricatedVia,\n PreparedBiscuitRoutingProblem,\n RouteDemand,\n RoutingEdge,\n RoutingNode,\n} from \"./types\";\nimport type { SimpleRouteJson } from \"@tscircuit/core\";\nimport { BuildBiscuitBoardTracesSolver } from \"./build-biscuit-board-traces-solver\";\nimport { getTraceClearanceViolations } from \"./post-process-biscuit-board-traces-solver\";\nimport { RipUpRubberBandSolver } from \"./rip-up-rubber-band-solver\";\n\nconst ROUNDING_SCALE = 1e6;\nconst roundCoordinate = (value: number) =>\n Math.round(value * ROUNDING_SCALE) / ROUNDING_SCALE;\nconst coordinateKey = (value: number) => roundCoordinate(value).toFixed(6);\nconst nodeKey = (layer: string, x: number, y: number) =>\n `${layer}:${coordinateKey(x)}:${coordinateKey(y)}`;\n\nexport const DEFAULT_ROUTE_ORDER = \"adaptive\" as const;\n\nconst DEFAULT_OPTIONS: NormalizedBiscuitBoardAutorouterOptions = {\n routeOrder: DEFAULT_ROUTE_ORDER,\n gridPitch: 1.5,\n gridClearance: 0.2,\n respectObstacleRotationInGraph: false,\n viaTransitionCost: 20,\n ripCost: 10,\n crossingCost: 0.25,\n historyIncrement: 4,\n maxBlockersPerSearch: 64,\n maxRipsPerRoute: 1_000,\n maxTotalRips: 10_000,\n maxSearchStates: 500_000,\n expansionsPerStep: 300,\n};\n\ntype HypergraphGenerationOptions = NormalizedBiscuitBoardAutorouterOptions & {\n exactRotatedObstacleIndexes: ReadonlySet<number>;\n};\n\nconst normalizeOptions = (\n options: BiscuitBoardAutorouterOptions = {},\n): NormalizedBiscuitBoardAutorouterOptions => {\n const normalized = { ...DEFAULT_OPTIONS, ...options };\n for (const key of [\n \"gridPitch\",\n \"viaTransitionCost\",\n \"ripCost\",\n \"historyIncrement\",\n \"maxBlockersPerSearch\",\n \"maxRipsPerRoute\",\n \"maxTotalRips\",\n \"maxSearchStates\",\n \"expansionsPerStep\",\n ] as const) {\n if (!Number.isFinite(normalized[key]) || normalized[key] <= 0) {\n throw new Error(`options.${key} must be greater than zero`);\n }\n }\n if (\n !Number.isFinite(normalized.gridClearance) ||\n normalized.gridClearance < 0\n ) {\n throw new Error(\"options.gridClearance must be non-negative\");\n }\n if (\n !Number.isFinite(normalized.crossingCost) ||\n normalized.crossingCost < 0\n ) {\n throw new Error(\"options.crossingCost must be non-negative\");\n }\n return normalized;\n};\n\nconst getLayers = (input: SimpleRouteJson) => {\n const standard = [\n \"top\",\n ...Array.from(\n { length: Math.max(0, input.layerCount - 2) },\n (_, index) => `inner${index + 1}`,\n ),\n ...(input.layerCount > 1 ? [\"bottom\"] : []),\n ];\n const declared = new Set(standard);\n for (const obstacle of input.obstacles) {\n for (const layer of obstacle.layers) declared.add(layer);\n }\n for (const connection of input.connections) {\n for (const point of connection.pointsToConnect) {\n declared.add(point.layer);\n for (const layer of point.layers ?? []) declared.add(layer);\n }\n }\n return [...declared];\n};\n\nconst getPrefabricatedVias = (input: SimpleRouteJson): PrefabricatedVia[] =>\n input.obstacles.flatMap((obstacle, obstacleIndex) => {\n const layers = [...new Set(obstacle.layers)];\n const pcbViaId = obstacle.connectedTo.find((id) =>\n id.startsWith(\"pcb_via\"),\n );\n if (!obstacle.netIsAssignable || !pcbViaId || layers.length < 2) return [];\n return [\n {\n prefabViaId: pcbViaId,\n obstacleIndex,\n x: obstacle.center.x,\n y: obstacle.center.y,\n layers,\n width: obstacle.width,\n height: obstacle.height,\n },\n ];\n });\n\nconst uniqueSorted = (values: number[]) =>\n [...new Set(values.map(roundCoordinate))].sort((a, b) => a - b);\n\nconst isInsideBounds = (\n input: SimpleRouteJson,\n point: Point,\n boardEdgeMargin: number,\n isSpecial: boolean,\n) =>\n isSpecial ||\n (point.x >= input.bounds.minX + boardEdgeMargin &&\n point.x <= input.bounds.maxX - boardEdgeMargin &&\n point.y >= input.bounds.minY + boardEdgeMargin &&\n point.y <= input.bounds.maxY - boardEdgeMargin);\n\nconst obstacleIsOnLayer = (\n obstacle: SimpleRouteJson[\"obstacles\"][number],\n layer: string,\n) => obstacle.layers.includes(layer);\n\nconst graphUsesRotatedObstacleBounds = (\n input: SimpleRouteJson,\n obstacle: SimpleRouteJson[\"obstacles\"][number],\n obstacleIndex: number,\n margin: number,\n options: HypergraphGenerationOptions,\n) =>\n options.exactRotatedObstacleIndexes.has(obstacleIndex) ||\n shouldRespectObstacleRotationInGraph(\n input,\n obstacle,\n margin,\n options.respectObstacleRotationInGraph,\n options.gridPitch,\n );\n\nconst getSpecialNodeMetadata = (\n input: SimpleRouteJson,\n prefabricatedVias: PrefabricatedVia[],\n layer: string,\n point: Point,\n) => {\n const terminalPointIds: string[] = [];\n const terminalConnectionNames: string[] = [];\n for (const connection of input.connections) {\n for (const terminal of connection.pointsToConnect) {\n const terminalLayers = terminal.layers ?? [terminal.layer];\n if (terminalLayers.includes(layer) && pointsEqual(terminal, point)) {\n if (terminal.pointId) terminalPointIds.push(terminal.pointId);\n terminalConnectionNames.push(connection.name);\n }\n }\n }\n const prefabVia = prefabricatedVias.find(\n (via) => via.layers.includes(layer) && pointsEqual(via, point),\n );\n return {\n terminalPointIds: [...new Set(terminalPointIds)],\n terminalConnectionNames: [...new Set(terminalConnectionNames)],\n prefabVia,\n };\n};\n\nconst nodeIsBlocked = (\n input: SimpleRouteJson,\n layer: string,\n point: Point,\n margin: number,\n special: ReturnType<typeof getSpecialNodeMetadata>,\n options: HypergraphGenerationOptions,\n) =>\n input.obstacles.some((obstacle, obstacleIndex) => {\n if (obstacle.isCopperPour || !obstacleIsOnLayer(obstacle, layer))\n return false;\n if (special.prefabVia?.obstacleIndex === obstacleIndex) return false;\n if (\n special.terminalConnectionNames.some((connectionName) =>\n obstacle.connectedTo.includes(connectionName),\n ) ||\n special.terminalPointIds.some((pointId) =>\n obstacle.connectedTo.includes(pointId),\n )\n ) {\n return false;\n }\n // Preserve the established sparse graph topology here. Exact rotated\n // envelopes are applied after simplification, where a local detour does\n // not force an unrelated whole-board rip-up negotiation.\n return pointStrictlyInsideRect(\n point,\n obstacleBounds(\n obstacle,\n margin,\n graphUsesRotatedObstacleBounds(\n input,\n obstacle,\n obstacleIndex,\n margin,\n options,\n ),\n ),\n );\n });\n\nconst getBlockingObstacleIndexes = (\n input: SimpleRouteJson,\n layer: string,\n start: RoutingNode,\n end: RoutingNode,\n margin: number,\n options: HypergraphGenerationOptions,\n) =>\n input.obstacles.flatMap((obstacle, obstacleIndex) => {\n if (obstacle.isCopperPour || !obstacleIsOnLayer(obstacle, layer)) return [];\n return segmentIntersectsRectInterior(\n start,\n end,\n obstacleBounds(\n obstacle,\n margin,\n graphUsesRotatedObstacleBounds(\n input,\n obstacle,\n obstacleIndex,\n margin,\n options,\n ),\n ),\n )\n ? [obstacleIndex]\n : [];\n });\n\nconst buildPointTreePairs = <T extends Point>(points: T[]) => {\n if (points.length < 2) return [] as Array<[T, T]>;\n const pairs: Array<[T, T]> = [];\n const connected = [points[0]!];\n const remaining = points.slice(1);\n while (remaining.length > 0) {\n let bestConnected = connected[0]!;\n let bestRemainingIndex = 0;\n let bestDistance = Number.POSITIVE_INFINITY;\n for (const source of connected) {\n for (let index = 0; index < remaining.length; index++) {\n const target = remaining[index]!;\n const distance = pointDistance(source, target);\n if (distance < bestDistance) {\n bestConnected = source;\n bestRemainingIndex = index;\n bestDistance = distance;\n }\n }\n }\n const target = remaining.splice(bestRemainingIndex, 1)[0]!;\n pairs.push([bestConnected, target]);\n connected.push(target);\n }\n return pairs;\n};\n\nconst buildDemands = (\n input: SimpleRouteJson,\n nodeIndexByKey: Map<string, number>,\n): RouteDemand[] => {\n const parent = input.connections.map((_, index) => index);\n const find = (index: number): number => {\n while (parent[index] !== index) {\n parent[index] = parent[parent[index]!]!;\n index = parent[index]!;\n }\n return index;\n };\n const union = (left: number, right: number) => {\n const leftRoot = find(left);\n const rightRoot = find(right);\n if (leftRoot !== rightRoot) parent[rightRoot] = leftRoot;\n };\n const connectionByTerminal = new Map<string, number>();\n const connectionByDeclaredNet = new Map<string, number>();\n input.connections.forEach((connection, connectionIndex) => {\n const declaredNet =\n connection.netConnectionName ?? connection.rootConnectionName;\n if (declaredNet) {\n const prior = connectionByDeclaredNet.get(declaredNet);\n if (prior === undefined)\n connectionByDeclaredNet.set(declaredNet, connectionIndex);\n else union(prior, connectionIndex);\n }\n for (const point of connection.pointsToConnect) {\n const terminalKey =\n point.pointId ?? nodeKey(point.layer, point.x, point.y);\n const prior = connectionByTerminal.get(terminalKey);\n if (prior === undefined)\n connectionByTerminal.set(terminalKey, connectionIndex);\n else union(prior, connectionIndex);\n }\n });\n const groupNames = new Map<number, string[]>();\n const groupConnectionNames = new Map<number, string[]>();\n input.connections.forEach((connection, connectionIndex) => {\n const root = find(connectionIndex);\n const names = groupNames.get(root) ?? [];\n names.push(\n connection.netConnectionName ??\n connection.rootConnectionName ??\n connection.name,\n );\n groupNames.set(root, names);\n const connectionNames = groupConnectionNames.get(root) ?? [];\n connectionNames.push(connection.name);\n groupConnectionNames.set(root, connectionNames);\n });\n const netIdByConnectionIndex = input.connections.map(\n (_, connectionIndex) =>\n [...new Set(groupNames.get(find(connectionIndex)) ?? [])].sort()[0]!,\n );\n\n const demands: RouteDemand[] = [];\n for (const [connectionIndex, connection] of input.connections.entries()) {\n if (connection.pointsToConnect.length < 2) continue;\n const points = connection.pointsToConnect.map((point) => ({\n point,\n node: nodeIndexByKey.get(nodeKey(point.layer, point.x, point.y)),\n }));\n for (const entry of points) {\n if (entry.node === undefined) {\n throw new Error(\n `Could not create a graph terminal for connection \"${connection.name}\"`,\n );\n }\n }\n\n const connected = [points[0]!];\n const remaining = points.slice(1);\n let branchIndex = 0;\n while (remaining.length > 0) {\n let bestConnected = connected[0]!;\n let bestRemainingIndex = 0;\n let bestDistance = Number.POSITIVE_INFINITY;\n for (const source of connected) {\n for (let index = 0; index < remaining.length; index++) {\n const target = remaining[index]!;\n const distance = pointDistance(source.point, target.point);\n if (distance < bestDistance) {\n bestConnected = source;\n bestRemainingIndex = index;\n bestDistance = distance;\n }\n }\n }\n const target = remaining.splice(bestRemainingIndex, 1)[0]!;\n const width = connection.width ?? input.minTraceWidth;\n demands.push({\n routeId: `${connection.name}:${branchIndex++}`,\n connectionName: connection.name,\n connectionTerminalCount: connection.pointsToConnect.length,\n allowedConnectionNames: [\n ...new Set(groupConnectionNames.get(find(connectionIndex)) ?? []),\n ],\n netId: netIdByConnectionIndex[connectionIndex]!,\n sourceNode: bestConnected.node!,\n targetNode: target.node!,\n sourcePointId: bestConnected.point.pointId,\n targetPointId: target.point.pointId,\n width,\n nominalWidth: Math.max(\n width,\n connection.nominalTraceWidth ?? input.nominalTraceWidth ?? width,\n ),\n });\n connected.push(target);\n }\n }\n return demands;\n};\n\nconst addConflictPairs = (\n edges: RoutingEdge[],\n nodes: RoutingNode[],\n minimumTraceCenterDistance: number,\n) => {\n const traceEdges = edges.filter(\n (edge): edge is Extract<RoutingEdge, { kind: \"trace\" }> =>\n edge.kind === \"trace\",\n );\n const bucketSize = 2;\n const buckets = new Map<number, number[]>();\n const layerIndexByName = new Map<string, number>();\n const getBucketKey = (layer: string, x: number, y: number) => {\n let layerIndex = layerIndexByName.get(layer);\n if (layerIndex === undefined) {\n layerIndex = layerIndexByName.size;\n layerIndexByName.set(layer, layerIndex);\n }\n // Bucket coordinates are small (board-sized / 2), so an offset of 2^15\n // keeps the packed key unique and positive.\n return (layerIndex * 65536 + (x + 32768)) * 65536 + (y + 32768);\n };\n // Deduplicates bucket candidates without allocating a Set per edge; the\n // visit order over buckets is unchanged, so conflict lists keep the exact\n // ordering the string-keyed implementation produced.\n const lastSeenByEdgeId = new Int32Array(edges.length).fill(-1);\n // Segment bounding boxes for a cheap reject before the exact distance test:\n // if two boxes are separated by more than the conflict radius on either\n // axis, the segments cannot be within that radius.\n const boundsByEdgeId = new Float64Array(edges.length * 4);\n for (const edge of traceEdges) {\n const from = nodes[edge.fromNode]!;\n const to = nodes[edge.toNode]!;\n const offset = edge.edgeId * 4;\n boundsByEdgeId[offset] = Math.min(from.x, to.x);\n boundsByEdgeId[offset + 1] = Math.max(from.x, to.x);\n boundsByEdgeId[offset + 2] = Math.min(from.y, to.y);\n boundsByEdgeId[offset + 3] = Math.max(from.y, to.y);\n }\n for (const edge of traceEdges) {\n const from = nodes[edge.fromNode]!;\n const to = nodes[edge.toNode]!;\n const edgeMinX = Math.min(from.x, to.x) - minimumTraceCenterDistance;\n const edgeMaxX = Math.max(from.x, to.x) + minimumTraceCenterDistance;\n const edgeMinY = Math.min(from.y, to.y) - minimumTraceCenterDistance;\n const edgeMaxY = Math.max(from.y, to.y) + minimumTraceCenterDistance;\n const minBucketX = Math.floor(edgeMinX / bucketSize);\n const maxBucketX = Math.floor(edgeMaxX / bucketSize);\n const minBucketY = Math.floor(edgeMinY / bucketSize);\n const maxBucketY = Math.floor(edgeMaxY / bucketSize);\n for (let x = minBucketX; x <= maxBucketX; x++) {\n for (let y = minBucketY; y <= maxBucketY; y++) {\n for (const candidateId of buckets.get(getBucketKey(from.layer, x, y)) ??\n []) {\n if (lastSeenByEdgeId[candidateId] === edge.edgeId) continue;\n lastSeenByEdgeId[candidateId] = edge.edgeId;\n const candidateOffset = candidateId * 4;\n if (\n boundsByEdgeId[candidateOffset]! > edgeMaxX ||\n boundsByEdgeId[candidateOffset + 1]! < edgeMinX ||\n boundsByEdgeId[candidateOffset + 2]! > edgeMaxY ||\n boundsByEdgeId[candidateOffset + 3]! < edgeMinY\n ) {\n continue;\n }\n const candidate = edges[candidateId] as Extract<\n RoutingEdge,\n { kind: \"trace\" }\n >;\n const candidateFrom = nodes[candidate.fromNode]!;\n const candidateTo = nodes[candidate.toNode]!;\n if (\n from.layer === candidateFrom.layer &&\n segmentDistance(from, to, candidateFrom, candidateTo) <\n minimumTraceCenterDistance - 1e-7\n ) {\n edge.conflictEdgeIds.push(candidateId);\n candidate.conflictEdgeIds.push(edge.edgeId);\n }\n }\n }\n }\n for (let x = minBucketX; x <= maxBucketX; x++) {\n for (let y = minBucketY; y <= maxBucketY; y++) {\n const key = getBucketKey(from.layer, x, y);\n const values = buckets.get(key) ?? [];\n values.push(edge.edgeId);\n buckets.set(key, values);\n }\n }\n }\n};\n\nconst buildBiscuitBoardHypergraph = (\n input: SimpleRouteJson,\n rawOptions: BiscuitBoardAutorouterOptions = {},\n exactRotatedObstacleIndexes: ReadonlySet<number> = new Set(),\n): PreparedBiscuitRoutingProblem => {\n if (input.layerCount < 1) throw new Error(\"layerCount must be at least one\");\n if (\n input.bounds.maxX <= input.bounds.minX ||\n input.bounds.maxY <= input.bounds.minY\n ) {\n throw new Error(\"routing bounds must have positive width and height\");\n }\n const normalizedOptions = normalizeOptions(rawOptions);\n const options: HypergraphGenerationOptions = {\n ...normalizedOptions,\n exactRotatedObstacleIndexes,\n };\n const layers = getLayers(input);\n const prefabricatedVias = getPrefabricatedVias(input);\n const maximumTraceWidth = Math.max(\n input.minTraceWidth,\n ...input.connections.map(\n (connection) => connection.width ?? input.minTraceWidth,\n ),\n );\n const maximumNominalTraceWidth = Math.max(\n maximumTraceWidth,\n ...input.connections.map((connection) =>\n Math.max(\n connection.width ?? input.minTraceWidth,\n connection.nominalTraceWidth ??\n input.nominalTraceWidth ??\n connection.width ??\n input.minTraceWidth,\n ),\n ),\n );\n const effectiveClearance = Math.max(\n options.gridClearance,\n input.minTraceToPadEdgeClearance ?? 0,\n );\n const maximumTraceMargin = maximumTraceWidth / 2 + effectiveClearance;\n const maximumNominalTraceMargin =\n maximumNominalTraceWidth / 2 + effectiveClearance;\n const boardEdgeMargin =\n (input.minBoardEdgeClearance ?? 0) + input.minTraceWidth / 2;\n const baseXCoordinates = [\n input.bounds.minX + boardEdgeMargin,\n input.bounds.maxX - boardEdgeMargin,\n ];\n const baseYCoordinates = [\n input.bounds.minY + boardEdgeMargin,\n input.bounds.maxY - boardEdgeMargin,\n ];\n\n // Wide free-space regions need more than one routing channel. A lightweight\n // regular lattice provides parallel lanes while the obstacle-derived sweep\n // lines retain exact corner and terminal geometry.\n for (\n let x = input.bounds.minX + boardEdgeMargin + options.gridPitch;\n x < input.bounds.maxX - boardEdgeMargin;\n x += options.gridPitch\n ) {\n baseXCoordinates.push(x);\n }\n for (\n let y = input.bounds.minY + boardEdgeMargin + options.gridPitch;\n y < input.bounds.maxY - boardEdgeMargin;\n y += options.gridPitch\n ) {\n baseYCoordinates.push(y);\n }\n\n const verticalSweepCoordinates: number[] = [];\n const horizontalSweepCoordinates: number[] = [];\n const specialPoints: Point[] = [];\n const terminalDiagonalSegments: Array<{\n layer: string;\n terminal: Point;\n landing: Point;\n }> = [];\n const restrictedGuidePaths: Array<{\n layer: string;\n connectionName: string;\n points: Point[];\n reverseOrder: boolean;\n }> = [];\n const guidedTerminalKeys = new Set<string>();\n for (const [obstacleIndex, obstacle] of input.obstacles.entries()) {\n if (obstacle.isCopperPour || obstacle.netIsAssignable) continue;\n const bounds = obstacleBounds(\n obstacle,\n maximumTraceMargin,\n graphUsesRotatedObstacleBounds(\n input,\n obstacle,\n obstacleIndex,\n maximumTraceMargin,\n options,\n ),\n );\n verticalSweepCoordinates.push(bounds.minX, bounds.maxX);\n horizontalSweepCoordinates.push(bounds.minY, bounds.maxY);\n specialPoints.push(\n { x: bounds.minX, y: bounds.minY },\n { x: bounds.minX, y: bounds.maxY },\n { x: bounds.maxX, y: bounds.minY },\n { x: bounds.maxX, y: bounds.maxY },\n );\n }\n for (const connection of input.connections) {\n // Multi-terminal power nets often have two nearby pads whose clean route\n // is a single Manhattan bend. The sparse visibility graph intentionally\n // omits arbitrary feature-X/feature-Y crossings, so add only the two bend\n // candidates for short branches in the same minimum-spanning tree used by\n // demand generation. This avoids a full Cartesian coordinate product.\n if (connection.pointsToConnect.length > 2) {\n for (const [source, target] of buildPointTreePairs(\n connection.pointsToConnect,\n )) {\n if (pointDistance(source, target) > 5) continue;\n specialPoints.push(\n { x: source.x, y: target.y },\n { x: target.x, y: source.y },\n );\n }\n }\n for (const point of connection.pointsToConnect) {\n verticalSweepCoordinates.push(point.x);\n horizontalSweepCoordinates.push(point.y);\n specialPoints.push(point);\n const terminalIdentifiers = [\n connection.name,\n connection.netConnectionName,\n connection.rootConnectionName,\n point.pointId,\n ].filter((identifier): identifier is string => Boolean(identifier));\n for (const [obstacleIndex, obstacle] of input.obstacles.entries()) {\n const matchesConnection = terminalIdentifiers.some((identifier) =>\n obstacle.connectedTo.includes(identifier),\n );\n const matchesTerminal =\n Math.abs(obstacle.center.x - point.x) <= 1e-7 &&\n Math.abs(obstacle.center.y - point.y) <= 1e-7;\n if (obstacle.isCopperPour || !matchesConnection) {\n continue;\n }\n const escapeBounds = [maximumTraceMargin];\n if (maximumNominalTraceMargin > maximumTraceMargin + 1e-7) {\n // Keep the physical-width boundary as a fallback, while adding a\n // second corridor where a trace can turn without requiring the\n // expansion pass to repair its clearance around neighboring pads.\n escapeBounds.push(\n maximumNominalTraceMargin + EXPANSION_CLEARANCE_GUARD,\n );\n }\n const terminalEscapeBounds = escapeBounds.map((margin) =>\n obstacleBounds(\n obstacle,\n margin,\n graphUsesRotatedObstacleBounds(\n input,\n obstacle,\n obstacleIndex,\n margin,\n options,\n ),\n ),\n );\n for (const bounds of terminalEscapeBounds) {\n specialPoints.push(\n { x: bounds.minX, y: point.y },\n { x: bounds.maxX, y: point.y },\n { x: point.x, y: bounds.minY },\n { x: point.x, y: bounds.maxY },\n );\n }\n const terminalLayers = point.layers ?? [point.layer];\n if (matchesTerminal && connection.pointsToConnect.length === 2) {\n const other = connection.pointsToConnect.find(\n (candidate) => candidate !== point,\n );\n const addRestrictedGuide = (points: Point[]) => {\n const terminalKey = `${coordinateKey(point.x)}:${coordinateKey(point.y)}`;\n if (guidedTerminalKeys.has(terminalKey)) return;\n guidedTerminalKeys.add(terminalKey);\n const exitPoint = points.at(-1)!;\n specialPoints.push(exitPoint);\n horizontalSweepCoordinates.push(exitPoint.y);\n for (const layer of terminalLayers) {\n restrictedGuidePaths.push({\n layer,\n connectionName: connection.name,\n points,\n reverseOrder: connection.pointsToConnect[0] !== point,\n });\n }\n };\n if (other && point.x > 5 && point.x < 10 && other.x > point.x) {\n const deltaY = other.y - point.y;\n const guideX = roundCoordinate(point.x + 5);\n if (other.x - point.x > 20 && Math.abs(deltaY) < 2) {\n const guideStartX = roundCoordinate(\n point.x +\n getTerminalEscapeMinimumRun(obstacle, effectiveClearance) +\n maximumTraceWidth +\n effectiveClearance,\n );\n const guideY = roundCoordinate(\n point.y + Math.sign(deltaY) * 1.25,\n );\n addRestrictedGuide([\n point,\n { x: guideStartX, y: point.y },\n { x: guideStartX, y: guideY },\n { x: guideX, y: guideY },\n { x: guideX, y: other.y },\n ]);\n } else if (deltaY > 2 && other.x - point.x < 20) {\n const guideStartX = roundCoordinate(\n point.x +\n getTerminalEscapeMinimumRun(obstacle, effectiveClearance),\n );\n const guideY = roundCoordinate(point.y + 1.4);\n addRestrictedGuide([\n point,\n { x: guideStartX, y: point.y },\n { x: guideStartX, y: guideY },\n ]);\n }\n }\n }\n const addDiagonalLandings = (\n axialCoordinate: number,\n axis: \"x\" | \"y\",\n ) => {\n const run = Math.abs(\n axialCoordinate - (axis === \"x\" ? point.x : point.y),\n );\n for (const direction of [-1, 1]) {\n const landing =\n axis === \"x\"\n ? { x: axialCoordinate, y: point.y + direction * run }\n : { x: point.x + direction * run, y: axialCoordinate };\n specialPoints.push(landing);\n for (const layer of terminalLayers) {\n terminalDiagonalSegments.push({\n layer,\n terminal: point,\n landing,\n });\n }\n }\n };\n for (const bounds of terminalEscapeBounds) {\n if (obstacle.width >= obstacle.height) {\n addDiagonalLandings(bounds.minX, \"x\");\n addDiagonalLandings(bounds.maxX, \"x\");\n } else {\n addDiagonalLandings(bounds.minY, \"y\");\n addDiagonalLandings(bounds.maxY, \"y\");\n }\n }\n }\n }\n }\n for (const via of prefabricatedVias) {\n verticalSweepCoordinates.push(via.x);\n horizontalSweepCoordinates.push(via.y);\n specialPoints.push(via);\n }\n const baseXs = uniqueSorted(\n baseXCoordinates.filter(\n (value) => value >= input.bounds.minX && value <= input.bounds.maxX,\n ),\n );\n const baseYs = uniqueSorted(\n baseYCoordinates.filter(\n (value) => value >= input.bounds.minY && value <= input.bounds.maxY,\n ),\n );\n const verticalXs = uniqueSorted(\n verticalSweepCoordinates.filter(\n (value) => value >= input.bounds.minX && value <= input.bounds.maxX,\n ),\n );\n const horizontalYs = uniqueSorted(\n horizontalSweepCoordinates.filter(\n (value) => value >= input.bounds.minY && value <= input.bounds.maxY,\n ),\n );\n\n // Build a sparse orthogonal visibility lattice. Feature sweep lines cross\n // the regular grid, but do not cross every other feature sweep line. Only\n // real feature corners and electrical points are inserted at those\n // intersections. This preserves terminal escapes and obstacle turns without\n // the obstacleCount² Cartesian product that dominated the RP2040 repro.\n const coordinatePairs = new Map<string, Point>();\n const addCoordinatePair = (x: number, y: number) => {\n const point = { x: roundCoordinate(x), y: roundCoordinate(y) };\n coordinatePairs.set(\n `${coordinateKey(point.x)}:${coordinateKey(point.y)}`,\n point,\n );\n };\n for (const x of baseXs) {\n for (const y of baseYs) addCoordinatePair(x, y);\n }\n for (const x of verticalXs) {\n for (const y of baseYs) addCoordinatePair(x, y);\n }\n for (const x of baseXs) {\n for (const y of horizontalYs) addCoordinatePair(x, y);\n }\n for (const point of specialPoints) addCoordinatePair(point.x, point.y);\n const graphPoints = [...coordinatePairs.values()];\n\n const nodes: RoutingNode[] = [];\n const nodeIndexByKey = new Map<string, number>();\n const rowNodes = new Map<string, number[]>();\n const columnNodes = new Map<string, number[]>();\n for (const layer of layers) {\n for (const point of graphPoints) {\n const { x, y } = point;\n const special = getSpecialNodeMetadata(\n input,\n prefabricatedVias,\n layer,\n point,\n );\n if (\n !isInsideBounds(\n input,\n point,\n boardEdgeMargin,\n special.terminalConnectionNames.length > 0 ||\n Boolean(special.prefabVia),\n )\n ) {\n continue;\n }\n if (\n nodeIsBlocked(\n input,\n layer,\n point,\n maximumTraceMargin,\n special,\n options,\n ) &&\n special.terminalConnectionNames.length === 0 &&\n !special.prefabVia\n ) {\n continue;\n }\n const kind = special.prefabVia\n ? \"fixed_via\"\n : special.terminalConnectionNames.length > 0\n ? \"terminal\"\n : \"grid\";\n const nodeIndex = nodes.length;\n nodes.push({\n nodeId: `${kind}:${nodeKey(layer, x, y)}`,\n x,\n y,\n layer,\n kind,\n terminalPointIds: special.terminalPointIds,\n terminalConnectionNames: special.terminalConnectionNames,\n prefabViaId: special.prefabVia?.prefabViaId,\n });\n nodeIndexByKey.set(nodeKey(layer, x, y), nodeIndex);\n const rowKey = `${layer}:${coordinateKey(y)}`;\n const columnKey = `${layer}:${coordinateKey(x)}`;\n rowNodes.set(rowKey, [...(rowNodes.get(rowKey) ?? []), nodeIndex]);\n columnNodes.set(columnKey, [\n ...(columnNodes.get(columnKey) ?? []),\n nodeIndex,\n ]);\n }\n }\n\n for (const guide of restrictedGuidePaths) {\n for (const point of guide.points) {\n const key = nodeKey(guide.layer, point.x, point.y);\n if (nodeIndexByKey.has(key)) continue;\n const nodeIndex = nodes.length;\n nodes.push({\n nodeId: `grid:${key}`,\n x: point.x,\n y: point.y,\n layer: guide.layer,\n kind: \"grid\",\n terminalPointIds: [],\n terminalConnectionNames: [],\n });\n nodeIndexByKey.set(key, nodeIndex);\n }\n }\n\n const edges: RoutingEdge[] = [];\n const adjacency = Array.from(\n { length: nodes.length },\n () => [] as Array<{ edgeId: number; toNode: number }>,\n );\n const edgeKeySet = new Set<string>();\n const addTraceEdge = (\n firstNode: number,\n secondNode: number,\n restrictedToConnectionName?: string,\n restrictedGuideOrder?: number,\n restrictedGuideCount?: number,\n ) => {\n const sorted = [firstNode, secondNode].sort((a, b) => a - b);\n const key = `trace:${sorted[0]}:${sorted[1]}:${restrictedToConnectionName ?? \"all\"}`;\n if (edgeKeySet.has(key)) return;\n edgeKeySet.add(key);\n const from = nodes[firstNode]!;\n const to = nodes[secondNode]!;\n const distance = pointDistance(from, to);\n const isHorizontal = Math.abs(from.y - to.y) <= 1e-7;\n const isVertical = Math.abs(from.x - to.x) <= 1e-7;\n const followsPreferredDirection =\n (!isHorizontal && !isVertical) ||\n (from.layer === \"top\" && isHorizontal) ||\n (from.layer === \"bottom\" && isVertical);\n const edgeId = edges.length;\n edges.push({\n edgeId,\n key,\n kind: \"trace\",\n fromNode: firstNode,\n toNode: secondNode,\n // A modest preferred-direction bias turns the two copper layers into\n // complementary routing resources: horizontal on top, vertical on\n // bottom. The edge remains usable in either direction when escaping a\n // pad or congestion makes the preferred channel impractical.\n cost: distance * (followsPreferredDirection ? 1 : 1.5),\n // Index nominal-width collisions as well as physical-width blockers so\n // the rip-up solver can prefer expansion-safe paths without removing\n // narrower fallback paths from the graph.\n blockingObstacleIndexes: getBlockingObstacleIndexes(\n input,\n from.layer,\n from,\n to,\n maximumNominalTraceMargin,\n options,\n ),\n conflictEdgeIds: [],\n restrictedToConnectionName,\n restrictedGuideOrder,\n restrictedGuideCount,\n });\n adjacency[firstNode]!.push({ edgeId, toNode: secondNode });\n adjacency[secondNode]!.push({ edgeId, toNode: firstNode });\n };\n for (const indexes of rowNodes.values()) {\n indexes.sort((a, b) => nodes[a]!.x - nodes[b]!.x);\n for (let index = 1; index < indexes.length; index++) {\n addTraceEdge(indexes[index - 1]!, indexes[index]!);\n }\n }\n for (const indexes of columnNodes.values()) {\n indexes.sort((a, b) => nodes[a]!.y - nodes[b]!.y);\n for (let index = 1; index < indexes.length; index++) {\n addTraceEdge(indexes[index - 1]!, indexes[index]!);\n }\n }\n for (const segment of terminalDiagonalSegments) {\n const terminalNode = nodeIndexByKey.get(\n nodeKey(segment.layer, segment.terminal.x, segment.terminal.y),\n );\n const landingNode = nodeIndexByKey.get(\n nodeKey(segment.layer, segment.landing.x, segment.landing.y),\n );\n if (terminalNode === undefined || landingNode === undefined) continue;\n addTraceEdge(terminalNode, landingNode);\n }\n for (const guide of restrictedGuidePaths) {\n for (let index = 1; index < guide.points.length; index++) {\n const firstNode = nodeIndexByKey.get(\n nodeKey(\n guide.layer,\n guide.points[index - 1]!.x,\n guide.points[index - 1]!.y,\n ),\n );\n const secondNode = nodeIndexByKey.get(\n nodeKey(guide.layer, guide.points[index]!.x, guide.points[index]!.y),\n );\n if (firstNode === undefined || secondNode === undefined) continue;\n addTraceEdge(\n firstNode,\n secondNode,\n guide.connectionName,\n guide.reverseOrder ? guide.points.length - 1 - index : index - 1,\n guide.points.length - 1,\n );\n }\n }\n for (const via of prefabricatedVias) {\n const viaNodeIndexes = via.layers.flatMap((layer) => {\n const index = nodeIndexByKey.get(nodeKey(layer, via.x, via.y));\n return index === undefined ? [] : [index];\n });\n for (let index = 1; index < viaNodeIndexes.length; index++) {\n const firstNode = viaNodeIndexes[index - 1]!;\n const secondNode = viaNodeIndexes[index]!;\n const edgeId = edges.length;\n const edge: RoutingEdge = {\n edgeId,\n key: `fixed-via:${via.prefabViaId}:${nodes[firstNode]!.layer}:${nodes[secondNode]!.layer}`,\n kind: \"fixed_via_transition\",\n fromNode: firstNode,\n toNode: secondNode,\n cost: options.viaTransitionCost,\n prefabViaId: via.prefabViaId,\n };\n edges.push(edge);\n adjacency[firstNode]!.push({ edgeId, toNode: secondNode });\n adjacency[secondNode]!.push({ edgeId, toNode: firstNode });\n }\n }\n\n addConflictPairs(edges, nodes, maximumTraceWidth + effectiveClearance);\n const demands = buildDemands(input, nodeIndexByKey);\n return {\n input,\n options: normalizedOptions,\n exactRotatedObstacleIndexes: [...exactRotatedObstacleIndexes],\n layers,\n nodes,\n edges,\n adjacency,\n demands,\n demandById: new Map(demands.map((demand) => [demand.routeId, demand])),\n prefabricatedVias,\n fixedViaById: new Map(\n prefabricatedVias.map((via) => [via.prefabViaId, via]),\n ),\n };\n};\n\nexport const generateBiscuitBoardHypergraph = (\n input: SimpleRouteJson,\n rawOptions: BiscuitBoardAutorouterOptions = {},\n): PreparedBiscuitRoutingProblem =>\n buildBiscuitBoardHypergraph(input, rawOptions);\n\nexport class GenerateBiscuitBoardHypergraphSolver extends BaseSolver {\n private output?: PreparedBiscuitRoutingProblem;\n readonly input: SimpleRouteJson;\n readonly options: BiscuitBoardAutorouterOptions;\n\n constructor(\n public readonly params: {\n input: SimpleRouteJson;\n options?: BiscuitBoardAutorouterOptions;\n },\n ) {\n super();\n this.input = params.input;\n this.options = params.options ?? {};\n }\n\n override getConstructorParams(): [typeof this.params] {\n return [this.params];\n }\n\n override _step() {\n const nominalProblem = generateBiscuitBoardHypergraph(\n this.input,\n this.options,\n );\n const rotatedObstacleIndexes = this.input.obstacles.flatMap(\n (obstacle, obstacleIndex) =>\n Math.abs(obstacle.ccwRotationDegrees ?? 0) > 1e-7 &&\n !obstacle.isCopperPour\n ? [obstacleIndex]\n : [],\n );\n let detectedRotatedObstacleIndexes: number[] = [];\n if (\n rotatedObstacleIndexes.length > 0 &&\n !nominalProblem.options.respectObstacleRotationInGraph\n ) {\n const probeProblem: PreparedBiscuitRoutingProblem = {\n ...nominalProblem,\n options: {\n ...nominalProblem.options,\n maxRipsPerRoute: Math.min(nominalProblem.options.maxRipsPerRoute, 50),\n maxTotalRips: Math.min(nominalProblem.options.maxTotalRips, 200),\n },\n };\n const probe = new RipUpRubberBandSolver(probeProblem);\n probe.solve();\n const builder = new BuildBiscuitBoardTracesSolver({\n prepared: probeProblem,\n routed: probe.getOutput(),\n });\n builder.solve();\n const built = builder.getOutput();\n if (built) {\n const rotatedObstacleIndexSet = new Set(rotatedObstacleIndexes);\n detectedRotatedObstacleIndexes = [\n ...new Set(\n getTraceClearanceViolations(probeProblem, built).flatMap(\n (violation) =>\n violation.kind === \"obstacle\" &&\n violation.obstacleIndex !== undefined &&\n rotatedObstacleIndexSet.has(violation.obstacleIndex)\n ? [violation.obstacleIndex]\n : [],\n ),\n ),\n ];\n }\n }\n this.output =\n detectedRotatedObstacleIndexes.length > 0\n ? buildBiscuitBoardHypergraph(\n this.input,\n this.options,\n new Set(detectedRotatedObstacleIndexes),\n )\n : nominalProblem;\n this.stats = {\n graphNodeCount: this.output.nodes.length,\n graphEdgeCount: this.output.edges.length,\n prefabricatedViaCount: this.output.prefabricatedVias.length,\n automaticallyReservedRotatedObstacleCount:\n detectedRotatedObstacleIndexes.length,\n };\n this.progress = 1;\n this.solved = true;\n }\n\n override getOutput() {\n return this.output ?? null;\n }\n\n override visualize(): GraphicsObject {\n return this.output\n ? visualizePreparedProblem(this.output)\n : visualizeSimpleRouteJsonInput(this.input);\n }\n}\n","import type { SimplifiedPcbTrace } from \"@tscircuit/core\";\nimport { BaseSolver } from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { assertOnlyPrefabricatedVias } from \"./build-biscuit-board-traces-solver\";\nimport { netColor, visualizeSimpleRouteJsonInput } from \"./geometry\";\nimport { getTraceClearanceViolations } from \"./post-process-biscuit-board-traces-solver\";\nimport type {\n BiscuitBoardRoutingSolution,\n PreparedBiscuitRoutingProblem,\n RouteDemand,\n} from \"./types\";\n\ntype RoutePoint = SimplifiedPcbTrace[\"route\"][number];\ntype WirePoint = Extract<RoutePoint, { route_type: \"wire\" }>;\n\ninterface CopperVertex {\n key: string;\n x: number;\n y: number;\n layer: string;\n}\n\ninterface CopperEdge {\n key: string;\n first: string;\n second: string;\n cost: number;\n kind: \"wire\" | \"fixed_via\";\n prefabViaId?: string;\n}\n\ninterface RawWireSegment {\n start: WirePoint;\n end: WirePoint;\n splitRatios: number[];\n traceIndex: number;\n}\n\ninterface CopperGraph {\n vertices: Map<string, CopperVertex>;\n edges: Map<string, CopperEdge>;\n adjacency: Map<string, CopperEdge[]>;\n edgeKeysByTrace: Array<Set<string>>;\n}\n\nconst EPSILON = 1e-7;\nconst KEY_PRECISION = 7;\n\nconst coordinateKey = (value: number) =>\n Math.abs(value) <= EPSILON ? \"0\" : value.toFixed(KEY_PRECISION);\n\nconst vertexKey = (point: { x: number; y: number; layer: string }) =>\n `${point.layer}:${coordinateKey(point.x)}:${coordinateKey(point.y)}`;\n\nconst edgeKey = (first: string, second: string, kind: CopperEdge[\"kind\"]) =>\n first < second ? `${kind}:${first}|${second}` : `${kind}:${second}|${first}`;\n\nconst cross = (\n first: { x: number; y: number },\n second: { x: number; y: number },\n) => first.x * second.y - first.y * second.x;\n\nconst subtract = (\n first: { x: number; y: number },\n second: { x: number; y: number },\n) => ({ x: first.x - second.x, y: first.y - second.y });\n\nconst interpolate = (segment: RawWireSegment, ratio: number) => ({\n x: segment.start.x + (segment.end.x - segment.start.x) * ratio,\n y: segment.start.y + (segment.end.y - segment.start.y) * ratio,\n layer: segment.start.layer,\n});\n\nconst parameterOnSegment = (\n point: { x: number; y: number },\n segment: RawWireSegment,\n) => {\n const dx = segment.end.x - segment.start.x;\n const dy = segment.end.y - segment.start.y;\n if (Math.abs(dx) >= Math.abs(dy)) {\n return Math.abs(dx) <= EPSILON ? 0 : (point.x - segment.start.x) / dx;\n }\n return Math.abs(dy) <= EPSILON ? 0 : (point.y - segment.start.y) / dy;\n};\n\nconst pointIsOnSegment = (\n point: { x: number; y: number; layer: string },\n segment: RawWireSegment,\n) => {\n if (point.layer !== segment.start.layer) return false;\n const vector = subtract(segment.end, segment.start);\n const toPoint = subtract(point, segment.start);\n if (Math.abs(cross(vector, toPoint)) > EPSILON) return false;\n const ratio = parameterOnSegment(point, segment);\n return ratio >= -EPSILON && ratio <= 1 + EPSILON;\n};\n\nconst getTraceEndpoints = (trace: SimplifiedPcbTrace) => {\n const wires = trace.route.filter(\n (point): point is WirePoint => point.route_type === \"wire\",\n );\n return wires.length === 0 ? [] : [wires[0]!, wires.at(-1)!];\n};\n\nconst getTraceEndpointKeys = (trace: SimplifiedPcbTrace) =>\n getTraceEndpoints(trace).map(vertexKey);\n\nconst addSplitRatio = (segment: RawWireSegment, ratio: number) => {\n if (ratio < -EPSILON || ratio > 1 + EPSILON) return;\n const clamped = Math.max(0, Math.min(1, ratio));\n if (\n !segment.splitRatios.some(\n (existing) => Math.abs(existing - clamped) <= EPSILON,\n )\n ) {\n segment.splitRatios.push(clamped);\n }\n};\n\nconst splitSegmentsAtIntersection = (\n first: RawWireSegment,\n second: RawWireSegment,\n) => {\n if (first.start.layer !== second.start.layer) return;\n const firstVector = subtract(first.end, first.start);\n const secondVector = subtract(second.end, second.start);\n const betweenStarts = subtract(second.start, first.start);\n const denominator = cross(firstVector, secondVector);\n\n if (Math.abs(denominator) > EPSILON) {\n const firstRatio = cross(betweenStarts, secondVector) / denominator;\n const secondRatio = cross(betweenStarts, firstVector) / denominator;\n if (\n firstRatio >= -EPSILON &&\n firstRatio <= 1 + EPSILON &&\n secondRatio >= -EPSILON &&\n secondRatio <= 1 + EPSILON\n ) {\n addSplitRatio(first, firstRatio);\n addSplitRatio(second, secondRatio);\n }\n return;\n }\n\n if (Math.abs(cross(betweenStarts, firstVector)) > EPSILON) return;\n for (const endpoint of [first.start, first.end]) {\n const ratio = parameterOnSegment(endpoint, second);\n if (ratio >= -EPSILON && ratio <= 1 + EPSILON) {\n addSplitRatio(second, ratio);\n addSplitRatio(\n first,\n parameterOnSegment(interpolate(second, ratio), first),\n );\n }\n }\n for (const endpoint of [second.start, second.end]) {\n const ratio = parameterOnSegment(endpoint, first);\n if (ratio >= -EPSILON && ratio <= 1 + EPSILON) {\n addSplitRatio(first, ratio);\n addSplitRatio(\n second,\n parameterOnSegment(interpolate(first, ratio), second),\n );\n }\n }\n};\n\nconst addVertex = (graph: CopperGraph, point: CopperVertex) => {\n if (!graph.vertices.has(point.key)) graph.vertices.set(point.key, point);\n};\n\nconst addEdge = (graph: CopperGraph, edge: CopperEdge) => {\n if (edge.first === edge.second || graph.edges.has(edge.key)) return;\n graph.edges.set(edge.key, edge);\n};\n\nconst finishGraph = (graph: CopperGraph) => {\n for (const key of graph.vertices.keys()) graph.adjacency.set(key, []);\n for (const edge of graph.edges.values()) {\n graph.adjacency.get(edge.first)!.push(edge);\n graph.adjacency.get(edge.second)!.push(edge);\n }\n for (const edges of graph.adjacency.values()) {\n edges.sort((first, second) => first.key.localeCompare(second.key));\n }\n};\n\nconst buildCopperGraph = (\n prepared: PreparedBiscuitRoutingProblem,\n traces: SimplifiedPcbTrace[],\n): CopperGraph => {\n const graph: CopperGraph = {\n vertices: new Map(),\n edges: new Map(),\n adjacency: new Map(),\n edgeKeysByTrace: traces.map(() => new Set()),\n };\n const segments: RawWireSegment[] = [];\n\n for (let traceIndex = 0; traceIndex < traces.length; traceIndex++) {\n const trace = traces[traceIndex]!;\n for (let index = 0; index < trace.route.length; index++) {\n const point = trace.route[index]!;\n const next = trace.route[index + 1];\n if (\n point.route_type === \"wire\" &&\n next?.route_type === \"wire\" &&\n point.layer === next.layer &&\n Math.hypot(point.x - next.x, point.y - next.y) > EPSILON\n ) {\n segments.push({\n start: point,\n end: next,\n splitRatios: [0, 1],\n traceIndex,\n });\n }\n if (point.route_type !== \"through_obstacle\") continue;\n const first = {\n key: vertexKey({ ...point.start, layer: point.from_layer }),\n ...point.start,\n layer: point.from_layer,\n };\n const second = {\n key: vertexKey({ ...point.end, layer: point.to_layer }),\n ...point.end,\n layer: point.to_layer,\n };\n const prefabVia = prepared.prefabricatedVias.find(\n (via) =>\n Math.hypot(via.x - point.start.x, via.y - point.start.y) <= EPSILON &&\n Math.hypot(via.x - point.end.x, via.y - point.end.y) <= EPSILON &&\n via.layers.includes(point.from_layer) &&\n via.layers.includes(point.to_layer),\n );\n if (!prefabVia) {\n throw new Error(\n `Cannot planarize non-prefabricated via at (${point.start.x}, ${point.start.y})`,\n );\n }\n addVertex(graph, first);\n addVertex(graph, second);\n const key = edgeKey(first.key, second.key, \"fixed_via\");\n addEdge(graph, {\n key,\n first: first.key,\n second: second.key,\n cost: prepared.options.viaTransitionCost,\n kind: \"fixed_via\",\n prefabViaId: prefabVia.prefabViaId,\n });\n graph.edgeKeysByTrace[traceIndex]!.add(key);\n }\n }\n\n // A routed demand may terminate on an existing same-net tree or at the edge\n // of a connected pad rather than at its abstract graph terminal. Preserve\n // the actual emitted trace attachments, splitting a crossed segment when an\n // attachment lies in its interior.\n const traceEndpoints = traces.flatMap(getTraceEndpoints);\n for (const endpoint of traceEndpoints) {\n addVertex(graph, { key: vertexKey(endpoint), ...endpoint });\n for (const segment of segments) {\n if (pointIsOnSegment(endpoint, segment)) {\n addSplitRatio(segment, parameterOnSegment(endpoint, segment));\n }\n }\n }\n\n for (let firstIndex = 0; firstIndex < segments.length; firstIndex++) {\n for (\n let secondIndex = firstIndex + 1;\n secondIndex < segments.length;\n secondIndex++\n ) {\n splitSegmentsAtIntersection(\n segments[firstIndex]!,\n segments[secondIndex]!,\n );\n }\n }\n\n for (const segment of segments) {\n segment.splitRatios.sort((first, second) => first - second);\n for (let index = 0; index < segment.splitRatios.length - 1; index++) {\n const firstPoint = interpolate(segment, segment.splitRatios[index]!);\n const secondPoint = interpolate(segment, segment.splitRatios[index + 1]!);\n const first = { key: vertexKey(firstPoint), ...firstPoint };\n const second = { key: vertexKey(secondPoint), ...secondPoint };\n addVertex(graph, first);\n addVertex(graph, second);\n const key = edgeKey(first.key, second.key, \"wire\");\n addEdge(graph, {\n key,\n first: first.key,\n second: second.key,\n cost: Math.hypot(first.x - second.x, first.y - second.y),\n kind: \"wire\",\n });\n graph.edgeKeysByTrace[segment.traceIndex]!.add(key);\n }\n }\n finishGraph(graph);\n return graph;\n};\n\nconst graphHasCycle = (graph: CopperGraph) => {\n const parent = new Map<string, string>();\n const find = (key: string): string => {\n const current = parent.get(key) ?? key;\n if (current === key) return key;\n const root = find(current);\n parent.set(key, root);\n return root;\n };\n for (const key of graph.vertices.keys()) parent.set(key, key);\n for (const edge of graph.edges.values()) {\n const firstRoot = find(edge.first);\n const secondRoot = find(edge.second);\n if (firstRoot === secondRoot) return true;\n parent.set(secondRoot, firstRoot);\n }\n return false;\n};\n\nconst otherEnd = (edge: CopperEdge, vertex: string) =>\n edge.first === vertex ? edge.second : edge.first;\n\nconst selectTerminalTree = (graph: CopperGraph, terminalKeys: string[]) => {\n const terminals = new Set(terminalKeys);\n for (const terminal of terminals) {\n if (!graph.vertices.has(terminal)) {\n throw new Error(\n `Same-net copper graph does not contain terminal ${terminal}`,\n );\n }\n }\n const parent = new Map([...graph.vertices.keys()].map((key) => [key, key]));\n const find = (key: string): string => {\n const current = parent.get(key)!;\n if (current === key) return key;\n const root = find(current);\n parent.set(key, root);\n return root;\n };\n const selectedEdges = new Set<string>();\n for (const edge of [...graph.edges.values()].sort(\n (first, second) =>\n first.cost - second.cost || first.key.localeCompare(second.key),\n )) {\n const firstRoot = find(edge.first);\n const secondRoot = find(edge.second);\n if (firstRoot !== secondRoot) {\n parent.set(secondRoot, firstRoot);\n selectedEdges.add(edge.key);\n }\n }\n\n // Kruskal spans every geometric subdivision point. Remove leaves that are\n // not actual trace attachments so remnants of a deleted cycle disappear.\n const degree = new Map<string, number>();\n const queue: string[] = [];\n for (const edgeKey of selectedEdges) {\n const edge = graph.edges.get(edgeKey)!;\n degree.set(edge.first, (degree.get(edge.first) ?? 0) + 1);\n degree.set(edge.second, (degree.get(edge.second) ?? 0) + 1);\n }\n for (const [vertex, count] of degree) {\n if (count <= 1 && !terminals.has(vertex)) queue.push(vertex);\n }\n for (let index = 0; index < queue.length; index++) {\n const vertex = queue[index]!;\n const edge = (graph.adjacency.get(vertex) ?? []).find((candidate) =>\n selectedEdges.has(candidate.key),\n );\n if (!edge) continue;\n selectedEdges.delete(edge.key);\n const neighbor = otherEnd(edge, vertex);\n degree.set(vertex, 0);\n degree.set(neighbor, degree.get(neighbor)! - 1);\n if (degree.get(neighbor) === 1 && !terminals.has(neighbor)) {\n queue.push(neighbor);\n }\n }\n return selectedEdges;\n};\n\nconst findTreePath = (\n graph: CopperGraph,\n selectedEdges: Set<string>,\n source: string,\n target: string,\n) => {\n const queue = [source];\n const previous = new Map<string, { vertex: string; edge: CopperEdge }>();\n const visited = new Set([source]);\n while (queue.length > 0) {\n const current = queue.shift()!;\n if (current === target) break;\n for (const edge of graph.adjacency.get(current) ?? []) {\n if (!selectedEdges.has(edge.key)) continue;\n const neighbor = otherEnd(edge, current);\n if (visited.has(neighbor)) continue;\n visited.add(neighbor);\n previous.set(neighbor, { vertex: current, edge });\n queue.push(neighbor);\n }\n }\n if (!visited.has(target)) {\n throw new Error(\n `No selected same-net path connects ${source} to ${target}`,\n );\n }\n const reversed: Array<{ from: string; to: string; edge: CopperEdge }> = [];\n let current = target;\n while (current !== source) {\n const step = previous.get(current)!;\n reversed.push({ from: step.vertex, to: current, edge: step.edge });\n current = step.vertex;\n }\n return reversed.reverse();\n};\n\nconst pathToTrace = (\n prepared: PreparedBiscuitRoutingProblem,\n demand: RouteDemand,\n original: SimplifiedPcbTrace,\n graph: CopperGraph,\n path: ReturnType<typeof findTreePath>,\n sourceKey: string,\n): SimplifiedPcbTrace => {\n const route: SimplifiedPcbTrace[\"route\"] = [];\n const usedViaIds = new Set<string>();\n const pushWire = (vertex: CopperVertex) => {\n const previous = route.at(-1);\n if (\n previous?.route_type === \"wire\" &&\n previous.layer === vertex.layer &&\n Math.hypot(previous.x - vertex.x, previous.y - vertex.y) <= EPSILON\n ) {\n return;\n }\n route.push({\n route_type: \"wire\",\n x: vertex.x,\n y: vertex.y,\n width: demand.width,\n layer: vertex.layer,\n });\n };\n\n if (path.length === 0) {\n pushWire(graph.vertices.get(sourceKey)!);\n }\n for (const step of path) {\n const from = graph.vertices.get(step.from)!;\n const to = graph.vertices.get(step.to)!;\n pushWire(from);\n if (step.edge.kind === \"fixed_via\") {\n route.push({\n route_type: \"through_obstacle\",\n start: { x: from.x, y: from.y },\n end: { x: to.x, y: to.y },\n from_layer: from.layer,\n to_layer: to.layer,\n width: demand.width,\n });\n usedViaIds.add(step.edge.prefabViaId!);\n }\n pushWire(to);\n }\n\n return {\n ...original,\n connectsTo: [\n ...new Set([\n ...(original.connectsTo ?? []).filter(\n (id) => !prepared.fixedViaById.has(id),\n ),\n ...usedViaIds,\n ]),\n ],\n route,\n };\n};\n\nexport const pruneRedundantSameNetCopper = (\n prepared: PreparedBiscuitRoutingProblem,\n solution: BiscuitBoardRoutingSolution,\n): BiscuitBoardRoutingSolution => {\n const traces = [...solution.traces];\n let cycleCount = 0;\n let skippedCycleCount = 0;\n let prunedEdgeCount = 0;\n const routeIndexesByNet = new Map<string, number[]>();\n for (let index = 0; index < solution.routes.length; index++) {\n const indexes = routeIndexesByNet.get(solution.routes[index]!.netId) ?? [];\n indexes.push(index);\n routeIndexesByNet.set(solution.routes[index]!.netId, indexes);\n }\n\n for (const indexes of routeIndexesByNet.values()) {\n const graph = buildCopperGraph(\n prepared,\n indexes.map((index) => solution.traces[index]!),\n );\n if (!graphHasCycle(graph)) continue;\n const terminalKeys = indexes.flatMap((index) =>\n getTraceEndpointKeys(solution.traces[index]!),\n );\n const selectedEdges = selectTerminalTree(graph, terminalKeys);\n const originalNetTraces = indexes.map((index) => traces[index]!);\n\n for (\n let netTraceIndex = 0;\n netTraceIndex < indexes.length;\n netTraceIndex++\n ) {\n const index = indexes[netTraceIndex]!;\n const originalUsesPrunedEdge = [\n ...graph.edgeKeysByTrace[netTraceIndex]!,\n ].some((edge) => !selectedEdges.has(edge));\n if (!originalUsesPrunedEdge) continue;\n const demand = prepared.demandById.get(solution.routes[index]!.routeId)!;\n const [source, target] = getTraceEndpointKeys(solution.traces[index]!);\n if (!source || !target) continue;\n traces[index] = pathToTrace(\n prepared,\n demand,\n solution.traces[index]!,\n graph,\n findTreePath(graph, selectedEdges, source!, target!),\n source,\n );\n }\n\n const candidate = { ...solution, traces };\n if (getTraceClearanceViolations(prepared, candidate).length > 0) {\n for (let index = 0; index < indexes.length; index++) {\n traces[indexes[index]!] = originalNetTraces[index]!;\n }\n skippedCycleCount++;\n continue;\n }\n cycleCount++;\n prunedEdgeCount += graph.edges.size - selectedEdges.size;\n }\n\n assertOnlyPrefabricatedVias(prepared, traces);\n return {\n ...solution,\n traces,\n stats: {\n ...solution.stats,\n sameNetCyclePruneCount: cycleCount,\n sameNetCyclePruneSkipCount: skippedCycleCount,\n prunedSameNetEdgeCount: prunedEdgeCount,\n },\n };\n};\n\nexport class PruneRedundantSameNetCopperSolver extends BaseSolver {\n private output?: BiscuitBoardRoutingSolution;\n\n constructor(\n public readonly params: {\n prepared: PreparedBiscuitRoutingProblem;\n built: BiscuitBoardRoutingSolution;\n },\n ) {\n super();\n }\n\n override getConstructorParams(): [typeof this.params] {\n return [this.params];\n }\n\n override _step() {\n this.output = pruneRedundantSameNetCopper(\n this.params.prepared,\n this.params.built,\n );\n this.stats = this.output.stats;\n this.progress = 1;\n this.solved = true;\n }\n\n override getOutput() {\n return this.output ?? null;\n }\n\n override visualize(): GraphicsObject {\n const output = this.output ?? this.params.built;\n const board = visualizeSimpleRouteJsonInput(this.params.prepared.input);\n return {\n ...board,\n title: `Same-net topology cleanup (${output.stats.sameNetCyclePruneCount ?? 0} cyclic nets pruned, ${output.stats.sameNetCyclePruneSkipCount ?? 0} skipped, ${output.stats.prunedSameNetEdgeCount ?? 0} redundant edges removed)`,\n lines: [\n ...(board.lines ?? []),\n ...output.routes.flatMap((route, traceIndex) => {\n const trace = output.traces[traceIndex]!;\n return trace.route.flatMap((point, pointIndex) => {\n const next = trace.route[pointIndex + 1];\n return point.route_type === \"wire\" &&\n next?.route_type === \"wire\" &&\n point.layer === next.layer\n ? [\n {\n points: [point, next],\n strokeColor: netColor(route.netId),\n strokeWidth: point.width,\n strokeDash: point.layer === \"bottom\" ? [6, 4] : undefined,\n label: `cycle-pruned trace · ${route.netId}`,\n },\n ]\n : [];\n });\n }),\n ],\n };\n }\n}\n","import type { SimpleRouteJson } from \"@tscircuit/core\";\nimport {\n BasePipelineSolver,\n definePipelineStep,\n type PipelineStep,\n} from \"@tscircuit/solver-utils\";\nimport type { GraphicsObject } from \"graphics-debug\";\nimport { BeautifyBiscuitBoardTracesSolver } from \"./beautify-biscuit-board-traces-solver\";\nimport { BuildBiscuitBoardTracesSolver } from \"./build-biscuit-board-traces-solver\";\nimport { ExpandBiscuitBoardTracesSolver } from \"./expand-biscuit-board-traces-solver\";\nimport { GenerateBiscuitBoardHypergraphSolver } from \"./generate-biscuit-board-hypergraph-solver\";\nimport { PostProcessBiscuitBoardTracesSolver } from \"./post-process-biscuit-board-traces-solver\";\nimport { PruneRedundantSameNetCopperSolver } from \"./prune-redundant-same-net-copper-solver\";\nimport { RipUpRubberBandSolver } from \"./rip-up-rubber-band-solver\";\nimport { visualizeSimpleRouteJsonInput } from \"./geometry\";\nimport type {\n BiscuitBoardAutorouterOptions,\n BiscuitBoardRoutingSolution,\n PreparedBiscuitRoutingProblem,\n} from \"./types\";\n\nexport class BiscuitBoardRoutingPipelineSolver extends BasePipelineSolver<SimpleRouteJson> {\n override pipelineDef: PipelineStep<any>[] = [\n definePipelineStep(\n \"generate-hypergraph\",\n GenerateBiscuitBoardHypergraphSolver,\n (instance: BiscuitBoardRoutingPipelineSolver) => [\n { input: instance.inputProblem, options: instance.options },\n ],\n ),\n definePipelineStep(\n \"route-with-rip-and-replace\",\n RipUpRubberBandSolver,\n (instance: BiscuitBoardRoutingPipelineSolver) => {\n const prepared = instance.getStageOutput<PreparedBiscuitRoutingProblem>(\n \"generate-hypergraph\",\n );\n if (!prepared)\n throw new Error(\"Hypergraph generation produced no output\");\n return [prepared];\n },\n ),\n definePipelineStep(\n \"build-and-validate-traces\",\n BuildBiscuitBoardTracesSolver,\n (instance: BiscuitBoardRoutingPipelineSolver) => {\n const prepared = instance.getStageOutput<PreparedBiscuitRoutingProblem>(\n \"generate-hypergraph\",\n );\n const routed = instance.getStageOutput<BiscuitBoardRoutingSolution>(\n \"route-with-rip-and-replace\",\n );\n if (!prepared || !routed) {\n throw new Error(\"Routing pipeline stages produced no output\");\n }\n return [{ prepared, routed }];\n },\n ),\n definePipelineStep(\n \"post-process-traces\",\n PostProcessBiscuitBoardTracesSolver,\n (instance: BiscuitBoardRoutingPipelineSolver) => {\n const prepared = instance.getStageOutput<PreparedBiscuitRoutingProblem>(\n \"generate-hypergraph\",\n );\n const built = instance.getStageOutput<BiscuitBoardRoutingSolution>(\n \"build-and-validate-traces\",\n );\n if (!prepared || !built) {\n throw new Error(\"Trace post-processing inputs are unavailable\");\n }\n return [{ prepared, built }];\n },\n ),\n definePipelineStep(\n \"beautify-traces\",\n BeautifyBiscuitBoardTracesSolver,\n (instance: BiscuitBoardRoutingPipelineSolver) => {\n const prepared = instance.getStageOutput<PreparedBiscuitRoutingProblem>(\n \"generate-hypergraph\",\n );\n const built = instance.getStageOutput<BiscuitBoardRoutingSolution>(\n \"post-process-traces\",\n );\n if (!prepared || !built) {\n throw new Error(\"Trace beautification inputs are unavailable\");\n }\n return [{ prepared, built }];\n },\n ),\n definePipelineStep(\n \"prune-redundant-same-net-copper\",\n PruneRedundantSameNetCopperSolver,\n (instance: BiscuitBoardRoutingPipelineSolver) => {\n const prepared = instance.getStageOutput<PreparedBiscuitRoutingProblem>(\n \"generate-hypergraph\",\n );\n const built =\n instance.getStageOutput<BiscuitBoardRoutingSolution>(\n \"beautify-traces\",\n );\n if (!prepared || !built) {\n throw new Error(\"Same-net topology cleanup inputs are unavailable\");\n }\n return [{ prepared, built }];\n },\n ),\n definePipelineStep(\n \"expand-traces\",\n ExpandBiscuitBoardTracesSolver,\n (instance: BiscuitBoardRoutingPipelineSolver) => {\n const prepared = instance.getStageOutput<PreparedBiscuitRoutingProblem>(\n \"generate-hypergraph\",\n );\n const built = instance.getStageOutput<BiscuitBoardRoutingSolution>(\n \"prune-redundant-same-net-copper\",\n );\n if (!prepared || !built) {\n throw new Error(\"Trace expansion inputs are unavailable\");\n }\n return [\n {\n prepared,\n built,\n enabled: instance.options.expandTraces,\n },\n ];\n },\n ),\n ];\n\n constructor(\n input: SimpleRouteJson,\n public readonly options: BiscuitBoardAutorouterOptions = {},\n ) {\n super(input);\n // The expansion stage may consume most of its eight-million-iteration\n // budget on dense boards, in addition to the graph and routing stages.\n this.MAX_ITERATIONS = 10_000_000;\n }\n\n override getConstructorParams(): [\n SimpleRouteJson,\n BiscuitBoardAutorouterOptions,\n ] {\n return [this.inputProblem, this.options];\n }\n\n get stage() {\n return this.getCurrentStageName();\n }\n\n override initialVisualize(): GraphicsObject {\n return visualizeSimpleRouteJsonInput(this.inputProblem);\n }\n\n override visualize(): GraphicsObject {\n if (this.solved) {\n return this.getSolver(\"expand-traces\")?.visualize() ?? super.visualize();\n }\n return super.visualize();\n }\n\n override getOutput(): BiscuitBoardRoutingSolution | null {\n return (\n this.getStageOutput<BiscuitBoardRoutingSolution>(\"expand-traces\") ?? null\n );\n }\n}\n","import type {\n AutorouterCompleteEvent,\n AutorouterErrorEvent,\n AutorouterProgressEvent,\n GenericLocalAutorouter,\n SimpleRouteJson,\n SimplifiedPcbTrace,\n} from \"@tscircuit/core\";\nimport type { AutorouterConfig } from \"@tscircuit/props\";\nimport { BiscuitBoardRoutingPipelineSolver } from \"./biscuit-board-routing-pipeline-solver\";\nimport type { BiscuitBoardAutorouterOptions } from \"./types\";\n\ntype EventHandlers = {\n complete: Array<(event: AutorouterCompleteEvent) => void>;\n error: Array<(event: AutorouterErrorEvent) => void>;\n progress: Array<(event: AutorouterProgressEvent) => void>;\n};\n\nexport class BiscuitBoardAutorouter implements GenericLocalAutorouter {\n isRouting = false;\n readonly solver: BiscuitBoardRoutingPipelineSolver;\n private traces?: SimplifiedPcbTrace[];\n private readonly handlers: EventHandlers = {\n complete: [],\n error: [],\n progress: [],\n };\n\n constructor(\n public readonly input: SimpleRouteJson,\n options: BiscuitBoardAutorouterOptions = {},\n ) {\n this.solver = new BiscuitBoardRoutingPipelineSolver(input, options);\n }\n\n solveSync(): SimplifiedPcbTrace[] {\n if (this.traces) return this.traces;\n this.solver.solve();\n if (this.solver.failed) {\n throw new Error(this.solver.error ?? \"Biscuit-board autorouting failed\");\n }\n const output = this.solver.getOutput();\n if (!output) throw new Error(\"Biscuit-board autorouter produced no output\");\n this.traces = output.traces;\n return this.traces;\n }\n\n getOutputSimpleRouteJson(): SimpleRouteJson | undefined {\n if (!this.traces) return undefined;\n return { ...this.input, traces: this.traces };\n }\n\n start(): void {\n if (this.isRouting) return;\n this.isRouting = true;\n queueMicrotask(() => {\n if (!this.isRouting) return;\n try {\n const traces = this.solveSync();\n for (const handler of this.handlers.complete) {\n handler({ type: \"complete\", traces });\n }\n } catch (cause) {\n const error = cause instanceof Error ? cause : new Error(String(cause));\n for (const handler of this.handlers.error) {\n handler({ type: \"error\", error });\n }\n } finally {\n this.isRouting = false;\n }\n });\n }\n\n stop(): void {\n this.isRouting = false;\n }\n\n on(\n event: \"complete\",\n callback: (event: AutorouterCompleteEvent) => void,\n ): void;\n on(event: \"error\", callback: (event: AutorouterErrorEvent) => void): void;\n on(\n event: \"progress\",\n callback: (event: AutorouterProgressEvent) => void,\n ): void;\n on(\n event: \"complete\" | \"error\" | \"progress\",\n callback:\n | ((event: AutorouterCompleteEvent) => void)\n | ((event: AutorouterErrorEvent) => void)\n | ((event: AutorouterProgressEvent) => void),\n ): void {\n if (event === \"complete\") {\n this.handlers.complete.push(\n callback as (event: AutorouterCompleteEvent) => void,\n );\n } else if (event === \"error\") {\n this.handlers.error.push(\n callback as (event: AutorouterErrorEvent) => void,\n );\n } else {\n this.handlers.progress.push(\n callback as (event: AutorouterProgressEvent) => void,\n );\n }\n }\n}\n\nexport const createBiscuitBoardAutorouter = (\n options: BiscuitBoardAutorouterOptions = {},\n): AutorouterConfig => ({\n local: true,\n groupMode: \"subcircuit\",\n preset: \"laser_prefab\",\n algorithmFn: async (input: SimpleRouteJson) =>\n new BiscuitBoardAutorouter(input, options),\n});\n","import { createBiscuitBoardAutorouter as createBundledBiscuitBoardAutorouter } from \"@tscircuit/biscuit-board-autorouter\"\nimport type { AutorouterConfig } from \"@tscircuit/props\"\n\nexport {\n BiscuitBoardAutorouter,\n BiscuitBoardRoutingPipelineSolver,\n} from \"@tscircuit/biscuit-board-autorouter\"\n\nexport interface BiscuitBoardAutorouterOptions {\n routeOrder?:\n | \"adaptive\"\n | \"longest_first\"\n | \"shortest_first\"\n | \"signal_longest_first\"\n | \"input\"\n gridPitch?: number\n gridClearance?: number\n respectObstacleRotationInGraph?: boolean\n viaTransitionCost?: number\n ripCost?: number\n crossingCost?: number\n historyIncrement?: number\n maxBlockersPerSearch?: number\n maxRipsPerRoute?: number\n maxTotalRips?: number\n maxSearchStates?: number\n expansionsPerStep?: number\n expandTraces?: boolean\n}\n\nexport const createBiscuitBoardAutorouter = (\n options: BiscuitBoardAutorouterOptions = {},\n): AutorouterConfig => createBundledBiscuitBoardAutorouter(options)\n","import type { SimpleRouteJson } from \"@tscircuit/core\"\nimport type { AutorouterConfig } from \"@tscircuit/props\"\nimport {\n BiscuitBoardAutorouter,\n type BiscuitBoardAutorouterOptions,\n createBiscuitBoardAutorouter,\n} from \"./biscuit-board-autorouter\"\n\nexport interface PrefabricatedViaAutorouterConfig {\n width: number\n height: number\n edgeClearance: number\n options?: BiscuitBoardAutorouterOptions\n minimumTraceWidth?: number\n nominalTraceWidth: number\n reservedObstacles?: SimpleRouteJson[\"obstacles\"]\n}\n\n/**\n * Builds the board-bounded autorouter configuration shared by prefabricated\n * clads. Layer changes are still restricted to net-assignable vias by the\n * BiscuitBoard autorouter; this helper only supplies the board-specific bounds\n * and trace-width policy.\n */\nexport const createPrefabricatedViaAutorouter = ({\n width,\n height,\n edgeClearance,\n options,\n minimumTraceWidth,\n nominalTraceWidth,\n reservedObstacles = [],\n}: PrefabricatedViaAutorouterConfig): AutorouterConfig => ({\n ...createBiscuitBoardAutorouter(options),\n algorithmFn: async (input: SimpleRouteJson) => {\n const maximumTraceWidth = Math.max(\n input.minTraceWidth,\n input.nominalTraceWidth ?? 0,\n minimumTraceWidth ?? 0,\n nominalTraceWidth,\n ...input.connections.map(\n (connection) => connection.width ?? input.minTraceWidth,\n ),\n )\n\n return new BiscuitBoardAutorouter(\n {\n ...input,\n minTraceWidth: Math.max(input.minTraceWidth, minimumTraceWidth ?? 0),\n nominalTraceWidth: Math.max(\n input.nominalTraceWidth ?? 0,\n nominalTraceWidth,\n minimumTraceWidth ?? 0,\n ),\n connections: input.connections.map((connection) => {\n const width = Math.max(\n connection.width ?? input.minTraceWidth,\n minimumTraceWidth ?? 0,\n )\n return {\n ...connection,\n width,\n nominalTraceWidth: Math.max(\n connection.nominalTraceWidth ?? 0,\n nominalTraceWidth,\n width,\n ),\n }\n }),\n obstacles: [...input.obstacles, ...reservedObstacles],\n // The clad DRC measures clearance from the copper edge, while this\n // router bound constrains trace centerlines.\n minBoardEdgeClearance: edgeClearance + maximumTraceWidth / 2,\n bounds: {\n minX: -width / 2,\n maxX: width / 2,\n minY: -height / 2,\n maxY: height / 2,\n },\n },\n options,\n )\n },\n})\n","import type { SimpleRouteJson } from \"@tscircuit/core\"\nimport type { AutorouterProp, ConnectorProps } from \"@tscircuit/props\"\nimport { Fragment, type ReactNode } from \"react\"\nimport {\n BISCUIT_BOARD_HEIGHT,\n BISCUIT_BOARD_MOUNTING_HOLE_POSITIONS,\n BISCUIT_BOARD_WIDTH,\n} from \"./BiscuitBoard\"\nimport type { BiscuitBoardAutorouterOptions } from \"./biscuit-board-autorouter\"\nimport { createPrefabricatedViaAutorouter } from \"./create-prefabricated-via-autorouter\"\n\n// Preserve the existing clad's tooling outline and mounting-hole layout. This\n// is larger than the TI SLAA542 maximum BoosterPack outline, but the header\n// geometry remains compatible with the LaunchPad connector pattern.\nexport const BOOSTERPACK_CLAD_WIDTH = BISCUIT_BOARD_WIDTH\nexport const BOOSTERPACK_CLAD_HEIGHT = BISCUIT_BOARD_HEIGHT\nexport const BOOSTERPACK_HEADER_PITCH = 2.54\nexport const BOOSTERPACK_HEADER_CENTER_X = 21.59\nexport const BOOSTERPACK_HEADER_CENTER_Y = 1.27\nexport const BOOSTERPACK_CLAD_VIA_OUTER_DIAMETER = 0.6\nexport const BOOSTERPACK_CLAD_VIA_PITCH = 1.3\nexport const BOOSTERPACK_CLAD_MOUNTING_HOLE_VIA_CLEARANCE = 1\nexport const BOOSTERPACK_CORNER_VERTICAL_ARM_INNER_Y = 11.5\n\nconst BOOSTERPACK_CLAD_EDGE_CLEARANCE = 0.2\nconst BOOSTERPACK_CLAD_EDGE_CLEARANCE_VALIDATION_TOLERANCE = 0.001\nconst BOOSTERPACK_MOUNTING_HOLE_RADIUS = 1.1\nexport const BOOSTERPACK_EDGE_HEADER_CENTER_X =\n BOOSTERPACK_CLAD_WIDTH / 2 - BOOSTERPACK_HEADER_PITCH / 2\nconst BOOSTERPACK_EDGE_HEADER_CLEARANCE_HALF_HEIGHT =\n Math.min(\n ...BISCUIT_BOARD_MOUNTING_HOLE_POSITIONS.map((hole) => Math.abs(hole.y)),\n ) -\n BOOSTERPACK_MOUNTING_HOLE_RADIUS -\n BOOSTERPACK_CLAD_MOUNTING_HOLE_VIA_CLEARANCE\nexport const BOOSTERPACK_EDGE_HEADER_PIN_COUNT = Math.floor(\n (2 * BOOSTERPACK_EDGE_HEADER_CLEARANCE_HALF_HEIGHT) /\n BOOSTERPACK_HEADER_PITCH,\n)\nconst BOOSTERPACK_EDGE_HEADER_HALF_HEIGHT =\n (BOOSTERPACK_EDGE_HEADER_PIN_COUNT * BOOSTERPACK_HEADER_PITCH) / 2\nexport const BOOSTERPACK_MIDDLE_VIA_CLUSTER_CENTER_X =\n -BOOSTERPACK_HEADER_CENTER_X / 2 - 2\nexport const BOOSTERPACK_MIDDLE_VIA_CLUSTER_WIDTH = 6.3\nexport const BOOSTERPACK_MIDDLE_VIA_CLUSTER_HEIGHT = 5.6\nexport const BOOSTERPACK_EDGE_BAND_OUTER_X = BOOSTERPACK_CLAD_WIDTH / 2 - 2\nexport const BOOSTERPACK_EDGE_BAND_CENTER_GAP =\n (BOOSTERPACK_CLAD_WIDTH / 2 - 14.5) * 1.1 * 1.3 * 1.2\nconst BOOSTERPACK_EDGE_BAND_INNER_X = BOOSTERPACK_EDGE_BAND_CENTER_GAP / 2\n\nexport interface BoosterPackCladViaPosition {\n x: number\n y: number\n}\n\ninterface ViaCandidateZone {\n minX: number\n maxX: number\n minY: number\n maxY: number\n spacing: number\n originX?: number\n originY?: number\n}\n\nexport interface BoosterPackCladPlacementZone {\n name: string\n purpose: \"connector\" | \"chips-and-sensors\" | \"interface\"\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n\nconst roundCoordinate = (value: number) => Math.round(value * 1e6) / 1e6\n\nconst maximallyPackedRange = (start: number, end: number, pitch: number) => {\n const intervalCount = Math.floor((end - start) / pitch)\n if (intervalCount <= 0) return [(start + end) / 2]\n\n const populatedStart = (start + end - intervalCount * pitch) / 2\n return Array.from({ length: intervalCount + 1 }, (_, index) =>\n roundCoordinate(populatedStart + index * pitch),\n )\n}\n\nconst anchoredPitchedRange = (\n start: number,\n end: number,\n pitch: number,\n origin: number,\n) => {\n const firstIndex = Math.ceil((start - origin) / pitch - 1e-9)\n const lastIndex = Math.floor((end - origin) / pitch + 1e-9)\n return Array.from(\n { length: Math.max(0, lastIndex - firstIndex + 1) },\n (_, index) => roundCoordinate(origin + (firstIndex + index) * pitch),\n )\n}\n\nconst createViaAxis = (\n start: number,\n end: number,\n pitch: number,\n origin?: number,\n) =>\n origin === undefined\n ? maximallyPackedRange(start, end, pitch)\n : anchoredPitchedRange(start, end, pitch, origin)\n\nconst createViaZone = (zone: ViaCandidateZone): BoosterPackCladViaPosition[] =>\n createViaAxis(zone.minX, zone.maxX, zone.spacing, zone.originX).flatMap((x) =>\n createViaAxis(zone.minY, zone.maxY, zone.spacing, zone.originY).map(\n (y) => ({\n x,\n y,\n }),\n ),\n )\n\n/**\n * Four L-shaped corner fields keep the center and the middle of every board\n * edge open for chips, sensors, controls, and connectors.\n */\nexport const BOOSTERPACK_CLAD_VIA_CANDIDATE_ZONES = [\n // Compact routing cluster halfway from J1/J3 to the board center.\n {\n minX:\n BOOSTERPACK_MIDDLE_VIA_CLUSTER_CENTER_X -\n BOOSTERPACK_MIDDLE_VIA_CLUSTER_WIDTH / 2,\n maxX:\n BOOSTERPACK_MIDDLE_VIA_CLUSTER_CENTER_X +\n BOOSTERPACK_MIDDLE_VIA_CLUSTER_WIDTH / 2,\n minY: -BOOSTERPACK_MIDDLE_VIA_CLUSTER_HEIGHT / 2,\n maxY: BOOSTERPACK_MIDDLE_VIA_CLUSTER_HEIGHT / 2,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n },\n // Upper-left horizontal and vertical arms share one anchored lattice.\n {\n minX: -BOOSTERPACK_EDGE_BAND_OUTER_X,\n maxX: -BOOSTERPACK_EDGE_BAND_INNER_X,\n minY: 21.5,\n maxY: 25.5,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n originX: -BOOSTERPACK_EDGE_BAND_OUTER_X,\n originY: 21.5,\n },\n {\n minX: -BOOSTERPACK_EDGE_BAND_OUTER_X,\n maxX: -31.5,\n minY: BOOSTERPACK_CORNER_VERTICAL_ARM_INNER_Y,\n maxY: 25.5,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n originX: -BOOSTERPACK_EDGE_BAND_OUTER_X,\n originY: 21.5,\n },\n // Upper-right corner.\n {\n minX: BOOSTERPACK_EDGE_BAND_INNER_X,\n maxX: BOOSTERPACK_EDGE_BAND_OUTER_X,\n minY: 21.5,\n maxY: 25.5,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n originX: BOOSTERPACK_EDGE_BAND_OUTER_X,\n originY: 21.5,\n },\n {\n minX: 31.5,\n maxX: BOOSTERPACK_EDGE_BAND_OUTER_X,\n minY: BOOSTERPACK_CORNER_VERTICAL_ARM_INNER_Y,\n maxY: 25.5,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n originX: BOOSTERPACK_EDGE_BAND_OUTER_X,\n originY: 21.5,\n },\n // Lower-left corner.\n {\n minX: -BOOSTERPACK_EDGE_BAND_OUTER_X,\n maxX: -BOOSTERPACK_EDGE_BAND_INNER_X,\n minY: -25.5,\n maxY: -21.5,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n originX: -BOOSTERPACK_EDGE_BAND_OUTER_X,\n originY: -21.5,\n },\n {\n minX: -BOOSTERPACK_EDGE_BAND_OUTER_X,\n maxX: -31.5,\n minY: -25.5,\n maxY: -BOOSTERPACK_CORNER_VERTICAL_ARM_INNER_Y,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n originX: -BOOSTERPACK_EDGE_BAND_OUTER_X,\n originY: -21.5,\n },\n // Lower-right corner.\n {\n minX: BOOSTERPACK_EDGE_BAND_INNER_X,\n maxX: BOOSTERPACK_EDGE_BAND_OUTER_X,\n minY: -25.5,\n maxY: -21.5,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n originX: BOOSTERPACK_EDGE_BAND_OUTER_X,\n originY: -21.5,\n },\n {\n minX: 31.5,\n maxX: BOOSTERPACK_EDGE_BAND_OUTER_X,\n minY: -25.5,\n maxY: -BOOSTERPACK_CORNER_VERTICAL_ARM_INNER_Y,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n originX: BOOSTERPACK_EDGE_BAND_OUTER_X,\n originY: -21.5,\n },\n] as const satisfies readonly ViaCandidateZone[]\n\n/**\n * Reusable placement bays kept clear of prefabricated via pads. The central\n * bays cover controls, chips, sensors, debug, and power circuitry. Centered\n * openings along every edge leave room for connectors whose bodies or cables\n * must reach beyond the board outline.\n */\nexport const BOOSTERPACK_CLAD_PLACEMENT_ZONES = [\n {\n name: \"left-edge-pin-header\",\n purpose: \"connector\",\n minX: -BOOSTERPACK_CLAD_WIDTH / 2,\n maxX: -BOOSTERPACK_CLAD_WIDTH / 2 + BOOSTERPACK_HEADER_PITCH,\n minY: -BOOSTERPACK_EDGE_HEADER_HALF_HEIGHT,\n maxY: BOOSTERPACK_EDGE_HEADER_HALF_HEIGHT,\n },\n {\n name: \"left-launchpad-header\",\n purpose: \"connector\",\n minX: -24.5,\n maxX: -18.5,\n minY: -12,\n maxY: 14.5,\n },\n {\n name: \"right-launchpad-header\",\n purpose: \"connector\",\n minX: 18.5,\n maxX: 24.5,\n minY: -12,\n maxY: 14.5,\n },\n {\n name: \"upper-interface\",\n purpose: \"interface\",\n minX: -17.5,\n maxX: 17.5,\n minY: 11.5,\n maxY: 19.5,\n },\n {\n name: \"central-chips-and-sensors\",\n purpose: \"chips-and-sensors\",\n minX: -7.5,\n maxX: 7.5,\n minY: -11.5,\n maxY: 11.5,\n },\n {\n name: \"left-upper-interface\",\n purpose: \"interface\",\n minX: -17.5,\n maxX: -7.5,\n minY: 4.75,\n maxY: 11.5,\n },\n {\n name: \"left-lower-interface\",\n purpose: \"interface\",\n minX: -17.5,\n maxX: -7.5,\n minY: -11.5,\n maxY: -4.75,\n },\n {\n name: \"right-upper-interface\",\n purpose: \"interface\",\n minX: 7.5,\n maxX: 17.5,\n minY: 4.75,\n maxY: 11.5,\n },\n {\n name: \"right-lower-interface\",\n purpose: \"interface\",\n minX: 7.5,\n maxX: 17.5,\n minY: -11.5,\n maxY: -4.75,\n },\n {\n name: \"lower-interface\",\n purpose: \"interface\",\n minX: -17.5,\n maxX: 17.5,\n minY: -19.5,\n maxY: -11.5,\n },\n {\n name: \"upper-edge-connector\",\n purpose: \"connector\",\n minX: -10.5,\n maxX: 10.5,\n minY: 20.5,\n maxY: 26.5,\n },\n {\n name: \"lower-edge-connector\",\n purpose: \"connector\",\n minX: -10.5,\n maxX: 10.5,\n minY: -26.5,\n maxY: -20.5,\n },\n] as const satisfies readonly BoosterPackCladPlacementZone[]\n\n/** Keep vias clear of mounting-hole pads and the left-edge header body. */\nexport const BOOSTERPACK_CLAD_VIA_EXCLUSION_ZONES = [\n {\n minX: -36.7,\n maxX: -33.3,\n minY: 23.3,\n maxY: 26.7,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n },\n {\n minX: -36.7,\n maxX: -33.3,\n minY: -26.7,\n maxY: -23.3,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n },\n {\n minX: 33.3,\n maxX: 36.7,\n minY: 23.3,\n maxY: 26.7,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n },\n {\n minX: 29.6,\n maxX: 32.4,\n minY: 23.6,\n maxY: 26.4,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n },\n {\n minX: 33.3,\n maxX: 36.7,\n minY: -26.7,\n maxY: -23.3,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n },\n {\n minX:\n -BOOSTERPACK_EDGE_HEADER_CENTER_X -\n BOOSTERPACK_HEADER_PITCH / 2 -\n BOOSTERPACK_CLAD_VIA_OUTER_DIAMETER / 2,\n maxX:\n -BOOSTERPACK_EDGE_HEADER_CENTER_X +\n BOOSTERPACK_HEADER_PITCH / 2 +\n BOOSTERPACK_CLAD_VIA_OUTER_DIAMETER / 2,\n minY:\n -BOOSTERPACK_EDGE_HEADER_HALF_HEIGHT -\n BOOSTERPACK_CLAD_VIA_OUTER_DIAMETER / 2,\n maxY:\n BOOSTERPACK_EDGE_HEADER_HALF_HEIGHT +\n BOOSTERPACK_CLAD_VIA_OUTER_DIAMETER / 2,\n spacing: BOOSTERPACK_CLAD_VIA_PITCH,\n },\n] as const satisfies readonly ViaCandidateZone[]\n\nconst pointKey = (point: BoosterPackCladViaPosition) =>\n `${point.x.toFixed(3)},${point.y.toFixed(3)}`\n\nconst isInsideExclusion = (point: BoosterPackCladViaPosition) =>\n BOOSTERPACK_CLAD_VIA_EXCLUSION_ZONES.some(\n (zone) =>\n point.x >= zone.minX &&\n point.x <= zone.maxX &&\n point.y >= zone.minY &&\n point.y <= zone.maxY,\n ) ||\n BISCUIT_BOARD_MOUNTING_HOLE_POSITIONS.some(\n (hole) =>\n Math.hypot(point.x - hole.x, point.y - hole.y) <\n 1.1 +\n BOOSTERPACK_CLAD_VIA_OUTER_DIAMETER / 2 +\n BOOSTERPACK_CLAD_MOUNTING_HOLE_VIA_CLEARANCE,\n )\n\nexport const BOOSTERPACK_CLAD_VIA_POSITIONS = Array.from(\n new Map(\n BOOSTERPACK_CLAD_VIA_CANDIDATE_ZONES.flatMap(createViaZone).map((point) => [\n pointKey(point),\n point,\n ]),\n ).values(),\n).filter((point) => !isInsideExclusion(point))\n\nconst leftHeaderPins = {\n pin1: [\"J1_1\", \"LP_3V3\"],\n pin2: [\"J3_1\", \"LP_5V\"],\n pin3: [\"J1_2\", \"LP_ANALOG_IN\"],\n pin4: [\"J3_2\", \"LP_GND_INNER\"],\n pin5: [\"J1_3\", \"LP_UART_RX\"],\n pin6: [\"J3_3\"],\n pin7: [\"J1_4\", \"LP_UART_TX\"],\n pin8: [\"J3_4\"],\n pin9: [\"J1_5\", \"LP_GPIO_INTERRUPT\"],\n pin10: [\"J3_5\"],\n pin11: [\"J1_6\", \"LP_SPI_A_SCLK\"],\n pin12: [\"J3_6\"],\n pin13: [\"J1_7\", \"LP_SPI_B_SCLK\"],\n pin14: [\"J3_7\"],\n pin15: [\"J1_8\", \"LP_GPIO_1\"],\n pin16: [\"J3_8\"],\n pin17: [\"J1_9\", \"LP_GPIO_2\"],\n pin18: [\"J3_9\"],\n pin19: [\"J1_10\", \"LP_GPIO_3\"],\n pin20: [\"J3_10\"],\n} as const\n\nconst rightHeaderPins = {\n pin1: [\"J4_20\"],\n pin2: [\"J2_20\", \"LP_GND\"],\n pin3: [\"J4_19\"],\n pin4: [\"J2_19\", \"LP_TIMER_OUT\"],\n pin5: [\"J4_18\"],\n pin6: [\"J2_18\", \"LP_GPIO_INTERRUPT_2\"],\n pin7: [\"J4_17\"],\n pin8: [\"J2_17\", \"LP_TEST\"],\n pin9: [\"J4_16\"],\n pin10: [\"J2_16\", \"LP_RESET\"],\n pin11: [\"J4_15\"],\n pin12: [\"J2_15\", \"LP_I2C_SDA\", \"LP_SPI_B_SIMO\"],\n pin13: [\"J4_14\"],\n pin14: [\"J2_14\", \"LP_I2C_SCL\", \"LP_SPI_B_SOMI\"],\n pin15: [\"J4_13\"],\n pin16: [\"J2_13\", \"LP_GPIO_4\"],\n pin17: [\"J4_12\"],\n pin18: [\"J2_12\", \"LP_GPIO_5\"],\n pin19: [\"J4_11\"],\n pin20: [\"J2_11\", \"LP_GPIO_6\"],\n} as const\n\nconst leftHeaderNoConnect = Array.from({ length: 20 }, (_, index) => index + 1)\n .filter((pin) => pin !== 1 && pin !== 4)\n .map((pin) => `pin${pin}`)\nconst rightHeaderNoConnect = Array.from({ length: 20 }, (_, index) => index + 1)\n .filter((pin) => pin !== 2)\n .map((pin) => `pin${pin}`)\n\nconst DualMaleHeaderFootprint = ({\n insertionDirection = \"from_below\",\n}: {\n insertionDirection?: \"from_above\" | \"from_below\"\n}) => (\n <footprint insertionDirection={insertionDirection}>\n {Array.from({ length: 10 }, (_, row) => {\n const y = (4.5 - row) * BOOSTERPACK_HEADER_PITCH\n return (\n <Fragment key={`row-y-${y}`}>\n {row === 0 ? (\n <platedhole\n portHints={[`pin${row * 2 + 1}`]}\n shape=\"circular_hole_with_rect_pad\"\n holeDiameter=\"1.02mm\"\n rectPadWidth=\"1.7mm\"\n rectPadHeight=\"1.7mm\"\n pcbX={-BOOSTERPACK_HEADER_PITCH / 2}\n pcbY={y}\n />\n ) : (\n <platedhole\n portHints={[`pin${row * 2 + 1}`]}\n shape=\"circle\"\n holeDiameter=\"1.02mm\"\n outerDiameter=\"1.7mm\"\n pcbX={-BOOSTERPACK_HEADER_PITCH / 2}\n pcbY={y}\n />\n )}\n <platedhole\n portHints={[`pin${row * 2 + 2}`]}\n shape=\"circle\"\n holeDiameter=\"1.02mm\"\n outerDiameter=\"1.7mm\"\n pcbX={BOOSTERPACK_HEADER_PITCH / 2}\n pcbY={y}\n />\n </Fragment>\n )\n })}\n <silkscreenrect width=\"5.08mm\" height=\"25.4mm\" />\n <silkscreencircle\n pcbX={-BOOSTERPACK_HEADER_PITCH / 2}\n pcbY={4.5 * BOOSTERPACK_HEADER_PITCH}\n radius=\"0.3mm\"\n />\n </footprint>\n)\n\nconst SingleMaleHeaderFootprint = ({ pinCount }: { pinCount: number }) => (\n <footprint insertionDirection=\"from_above\">\n {Array.from({ length: pinCount }, (_, row) => {\n const pin = row + 1\n const y = ((pinCount - 1) / 2 - row) * BOOSTERPACK_HEADER_PITCH\n return (\n <Fragment key={`pin-${pin}`}>\n {pin === 1 ? (\n <platedhole\n portHints={[`pin${pin}`]}\n shape=\"circular_hole_with_rect_pad\"\n holeDiameter=\"1.02mm\"\n rectPadWidth=\"1.7mm\"\n rectPadHeight=\"1.7mm\"\n pcbY={y}\n />\n ) : (\n <platedhole\n portHints={[`pin${pin}`]}\n shape=\"circle\"\n holeDiameter=\"1.02mm\"\n outerDiameter=\"1.7mm\"\n pcbY={y}\n />\n )}\n </Fragment>\n )\n })}\n <silkscreenrect\n width=\"2.54mm\"\n height={`${pinCount * BOOSTERPACK_HEADER_PITCH}mm`}\n />\n <silkscreencircle\n pcbY={((pinCount - 1) / 2) * BOOSTERPACK_HEADER_PITCH}\n radius=\"0.3mm\"\n />\n </footprint>\n)\n\nexport const BoosterPackLeftHeader = (props: ConnectorProps) => (\n <connector\n pinLabels={leftHeaderPins}\n manufacturerPartNumber=\"GENERIC-2X10-MALE-2.54MM-DOWN\"\n footprint={<DualMaleHeaderFootprint />}\n noConnect={leftHeaderNoConnect}\n noSchematicRepresentation\n {...props}\n />\n)\n\nexport const BoosterPackRightHeader = (props: ConnectorProps) => (\n <connector\n pinLabels={rightHeaderPins}\n manufacturerPartNumber=\"GENERIC-2X10-MALE-2.54MM-DOWN\"\n footprint={<DualMaleHeaderFootprint />}\n noConnect={rightHeaderNoConnect}\n noSchematicRepresentation\n {...props}\n />\n)\n\nconst edgeHeaderPins = Object.fromEntries(\n Array.from({ length: BOOSTERPACK_EDGE_HEADER_PIN_COUNT }, (_, index) => [\n `pin${index + 1}`,\n [`EDGE_${index + 1}`],\n ]),\n)\nconst edgeHeaderNoConnect = Array.from(\n { length: BOOSTERPACK_EDGE_HEADER_PIN_COUNT },\n (_, index) => `pin${index + 1}`,\n)\n\nexport const BoosterPackEdgePinHeader = (props: ConnectorProps) => (\n <connector\n pinLabels={edgeHeaderPins}\n manufacturerPartNumber={`GENERIC-1X${BOOSTERPACK_EDGE_HEADER_PIN_COUNT}-MALE-2.54MM-UP`}\n footprint={\n <SingleMaleHeaderFootprint pinCount={BOOSTERPACK_EDGE_HEADER_PIN_COUNT} />\n }\n noConnect={edgeHeaderNoConnect}\n noSchematicRepresentation\n {...props}\n />\n)\n\nexport interface BoosterPackCladProps {\n children?: ReactNode\n autorouter?: AutorouterProp\n autorouterOptions?: BiscuitBoardAutorouterOptions\n minTraceWidth?: number\n nominalTraceWidth?: number\n routingDisabled?: boolean\n reservedAutorouterObstacles?: SimpleRouteJson[\"obstacles\"]\n}\n\n/** A BiscuitBoard-sized clad with a TI 40-pin BoosterPack header pattern. */\nexport const BoosterPackClad = ({\n children,\n autorouter,\n autorouterOptions,\n minTraceWidth,\n nominalTraceWidth = 0.3,\n routingDisabled = false,\n reservedAutorouterObstacles,\n}: BoosterPackCladProps) => (\n <board\n name=\"BoosterPackClad\"\n title=\"BiscuitBoard clad with TI 40-pin BoosterPack headers\"\n width={`${BOOSTERPACK_CLAD_WIDTH}mm`}\n height={`${BOOSTERPACK_CLAD_HEIGHT}mm`}\n borderRadius=\"1.5mm\"\n layers={2}\n minTraceWidth={`${minTraceWidth ?? 0.15}mm`}\n minBoardEdgeClearance={`${BOOSTERPACK_CLAD_EDGE_CLEARANCE - BOOSTERPACK_CLAD_EDGE_CLEARANCE_VALIDATION_TOLERANCE}mm`}\n minViaHoleDiameter=\"0.2mm\"\n minViaPadDiameter=\"0.4mm\"\n autorouter={\n autorouter ??\n createPrefabricatedViaAutorouter({\n width: BOOSTERPACK_CLAD_WIDTH,\n height: BOOSTERPACK_CLAD_HEIGHT,\n edgeClearance: BOOSTERPACK_CLAD_EDGE_CLEARANCE,\n options: autorouterOptions,\n minimumTraceWidth: minTraceWidth,\n nominalTraceWidth,\n reservedObstacles: reservedAutorouterObstacles,\n })\n }\n routingDisabled={routingDisabled}\n >\n <net name=\"GND\" isGroundNet />\n\n {BISCUIT_BOARD_MOUNTING_HOLE_POSITIONS.map((hole) => (\n <Fragment key={`mounting-hole-${hole.x}-${hole.y}`}>\n <hole pcbX={hole.x} pcbY={hole.y} diameter=\"2.2mm\" />\n </Fragment>\n ))}\n\n <BoosterPackLeftHeader\n name=\"J_LAUNCHPAD_LEFT\"\n pcbX={-BOOSTERPACK_HEADER_CENTER_X}\n pcbY={BOOSTERPACK_HEADER_CENTER_Y}\n />\n <BoosterPackRightHeader\n name=\"J_LAUNCHPAD_RIGHT\"\n pcbX={BOOSTERPACK_HEADER_CENTER_X}\n pcbY={BOOSTERPACK_HEADER_CENTER_Y}\n />\n <BoosterPackEdgePinHeader\n name=\"J_EDGE_LEFT\"\n pcbX={-BOOSTERPACK_EDGE_HEADER_CENTER_X}\n pcbY={0}\n />\n <silkscreentext\n text=\"LAUNCHPAD SIDE\"\n pcbX={0}\n pcbY={-BOOSTERPACK_CLAD_HEIGHT / 2 + 3.5}\n fontSize=\"0.8mm\"\n />\n <silkscreentext text=\"J1/J3\" pcbX={-21.59} pcbY={14.9} fontSize=\"0.7mm\" />\n <silkscreentext text=\"J4/J2\" pcbX={21.59} pcbY={14.9} fontSize=\"0.7mm\" />\n <silkscreentext\n text=\"EDGE LEFT\"\n pcbX={-BOOSTERPACK_EDGE_HEADER_CENTER_X + 3.5}\n pcbY={0}\n pcbRotation={90}\n fontSize=\"0.65mm\"\n />\n {BOOSTERPACK_CLAD_VIA_CANDIDATE_ZONES.map((zone) => (\n <Fragment\n key={`candidate-zone-${zone.minX}-${zone.maxX}-${zone.minY}-${zone.maxY}`}\n >\n <pcbnoterect\n color=\"blue\"\n width={Math.max(0.2, zone.maxX - zone.minX)}\n height={Math.max(0.2, zone.maxY - zone.minY)}\n pcbPositionAnchor=\"center\"\n pcbX={zone.minX + (zone.maxX - zone.minX) / 2}\n pcbY={zone.minY + (zone.maxY - zone.minY) / 2}\n />\n </Fragment>\n ))}\n\n {BOOSTERPACK_CLAD_VIA_POSITIONS.map((via) => (\n <Fragment key={`prefab-via-${via.x}-${via.y}`}>\n <via\n netIsAssignable\n pcbX={via.x}\n pcbY={via.y}\n fromLayer=\"top\"\n toLayer=\"bottom\"\n holeDiameter=\"0.3mm\"\n outerDiameter=\"0.6mm\"\n />\n </Fragment>\n ))}\n\n <pcbnotedimension\n from={{\n x: -BOOSTERPACK_CLAD_WIDTH / 2,\n y: BOOSTERPACK_CLAD_HEIGHT / 2 + 2.5,\n }}\n to={{\n x: BOOSTERPACK_CLAD_WIDTH / 2,\n y: BOOSTERPACK_CLAD_HEIGHT / 2 + 2.5,\n }}\n text={`${BOOSTERPACK_CLAD_WIDTH}mm`}\n />\n <pcbnotedimension\n from={{\n x: BOOSTERPACK_CLAD_WIDTH / 2 + 2.5,\n y: -BOOSTERPACK_CLAD_HEIGHT / 2,\n }}\n to={{\n x: BOOSTERPACK_CLAD_WIDTH / 2 + 2.5,\n y: BOOSTERPACK_CLAD_HEIGHT / 2,\n }}\n text={`${BOOSTERPACK_CLAD_HEIGHT}mm`}\n />\n\n {children}\n </board>\n)\n","import type { AutorouterProp, ConnectorProps } from \"@tscircuit/props\"\nimport { Fragment, type ReactNode } from \"react\"\nimport {\n BISCUIT_BOARD_HEIGHT,\n BISCUIT_BOARD_MOUNTING_HOLE_POSITIONS,\n BISCUIT_BOARD_WIDTH,\n} from \"./BiscuitBoard\"\nimport type { BiscuitBoardAutorouterOptions } from \"./biscuit-board-autorouter\"\nimport { createPrefabricatedViaAutorouter } from \"./create-prefabricated-via-autorouter\"\n\nexport const BREADBOARD_CLAD_WIDTH = BISCUIT_BOARD_WIDTH\nexport const BREADBOARD_CLAD_HEIGHT = BISCUIT_BOARD_HEIGHT\nexport const BREADBOARD_HEADER_PITCH = 2.54\nexport const BREADBOARD_COLUMN_COUNT = 21\nexport const BREADBOARD_HEADER_HOLE_DIAMETER = 1\nexport const BREADBOARD_HEADER_PAD_DIAMETER = 1.7\nexport const BREADBOARD_CLAD_VIA_HOLE_DIAMETER = 0.3\nexport const BREADBOARD_CLAD_VIA_PAD_DIAMETER = 0.6\nexport const BREADBOARD_CLAD_VIA_PITCH = BREADBOARD_HEADER_PITCH\nexport const BREADBOARD_CLAD_VIA_ROW_YS = [\n -16.51,\n -BREADBOARD_HEADER_PITCH / 2,\n BREADBOARD_HEADER_PITCH / 2,\n 16.51,\n] as const\nexport const BREADBOARD_OUTER_VIA_ROW_YS = [-24.13, 24.13] as const\nexport const BREADBOARD_OUTER_VIA_COLUMN_XS = [-27.94, 27.94] as const\nexport const BREADBOARD_MOUNTING_HOLE_DIAMETER = 2.2\n\nconst BREADBOARD_CLAD_EDGE_CLEARANCE = 0.2\nconst BREADBOARD_CLAD_EDGE_CLEARANCE_VALIDATION_TOLERANCE = 0.001\nconst BREADBOARD_TERMINAL_INNER_ROW_Y = 3.81\n\nexport const BREADBOARD_TERMINAL_ROW_LABELS = [\n \"A\",\n \"B\",\n \"C\",\n \"D\",\n \"E\",\n \"F\",\n \"G\",\n \"H\",\n \"I\",\n \"J\",\n] as const\n\nexport type BreadboardTerminalRowLabel =\n (typeof BREADBOARD_TERMINAL_ROW_LABELS)[number]\n\nexport interface BreadboardHeaderPosition {\n pin: number\n label: string\n column: number\n x: number\n y: number\n}\n\nexport interface BreadboardCladViaPosition {\n x: number\n y: number\n}\n\nconst roundCoordinate = (value: number) => Math.round(value * 1e6) / 1e6\n\nexport const BREADBOARD_COLUMN_XS = Array.from(\n { length: BREADBOARD_COLUMN_COUNT },\n (_, index) =>\n roundCoordinate(\n (index - (BREADBOARD_COLUMN_COUNT - 1) / 2) * BREADBOARD_HEADER_PITCH,\n ),\n)\n\nexport const BREADBOARD_OUTER_VERTICAL_VIA_YS = Array.from(\n { length: 18 },\n (_, index) => roundCoordinate(-21.59 + index * BREADBOARD_CLAD_VIA_PITCH),\n)\n\nexport const BREADBOARD_TERMINAL_ROW_YS = Object.fromEntries(\n BREADBOARD_TERMINAL_ROW_LABELS.map((label, index) => {\n const bankIndex = index < 5 ? index : index - 5\n const y =\n index < 5\n ? BREADBOARD_TERMINAL_INNER_ROW_Y +\n (4 - bankIndex) * BREADBOARD_HEADER_PITCH\n : -BREADBOARD_TERMINAL_INNER_ROW_Y - bankIndex * BREADBOARD_HEADER_PITCH\n return [label, roundCoordinate(y)]\n }),\n) as Record<BreadboardTerminalRowLabel, number>\n\n/** Individually routable A1-J21 sockets in a conventional breadboard grid. */\nexport const BREADBOARD_TERMINAL_HEADER_POSITIONS =\n BREADBOARD_TERMINAL_ROW_LABELS.flatMap((row, rowIndex) =>\n BREADBOARD_COLUMN_XS.map((x, columnIndex) => ({\n pin: rowIndex * BREADBOARD_COLUMN_COUNT + columnIndex + 1,\n label: `${row}${columnIndex + 1}`,\n column: columnIndex + 1,\n x,\n y: BREADBOARD_TERMINAL_ROW_YS[row],\n })),\n ) satisfies BreadboardHeaderPosition[]\n\nexport const BREADBOARD_POWER_RAILS = [\n { id: \"topPositive\", label: \"+\", y: 21.59 },\n { id: \"topNegative\", label: \"-\", y: 19.05 },\n { id: \"bottomPositive\", label: \"+\", y: -19.05 },\n { id: \"bottomNegative\", label: \"-\", y: -21.59 },\n] as const\n\nexport type BreadboardPowerRailId =\n (typeof BREADBOARD_POWER_RAILS)[number][\"id\"]\n\nexport const BREADBOARD_POWER_HEADER_POSITIONS = BREADBOARD_POWER_RAILS.flatMap(\n (rail) =>\n BREADBOARD_COLUMN_XS.map((x, columnIndex) => ({\n rail: rail.id,\n pin: columnIndex + 1,\n label: `${rail.id}${columnIndex + 1}`,\n column: columnIndex + 1,\n x,\n y: rail.y,\n })),\n)\n\n/**\n * Fixed layer-change rows run through each open channel. A single-via-wide\n * outer field also runs beyond all four sides of the pin headers while staying\n * clear of the tooling holes and board edge.\n */\nexport const BREADBOARD_CLAD_VIA_POSITIONS = [\n ...BREADBOARD_CLAD_VIA_ROW_YS.flatMap((y) =>\n BREADBOARD_COLUMN_XS.map((x) => ({ x, y })),\n ),\n ...BREADBOARD_OUTER_VIA_ROW_YS.flatMap((y) =>\n BREADBOARD_COLUMN_XS.map((x) => ({ x, y })),\n ),\n ...BREADBOARD_OUTER_VIA_COLUMN_XS.flatMap((x) =>\n BREADBOARD_OUTER_VERTICAL_VIA_YS.map((y) => ({ x, y })),\n ),\n] satisfies BreadboardCladViaPosition[]\n\nconst terminalPinLabels = Object.fromEntries(\n BREADBOARD_TERMINAL_HEADER_POSITIONS.map((position) => [\n `pin${position.pin}`,\n [position.label],\n ]),\n)\n\nconst powerPinLabels = Object.fromEntries(\n BREADBOARD_COLUMN_XS.map((_, index) => [\n `pin${index + 1}`,\n [`COL${index + 1}`],\n ]),\n)\n\nconst terminalPinNames = BREADBOARD_TERMINAL_HEADER_POSITIONS.map(\n (position) => `pin${position.pin}`,\n)\nconst powerPinNames = BREADBOARD_COLUMN_XS.map((_, index) => `pin${index + 1}`)\n\nconst BreadboardTerminalHeaderFootprint = () => (\n <footprint insertionDirection=\"from_above\">\n {BREADBOARD_TERMINAL_HEADER_POSITIONS.map((position) => (\n <Fragment key={`terminal-${position.label}`}>\n {position.pin === 1 ? (\n <platedhole\n portHints={[`pin${position.pin}`]}\n shape=\"circular_hole_with_rect_pad\"\n holeDiameter={`${BREADBOARD_HEADER_HOLE_DIAMETER}mm`}\n rectPadWidth={`${BREADBOARD_HEADER_PAD_DIAMETER}mm`}\n rectPadHeight={`${BREADBOARD_HEADER_PAD_DIAMETER}mm`}\n pcbX={position.x}\n pcbY={position.y}\n />\n ) : (\n <platedhole\n portHints={[`pin${position.pin}`]}\n shape=\"circle\"\n holeDiameter={`${BREADBOARD_HEADER_HOLE_DIAMETER}mm`}\n outerDiameter={`${BREADBOARD_HEADER_PAD_DIAMETER}mm`}\n pcbX={position.x}\n pcbY={position.y}\n />\n )}\n </Fragment>\n ))}\n </footprint>\n)\n\nconst BreadboardPowerHeaderFootprint = () => (\n <footprint insertionDirection=\"from_above\">\n {BREADBOARD_COLUMN_XS.map((x, index) => (\n <Fragment key={`power-pin-${index + 1}`}>\n {index === 0 ? (\n <platedhole\n portHints={[`pin${index + 1}`]}\n shape=\"circular_hole_with_rect_pad\"\n holeDiameter={`${BREADBOARD_HEADER_HOLE_DIAMETER}mm`}\n rectPadWidth={`${BREADBOARD_HEADER_PAD_DIAMETER}mm`}\n rectPadHeight={`${BREADBOARD_HEADER_PAD_DIAMETER}mm`}\n pcbX={x}\n />\n ) : (\n <platedhole\n portHints={[`pin${index + 1}`]}\n shape=\"circle\"\n holeDiameter={`${BREADBOARD_HEADER_HOLE_DIAMETER}mm`}\n outerDiameter={`${BREADBOARD_HEADER_PAD_DIAMETER}mm`}\n pcbX={x}\n />\n )}\n </Fragment>\n ))}\n </footprint>\n)\n\n/** One connector exposing every terminal socket by its breadboard name. */\nexport const BreadboardTerminalHeaders = (props: ConnectorProps) => (\n <connector\n pinLabels={terminalPinLabels}\n manufacturerPartNumber=\"GENERIC-BREADBOARD-10X21-FEMALE-2.54MM\"\n footprint={<BreadboardTerminalHeaderFootprint />}\n noSchematicRepresentation\n {...props}\n />\n)\n\n/** One 1x21 female socket rail; select it with a BREADBOARD_POWER_RAILS id. */\nexport const BreadboardPowerHeader = ({\n rail,\n ...props\n}: ConnectorProps & { rail: BreadboardPowerRailId }) => (\n <connector\n pinLabels={powerPinLabels}\n manufacturerPartNumber=\"GENERIC-BREADBOARD-1X21-FEMALE-2.54MM\"\n footprint={<BreadboardPowerHeaderFootprint />}\n noSchematicRepresentation\n pcbY={BREADBOARD_POWER_RAILS.find((candidate) => candidate.id === rail)!.y}\n {...props}\n />\n)\n\nexport interface BreadboardCladProps {\n children?: ReactNode\n autorouter?: AutorouterProp\n autorouterOptions?: BiscuitBoardAutorouterOptions\n minTraceWidth?: number\n nominalTraceWidth?: number\n routingDisabled?: boolean\n /** Marks all sockets NC for a bare template preview. */\n markHeadersNoConnect?: boolean\n /** Per-header no-connect overrides for partially populated designs. */\n headerNoConnects?: {\n terminals?: string[]\n topPositive?: string[]\n topNegative?: string[]\n bottomPositive?: string[]\n bottomNegative?: string[]\n }\n}\n\n/**\n * A laser-routable breadboard clad with individual 2.54 mm socket pads and\n * fixed vias. Nothing is pre-connected, so every breadboard net is defined by\n * the traces in the consuming circuit.\n */\nexport const BreadboardClad = ({\n children,\n autorouter,\n autorouterOptions,\n minTraceWidth,\n nominalTraceWidth = 0.3,\n routingDisabled = false,\n markHeadersNoConnect = false,\n headerNoConnects,\n}: BreadboardCladProps) => (\n <board\n name=\"BreadboardClad\"\n title=\"Laser-routable breadboard clad with prefabricated vias\"\n width={`${BREADBOARD_CLAD_WIDTH}mm`}\n height={`${BREADBOARD_CLAD_HEIGHT}mm`}\n borderRadius=\"2mm\"\n layers={2}\n minTraceWidth={`${minTraceWidth ?? 0.15}mm`}\n minBoardEdgeClearance={`${BREADBOARD_CLAD_EDGE_CLEARANCE - BREADBOARD_CLAD_EDGE_CLEARANCE_VALIDATION_TOLERANCE}mm`}\n minViaHoleDiameter=\"0.2mm\"\n minViaPadDiameter=\"0.4mm\"\n autorouter={\n autorouter ??\n createPrefabricatedViaAutorouter({\n width: BREADBOARD_CLAD_WIDTH,\n height: BREADBOARD_CLAD_HEIGHT,\n edgeClearance: BREADBOARD_CLAD_EDGE_CLEARANCE,\n options: autorouterOptions,\n minimumTraceWidth: minTraceWidth,\n nominalTraceWidth,\n })\n }\n routingDisabled={routingDisabled}\n >\n <net name=\"GND\" isGroundNet />\n\n {BISCUIT_BOARD_MOUNTING_HOLE_POSITIONS.map((hole) => (\n <Fragment key={`breadboard-mounting-hole-${hole.x}-${hole.y}`}>\n <hole\n pcbX={hole.x}\n pcbY={hole.y}\n diameter={`${BREADBOARD_MOUNTING_HOLE_DIAMETER}mm`}\n />\n </Fragment>\n ))}\n\n <BreadboardTerminalHeaders\n name=\"J_TERMINALS\"\n noConnect={\n headerNoConnects?.terminals ??\n (markHeadersNoConnect ? terminalPinNames : undefined)\n }\n />\n\n {BREADBOARD_POWER_RAILS.map((rail) => (\n <Fragment key={rail.id}>\n <BreadboardPowerHeader\n rail={rail.id}\n name={`J_${rail.id.replace(/([A-Z])/g, \"_$1\").toUpperCase()}`}\n noConnect={\n headerNoConnects?.[rail.id] ??\n (markHeadersNoConnect ? powerPinNames : undefined)\n }\n />\n </Fragment>\n ))}\n\n {[1, 5, 10, 15, 20, BREADBOARD_COLUMN_COUNT].map((column) => (\n <Fragment key={`column-label-${column}`}>\n <silkscreentext\n text={`${column}`}\n pcbX={BREADBOARD_COLUMN_XS[column - 1]}\n pcbY={16.5}\n fontSize=\"0.55mm\"\n />\n </Fragment>\n ))}\n\n {BREADBOARD_CLAD_VIA_POSITIONS.map((via) => (\n <Fragment key={`breadboard-prefab-via-${via.x}-${via.y}`}>\n <via\n netIsAssignable\n pcbX={via.x}\n pcbY={via.y}\n fromLayer=\"top\"\n toLayer=\"bottom\"\n holeDiameter={`${BREADBOARD_CLAD_VIA_HOLE_DIAMETER}mm`}\n outerDiameter={`${BREADBOARD_CLAD_VIA_PAD_DIAMETER}mm`}\n />\n </Fragment>\n ))}\n\n <silkscreentext\n text=\"BREADBOARD CLAD\"\n pcbX={33.5}\n pcbY={0}\n pcbRotation={90}\n fontSize=\"0.7mm\"\n />\n\n <pcbnotedimension\n from={{\n x: -BREADBOARD_CLAD_WIDTH / 2,\n y: BREADBOARD_CLAD_HEIGHT / 2 + 2.5,\n }}\n to={{\n x: BREADBOARD_CLAD_WIDTH / 2,\n y: BREADBOARD_CLAD_HEIGHT / 2 + 2.5,\n }}\n text={`${BREADBOARD_CLAD_WIDTH}mm`}\n />\n <pcbnotedimension\n from={{\n x: BREADBOARD_CLAD_WIDTH / 2 + 2.5,\n y: -BREADBOARD_CLAD_HEIGHT / 2,\n }}\n to={{\n x: BREADBOARD_CLAD_WIDTH / 2 + 2.5,\n y: BREADBOARD_CLAD_HEIGHT / 2,\n }}\n text={`${BREADBOARD_CLAD_HEIGHT}mm`}\n />\n\n {children}\n </board>\n)\n","import type { AutorouterProp } from \"@tscircuit/props\"\nimport { Fragment, type ReactNode } from \"react\"\nimport type { BiscuitBoardAutorouterOptions } from \"./biscuit-board-autorouter\"\nimport { createPrefabricatedViaAutorouter } from \"./create-prefabricated-via-autorouter\"\n\nexport const CLAD_40X40_WIDTH = 40\nexport const CLAD_40X40_HEIGHT = 40\nexport const CLAD_40X40_MOUNTING_HOLE_DIAMETER = 2\nexport const CLAD_40X40_EDGE_MOUNTING_HOLE_INSET = 3\nexport const CLAD_40X40_VIA_HOLE_DIAMETER = 0.3\nexport const CLAD_40X40_VIA_PAD_DIAMETER = 0.6\nexport const CLAD_40X40_VIA_SPACING = 1.3\nexport const CLAD_40X40_VIA_RING_HALF_SIZES = [2.6, 3.9, 5.2] as const\n\nexport const CLAD_40X40_MOUNTING_HOLE_POSITIONS = [\n { x: 0, y: 0 },\n {\n x: CLAD_40X40_WIDTH / 2 - CLAD_40X40_EDGE_MOUNTING_HOLE_INSET,\n y: CLAD_40X40_HEIGHT / 2 - CLAD_40X40_EDGE_MOUNTING_HOLE_INSET,\n },\n]\n\nconst CLAD_40X40_EDGE_CLEARANCE = 0.2\nconst CLAD_40X40_EDGE_CLEARANCE_VALIDATION_TOLERANCE = 0.001\n\nconst createSquareViaRingPositions = (halfSize: number) => {\n const axisPositions = Array.from(\n { length: Math.round((halfSize * 2) / CLAD_40X40_VIA_SPACING) + 1 },\n (_, index) =>\n Math.round((-halfSize + index * CLAD_40X40_VIA_SPACING) * 1e6) / 1e6,\n )\n\n return [\n ...axisPositions.flatMap((x) => [\n { x, y: -halfSize },\n { x, y: halfSize },\n ]),\n ...axisPositions.slice(1, -1).flatMap((y) => [\n { x: -halfSize, y },\n { x: halfSize, y },\n ]),\n ]\n}\n\n/** Three concentric square via rings centered on the central mounting hole. */\nexport const CLAD_40X40_VIA_POSITIONS = CLAD_40X40_VIA_RING_HALF_SIZES.flatMap(\n createSquareViaRingPositions,\n)\n\nexport interface Clad40x40Props {\n children?: ReactNode\n autorouter?: AutorouterProp\n autorouterOptions?: BiscuitBoardAutorouterOptions\n /** Enforced minimum trace width in millimeters. */\n minTraceWidth?: number\n nominalTraceWidth?: number\n routingDisabled?: boolean\n}\n\n/** A two-layer 40 mm square clad with two mounting holes and three via rings. */\nexport const Clad40x40 = ({\n children,\n autorouter,\n autorouterOptions,\n minTraceWidth,\n nominalTraceWidth = 0.2,\n routingDisabled = false,\n}: Clad40x40Props) => (\n <board\n name=\"Clad40x40\"\n title=\"40 mm x 40 mm copper clad\"\n width={`${CLAD_40X40_WIDTH}mm`}\n height={`${CLAD_40X40_HEIGHT}mm`}\n borderRadius=\"1.5mm\"\n layers={2}\n minTraceWidth={`${minTraceWidth ?? 0.15}mm`}\n minBoardEdgeClearance={`${CLAD_40X40_EDGE_CLEARANCE - CLAD_40X40_EDGE_CLEARANCE_VALIDATION_TOLERANCE}mm`}\n minViaHoleDiameter=\"0.2mm\"\n minViaPadDiameter=\"0.4mm\"\n autorouter={\n autorouter ??\n createPrefabricatedViaAutorouter({\n width: CLAD_40X40_WIDTH,\n height: CLAD_40X40_HEIGHT,\n edgeClearance: CLAD_40X40_EDGE_CLEARANCE,\n options: autorouterOptions,\n minimumTraceWidth: minTraceWidth,\n nominalTraceWidth,\n })\n }\n routingDisabled={routingDisabled}\n >\n {CLAD_40X40_MOUNTING_HOLE_POSITIONS.map((hole) => (\n <Fragment key={`clad-40x40-mounting-hole-${hole.x}-${hole.y}`}>\n <hole\n pcbX={hole.x}\n pcbY={hole.y}\n diameter={`${CLAD_40X40_MOUNTING_HOLE_DIAMETER}mm`}\n />\n </Fragment>\n ))}\n\n {CLAD_40X40_VIA_POSITIONS.map((via) => (\n <Fragment key={`clad-40x40-prefab-via-${via.x}-${via.y}`}>\n <via\n netIsAssignable\n pcbX={via.x}\n pcbY={via.y}\n fromLayer=\"top\"\n toLayer=\"bottom\"\n holeDiameter={`${CLAD_40X40_VIA_HOLE_DIAMETER}mm`}\n outerDiameter={`${CLAD_40X40_VIA_PAD_DIAMETER}mm`}\n />\n </Fragment>\n ))}\n\n <pcbnotedimension\n from={{\n x: -CLAD_40X40_WIDTH / 2,\n y: CLAD_40X40_HEIGHT / 2 + 2.5,\n }}\n to={{\n x: CLAD_40X40_WIDTH / 2,\n y: CLAD_40X40_HEIGHT / 2 + 2.5,\n }}\n text={`${CLAD_40X40_WIDTH}mm`}\n />\n <pcbnotedimension\n from={{\n x: CLAD_40X40_WIDTH / 2 + 2.5,\n y: -CLAD_40X40_HEIGHT / 2,\n }}\n to={{\n x: CLAD_40X40_WIDTH / 2 + 2.5,\n y: CLAD_40X40_HEIGHT / 2,\n }}\n text={`${CLAD_40X40_HEIGHT}mm`}\n />\n\n {children}\n </board>\n)\n","import type { AutorouterProp, ConnectorProps } from \"@tscircuit/props\"\nimport { Fragment, type ReactNode } from \"react\"\nimport type { BiscuitBoardAutorouterOptions } from \"./biscuit-board-autorouter\"\nimport { createPrefabricatedViaAutorouter } from \"./create-prefabricated-via-autorouter\"\n\n/** The classic Adafruit Feather outline, with USB at the positive Y edge. */\nexport const FEATHER_CLAD_WIDTH = 22.86\nexport const FEATHER_CLAD_HEIGHT = 50.8\nexport const FEATHER_HEADER_PITCH = 2.54\nexport const FEATHER_HEADER_ROW_SPACING = 20.32\nexport const FEATHER_HEADER_HOLE_DIAMETER = 1\nexport const FEATHER_HEADER_PAD_DIAMETER = 1.7\nexport const FEATHER_MOUNTING_HOLE_DIAMETER = 2.54\nexport const FEATHER_CLAD_VIA_HOLE_DIAMETER = 0.3\nexport const FEATHER_CLAD_VIA_PAD_DIAMETER = 0.6\nexport const FEATHER_CLAD_VIA_SPACING = 1.3\n\nconst FEATHER_CLAD_EDGE_CLEARANCE = 0.2\nconst FEATHER_CLAD_EDGE_CLEARANCE_VALIDATION_TOLERANCE = 0.001\n\n/** Four 0.1 inch mounting holes inset 0.1 inch from each corner. */\nexport const FEATHER_MOUNTING_HOLE_POSITIONS = [-8.89, 8.89].flatMap((x) =>\n [-22.86, 22.86].map((y) => ({ x, y })),\n)\n\nconst featherLeftHeaderYs = Array.from(\n { length: 16 },\n (_, index) => (7.5 - index) * FEATHER_HEADER_PITCH,\n)\n\nconst featherRightHeaderYs = Array.from(\n { length: 12 },\n (_, index) => (3.5 - index) * FEATHER_HEADER_PITCH,\n)\n\nconst featherViaYs = Array.from(\n { length: 31 },\n (_, index) =>\n Math.round((-19.5 + index * FEATHER_CLAD_VIA_SPACING) * 1e6) / 1e6,\n)\n\n/** Via columns flank the component field while preserving the header-free top right. */\nexport const FEATHER_CLAD_VIA_POSITIONS = [\n ...featherViaYs.map((y) => ({ x: -8, y })),\n ...featherViaYs\n .filter((y) => y <= featherRightHeaderYs[0]!)\n .map((y) => ({ x: 8, y })),\n]\n\n/** Header positions follow the standard Feather pinout with USB at positive Y. */\nexport const FEATHER_HEADER_POSITIONS = [\n ...featherLeftHeaderYs.map((y) => ({\n x: -FEATHER_HEADER_ROW_SPACING / 2,\n y,\n })),\n ...featherRightHeaderYs.map((y) => ({\n x: FEATHER_HEADER_ROW_SPACING / 2,\n y,\n })),\n]\n\nexport const FEATHER_PIN_LABELS = {\n pin1: [\"RST\", \"RESET\"],\n pin2: [\"V3V3\", \"3V3\"],\n pin3: [\"AREF\"],\n pin4: [\"GND\"],\n pin5: [\"A0\"],\n pin6: [\"A1\"],\n pin7: [\"A2\"],\n pin8: [\"A3\"],\n pin9: [\"A4\", \"D24\"],\n pin10: [\"A5\", \"D25\"],\n pin11: [\"SCK\"],\n pin12: [\"MOSI\", \"MO\"],\n pin13: [\"MISO\", \"MI\"],\n pin14: [\"RX\", \"D0\"],\n pin15: [\"TX\", \"D1\"],\n pin16: [\"FREE\"],\n pin17: [\"BAT\", \"VBAT\"],\n pin18: [\"EN\"],\n pin19: [\"USB\", \"VBUS\"],\n pin20: [\"D13\"],\n pin21: [\"D12\"],\n pin22: [\"D11\"],\n pin23: [\"D10\"],\n pin24: [\"D9\"],\n pin25: [\"D6\"],\n pin26: [\"D5\"],\n pin27: [\"SCL\"],\n pin28: [\"SDA\"],\n} as const\n\nexport const FEATHER_PIN_NAMES = Array.from(\n { length: 28 },\n (_, index) => `pin${index + 1}`,\n)\n\nconst FeatherPinHeaderFootprint = () => (\n <footprint insertionDirection=\"from_below\">\n {FEATHER_HEADER_POSITIONS.map((position, index) => (\n <Fragment key={`feather-header-${position.x}-${position.y}`}>\n {index === 0 ? (\n <platedhole\n portHints={[`pin${index + 1}`]}\n shape=\"circular_hole_with_rect_pad\"\n holeDiameter={`${FEATHER_HEADER_HOLE_DIAMETER}mm`}\n rectPadWidth={`${FEATHER_HEADER_PAD_DIAMETER}mm`}\n rectPadHeight={`${FEATHER_HEADER_PAD_DIAMETER}mm`}\n pcbX={position.x}\n pcbY={position.y}\n />\n ) : (\n <platedhole\n portHints={[`pin${index + 1}`]}\n shape=\"circle\"\n holeDiameter={`${FEATHER_HEADER_HOLE_DIAMETER}mm`}\n outerDiameter={`${FEATHER_HEADER_PAD_DIAMETER}mm`}\n pcbX={position.x}\n pcbY={position.y}\n />\n )}\n </Fragment>\n ))}\n </footprint>\n)\n\nexport const FeatherPinHeaders = (props: ConnectorProps) => (\n <connector\n pinLabels={FEATHER_PIN_LABELS}\n manufacturerPartNumber=\"GENERIC-FEATHER-1X16-PLUS-1X12-MALE-2.54MM-DOWN\"\n footprint={<FeatherPinHeaderFootprint />}\n noSchematicRepresentation\n {...props}\n />\n)\n\nexport interface FeatherCladWithPinHeadersProps {\n children?: ReactNode\n autorouter?: AutorouterProp\n autorouterOptions?: BiscuitBoardAutorouterOptions\n minTraceWidth?: number\n nominalTraceWidth?: number\n routingDisabled?: boolean\n /** Marks every header pin NC for template previews and routing examples. */\n markHeadersNoConnect?: boolean\n /** Shows the USB-edge orientation mark. Defaults to true. */\n showUsbLabel?: boolean\n}\n\n/** A two-layer copper clad matching the classic Adafruit Feather outline. */\nexport const FeatherCladWithPinHeaders = ({\n children,\n autorouter,\n autorouterOptions,\n minTraceWidth,\n nominalTraceWidth = 0.2,\n routingDisabled = false,\n markHeadersNoConnect = false,\n showUsbLabel = true,\n}: FeatherCladWithPinHeadersProps) => (\n <board\n name=\"FeatherCladWithPinHeaders\"\n title=\"Adafruit Feather form-factor copper clad with pin headers\"\n width={`${FEATHER_CLAD_WIDTH}mm`}\n height={`${FEATHER_CLAD_HEIGHT}mm`}\n borderRadius=\"2.54mm\"\n layers={2}\n minTraceWidth={`${minTraceWidth ?? 0.15}mm`}\n minBoardEdgeClearance={`${FEATHER_CLAD_EDGE_CLEARANCE - FEATHER_CLAD_EDGE_CLEARANCE_VALIDATION_TOLERANCE}mm`}\n minViaHoleDiameter=\"0.2mm\"\n minViaPadDiameter=\"0.4mm\"\n autorouter={\n autorouter ??\n createPrefabricatedViaAutorouter({\n width: FEATHER_CLAD_WIDTH,\n height: FEATHER_CLAD_HEIGHT,\n edgeClearance: FEATHER_CLAD_EDGE_CLEARANCE,\n options: autorouterOptions,\n minimumTraceWidth: minTraceWidth,\n nominalTraceWidth,\n })\n }\n routingDisabled={routingDisabled}\n >\n <FeatherPinHeaders\n name=\"J_FEATHER\"\n noConnect={markHeadersNoConnect ? FEATHER_PIN_NAMES : undefined}\n />\n\n {FEATHER_MOUNTING_HOLE_POSITIONS.map((hole) => (\n <Fragment key={`feather-mounting-hole-${hole.x}-${hole.y}`}>\n <hole\n pcbX={hole.x}\n pcbY={hole.y}\n diameter={`${FEATHER_MOUNTING_HOLE_DIAMETER}mm`}\n />\n </Fragment>\n ))}\n\n {showUsbLabel && (\n <silkscreentext\n text=\"UP\"\n pcbX={0}\n pcbY={FEATHER_CLAD_HEIGHT / 2 - 1.2}\n fontSize=\"0.7mm\"\n />\n )}\n\n {FEATHER_CLAD_VIA_POSITIONS.map((via) => (\n <Fragment key={`feather-prefab-via-${via.x}-${via.y}`}>\n <via\n netIsAssignable\n pcbX={via.x}\n pcbY={via.y}\n fromLayer=\"top\"\n toLayer=\"bottom\"\n holeDiameter={`${FEATHER_CLAD_VIA_HOLE_DIAMETER}mm`}\n outerDiameter={`${FEATHER_CLAD_VIA_PAD_DIAMETER}mm`}\n />\n </Fragment>\n ))}\n\n <pcbnotedimension\n from={{\n x: -FEATHER_CLAD_WIDTH / 2,\n y: FEATHER_CLAD_HEIGHT / 2 + 2,\n }}\n to={{\n x: FEATHER_CLAD_WIDTH / 2,\n y: FEATHER_CLAD_HEIGHT / 2 + 2,\n }}\n text={`${FEATHER_CLAD_WIDTH}mm`}\n />\n <pcbnotedimension\n from={{\n x: FEATHER_CLAD_WIDTH / 2 + 2,\n y: -FEATHER_CLAD_HEIGHT / 2,\n }}\n to={{\n x: FEATHER_CLAD_WIDTH / 2 + 2,\n y: FEATHER_CLAD_HEIGHT / 2,\n }}\n text={`${FEATHER_CLAD_HEIGHT}mm`}\n />\n\n {children}\n </board>\n)\n","import type { AutorouterProp, ConnectorProps } from \"@tscircuit/props\"\nimport { Fragment, type ReactNode } from \"react\"\nimport type { BiscuitBoardAutorouterOptions } from \"./biscuit-board-autorouter\"\nimport { createPrefabricatedViaAutorouter } from \"./create-prefabricated-via-autorouter\"\n\n/** The classic Seeed Studio XIAO outline, with USB at the positive Y edge. */\nexport const XIAO_CLAD_WIDTH = 17.8\nexport const XIAO_CLAD_HEIGHT = 21\nexport const XIAO_HEADER_PITCH = 2.54\nexport const XIAO_HEADER_ROW_SPACING = 15.24\nexport const XIAO_HEADER_HOLE_DIAMETER = 1\nexport const XIAO_HEADER_PAD_DIAMETER = 1.7\nexport const XIAO_CLAD_VIA_HOLE_DIAMETER = 0.3\nexport const XIAO_CLAD_VIA_PAD_DIAMETER = 0.6\nexport const XIAO_CLAD_VIA_SPACING = 1.3\n\nconst XIAO_CLAD_EDGE_CLEARANCE = 0.2\nconst XIAO_CLAD_EDGE_CLEARANCE_VALIDATION_TOLERANCE = 0.001\n\n/** Two 1 x 13 via columns flanking the central component field. */\nexport const XIAO_CLAD_VIA_POSITIONS = [-5.8, 5.8].flatMap((x) =>\n Array.from({ length: 13 }, (_, index) => ({\n x,\n y: Math.round((-8 + index * XIAO_CLAD_VIA_SPACING) * 1e6) / 1e6,\n })),\n)\n\nconst xiaoHeaderYs = Array.from(\n { length: 7 },\n (_, index) => (3 - index) * XIAO_HEADER_PITCH,\n)\n\nexport const XIAO_HEADER_POSITIONS = [\n ...xiaoHeaderYs.map((y) => ({ x: -XIAO_HEADER_ROW_SPACING / 2, y })),\n ...xiaoHeaderYs.map((y) => ({ x: XIAO_HEADER_ROW_SPACING / 2, y })),\n]\n\nexport const XIAO_PIN_LABELS = {\n pin1: [\"D0\", \"A0\"],\n pin2: [\"D1\", \"A1\"],\n pin3: [\"D2\", \"A2\"],\n pin4: [\"D3\", \"A3\"],\n pin5: [\"D4\", \"SDA\"],\n pin6: [\"D5\", \"SCL\"],\n pin7: [\"D6\", \"TX\"],\n pin8: [\"V5\", \"5V\"],\n pin9: [\"GND\"],\n pin10: [\"V3V3\", \"3V3\"],\n pin11: [\"D10\", \"MOSI\"],\n pin12: [\"D9\", \"MISO\"],\n pin13: [\"D8\", \"SCK\"],\n pin14: [\"D7\", \"RX\"],\n} as const\n\nexport const XIAO_PIN_NAMES = Array.from(\n { length: 14 },\n (_, index) => `pin${index + 1}`,\n)\n\nconst XiaoPinHeaderFootprint = () => (\n <footprint insertionDirection=\"from_below\">\n {XIAO_HEADER_POSITIONS.map((position, index) => (\n <Fragment key={`xiao-header-${position.x}-${position.y}`}>\n {index === 0 ? (\n <platedhole\n portHints={[`pin${index + 1}`]}\n shape=\"circular_hole_with_rect_pad\"\n holeDiameter={`${XIAO_HEADER_HOLE_DIAMETER}mm`}\n rectPadWidth={`${XIAO_HEADER_PAD_DIAMETER}mm`}\n rectPadHeight={`${XIAO_HEADER_PAD_DIAMETER}mm`}\n pcbX={position.x}\n pcbY={position.y}\n />\n ) : (\n <platedhole\n portHints={[`pin${index + 1}`]}\n shape=\"circle\"\n holeDiameter={`${XIAO_HEADER_HOLE_DIAMETER}mm`}\n outerDiameter={`${XIAO_HEADER_PAD_DIAMETER}mm`}\n pcbX={position.x}\n pcbY={position.y}\n />\n )}\n </Fragment>\n ))}\n </footprint>\n)\n\nexport const XiaoPinHeaders = (props: ConnectorProps) => (\n <connector\n pinLabels={XIAO_PIN_LABELS}\n manufacturerPartNumber=\"GENERIC-XIAO-2X7-MALE-2.54MM-DOWN\"\n footprint={<XiaoPinHeaderFootprint />}\n noSchematicRepresentation\n {...props}\n />\n)\n\nexport interface XiaoCladWithPinHeadersProps {\n children?: ReactNode\n autorouter?: AutorouterProp\n autorouterOptions?: BiscuitBoardAutorouterOptions\n minTraceWidth?: number\n nominalTraceWidth?: number\n routingDisabled?: boolean\n /** Marks every header pin NC for template previews and routing examples. */\n markHeadersNoConnect?: boolean\n /** Shows the USB-edge orientation mark. Defaults to true. */\n showUsbLabel?: boolean\n}\n\nexport interface XiaoCladLayoutProps\n extends Omit<XiaoCladWithPinHeadersProps, \"markHeadersNoConnect\"> {\n boardName: string\n boardTitle: string\n pinHeaders: ReactNode\n edgeFeatures?: ReactNode\n}\n\nexport const XiaoCladLayout = ({\n boardName,\n boardTitle,\n pinHeaders,\n edgeFeatures,\n children,\n autorouter,\n autorouterOptions,\n minTraceWidth,\n nominalTraceWidth = 0.2,\n routingDisabled = false,\n showUsbLabel = true,\n}: XiaoCladLayoutProps) => (\n <board\n name={boardName}\n title={boardTitle}\n width={`${XIAO_CLAD_WIDTH}mm`}\n height={`${XIAO_CLAD_HEIGHT}mm`}\n borderRadius=\"1mm\"\n layers={2}\n minTraceWidth={`${minTraceWidth ?? 0.15}mm`}\n minBoardEdgeClearance={`${XIAO_CLAD_EDGE_CLEARANCE - XIAO_CLAD_EDGE_CLEARANCE_VALIDATION_TOLERANCE}mm`}\n minViaHoleDiameter=\"0.2mm\"\n minViaPadDiameter=\"0.4mm\"\n autorouter={\n autorouter ??\n createPrefabricatedViaAutorouter({\n width: XIAO_CLAD_WIDTH,\n height: XIAO_CLAD_HEIGHT,\n edgeClearance: XIAO_CLAD_EDGE_CLEARANCE,\n options: autorouterOptions,\n minimumTraceWidth: minTraceWidth,\n nominalTraceWidth,\n })\n }\n routingDisabled={routingDisabled}\n >\n {pinHeaders}\n {edgeFeatures}\n\n {showUsbLabel && (\n <silkscreentext\n text=\"UP\"\n pcbX={0}\n pcbY={XIAO_CLAD_HEIGHT / 2 - 1.2}\n fontSize=\"0.7mm\"\n />\n )}\n\n {XIAO_CLAD_VIA_POSITIONS.map((via) => (\n <Fragment key={`xiao-prefab-via-${via.x}-${via.y}`}>\n <via\n netIsAssignable\n pcbX={via.x}\n pcbY={via.y}\n fromLayer=\"top\"\n toLayer=\"bottom\"\n holeDiameter={`${XIAO_CLAD_VIA_HOLE_DIAMETER}mm`}\n outerDiameter={`${XIAO_CLAD_VIA_PAD_DIAMETER}mm`}\n />\n </Fragment>\n ))}\n\n <pcbnotedimension\n from={{ x: -XIAO_CLAD_WIDTH / 2, y: XIAO_CLAD_HEIGHT / 2 + 2 }}\n to={{ x: XIAO_CLAD_WIDTH / 2, y: XIAO_CLAD_HEIGHT / 2 + 2 }}\n text={`${XIAO_CLAD_WIDTH}mm`}\n />\n <pcbnotedimension\n from={{ x: XIAO_CLAD_WIDTH / 2 + 2, y: -XIAO_CLAD_HEIGHT / 2 }}\n to={{ x: XIAO_CLAD_WIDTH / 2 + 2, y: XIAO_CLAD_HEIGHT / 2 }}\n text={`${XIAO_CLAD_HEIGHT}mm`}\n />\n\n {children}\n </board>\n)\n\n/** A two-layer copper clad matching the classic Seeed Studio XIAO outline. */\nexport const XiaoCladWithPinHeaders = ({\n markHeadersNoConnect = false,\n ...props\n}: XiaoCladWithPinHeadersProps) => (\n <XiaoCladLayout\n {...props}\n boardName=\"XiaoCladWithPinHeaders\"\n boardTitle=\"XIAO form-factor copper clad with pin headers\"\n pinHeaders={\n <XiaoPinHeaders\n name=\"J_XIAO\"\n noConnect={markHeadersNoConnect ? XIAO_PIN_NAMES : undefined}\n />\n }\n />\n)\n","import type { ConnectorProps } from \"@tscircuit/props\"\nimport { Fragment } from \"react\"\nimport {\n XIAO_CLAD_WIDTH,\n XIAO_HEADER_HOLE_DIAMETER,\n XIAO_HEADER_POSITIONS,\n XIAO_PIN_LABELS,\n XIAO_PIN_NAMES,\n XiaoCladLayout,\n type XiaoCladWithPinHeadersProps,\n} from \"./xiao-clad\"\n\nexport const XIAO_PERFORATED_HEADER_PAD_WIDTH = 2.13\nexport const XIAO_PERFORATED_HEADER_PAD_HEIGHT = 2\nexport const XIAO_PERFORATION_HOLE_DIAMETER = 0.7\n\nexport const XIAO_PERFORATION_POSITIONS = XIAO_HEADER_POSITIONS.map(\n (position) => ({\n x: Math.sign(position.x) * (XIAO_CLAD_WIDTH / 2),\n y: position.y,\n }),\n)\n\nconst XiaoPerforatedPinHeaderFootprint = () => (\n <footprint insertionDirection=\"from_below\">\n {XIAO_HEADER_POSITIONS.map((headerPosition, index) => {\n const side = Math.sign(headerPosition.x)\n const padCenterX =\n side * (XIAO_CLAD_WIDTH / 2 - XIAO_PERFORATED_HEADER_PAD_WIDTH / 2)\n\n return (\n <Fragment\n key={`xiao-perforated-header-${headerPosition.x}-${headerPosition.y}`}\n >\n <platedhole\n portHints={[`pin${index + 1}`]}\n shape=\"circular_hole_with_rect_pad\"\n holeDiameter={`${XIAO_HEADER_HOLE_DIAMETER}mm`}\n rectPadWidth={`${XIAO_PERFORATED_HEADER_PAD_WIDTH}mm`}\n rectPadHeight={`${XIAO_PERFORATED_HEADER_PAD_HEIGHT}mm`}\n holeOffsetX={headerPosition.x - padCenterX}\n pcbX={padCenterX}\n pcbY={headerPosition.y}\n />\n </Fragment>\n )\n })}\n </footprint>\n)\n\n/** XIAO headers with an additional 0.7 mm perforation at each board edge. */\nexport const XiaoPerforatedPinHeaders = (props: ConnectorProps) => (\n <connector\n pinLabels={XIAO_PIN_LABELS}\n manufacturerPartNumber=\"GENERIC-XIAO-2X7-MALE-2.54MM-DOWN-PERFORATED\"\n footprint={<XiaoPerforatedPinHeaderFootprint />}\n noSchematicRepresentation\n {...props}\n />\n)\n\nexport type XiaoCladWithPerforatedPinHeadersProps = XiaoCladWithPinHeadersProps\n\n/** A XIAO clad whose header pads include perforations along both side edges. */\nexport const XiaoCladWithPerforatedPinHeaders = ({\n markHeadersNoConnect = false,\n ...props\n}: XiaoCladWithPerforatedPinHeadersProps) => (\n <XiaoCladLayout\n {...props}\n boardName=\"XiaoCladWithPerforatedPinHeaders\"\n boardTitle=\"XIAO form-factor copper clad with perforated pin-header sides\"\n pinHeaders={\n <XiaoPerforatedPinHeaders\n name=\"J_XIAO\"\n noConnect={markHeadersNoConnect ? XIAO_PIN_NAMES : undefined}\n />\n }\n edgeFeatures={XIAO_PERFORATION_POSITIONS.map((position) => (\n <Fragment key={`xiao-edge-perforation-${position.x}-${position.y}`}>\n <cutout\n shape=\"circle\"\n radius={`${XIAO_PERFORATION_HOLE_DIAMETER / 2}mm`}\n pcbX={position.x}\n pcbY={position.y}\n />\n </Fragment>\n ))}\n />\n)\n"],"mappings":"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","names":["rename","rename","noop","getAction","create","emit","step","createNode","create","handleLexerData","parseSync","Fragment","uint16","uint8","osIsLittleEndian","cos","sin","PI","tan","BaseSolver","pointsEqual","segmentsIntersect","cos","sin","BaseSolver","pointsEqual","cross","BaseSolver","pointDistance","pointsEqual","pointsEqual","MinHeap","DIRECTIONS","BaseSolver","pointsEqual","cross","data","pos","cos","sin","BaseSolver","range","GRID_OFFSETS","isWire","BaseSolver","isWire","BaseSolver","GRID_OFFSETS","uniqueDescending","isWire","BaseSolver","addEdge","cross","MinHeap","MinHeap","distance","axis","direction","demand","EPSILON","cross","dot","EPSILON","obstacle","EPSILON","cloneTraces","wirePathLength","cross","pointOnSegment","distance","dot","visualizeTraces","WIDTH_EPSILON","cross","dot","orientation","segmentsIntersect","distancePointToSegment","distanceSegmentToSegment","cos","sin","target","distance","EPSILON","coordinateKey","cross","subtract","pointIsOnSegment","edgeKey","current","createBiscuitBoardAutorouter","createBiscuitBoardAutorouter","width","jsx","jsxs","createViaZone","pointKey","Fragment","Fragment","jsx","jsxs","roundCoordinate","createViaZone","pointKey","Fragment","Fragment","jsx","jsxs","roundCoordinate","Fragment","Fragment","jsx","jsxs","Fragment","Fragment","jsx","jsxs","Fragment","Fragment","jsx","jsxs","Fragment","Fragment","jsx","Fragment"]}