@tscircuit/circuit-json-util 0.0.41

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":["../index.ts","../lib/su.ts","../lib/transform-soup-elements.ts","../lib/direction-to-vec.ts","../lib/apply-selector.ts","../lib/convert-abbreviation-to-soup-element-type.ts","../lib/get-element-id.ts","../lib/get-element-by-id.ts","../lib/readable-name-functions/get-readable-name-for-pcb-trace.ts","../lib/readable-name-functions/get-readable-name-for-pcb-port.ts","../lib/readable-name-functions/get-readable-name-for-pcb-smtpad.ts","../lib/readable-name-functions/get-readable-name-for-element.ts","../lib/get-bounds-of-pcb-elements.ts"],"sourcesContent":["export * from \"./lib/su\"\nexport * from \"./lib/transform-soup-elements\"\nexport * from \"./lib/direction-to-vec\"\nexport * from \"./lib/apply-selector\"\nexport * from \"./lib/get-element-by-id\"\nexport * from \"./lib/get-element-id\"\nexport * from \"./lib/readable-name-functions/get-readable-name-for-element\"\nexport * from \"./lib/get-bounds-of-pcb-elements\"\n\nexport { default as su } from \"./lib/su\"\n","import type {\n AnySoupElement,\n AnySoupElementInput,\n SourceComponentBase,\n SourcePort,\n} from \"@tscircuit/soup\"\nimport * as Soup from \"@tscircuit/soup\"\n\ntype SoupOps<\n K extends AnySoupElement[\"type\"],\n T extends AnySoupElement | AnySoupElementInput,\n> = {\n get: (id: string) => Extract<T, { type: K }> | null\n select: (selector: string) => Extract<T, { type: K }> | null\n getWhere: (where: any) => Extract<T, { type: K }> | null\n getUsing: (using: {\n [key: `${string}_id`]: string\n }) => Extract<T, { type: K }> | null\n insert: (\n elm: Omit<Extract<T, { type: K }>, \"type\" | `${K}_id`>,\n ) => Extract<T, { type: K }>\n update: (\n id: string,\n newProps: Partial<Extract<T, { type: K }>>,\n ) => Extract<T, { type: K }>\n delete: (id: string) => void\n list: (where?: any) => Extract<T, { type: K }>[]\n}\n\nexport type SoupUtilObjects = {\n [K in AnySoupElement[\"type\"]]: SoupOps<K, AnySoupElement>\n} & {\n toArray: () => AnySoupElement[]\n}\nexport type SoupInputUtilObjects = {\n [K in AnySoupElementInput[\"type\"]]: SoupOps<K, AnySoupElementInput>\n}\n\nexport type SoupUtilOptions = {\n validateInserts?: boolean\n}\n\nexport type GetSoupUtilFn = ((\n soup: AnySoupElement[],\n options?: SoupUtilOptions,\n) => SoupUtilObjects) & {\n unparsed: (soup: AnySoupElementInput[]) => SoupInputUtilObjects\n}\n\ninterface InternalStore {\n counts: Record<string, number>\n}\n\nexport const su: GetSoupUtilFn = ((\n soup: AnySoupElement[],\n options: SoupUtilOptions = {},\n) => {\n let internalStore: InternalStore = (soup as any)._internal_store\n if (!internalStore) {\n internalStore = {\n counts: {},\n } as InternalStore\n ;(soup as any)._internal_store = internalStore\n\n // Initialize counts\n for (const elm of soup) {\n const type = elm.type\n const idVal = (elm as any)[`${type}_id`]\n if (!idVal) continue\n const idNum = Number.parseInt(idVal.split(\"_\").pop())\n if (!Number.isNaN(idNum)) {\n internalStore.counts[type] = Math.max(\n internalStore.counts[type] ?? 0,\n idNum,\n )\n }\n }\n }\n const su = new Proxy(\n {},\n {\n get: (proxy_target: any, component_type: string) => {\n if (component_type === \"toArray\") {\n return () => soup\n }\n\n return {\n get: (id: string) =>\n soup.find(\n (e: any) =>\n e.type === component_type && e[`${component_type}_id`] === id,\n ),\n getUsing: (using: any) => {\n const keys = Object.keys(using)\n if (keys.length !== 1) {\n throw new Error(\n \"getUsing requires exactly one key, e.g. { pcb_component_id }\",\n )\n }\n const join_key = keys[0] as string\n const join_type = join_key.replace(\"_id\", \"\")\n const joiner: any = soup.find(\n (e: any) =>\n e.type === join_type && e[join_key] === using[join_key],\n )\n if (!joiner) return null\n return soup.find(\n (e: any) =>\n e.type === component_type &&\n e[`${component_type}_id`] === joiner[`${component_type}_id`],\n )\n },\n getWhere: (where: any) => {\n const keys = Object.keys(where)\n return soup.find(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n )\n },\n list: (where?: any) => {\n const keys = !where ? [] : Object.keys(where)\n return soup.filter(\n (e: any) =>\n e.type === component_type &&\n keys.every((key) => e[key] === where[key]),\n )\n },\n insert: (elm: any) => {\n internalStore.counts[component_type] ??= -1\n internalStore.counts[component_type]++\n const index = internalStore.counts[component_type]\n const newElm = {\n type: component_type,\n [`${component_type}_id`]: `${component_type}_${index}`,\n ...elm,\n }\n\n if (options.validateInserts) {\n const parser =\n (Soup as any)[component_type] ?? Soup.any_soup_element\n parser.parse(newElm)\n }\n\n soup.push(newElm)\n return newElm\n },\n delete: (id: string) => {\n const elm = soup.find(\n (e) => (e as any)[`${component_type}_id`] === id,\n )\n if (!elm) return\n soup.splice(soup.indexOf(elm), 1)\n },\n update: (id: string, newProps: any) => {\n const elm = soup.find(\n (e) => (e as any)[`${component_type}_id`] === id,\n )\n if (!elm) return\n Object.assign(elm, newProps)\n return elm\n },\n select: (selector: string) => {\n // TODO when applySelector is isolated we can use it, until then we\n // do a poor man's selector implementation for two common cases\n if (component_type === \"source_component\") {\n return soup.find(\n (e) =>\n e.type === \"source_component\" &&\n e.name === selector.replace(/\\./g, \"\"),\n )\n } else if (\n component_type === \"pcb_port\" ||\n component_type === \"source_port\" ||\n component_type === \"schematic_port\"\n ) {\n const [component_name, port_selector] = selector\n .replace(/\\./g, \"\")\n .split(/[\\s\\>]+/)\n const source_component = soup.find(\n (e) =>\n e.type === \"source_component\" && e.name === component_name,\n ) as SourceComponentBase\n if (!source_component) return null\n const source_port = soup.find(\n (e) =>\n e.type === \"source_port\" &&\n e.source_component_id ===\n source_component.source_component_id &&\n (e.name === port_selector ||\n (e.port_hints ?? []).includes(port_selector!)),\n ) as SourcePort\n if (!source_port) return null\n if (component_type === \"source_port\") return source_port\n\n if (component_type === \"pcb_port\") {\n return soup.find(\n (e) =>\n e.type === \"pcb_port\" &&\n e.source_port_id === source_port.source_port_id,\n )\n } else if (component_type === \"schematic_port\") {\n return soup.find(\n (e) =>\n e.type === \"schematic_port\" &&\n e.source_port_id === source_port.source_port_id,\n )\n }\n }\n },\n }\n },\n },\n )\n\n return su\n}) as any\nsu.unparsed = su as any\n\nexport default su\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { type Matrix, applyToPoint, decomposeTSR } from \"transformation-matrix\"\nimport {\n directionToVec,\n rotateDirection,\n vecToDirection,\n} from \"./direction-to-vec\"\n\nexport const transformSchematicElement = (\n elm: AnySoupElement,\n matrix: Matrix,\n) => {\n if (elm.type === \"schematic_component\") {\n // TODO handle rotation\n elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"schematic_port\") {\n elm.center = applyToPoint(matrix, elm.center)\n\n if (elm.facing_direction) {\n elm.facing_direction = rotateDirection(\n elm.facing_direction,\n -(Math.atan2(matrix.b, matrix.a) / Math.PI) * 2,\n )\n }\n } else if (elm.type === \"schematic_text\") {\n elm.position = applyToPoint(matrix, elm.position)\n // } else if (elm.type === \"schematic_group\") {\n // elm.center = applyToPoint(matrix, elm.center)\n } else if (elm.type === \"schematic_trace\") {\n } else if (elm.type === \"schematic_box\") {\n const { x, y } = applyToPoint(matrix, { x: elm.x, y: elm.y })\n elm.x = x\n elm.y = y\n } else if (elm.type === \"schematic_line\") {\n const { x: x1, y: y1 } = applyToPoint(matrix, { x: elm.x1, y: elm.y1 })\n const { x: x2, y: y2 } = applyToPoint(matrix, { x: elm.x2, y: elm.y2 })\n elm.x1 = x1\n elm.y1 = y1\n elm.x2 = x2\n elm.y2 = y2\n }\n return elm\n}\n\nexport const transformSchematicElements = (\n elms: AnySoupElement[],\n matrix: Matrix,\n) => {\n return elms.map((elm) => transformSchematicElement(elm, matrix))\n}\n\nexport const transformPCBElement = (elm: AnySoupElement, matrix: Matrix) => {\n if (\n elm.type === \"pcb_plated_hole\" ||\n elm.type === \"pcb_hole\" ||\n elm.type === \"pcb_via\" ||\n elm.type === \"pcb_smtpad\" ||\n elm.type === \"pcb_port\"\n ) {\n const { x, y } = applyToPoint(matrix, { x: elm.x, y: elm.y })\n elm.x = x\n elm.y = y\n } else if (elm.type === \"pcb_keepout\" || elm.type === \"pcb_board\") {\n // TODO adjust size/rotation\n elm.center = applyToPoint(matrix, elm.center)\n } else if (\n elm.type === \"pcb_silkscreen_text\" ||\n elm.type === \"pcb_fabrication_note_text\"\n ) {\n elm.anchor_position = applyToPoint(matrix, elm.anchor_position)\n } else if (\n elm.type === \"pcb_silkscreen_circle\" ||\n elm.type === \"pcb_silkscreen_rect\" ||\n elm.type === \"pcb_component\"\n ) {\n elm.center = applyToPoint(matrix, elm.center)\n } else if (\n elm.type === \"pcb_silkscreen_path\" ||\n elm.type === \"pcb_trace\" ||\n elm.type === \"pcb_fabrication_note_path\"\n ) {\n elm.route = elm.route.map((rp) => {\n const tp = applyToPoint(matrix, rp) as { x: number; y: number }\n rp.x = tp.x\n rp.y = tp.y\n return rp\n })\n } else if (elm.type === \"pcb_silkscreen_line\") {\n const p1 = { x: elm.x1, y: elm.y1 }\n const p2 = { x: elm.x2, y: elm.y2 }\n const p1t = applyToPoint(matrix, p1)\n const p2t = applyToPoint(matrix, p2)\n elm.x1 = p1t.x\n elm.y1 = p1t.y\n elm.x2 = p2t.x\n elm.y2 = p2t.y\n } else if (elm.type === \"cad_component\") {\n const newPos = applyToPoint(matrix, {\n x: elm.position.x,\n y: elm.position.y,\n })\n elm.position.x = newPos.x\n elm.position.y = newPos.y\n }\n return elm\n}\n\nexport const transformPCBElements = (\n elms: AnySoupElement[],\n matrix: Matrix,\n) => {\n const tsr = decomposeTSR(matrix)\n const flipPadWidthHeight =\n Math.round(tsr.rotation.angle / (Math.PI / 2)) % 2 === 1\n let transformedElms = elms.map((elm) => transformPCBElement(elm, matrix))\n if (flipPadWidthHeight) {\n transformedElms = transformedElms.map((elm) => {\n if (elm.type === \"pcb_smtpad\" && elm.shape === \"rect\") {\n ;[elm.width, elm.height] = [elm.height, elm.width]\n }\n return elm\n })\n }\n return transformedElms\n}\n","export const directionToVec = (direction: \"up\" | \"down\" | \"left\" | \"right\") => {\n if (direction === \"up\") return { x: 0, y: 1 }\n else if (direction === \"down\") return { x: 0, y: -1 }\n else if (direction === \"left\") return { x: -1, y: 0 }\n else if (direction === \"right\") return { x: 1, y: 0 }\n else throw new Error(\"Invalid direction\")\n}\n\nexport const vecToDirection = ({ x, y }: { x: number; y: number }) => {\n if (x > y) y = 0\n if (y > x) x = 0\n if (x > 0 && y === 0) return \"right\"\n else if (x < 0 && y === 0) return \"left\"\n else if (x === 0 && y > 0) return \"up\"\n else if (x === 0 && y < 0) return \"down\"\n else throw new Error(`Invalid vector for direction conversion (${x}, ${y})`)\n}\n\nexport const rotateClockwise = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"right\"\n else if (direction === \"right\") return \"down\"\n else if (direction === \"down\") return \"left\"\n else if (direction === \"left\") return \"up\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const rotateCounterClockwise = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"left\"\n else if (direction === \"left\") return \"down\"\n else if (direction === \"down\") return \"right\"\n else if (direction === \"right\") return \"up\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const rotateDirection = (\n direction: \"up\" | \"down\" | \"left\" | \"right\",\n num90DegreeClockwiseTurns: number\n) => {\n while (num90DegreeClockwiseTurns > 0) {\n direction = rotateClockwise(direction)\n num90DegreeClockwiseTurns--\n }\n while (num90DegreeClockwiseTurns < 0) {\n direction = rotateCounterClockwise(direction)\n num90DegreeClockwiseTurns++\n }\n return direction\n}\n\nexport const oppositeDirection = (\n direction: \"up\" | \"down\" | \"left\" | \"right\"\n) => {\n if (direction === \"up\") return \"down\"\n else if (direction === \"down\") return \"up\"\n else if (direction === \"left\") return \"right\"\n else if (direction === \"right\") return \"left\"\n throw new Error(`Invalid direction: ${direction}`)\n}\n\nexport const oppositeSide = (\n sideOrDir: \"up\" | \"down\" | \"top\" | \"bottom\" | \"left\" | \"right\"\n) => {\n if (sideOrDir === \"top\" || sideOrDir === \"up\") return \"bottom\"\n else if (sideOrDir === \"bottom\" || sideOrDir === \"down\") return \"top\"\n else if (sideOrDir === \"left\") return \"right\"\n else if (sideOrDir === \"right\") return \"left\"\n throw new Error(`Invalid sideOrDir: ${sideOrDir}`)\n}\n","import * as parsel from \"parsel-js\"\nimport { convertAbbrToType } from \"./convert-abbreviation-to-soup-element-type\"\nimport type { AnySoupElement } from \"@tscircuit/soup\"\n\nconst filterByType = (\n elements: AnySoupElement[],\n type: string\n): AnySoupElement[] => {\n type = convertAbbrToType(type)\n return elements.filter(\n (elm) => (\"ftype\" in elm && elm.ftype === type) || elm.type === type\n )\n}\n\n/**\n * Filter elements to match the selector, e.g. to access the left port of a\n * resistor you can do \".R1 > port.left\"\n */\nexport const applySelector = (\n elements: AnySoupElement[],\n selectorRaw: string\n): AnySoupElement[] => {\n const selectorAST = parsel.parse(selectorRaw)\n return applySelectorAST(elements, selectorAST!)\n}\n\nconst doesElmMatchClassName = (elm: AnySoupElement, className: string) =>\n (\"name\" in elm && elm.name === className) ||\n (\"port_hints\" in elm && elm.port_hints?.includes(className))\n\nexport const applySelectorAST = (\n elements: AnySoupElement[],\n selectorAST: parsel.AST\n): AnySoupElement[] => {\n switch (selectorAST.type) {\n case \"complex\": {\n switch (selectorAST.combinator) {\n case \" \": // TODO technically should do a deep search\n case \">\": {\n const { left, right } = selectorAST\n if (left.type === \"class\" || left.type === \"type\") {\n // TODO should also check if content matches any element tags\n let matchElms: AnySoupElement[]\n if (left.type === \"class\") {\n matchElms = elements.filter((elm) =>\n doesElmMatchClassName(elm, left.name)\n )\n } else if (left.type === \"type\") {\n matchElms = filterByType(elements, left.name)\n } else {\n matchElms = []\n }\n\n const childrenOfMatchingElms = matchElms.flatMap((matchElm) =>\n elements.filter(\n (elm: any) =>\n elm[`${matchElm.type}_id`] ===\n (matchElm as any)[`${matchElm.type}_id`] && elm !== matchElm\n )\n )\n return applySelectorAST(childrenOfMatchingElms, right)\n } else {\n throw new Error(`unsupported selector type \"${left.type}\" `)\n }\n }\n default: {\n throw new Error(\n `Couldn't apply selector AST for complex combinator \"${selectorAST.combinator}\"`\n )\n }\n }\n return []\n }\n case \"compound\": {\n const conditionsToMatch = selectorAST.list.map((part) => {\n switch (part.type) {\n case \"class\": {\n return (elm: any) => doesElmMatchClassName(elm, part.name)\n }\n case \"type\": {\n const name = convertAbbrToType(part.name)\n return (elm: any) => elm.type === name\n }\n }\n })\n\n return elements.filter((elm) =>\n conditionsToMatch.every((condFn) => condFn?.(elm))\n )\n }\n case \"type\": {\n return filterByType(elements, selectorAST.name) as AnySoupElement[]\n }\n case \"class\": {\n return elements.filter((elm) =>\n doesElmMatchClassName(elm, selectorAST.name)\n )\n }\n default: {\n throw new Error(\n `Couldn't apply selector AST for type: \"${\n selectorAST.type\n }\" ${JSON.stringify(selectorAST, null, \" \")}`\n )\n }\n }\n}\n","export const convertAbbrToType = (abbr: string): string => {\n switch (abbr) {\n case \"port\":\n return \"source_port\"\n case \"net\":\n return \"source_net\"\n case \"power\":\n return \"simple_power_source\"\n }\n return abbr\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\n\nexport const getElementId = (elm: AnySoupElement): string => {\n const type = elm.type\n const id = (elm as any)[`${type}_id`]\n return id\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { getElementId } from \"./get-element-id\"\n\nexport const getElementById = (\n soup: AnySoupElement[],\n id: string,\n): AnySoupElement | null => {\n return soup.find((elm) => getElementId(elm) === id) ?? null\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { su } from \"../su\"\n\nexport function getReadableNameForPcbTrace(\n soup: AnySoupElement[],\n pcb_trace_id: string,\n) {\n // Find the pcb_trace object\n const pcbTrace = su(soup).pcb_trace.get(pcb_trace_id)\n\n if (!pcbTrace) {\n return `trace[${pcb_trace_id}]`\n }\n\n // Get the connected ports\n const connectedPcbPortIds: string[] = pcbTrace.route\n .flatMap((point: any) => [point.start_pcb_port_id, point.end_pcb_port_id])\n .filter(Boolean)\n\n if (connectedPcbPortIds.length === 0) {\n return `trace[${pcb_trace_id}]`\n }\n\n // Function to get component name and port hint\n function getComponentAndPortInfo(pcb_port_id: string) {\n const pcbPort = su(soup).pcb_port.get(pcb_port_id)\n if (!pcbPort) return null\n\n const pcbComponent = su(soup).pcb_component.get(pcbPort.pcb_component_id)\n if (!pcbComponent) return null\n const sourceComponent = su(soup).source_component.get(\n pcbComponent.source_component_id,\n )\n if (!sourceComponent) return null\n\n const sourcePort = su(soup).source_port.get(pcbPort.source_port_id)\n const portHint = sourcePort?.port_hints ? sourcePort.port_hints[1] : \"\"\n\n return {\n componentName: sourceComponent.name,\n portHint: portHint,\n }\n }\n\n // Generate the readable selector\n const selectorParts = connectedPcbPortIds.map((portId) => {\n const info = getComponentAndPortInfo(portId)\n if (info) {\n return `.${info.componentName} > port.${info.portHint}`\n }\n return `port[${portId}]`\n })\n\n return `trace[${selectorParts.join(\", \")}]`\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { su } from \"../su\"\n\nexport const getReadableNameForPcbPort = (\n soup: AnySoupElement[],\n pcb_port_id: string,\n): string => {\n const pcbPort = su(soup).pcb_port.get(pcb_port_id)\n if (!pcbPort) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the component information\n const pcbComponent = su(soup).pcb_component.get(pcbPort?.pcb_component_id)\n\n if (!pcbComponent) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the source component information\n const sourceComponent = su(soup).source_component.get(\n pcbComponent.source_component_id,\n )\n\n if (!sourceComponent) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Get the source port information\n const sourcePort = su(soup).source_port.get(pcbPort.source_port_id)\n\n if (!sourcePort) {\n return `pcb_port[#${pcb_port_id}]`\n }\n\n // Determine the pad number or hint\n let padIdentifier: string\n if (sourcePort?.port_hints && sourcePort.port_hints.length > 0) {\n padIdentifier = sourcePort.port_hints[0]!\n } else if (sourcePort.port_hints && sourcePort.port_hints.length > 0) {\n padIdentifier = sourcePort.port_hints[0]!\n } else {\n padIdentifier = pcb_port_id\n }\n\n return `pcb_port[.${sourceComponent.name} > .${padIdentifier}]`\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { su } from \"../su\"\nimport { getReadableNameForPcbPort } from \"./get-readable-name-for-pcb-port\"\n\nexport function getReadableNameForPcbSmtpad(\n soup: AnySoupElement[],\n pcb_smtpad_id: string,\n): string {\n // Find the pcb_smtpad object\n const pcbSmtpad = su(soup).pcb_smtpad.get(pcb_smtpad_id)\n\n if (!pcbSmtpad || !pcbSmtpad.pcb_port_id) {\n return `smtpad[${pcb_smtpad_id}]`\n }\n\n return getReadableNameForPcbPort(soup, pcbSmtpad.pcb_port_id)\n}\n","import type { AnySoupElement } from \"@tscircuit/soup\"\nimport { getReadableNameForPcbTrace } from \"./get-readable-name-for-pcb-trace\"\nimport { getReadableNameForPcbSmtpad } from \"./get-readable-name-for-pcb-smtpad\"\nimport { getReadableNameForPcbPort } from \"./get-readable-name-for-pcb-port\"\nimport { getElementById } from \"lib/get-element-by-id\"\nimport { getElementId } from \"lib/get-element-id\"\n\nexport const getReadableNameForElement = (\n soup: AnySoupElement[],\n elm: AnySoupElement | string,\n): string => {\n if (typeof elm === \"string\") {\n const elmObj = getElementById(soup, elm)\n if (!elmObj) `unknown (could not find element with id ${elm})`\n return getReadableNameForElement(soup, elmObj as any)\n }\n switch (elm.type) {\n case \"pcb_port\":\n return getReadableNameForPcbPort(soup, elm.pcb_port_id)\n case \"pcb_smtpad\":\n return getReadableNameForPcbSmtpad(soup, elm.pcb_smtpad_id)\n case \"pcb_trace\":\n return getReadableNameForPcbTrace(soup, elm.pcb_trace_id)\n case \"source_component\":\n return `source_component[${elm.name}]`\n default:\n return `${elm.type}[#${getElementId(elm)}]`\n }\n}\n\nexport {\n getReadableNameForPcbPort,\n getReadableNameForPcbSmtpad,\n getReadableNameForPcbTrace,\n}\n","import type { AnyCircuitElement } from \"@tscircuit/soup\"\n\nexport const getBoundsOfPcbElements = (\n elements: AnyCircuitElement[],\n): { minX: number; minY: number; maxX: number; maxY: number } => {\n let minX = Number.POSITIVE_INFINITY\n let minY = Number.POSITIVE_INFINITY\n let maxX = Number.NEGATIVE_INFINITY\n let maxY = Number.NEGATIVE_INFINITY\n\n for (const elm of elements) {\n if (!elm.type.startsWith(\"pcb_\")) continue\n if (\"x\" in elm && \"y\" in elm) {\n minX = Math.min(minX, elm.x)\n minY = Math.min(minY, elm.y)\n maxX = Math.max(maxX, elm.x)\n maxY = Math.max(maxY, elm.y)\n\n if (\"width\" in elm) {\n maxX = Math.max(maxX, elm.x + elm.width)\n }\n if (\"height\" in elm) {\n maxY = Math.max(maxY, elm.y + elm.height)\n }\n if (\"radius\" in elm) {\n minX = Math.min(minX, elm.x - elm.radius)\n minY = Math.min(minY, elm.y - elm.radius)\n maxX = Math.max(maxX, elm.x + elm.radius)\n maxY = Math.max(maxY, elm.y + elm.radius)\n }\n } else if (elm.type === \"pcb_trace\") {\n for (const point of elm.route) {\n minX = Math.min(minX, point.x)\n minY = Math.min(minY, point.y)\n maxX = Math.max(maxX, point.x)\n maxY = Math.max(maxY, point.y)\n }\n }\n }\n\n return { minX, minY, maxX, maxY }\n}\n"],"mappings":"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","names":["su"]}