altium-to-circuit-json 0.0.13 → 0.0.14

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.js CHANGED
@@ -695,6 +695,11 @@ var CARDINAL_DIRECTIONS = [
695
695
  ];
696
696
  var SYMBOL_CATALOG = symbols;
697
697
  var SYMBOL_NAMES = Object.keys(SYMBOL_CATALOG);
698
+ var INLINE_NET_LABEL_COLOR = "rgb(132, 0, 0)";
699
+ var DEFAULT_INLINE_NET_LABEL_FONT_SIZE = 0.18;
700
+ var MIN_INLINE_NET_LABEL_FONT_SIZE = 0.1;
701
+ var INLINE_NET_LABEL_CHARACTER_WIDTH = 0.12;
702
+ var INLINE_NET_LABEL_HORIZONTAL_PADDING = 0.12;
698
703
  function convertSemanticSchematic(document, options) {
699
704
  const handledRecords = /* @__PURE__ */ new Set();
700
705
  const elements = [];
@@ -742,6 +747,12 @@ function convertComponents(params) {
742
747
  (record) => record.recordKind === "2" && (!isPinHidden(record) || options.includeHidden === true)
743
748
  );
744
749
  if (pins.length === 0) continue;
750
+ const visibleSymbolLabels = new Set(
751
+ visibleOwnedRecords.filter((record) => record.recordKind === "4").flatMap((record) => {
752
+ const text = record.getDecoded("TEXT")?.trim().toUpperCase();
753
+ return text ? [text] : [];
754
+ })
755
+ );
745
756
  const designator = findOwnedText(ownedRecords, "34", "Designator") ?? componentRecord.getDecoded("DESIGNATOR") ?? `U${componentIndex}`;
746
757
  const value = findOwnedText(ownedRecords, "41", "Comment") ?? componentRecord.getDecoded("COMMENT") ?? componentRecord.getDecoded("DESIGNITEMID") ?? componentRecord.getDecoded("LIBREFERENCE") ?? "";
747
758
  const libraryReference = componentRecord.getDecoded("LIBREFERENCE") ?? componentRecord.getDecoded("DESIGNITEMID") ?? designator;
@@ -774,7 +785,8 @@ function convertComponents(params) {
774
785
  pin,
775
786
  pinIndex,
776
787
  schematicComponentId,
777
- sourceComponentId
788
+ sourceComponentId,
789
+ visibleSymbolLabels
778
790
  })
779
791
  );
780
792
  const bodyBounds = getComponentBodyBounds(
@@ -863,7 +875,8 @@ function convertComponentPin(params) {
863
875
  pin,
864
876
  pinIndex,
865
877
  schematicComponentId,
866
- sourceComponentId
878
+ sourceComponentId,
879
+ visibleSymbolLabels
867
880
  } = params;
868
881
  const recordIndex = document.records.indexOf(pin);
869
882
  const pinConglomerate = pin.getNumber("PINCONGLOMERATE");
@@ -894,10 +907,13 @@ function convertComponentPin(params) {
894
907
  ...pinNumber === void 0 ? {} : { pin_number: pinNumber }
895
908
  };
896
909
  const electricalType = pin.getNumber("ELECTRICAL");
910
+ const normalizedName = name.trim().toUpperCase();
911
+ const functionalName = normalizedName.replace(/\d+$/u, "");
912
+ const showName = pinConglomerate === void 0 || (pinConglomerate & 8) !== 0 || visibleSymbolLabels.has(normalizedName) || visibleSymbolLabels.has(functionalName);
897
913
  const schematicPort = {
898
914
  type: "schematic_port",
899
915
  center: scalePoint(terminalPoint, options.scale),
900
- display_pin_label: name,
916
+ ...showName && name ? { display_pin_label: name } : {},
901
917
  distance_from_component_edge: pinLength * options.scale,
902
918
  facing_direction: direction,
903
919
  is_connected: false,
@@ -1201,6 +1217,8 @@ function convertConnectivity(params) {
1201
1217
  } = params;
1202
1218
  const sourceNetIdByName = /* @__PURE__ */ new Map();
1203
1219
  const sourceNetIdByRecord = /* @__PURE__ */ new Map();
1220
+ const sourcePortCountByRecord = /* @__PURE__ */ new Map();
1221
+ const sourceTraceIdByRecord = /* @__PURE__ */ new Map();
1204
1222
  const schematicTraceIdByRecord = /* @__PURE__ */ new Map();
1205
1223
  const portsByPoint = groupByPoint(convertedPorts);
1206
1224
  for (const [netIndex, net] of graph.nets.entries()) {
@@ -1226,6 +1244,10 @@ function convertConnectivity(params) {
1226
1244
  if (firstSourceNetId) sourceNetIdByRecord.set(record, firstSourceNetId);
1227
1245
  }
1228
1246
  const sourceTraceId = `source_trace_altium_${netIndex}`;
1247
+ for (const record of net.records) {
1248
+ sourcePortCountByRecord.set(record, connectedPorts.length);
1249
+ sourceTraceIdByRecord.set(record, sourceTraceId);
1250
+ }
1229
1251
  const sourceTrace = {
1230
1252
  type: "source_trace",
1231
1253
  connected_source_net_ids: sourceNetIds,
@@ -1324,7 +1346,9 @@ function convertConnectivity(params) {
1324
1346
  return {
1325
1347
  schematicTraceIdByRecord,
1326
1348
  sourceNetIdByName,
1327
- sourceNetIdByRecord
1349
+ sourceNetIdByRecord,
1350
+ sourcePortCountByRecord,
1351
+ sourceTraceIdByRecord
1328
1352
  };
1329
1353
  }
1330
1354
  function getEquivalentPortPrunedSegmentKeys(params) {
@@ -1433,8 +1457,27 @@ function convertNetLabels(params) {
1433
1457
  const name = record.recordKind === "18" ? record.getDecoded("NAME") : record.getDecoded("TEXT");
1434
1458
  const location = getLocation(record);
1435
1459
  if (!name || !location) continue;
1436
- const wire = graph.getConnectedWiresForRecord(record)[0];
1460
+ const connectedWires = graph.getConnectedWiresForRecord(record);
1461
+ const wire = connectedWires[0];
1437
1462
  if (recordKind === "4" && !wire) continue;
1463
+ const sourceTraceId = connectivity.sourceTraceIdByRecord.get(record);
1464
+ const shouldRenderInline = Boolean(sourceTraceId) && (recordKind === "25" || recordKind === "18" && (record.getNumber("IOTYPE") ?? 0) === 0 && connectivity.sourcePortCountByRecord.get(record) === 2 && !isPowerNet(name));
1465
+ if (shouldRenderInline && sourceTraceId) {
1466
+ handledRecords.add(record);
1467
+ elements.push(
1468
+ createInlineNetLabelText({
1469
+ connectedWires,
1470
+ document,
1471
+ location,
1472
+ name,
1473
+ options,
1474
+ record,
1475
+ recordIndex,
1476
+ sourceTraceId
1477
+ })
1478
+ );
1479
+ continue;
1480
+ }
1438
1481
  handledRecords.add(record);
1439
1482
  const sourceNetId = connectivity.sourceNetIdByRecord.get(record) ?? getOrCreateSourceNet({
1440
1483
  elements,
@@ -1459,6 +1502,86 @@ function convertNetLabels(params) {
1459
1502
  elements.push(schematicNetLabel);
1460
1503
  }
1461
1504
  }
1505
+ function createInlineNetLabelText(params) {
1506
+ const {
1507
+ connectedWires,
1508
+ document,
1509
+ location,
1510
+ name,
1511
+ options,
1512
+ record,
1513
+ recordIndex,
1514
+ sourceTraceId
1515
+ } = params;
1516
+ const direction = getInlineNetLabelDirection(record, location, connectedWires);
1517
+ const scaledLocation = scalePoint(location, options.scale);
1518
+ const fontSize = getInlineNetLabelFontSize(record, document, options.scale);
1519
+ const fontScale = fontSize / DEFAULT_INLINE_NET_LABEL_FONT_SIZE;
1520
+ const textWidth = (name.length * INLINE_NET_LABEL_CHARACTER_WIDTH + INLINE_NET_LABEL_HORIZONTAL_PADDING) * fontScale;
1521
+ const isVertical = direction === "up" || direction === "down";
1522
+ const directionSign = direction === "left" || direction === "down" ? -1 : 1;
1523
+ const isTerminalPort = record.recordKind === "18";
1524
+ const anchor = isTerminalPort ? directionSign > 0 ? "left" : "right" : "center";
1525
+ const position = isTerminalPort ? isVertical ? {
1526
+ x: scaledLocation.x - fontSize / 2,
1527
+ y: scaledLocation.y
1528
+ } : {
1529
+ x: scaledLocation.x,
1530
+ y: scaledLocation.y + fontSize / 2
1531
+ } : isVertical ? {
1532
+ x: scaledLocation.x - fontSize / 2,
1533
+ y: scaledLocation.y + directionSign * textWidth / 2
1534
+ } : {
1535
+ x: scaledLocation.x + directionSign * textWidth / 2,
1536
+ y: scaledLocation.y + fontSize / 2
1537
+ };
1538
+ return {
1539
+ type: "schematic_text",
1540
+ anchor,
1541
+ color: INLINE_NET_LABEL_COLOR,
1542
+ font_size: fontSize,
1543
+ position,
1544
+ rotation: isVertical ? -90 : 0,
1545
+ schematic_sheet_id: options.schematicSheetId,
1546
+ schematic_text_id: `schematic_inline_net_label_altium_${recordIndex}`,
1547
+ source_trace_id: sourceTraceId,
1548
+ text: name
1549
+ };
1550
+ }
1551
+ function getInlineNetLabelFontSize(record, document, scale) {
1552
+ const fontId = Math.max(
1553
+ Math.round(Number(record.getCaseInsensitive("FONTID") ?? 1)),
1554
+ 1
1555
+ );
1556
+ const sheetRecord = document.records.find(
1557
+ (candidate) => candidate.recordKind === "31"
1558
+ );
1559
+ const sourceFontSize = Number(
1560
+ sheetRecord?.getCaseInsensitive(`SIZE${fontId}`) ?? DEFAULT_INLINE_NET_LABEL_FONT_SIZE / scale
1561
+ );
1562
+ return Math.min(
1563
+ DEFAULT_INLINE_NET_LABEL_FONT_SIZE,
1564
+ Math.max(MIN_INLINE_NET_LABEL_FONT_SIZE, sourceFontSize * scale)
1565
+ );
1566
+ }
1567
+ function getInlineNetLabelDirection(record, location, connectedWires) {
1568
+ if (record.recordKind !== "18") return getRecordDirection(record);
1569
+ for (const wire of connectedWires) {
1570
+ const points = getSchematicRecordPoints(wire);
1571
+ for (let pointIndex = 1; pointIndex < points.length; pointIndex++) {
1572
+ const start = points[pointIndex - 1];
1573
+ const end = points[pointIndex];
1574
+ if (!start || !end || !isPointOnSegment(location, start, end)) continue;
1575
+ const other = pointsEqual(location, start) ? end : pointsEqual(location, end) ? start : void 0;
1576
+ if (!other) continue;
1577
+ const dx = location.x - other.x;
1578
+ const dy = location.y - other.y;
1579
+ if (Math.abs(dx) >= Math.abs(dy)) return dx < 0 ? "left" : "right";
1580
+ return dy < 0 ? "down" : "up";
1581
+ }
1582
+ }
1583
+ return getRecordDirection(record);
1584
+ }
1462
1585
  function getOrCreateSourceNet(params) {
1463
1586
  const { elements, name, sourceNetIdByName } = params;
1464
1587
  const normalizedName = name.trim().toUpperCase();
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../lib/convert-altium-pcb-doc-to-circuit-json.ts","../lib/convert-altium-sch-doc-to-circuit-json.ts","../lib/schematic/convert-semantic-schematic.ts","../lib/convert-altium-to-circuit-json.ts"],"sourcesContent":["import {\n AltiumArcRecord,\n AltiumFillRecord,\n AltiumPadRecord,\n type AltiumPcbDocument,\n type AltiumPoint,\n type AltiumRecord,\n AltiumRegionRecord,\n AltiumTextRecord,\n AltiumTrackRecord,\n AltiumViaRecord,\n getAltiumBounds,\n getPcbLayerStack,\n getPcbRegionGeometry,\n parseAltiumMeasurementToMils,\n} from \"altiumts\"\nimport type {\n AnyCircuitElement,\n LayerRef,\n PcbBoard,\n PcbComponent,\n PcbCourtyardOutline,\n PcbCutout,\n PcbHole,\n PcbPlatedHole,\n PcbSilkscreenLine,\n PcbSilkscreenPath,\n PcbSilkscreenRect,\n PcbSilkscreenText,\n PcbSmtPad,\n PcbTrace,\n PcbVia,\n} from \"circuit-json\"\n\nconst MILS_TO_MILLIMETERS = 0.0254\nconst BOARD_ID = \"pcb_board_altium\"\nconst BOARD_GRAPHICS_COMPONENT_ID = \"pcb_component_altium_board_graphics\"\n\nexport interface ConvertAltiumPcbDocOptions {\n includeBoardOutline?: boolean\n includeComponents?: boolean\n includeCourtyards?: boolean\n includePads?: boolean\n includeSilkscreen?: boolean\n includeTraces?: boolean\n includeVias?: boolean\n}\n\nexport function convertAltiumPcbDocToCircuitJson(\n document: AltiumPcbDocument,\n options: ConvertAltiumPcbDocOptions = {},\n): AnyCircuitElement[] {\n const elements: AnyCircuitElement[] = []\n\n if (options.includeBoardOutline !== false) {\n elements.push(createBoard(document))\n for (const [index, cutout] of document.boardGeometry.cutouts.entries()) {\n if (cutout.outline.points.length < 3) continue\n elements.push({\n type: \"pcb_cutout\",\n pcb_cutout_id: `pcb_cutout_altium_${index}`,\n pcb_board_id: BOARD_ID,\n shape: \"polygon\",\n points: cutout.outline.points.map(toMillimeterPoint),\n } satisfies PcbCutout)\n }\n }\n\n if (options.includeComponents !== false) {\n for (const [index, component] of document.components.entries()) {\n const position = component.position\n if (!position) continue\n const bounds = document.getComponentBounds(component)\n elements.push({\n type: \"pcb_component\",\n pcb_component_id: componentId(index),\n source_component_id: `source_component_altium_${index}`,\n center: toMillimeterPoint(position),\n width: milsToMillimeters(\n bounds ? bounds.maxX - bounds.minX : (component.heightMils ?? 20),\n ),\n height: milsToMillimeters(\n bounds ? bounds.maxY - bounds.minY : (component.heightMils ?? 20),\n ),\n layer: component.side === \"bottom\" ? \"bottom\" : \"top\",\n rotation: component.rotation,\n position_mode: \"none\",\n obstructs_within_bounds: false,\n } satisfies PcbComponent)\n }\n }\n\n if (\n options.includeCourtyards !== false &&\n options.includeComponents !== false\n ) {\n elements.push(...convertCourtyards(document))\n }\n\n for (const [index, record] of document.records.entries()) {\n if (record instanceof AltiumPadRecord && options.includePads !== false) {\n const pad = convertPad(record, index)\n if (pad) elements.push(pad)\n continue\n }\n\n if (record instanceof AltiumTrackRecord) {\n if (isCourtyardLayer(record.layer)) continue\n if (isOverlayLayer(record.layer)) {\n if (options.includeSilkscreen === false) continue\n const line = convertSilkscreenLine(record, index)\n if (line) elements.push(line)\n } else if (options.includeTraces !== false) {\n const trace = convertTrack(record, index)\n if (trace) elements.push(trace)\n }\n continue\n }\n\n if (record instanceof AltiumViaRecord && options.includeVias !== false) {\n const via = convertVia(record, index)\n if (via) elements.push(via)\n continue\n }\n\n if (\n options.includeSilkscreen === false ||\n !isOverlayLayer(getLayer(record))\n ) {\n continue\n }\n\n if (record instanceof AltiumArcRecord) {\n const path = convertSilkscreenArc(record, index)\n if (path) elements.push(path)\n } else if (record instanceof AltiumFillRecord) {\n const rect = convertSilkscreenFill(record, index)\n if (rect) elements.push(rect)\n } else if (record instanceof AltiumTextRecord) {\n const text = convertSilkscreenText(record, index)\n if (text) elements.push(text)\n }\n }\n\n return elements\n}\n\ninterface CourtyardPath {\n componentId: string\n layer: \"top\" | \"bottom\"\n points: AltiumPoint[]\n strokeWidthMils: number\n}\n\nfunction convertCourtyards(document: AltiumPcbDocument): PcbCourtyardOutline[] {\n const componentIds = new Map(\n document.components.flatMap((component, index) =>\n component.position ? [[component, componentId(index)] as const] : [],\n ),\n )\n const paths: CourtyardPath[] = []\n\n for (const record of document.records) {\n const layer = getLayer(record)\n if (!isCourtyardLayer(layer)) continue\n const component = document.getComponentForRecord(record)\n const ownedComponentId = component ? componentIds.get(component) : undefined\n if (!ownedComponentId) continue\n const points = getCourtyardRecordPoints(record)\n if (points.length < 2) continue\n paths.push({\n componentId: ownedComponentId,\n layer: mapCourtyardLayer(layer),\n points,\n strokeWidthMils:\n record instanceof AltiumTrackRecord || record instanceof AltiumArcRecord\n ? (record.widthMils ?? 4)\n : 0,\n })\n }\n\n const courtyards: PcbCourtyardOutline[] = []\n for (const path of stitchCourtyardPaths(paths)) {\n if (!isClosedAltiumPath(path.points)) continue\n const outline = removeClosingPoint(path.points).map(toMillimeterPoint)\n if (outline.length < 3) continue\n courtyards.push({\n type: \"pcb_courtyard_outline\",\n pcb_courtyard_outline_id: `pcb_courtyard_outline_altium_${courtyards.length}`,\n pcb_component_id: path.componentId,\n layer: path.layer,\n outline,\n })\n }\n return courtyards\n}\n\nfunction getCourtyardRecordPoints(record: AltiumRecord): AltiumPoint[] {\n if (record instanceof AltiumTrackRecord) {\n return record.start && record.end ? [record.start, record.end] : []\n }\n if (record instanceof AltiumArcRecord) {\n return record.center && record.radiusMils\n ? approximateArc(\n record.center,\n record.radiusMils,\n record.startAngle,\n record.endAngle,\n )\n : []\n }\n if (record instanceof AltiumRegionRecord) {\n return getPcbRegionGeometry(record).outline.points\n }\n return []\n}\n\nfunction stitchCourtyardPaths(paths: CourtyardPath[]): CourtyardPath[] {\n const groups = new Map<string, CourtyardPath[]>()\n for (const path of deduplicateCourtyardPaths(paths)) {\n const key = [\n path.componentId,\n path.layer,\n path.strokeWidthMils.toFixed(4),\n ].join(\"|\")\n const group = groups.get(key) ?? []\n group.push(path)\n groups.set(key, group)\n }\n return [...groups.values()].flatMap(stitchCourtyardPathGroup)\n}\n\nfunction stitchCourtyardPathGroup(group: CourtyardPath[]): CourtyardPath[] {\n const remaining = [...group]\n const stitched: CourtyardPath[] = []\n while (remaining.length > 0) {\n const first = remaining.shift()\n if (!first) break\n const path = { ...first, points: [...first.points] }\n while (appendConnectedCourtyardPath(path, remaining)) {\n // Continue until no segment can extend either end of this path.\n }\n stitched.push(path)\n }\n return stitched\n}\n\nfunction appendConnectedCourtyardPath(\n stitched: CourtyardPath,\n remaining: CourtyardPath[],\n): boolean {\n const stitchedStart = stitched.points[0]\n const stitchedEnd = stitched.points.at(-1)\n if (!stitchedStart || !stitchedEnd) return false\n\n for (const [index, candidate] of remaining.entries()) {\n const candidateStart = candidate.points[0]\n const candidateEnd = candidate.points.at(-1)\n if (!candidateStart || !candidateEnd) continue\n if (altiumPointsApproximatelyEqual(stitchedEnd, candidateStart)) {\n stitched.points.push(...candidate.points.slice(1))\n } else if (altiumPointsApproximatelyEqual(stitchedEnd, candidateEnd)) {\n stitched.points.push(...candidate.points.toReversed().slice(1))\n } else if (altiumPointsApproximatelyEqual(stitchedStart, candidateEnd)) {\n stitched.points.unshift(...candidate.points.slice(0, -1))\n } else if (altiumPointsApproximatelyEqual(stitchedStart, candidateStart)) {\n stitched.points.unshift(...candidate.points.toReversed().slice(0, -1))\n } else {\n continue\n }\n remaining.splice(index, 1)\n return true\n }\n return false\n}\n\nfunction deduplicateCourtyardPaths(paths: CourtyardPath[]): CourtyardPath[] {\n const signatures = new Set<string>()\n return paths.filter((path) => {\n const forwardPoints = path.points.map(formatAltiumPoint).join(\"|\")\n const reversePoints = path.points\n .toReversed()\n .map(formatAltiumPoint)\n .join(\"|\")\n const pointsSignature =\n forwardPoints < reversePoints ? forwardPoints : reversePoints\n const signature = [\n path.componentId,\n path.layer,\n path.strokeWidthMils.toFixed(4),\n pointsSignature,\n ].join(\"|\")\n if (signatures.has(signature)) return false\n signatures.add(signature)\n return true\n })\n}\n\nfunction formatAltiumPoint(point: AltiumPoint): string {\n return `${point.x.toFixed(4)},${point.y.toFixed(4)}`\n}\n\nfunction isClosedAltiumPath(points: AltiumPoint[]): boolean {\n const first = points[0]\n const last = points.at(-1)\n return Boolean(first && last && altiumPointsApproximatelyEqual(first, last))\n}\n\nfunction removeClosingPoint(points: AltiumPoint[]): AltiumPoint[] {\n const first = points[0]\n const last = points.at(-1)\n return first && last && altiumPointsApproximatelyEqual(first, last)\n ? points.slice(0, -1)\n : points\n}\n\nfunction altiumPointsApproximatelyEqual(\n left: AltiumPoint,\n right: AltiumPoint,\n): boolean {\n return (\n Math.abs(left.x - right.x) <= 0.01 && Math.abs(left.y - right.y) <= 0.01\n )\n}\n\nfunction createBoard(document: AltiumPcbDocument): PcbBoard {\n const outline = document.boardGeometry.outline.points.map(toMillimeterPoint)\n const bounds =\n getAltiumBounds(document.boardGeometry.outline.points) ??\n getFallbackPcbBounds(document.records)\n const width = Math.max(milsToMillimeters(bounds.maxX - bounds.minX), 0.1)\n const height = Math.max(milsToMillimeters(bounds.maxY - bounds.minY), 0.1)\n const numLayers = document.board\n ? Math.max(\n getPcbLayerStack(document.board).entries.filter((entry) =>\n Boolean(mapCopperLayer(entry.name ?? entry.layerId)),\n ).length,\n 2,\n )\n : 2\n\n return {\n type: \"pcb_board\",\n pcb_board_id: BOARD_ID,\n center: {\n x: milsToMillimeters((bounds.minX + bounds.maxX) / 2),\n y: milsToMillimeters((bounds.minY + bounds.maxY) / 2),\n },\n width,\n height,\n ...(outline.length >= 3 ? { shape: \"polygon\" as const, outline } : {}),\n thickness: 1.6,\n num_layers: numLayers,\n material: \"fr4\",\n }\n}\n\nfunction getFallbackPcbBounds(records: AltiumRecord[]): {\n maxX: number\n maxY: number\n minX: number\n minY: number\n} {\n const points: AltiumPoint[] = []\n for (const record of records) {\n if (\n record instanceof AltiumPadRecord ||\n record instanceof AltiumViaRecord\n ) {\n if (record.position) points.push(record.position)\n } else if (record instanceof AltiumTrackRecord) {\n if (record.start) points.push(record.start)\n if (record.end) points.push(record.end)\n }\n }\n return getAltiumBounds(points) ?? { minX: 0, minY: 0, maxX: 1000, maxY: 800 }\n}\n\nfunction convertTrack(\n record: AltiumTrackRecord,\n index: number,\n): PcbTrace | undefined {\n const start = record.start\n const end = record.end\n const layer = mapCopperLayer(record.layer)\n if (!start || !end || !layer) return undefined\n const width = milsToMillimeters(record.widthMils ?? 4)\n return {\n type: \"pcb_trace\",\n pcb_trace_id: `pcb_trace_altium_${index}`,\n should_round_corners: true,\n route: [\n { route_type: \"wire\", ...toMillimeterPoint(start), width, layer },\n { route_type: \"wire\", ...toMillimeterPoint(end), width, layer },\n ],\n }\n}\n\nfunction convertVia(\n record: AltiumViaRecord,\n index: number,\n): PcbVia | undefined {\n if (!record.position) return undefined\n const startLayer = mapCopperLayer(record.startLayer) ?? \"top\"\n const endLayer = mapCopperLayer(record.endLayer) ?? \"bottom\"\n const layers = startLayer === endLayer ? [startLayer] : [startLayer, endLayer]\n const outerDiameter = milsToMillimeters(record.diameterMils ?? 20)\n return {\n type: \"pcb_via\",\n pcb_via_id: `pcb_via_altium_${index}`,\n ...toMillimeterPoint(record.position),\n outer_diameter: outerDiameter,\n hole_diameter: milsToMillimeters(\n record.holeSizeMils ?? (record.diameterMils ?? 20) * 0.45,\n ),\n layers,\n is_tented: record.tentedTop === true && record.tentedBottom === true,\n }\n}\n\nfunction convertPad(\n record: AltiumPadRecord,\n index: number,\n): PcbSmtPad | PcbPlatedHole | PcbHole | undefined {\n const position = record.position\n const size = record.size\n if (!position || !size) return undefined\n const x = milsToMillimeters(position.x)\n const y = milsToMillimeters(position.y)\n const width = milsToMillimeters(size.width)\n const height = milsToMillimeters(size.height)\n const holeDiameter = milsToMillimeters(record.holeSizeMils ?? 0)\n const shape = normalizeShape(record.shape)\n const id = `altium_${index}`\n\n if (record.plated === false && holeDiameter > 0) {\n return {\n type: \"pcb_hole\",\n pcb_hole_id: `pcb_hole_${id}`,\n hole_shape: \"circle\",\n hole_diameter: holeDiameter,\n x,\n y,\n }\n }\n\n if (record.behavior === \"through-hole\" || holeDiameter > 0) {\n const slotLengthMils = getMeasurement(record, \"SLOTLENGTH\")\n const holeWidthMils = record.holeWidthMils ?? record.holeSizeMils\n const isSlot =\n normalizeShape(record.holeType).includes(\"SLOT\") ||\n (slotLengthMils ?? 0) > (record.holeSizeMils ?? 0) ||\n (holeWidthMils ?? 0) > (record.holeSizeMils ?? 0)\n const layers: LayerRef[] = [\"top\", \"bottom\"]\n\n if (isSlot) {\n const holeWidth = milsToMillimeters(\n Math.max(\n slotLengthMils ?? holeWidthMils ?? record.holeSizeMils ?? 1,\n 1,\n ),\n )\n const holeHeight = Math.max(holeDiameter, MILS_TO_MILLIMETERS)\n if (isRectangularShape(shape)) {\n const rotated = record.holeRotation !== 0 || record.rotation !== 0\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: rotated\n ? \"rotated_pill_hole_with_rect_pad\"\n : \"pill_hole_with_rect_pad\",\n hole_shape: rotated ? \"rotated_pill\" : \"pill\",\n pad_shape: \"rect\",\n hole_width: holeWidth,\n hole_height: holeHeight,\n ...(rotated ? { hole_ccw_rotation: record.holeRotation } : {}),\n rect_pad_width: width,\n rect_pad_height: height,\n ...(rotated ? { rect_ccw_rotation: record.rotation } : {}),\n hole_offset_x: 0,\n hole_offset_y: 0,\n x,\n y,\n layers,\n } as PcbPlatedHole\n }\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: \"pill\",\n outer_width: width,\n outer_height: height,\n hole_width: holeWidth,\n hole_height: holeHeight,\n ccw_rotation: record.holeRotation || record.rotation,\n x,\n y,\n layers,\n }\n }\n\n if (isRectangularShape(shape)) {\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: \"circular_hole_with_rect_pad\",\n hole_shape: \"circle\",\n pad_shape: \"rect\",\n hole_diameter: Math.max(holeDiameter, MILS_TO_MILLIMETERS),\n rect_pad_width: width,\n rect_pad_height: height,\n rect_border_radius: shape.includes(\"ROUNDRECT\")\n ? Math.min(width, height) * 0.18\n : 0,\n rect_ccw_rotation: record.rotation,\n hole_offset_x: 0,\n hole_offset_y: 0,\n x,\n y,\n layers,\n }\n }\n\n if (shape.includes(\"OCTAGON\")) {\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: \"hole_with_polygon_pad\",\n hole_shape: \"circle\",\n hole_diameter: Math.max(holeDiameter, MILS_TO_MILLIMETERS),\n pad_outline: createOctagonPoints(x, y, width, height, record.rotation),\n hole_offset_x: 0,\n hole_offset_y: 0,\n x,\n y,\n layers,\n }\n }\n\n if (shape === \"ROUND\" || shape === \"CIRCLE\" || shape === \"OVAL\") {\n if (Math.abs(width - height) >= 0.0001) {\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: \"pill\",\n outer_width: width,\n outer_height: height,\n hole_width: Math.max(holeDiameter, MILS_TO_MILLIMETERS),\n hole_height: Math.max(holeDiameter, MILS_TO_MILLIMETERS),\n ccw_rotation: record.rotation,\n x,\n y,\n layers,\n }\n }\n }\n\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: \"circle\",\n outer_diameter: Math.max(width, height),\n hole_diameter: Math.max(holeDiameter, MILS_TO_MILLIMETERS),\n x,\n y,\n layers,\n }\n }\n\n const layer = mapCopperLayer(record.layer)\n if (!layer) return undefined\n const base = {\n type: \"pcb_smtpad\" as const,\n pcb_smtpad_id: `pcb_smtpad_${id}`,\n x,\n y,\n layer,\n soldermask_margin:\n record.solderMaskExpansionMils === undefined\n ? undefined\n : milsToMillimeters(record.solderMaskExpansionMils),\n }\n\n if (shape.includes(\"OCTAGON\")) {\n return {\n ...base,\n shape: \"polygon\",\n points: createOctagonPoints(x, y, width, height, record.rotation),\n }\n }\n if (shape === \"ROUND\" || shape === \"CIRCLE\" || shape === \"OVAL\") {\n if (Math.abs(width - height) < 0.0001) {\n return { ...base, shape: \"circle\", radius: width / 2 }\n }\n return record.rotation === 0\n ? {\n ...base,\n shape: \"pill\",\n width,\n height,\n radius: Math.min(width, height) / 2,\n }\n : {\n ...base,\n shape: \"rotated_pill\",\n width,\n height,\n radius: Math.min(width, height) / 2,\n ccw_rotation: record.rotation,\n }\n }\n\n const cornerRadius = shape.includes(\"ROUNDRECT\")\n ? Math.min(width, height) * 0.18\n : undefined\n return record.rotation === 0\n ? { ...base, shape: \"rect\", width, height, corner_radius: cornerRadius }\n : {\n ...base,\n shape: \"rotated_rect\",\n width,\n height,\n corner_radius: cornerRadius,\n ccw_rotation: record.rotation,\n }\n}\n\nfunction convertSilkscreenLine(\n record: AltiumTrackRecord,\n index: number,\n): PcbSilkscreenLine | undefined {\n if (!record.start || !record.end) return undefined\n return {\n type: \"pcb_silkscreen_line\",\n pcb_silkscreen_line_id: `pcb_silkscreen_line_altium_${index}`,\n pcb_component_id: pcbComponentIdForRecord(record),\n stroke_width: milsToMillimeters(record.widthMils ?? 4),\n ...withNumberedPoints(record.start, record.end),\n layer: mapOverlayLayer(record.layer),\n }\n}\n\nfunction convertSilkscreenArc(\n record: AltiumArcRecord,\n index: number,\n): PcbSilkscreenPath | undefined {\n if (!record.center || !record.radiusMils) return undefined\n const points = approximateArc(\n record.center,\n record.radiusMils,\n record.startAngle,\n record.endAngle,\n )\n return {\n type: \"pcb_silkscreen_path\",\n pcb_silkscreen_path_id: `pcb_silkscreen_path_altium_${index}`,\n pcb_component_id: pcbComponentIdForRecord(record),\n route: points.map(toMillimeterPoint),\n stroke_width: milsToMillimeters(record.widthMils ?? 4),\n layer: mapOverlayLayer(record.layer),\n }\n}\n\nfunction convertSilkscreenFill(\n record: AltiumFillRecord,\n index: number,\n): PcbSilkscreenRect | undefined {\n if (!record.bounds) return undefined\n const width = milsToMillimeters(record.bounds.maxX - record.bounds.minX)\n const height = milsToMillimeters(record.bounds.maxY - record.bounds.minY)\n return {\n type: \"pcb_silkscreen_rect\",\n pcb_silkscreen_rect_id: `pcb_silkscreen_rect_altium_${index}`,\n pcb_component_id: pcbComponentIdForRecord(record),\n center: {\n x: milsToMillimeters((record.bounds.minX + record.bounds.maxX) / 2),\n y: milsToMillimeters((record.bounds.minY + record.bounds.maxY) / 2),\n },\n width,\n height,\n stroke_width: Math.min(width, height),\n is_filled: true,\n has_stroke: false,\n ccw_rotation: record.rotation,\n layer: mapOverlayLayer(record.layer),\n }\n}\n\nfunction convertSilkscreenText(\n record: AltiumTextRecord,\n index: number,\n): PcbSilkscreenText | undefined {\n const text =\n decodeAltiumWideString(record.getDecoded(\"WIDESTRING\")) ||\n record.getDecoded(\"TEXT\") ||\n record.text\n if (!record.position || !text) return undefined\n return {\n type: \"pcb_silkscreen_text\",\n pcb_silkscreen_text_id: `pcb_silkscreen_text_altium_${index}`,\n pcb_component_id: pcbComponentIdForRecord(record),\n text,\n font: \"tscircuit2024\",\n font_size: milsToMillimeters(record.heightMils ?? 30),\n anchor_position: toMillimeterPoint(record.position),\n anchor_alignment: mapTextAnchor(record.justification),\n ccw_rotation: record.rotation,\n layer: mapOverlayLayer(record.layer),\n is_mirrored: record.mirrored,\n }\n}\n\nfunction decodeAltiumWideString(raw: string | undefined): string {\n if (!raw) return \"\"\n if (!/^\\d+(?:,\\d+)*$/u.test(raw)) return raw\n try {\n return String.fromCodePoint(...raw.split(\",\").map(Number))\n } catch {\n return raw\n }\n}\n\nfunction pcbComponentIdForRecord(record: AltiumRecord): string {\n const index = record.getNumber(\"COMPONENT\")\n return index === undefined || index < 0\n ? BOARD_GRAPHICS_COMPONENT_ID\n : componentId(index)\n}\n\nfunction componentId(index: number): string {\n return `pcb_component_altium_${index}`\n}\n\nfunction mapTextAnchor(\n justification: string | undefined,\n): \"bottom_left\" | \"bottom_center\" | \"bottom_right\" | \"center\" {\n const normalized = justification?.replace(/[\\s_-]+/gu, \"\").toUpperCase()\n if (normalized?.includes(\"CENTER\")) return \"bottom_center\"\n if (normalized?.includes(\"RIGHT\")) return \"bottom_right\"\n if (normalized?.includes(\"LEFT\")) return \"bottom_left\"\n return \"center\"\n}\n\nfunction mapCopperLayer(layer: string | undefined): LayerRef | undefined {\n const normalized = normalizeLayer(layer)\n if (normalized === \"TOP\" || normalized === \"TOPLAYER\") return \"top\"\n if (normalized === \"BOTTOM\" || normalized === \"BOTTOMLAYER\") return \"bottom\"\n const innerMatch = /^(?:MID|MIDLAYER|INTERNALPLANE)(\\d+)$/u.exec(normalized)\n if (!innerMatch?.[1]) return undefined\n const innerNumber = Math.min(Math.max(Number(innerMatch[1]), 1), 8)\n return `inner${innerNumber}` as LayerRef\n}\n\nfunction isOverlayLayer(layer: string | undefined): boolean {\n const normalized = normalizeLayer(layer)\n return normalized === \"TOPOVERLAY\" || normalized === \"BOTTOMOVERLAY\"\n}\n\nfunction isCourtyardLayer(layer: string | undefined): boolean {\n const normalized = normalizeLayer(layer)\n return normalized === \"MECHANICAL15\" || normalized === \"MECHANICAL16\"\n}\n\nfunction mapCourtyardLayer(layer: string | undefined): \"top\" | \"bottom\" {\n return normalizeLayer(layer) === \"MECHANICAL16\" ? \"bottom\" : \"top\"\n}\n\nfunction mapOverlayLayer(layer: string | undefined): \"top\" | \"bottom\" {\n return normalizeLayer(layer) === \"BOTTOMOVERLAY\" ? \"bottom\" : \"top\"\n}\n\nfunction getLayer(record: AltiumRecord): string | undefined {\n return record.getDecoded(\"LAYER\")\n}\n\nfunction normalizeLayer(layer: string | undefined): string {\n return (layer ?? \"\").replace(/[\\s_.-]+/gu, \"\").toUpperCase()\n}\n\nfunction normalizeShape(shape: string | undefined): string {\n return (shape ?? \"ROUND\").replace(/[\\s_-]+/gu, \"\").toUpperCase()\n}\n\nfunction isRectangularShape(shape: string): boolean {\n return shape.includes(\"RECT\") || shape === \"SQUARE\"\n}\n\nfunction getMeasurement(record: AltiumRecord, key: string): number | undefined {\n return parseAltiumMeasurementToMils(record.getCaseInsensitive(key))\n}\n\nfunction milsToMillimeters(value: number): number {\n return value * MILS_TO_MILLIMETERS\n}\n\nfunction toMillimeterPoint(point: AltiumPoint): { x: number; y: number } {\n return { x: milsToMillimeters(point.x), y: milsToMillimeters(point.y) }\n}\n\nfunction withNumberedPoints(\n start: AltiumPoint,\n end: AltiumPoint,\n): { x1: number; x2: number; y1: number; y2: number } {\n return {\n x1: milsToMillimeters(start.x),\n y1: milsToMillimeters(start.y),\n x2: milsToMillimeters(end.x),\n y2: milsToMillimeters(end.y),\n }\n}\n\nfunction approximateArc(\n center: AltiumPoint,\n radius: number,\n startAngle: number,\n endAngle: number,\n): AltiumPoint[] {\n const sweep = endAngle - startAngle || 360\n const segments = Math.max(8, Math.ceil(Math.abs(sweep) / 7.5))\n return Array.from({ length: segments + 1 }, (_, index) => {\n const angle = startAngle + (sweep * index) / segments\n const radians = (angle * Math.PI) / 180\n return {\n x: center.x + Math.cos(radians) * radius,\n y: center.y + Math.sin(radians) * radius,\n }\n })\n}\n\nfunction createOctagonPoints(\n x: number,\n y: number,\n width: number,\n height: number,\n rotation: number,\n): Array<{ x: number; y: number }> {\n const halfWidth = width / 2\n const halfHeight = height / 2\n const chamfer = Math.min(width, height) / 4\n const points = [\n { x: -halfWidth + chamfer, y: -halfHeight },\n { x: halfWidth - chamfer, y: -halfHeight },\n { x: halfWidth, y: -halfHeight + chamfer },\n { x: halfWidth, y: halfHeight - chamfer },\n { x: halfWidth - chamfer, y: halfHeight },\n { x: -halfWidth + chamfer, y: halfHeight },\n { x: -halfWidth, y: halfHeight - chamfer },\n { x: -halfWidth, y: -halfHeight + chamfer },\n ]\n const radians = (rotation * Math.PI) / 180\n return points.map((point) => ({\n x: x + point.x * Math.cos(radians) - point.y * Math.sin(radians),\n y: y + point.x * Math.sin(radians) + point.y * Math.cos(radians),\n }))\n}\n","import {\n type AltiumPoint,\n type AltiumRecord,\n type AltiumSchDoc,\n getSchematicRecordPoints,\n} from \"altiumts\"\nimport type {\n AnyCircuitElement,\n Point,\n SchematicArc,\n SchematicCircle,\n SchematicGroup,\n SchematicLine,\n SchematicPath,\n SchematicRect,\n SchematicSheet,\n SchematicText,\n SchematicTrace,\n} from \"circuit-json\"\nimport { convertSemanticSchematic } from \"./schematic/convert-semantic-schematic\"\n\nconst SCHEMATIC_SHEET_ID = \"schematic_sheet_altium\"\n// circuit-to-svg renders schematic_sheet as a centered A4 page. Keep imported\n// coordinates inside the same 5 mm inset used by that renderer.\nconst SCHEMATIC_UNIT_TO_MILLIMETERS = 10.16 / 1.1\nconst SCHEMATIC_SHEET_INSET = 5 / SCHEMATIC_UNIT_TO_MILLIMETERS\nconst SCHEMATIC_SHEET_WIDTH = 297 / SCHEMATIC_UNIT_TO_MILLIMETERS\nconst SCHEMATIC_SHEET_HEIGHT = 210 / SCHEMATIC_UNIT_TO_MILLIMETERS\nconst SCHEMATIC_SHEET_INNER_WIDTH =\n SCHEMATIC_SHEET_WIDTH - SCHEMATIC_SHEET_INSET * 2\nconst SCHEMATIC_SHEET_INNER_HEIGHT =\n SCHEMATIC_SHEET_HEIGHT - SCHEMATIC_SHEET_INSET * 2\n\nexport interface ConvertAltiumSchDocOptions {\n centerOnSchematicSheet?: boolean\n includeHidden?: boolean\n includeSheetBorder?: boolean\n includeText?: boolean\n schematicUnitScale?: number\n sheetName?: string\n}\n\ninterface SchematicContext {\n document: AltiumSchDoc\n records: AltiumRecord[]\n scale: number\n sheetRecord?: AltiumRecord\n}\n\nexport function convertAltiumSchDocToCircuitJson(\n document: AltiumSchDoc,\n options: ConvertAltiumSchDocOptions = {},\n): AnyCircuitElement[] {\n const records = document.records\n const sheetRecord = records.find((record) => record.recordKind === \"31\")\n const sheetDimensions = getAltiumSheetDimensions(sheetRecord)\n const scale = options.schematicUnitScale ?? getPageFitScale(sheetDimensions)\n if (!Number.isFinite(scale) || scale <= 0) {\n throw new RangeError(\"schematicUnitScale must be a positive finite number\")\n }\n\n const context: SchematicContext = { document, records, scale, sheetRecord }\n const elements: AnyCircuitElement[] = [\n {\n type: \"schematic_sheet\",\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n name: options.sheetName ?? \"Altium schematic\",\n outline_color: \"#334155\",\n sheet_index: 0,\n } satisfies SchematicSheet,\n ]\n\n if (options.includeSheetBorder === true) {\n elements.push(createSheetBorder(sheetRecord, scale))\n }\n\n const semanticConversion = convertSemanticSchematic(document, {\n includeHidden: options.includeHidden,\n includeText: options.includeText,\n scale,\n schematicSheetId: SCHEMATIC_SHEET_ID,\n })\n elements.push(...semanticConversion.elements)\n\n for (const [index, record] of records.entries()) {\n if (semanticConversion.handledRecords.has(record)) continue\n if (!shouldRenderSchematicRecord(record, context)) continue\n const converted = convertSchematicRecord(record, index, context, options)\n elements.push(...converted)\n }\n\n const schematicComponentIds = elements\n .filter(\n (\n element,\n ): element is Extract<\n AnyCircuitElement,\n { type: \"schematic_component\" }\n > => element.type === \"schematic_component\",\n )\n .map((element) => element.schematic_component_id)\n if (schematicComponentIds.length > 0) {\n elements.push({\n type: \"schematic_group\",\n schematic_group_id: \"schematic_group_altium\",\n source_group_id: \"source_group_altium\",\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: {\n x: (sheetDimensions.width * scale) / 2,\n y: (sheetDimensions.height * scale) / 2,\n },\n width: sheetDimensions.width * scale,\n height: sheetDimensions.height * scale,\n schematic_component_ids: schematicComponentIds,\n name: options.sheetName ?? \"Altium schematic\",\n } satisfies SchematicGroup)\n }\n\n if (options.centerOnSchematicSheet === false) return elements\n\n const offset = {\n x: (-sheetDimensions.width * scale) / 2,\n y: (-sheetDimensions.height * scale) / 2,\n }\n return elements.map((element) => translateSchematicElement(element, offset))\n}\n\ninterface SheetDimensions {\n height: number\n width: number\n}\n\nfunction getAltiumSheetDimensions(\n sheetRecord: AltiumRecord | undefined,\n): SheetDimensions {\n return {\n width: getPositiveNumber(sheetRecord?.getCaseInsensitive(\"CUSTOMX\"), 1000),\n height: getPositiveNumber(sheetRecord?.getCaseInsensitive(\"CUSTOMY\"), 800),\n }\n}\n\nfunction getPositiveNumber(value: unknown, fallback: number): number {\n const parsed = Number(value)\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback\n}\n\nfunction getPageFitScale(sheetDimensions: SheetDimensions): number {\n return Math.min(\n SCHEMATIC_SHEET_INNER_WIDTH / sheetDimensions.width,\n SCHEMATIC_SHEET_INNER_HEIGHT / sheetDimensions.height,\n )\n}\n\nfunction translatePoint(point: Point, offset: Point): Point {\n return { x: point.x + offset.x, y: point.y + offset.y }\n}\n\nfunction translateSchematicElement(\n element: AnyCircuitElement,\n offset: Point,\n): AnyCircuitElement {\n switch (element.type) {\n case \"schematic_component\":\n case \"schematic_port\":\n case \"schematic_rect\":\n case \"schematic_circle\":\n case \"schematic_arc\":\n return { ...element, center: translatePoint(element.center, offset) }\n case \"schematic_net_label\":\n return {\n ...element,\n center: translatePoint(element.center, offset),\n ...(element.anchor_position\n ? {\n anchor_position: translatePoint(element.anchor_position, offset),\n }\n : {}),\n }\n case \"schematic_text\":\n return { ...element, position: translatePoint(element.position, offset) }\n case \"schematic_path\":\n return {\n ...element,\n points: element.points.map((point) => translatePoint(point, offset)),\n }\n case \"schematic_line\":\n return {\n ...element,\n x1: element.x1 + offset.x,\n x2: element.x2 + offset.x,\n y1: element.y1 + offset.y,\n y2: element.y2 + offset.y,\n }\n case \"schematic_trace\":\n return {\n ...element,\n edges: element.edges.map((edge) => ({\n ...edge,\n from: translatePoint(edge.from, offset),\n to: translatePoint(edge.to, offset),\n })),\n junctions: element.junctions.map((junction) =>\n translatePoint(junction, offset),\n ),\n }\n default:\n return element\n }\n}\n\nfunction convertSchematicRecord(\n record: AltiumRecord,\n index: number,\n context: SchematicContext,\n options: ConvertAltiumSchDocOptions,\n): AnyCircuitElement[] {\n const kind = record.recordKind\n const scale = context.scale\n const color = altiumColorToCss(record.getCaseInsensitive(\"COLOR\"), \"#1f2937\")\n const strokeWidth = Math.max(\n Number(record.getCaseInsensitive(\"LINEWIDTH\") ?? 1) * scale,\n 0.05,\n )\n\n if (kind === \"27\") {\n const points = getSchematicRecordPoints(record).map((point) =>\n scalePoint(point, scale),\n )\n if (points.length < 2) return []\n return [\n {\n type: \"schematic_trace\",\n schematic_trace_id: `schematic_trace_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n junctions: [],\n edges: points.slice(1).map((point, pointIndex) => ({\n from: points[pointIndex] ?? point,\n to: point,\n })),\n } satisfies SchematicTrace,\n ]\n }\n\n if (kind === \"6\" || kind === \"7\") {\n const points = getSchematicRecordPoints(record).map((point) =>\n scalePoint(point, scale),\n )\n if (points.length < 2) return []\n return [\n {\n type: \"schematic_path\",\n schematic_path_id: `schematic_path_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n points,\n stroke_width: strokeWidth,\n stroke_color: color,\n fill_color:\n kind === \"7\"\n ? altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"transparent\",\n )\n : undefined,\n is_filled: kind === \"7\",\n is_dashed: false,\n } satisfies SchematicPath,\n ]\n }\n\n if (kind === \"13\") {\n const location = getLocation(record)\n const corner = getCorner(record)\n if (!location || !corner) return []\n return [createLine(index, location, corner, color, strokeWidth, scale)]\n }\n\n if (kind === \"10\" || kind === \"14\") {\n const rectangle = getRectangle(record)\n if (!rectangle) return []\n return [\n {\n type: \"schematic_rect\",\n schematic_rect_id: `schematic_rect_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: scalePoint(\n {\n x: (rectangle.minX + rectangle.maxX) / 2,\n y: (rectangle.minY + rectangle.maxY) / 2,\n },\n scale,\n ),\n width: (rectangle.maxX - rectangle.minX) * scale,\n height: (rectangle.maxY - rectangle.minY) * scale,\n rotation: 0,\n stroke_width: strokeWidth,\n color,\n is_filled: record.getBoolean(\"ISSOLID\") === true,\n fill_color: altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"#ffffff\",\n ),\n is_dashed: false,\n } satisfies SchematicRect,\n ]\n }\n\n if (kind === \"8\") {\n const center = getLocation(record)\n if (!center) return []\n const radiusX = getCoordinate(record, \"RADIUS\", 1)\n const radiusY = getCoordinate(record, \"SECONDARYRADIUS\", radiusX)\n if (Math.abs(radiusX - radiusY) < 0.0001) {\n return [\n {\n type: \"schematic_circle\",\n schematic_circle_id: `schematic_circle_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: scalePoint(center, scale),\n radius: radiusX * scale,\n stroke_width: strokeWidth,\n color,\n is_filled: record.getBoolean(\"ISSOLID\") === true,\n fill_color: altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"#ffffff\",\n ),\n is_dashed: false,\n } satisfies SchematicCircle,\n ]\n }\n return [\n {\n type: \"schematic_path\",\n schematic_path_id: `schematic_ellipse_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n points: approximateEllipse(center, radiusX, radiusY).map((point) =>\n scalePoint(point, scale),\n ),\n stroke_width: strokeWidth,\n stroke_color: color,\n fill_color: altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"#ffffff\",\n ),\n is_filled: record.getBoolean(\"ISSOLID\") === true,\n is_dashed: false,\n } satisfies SchematicPath,\n ]\n }\n\n if (kind === \"11\" || kind === \"12\") {\n const center = getLocation(record)\n if (!center) return []\n return [\n {\n type: \"schematic_arc\",\n schematic_arc_id: `schematic_arc_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: scalePoint(center, scale),\n radius: getCoordinate(record, \"RADIUS\", 1) * scale,\n start_angle_degrees: Number(\n record.getCaseInsensitive(\"STARTANGLE\") ?? 0,\n ),\n end_angle_degrees: Number(record.getCaseInsensitive(\"ENDANGLE\") ?? 360),\n direction: \"counterclockwise\",\n stroke_width: strokeWidth,\n color,\n is_dashed: false,\n } satisfies SchematicArc,\n ]\n }\n\n if (kind === \"2\") {\n return convertPin(record, index, context, options, color)\n }\n\n if (kind === \"29\") {\n const location = getLocation(record)\n if (!location) return []\n return [\n {\n type: \"schematic_circle\",\n schematic_circle_id: `schematic_junction_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: scalePoint(location, scale),\n radius: Math.max(\n Number(record.getCaseInsensitive(\"SIZE\") ?? 1) * 0.18,\n 0.15,\n ),\n color,\n is_filled: true,\n fill_color: color,\n is_dashed: false,\n } satisfies SchematicCircle,\n ]\n }\n\n if (kind === \"22\") {\n const location = getLocation(record)\n if (!location) return []\n // altiumts renders the \"Small Cross\" no-ERC symbol with four Altium\n // coordinate units on either side of its anchor.\n const radius = 4\n const noErcStrokeWidth = Math.max(scale, 0.02)\n return [\n createLine(\n index,\n { x: location.x - radius, y: location.y - radius },\n { x: location.x + radius, y: location.y + radius },\n color,\n noErcStrokeWidth,\n scale,\n \"a\",\n ),\n createLine(\n index,\n { x: location.x + radius, y: location.y - radius },\n { x: location.x - radius, y: location.y + radius },\n color,\n noErcStrokeWidth,\n scale,\n \"b\",\n ),\n ]\n }\n\n if (kind === \"17\") {\n return convertPowerPort(record, index, context, options, color)\n }\n\n if (kind === \"18\") {\n return convertPort(record, index, context, options, color)\n }\n\n if (kind === \"4\" || kind === \"25\" || kind === \"34\" || kind === \"41\") {\n if (options.includeText === false) return []\n if (record.getBoolean(\"ISHIDDEN\") && !options.includeHidden) return []\n const text =\n record.getDecoded(\"TEXT\") ??\n record.getDecoded(\"NAME\") ??\n record.getDecoded(\"DESIGNATOR\")\n const location = getLocation(record)\n if (!text || !location) return []\n return [createText(record, index, text, location, color, context)]\n }\n\n if (kind === \"28\") {\n const rectangle = getRectangle(record)\n const text = decodeMultilineText(record.getDecoded(\"TEXT\") ?? \"\")\n if (!rectangle || !text || options.includeText === false) return []\n const fontSize = getFontSize(record, context)\n const fontFamily = getFontFamily(record, context)\n const margin = Math.max(getCoordinate(record, \"TEXTMARGIN\", 0), 0)\n const frameWidth = rectangle.maxX - rectangle.minX\n const frameHeight = rectangle.maxY - rectangle.minY\n const availableWidth = Math.max(frameWidth - margin * 2, fontSize)\n const availableHeight = Math.max(frameHeight - margin * 2, fontSize)\n const wrappedLines =\n record.getBoolean(\"WORDWRAP\") === false\n ? text.split(\"\\n\")\n : wrapSchematicText(text, availableWidth, fontSize, fontFamily)\n const lineHeight = fontSize\n const visibleLines =\n record.getBoolean(\"CLIPTORECT\") === false\n ? wrappedLines\n : wrappedLines.slice(\n 0,\n Math.max(Math.ceil(availableHeight / lineHeight), 1),\n )\n const alignment = Number(record.getCaseInsensitive(\"ALIGNMENT\") ?? 1)\n const horizontalAnchor =\n alignment === 2 ? \"center\" : alignment === 3 ? \"right\" : \"left\"\n const textX =\n horizontalAnchor === \"center\"\n ? (rectangle.minX + rectangle.maxX) / 2\n : horizontalAnchor === \"right\"\n ? rectangle.maxX - margin\n : rectangle.minX + margin\n const textColor = altiumColorToCss(\n record.getCaseInsensitive(\"TEXTCOLOR\") ??\n record.getCaseInsensitive(\"COLOR\"),\n \"#1f2937\",\n )\n const elements: AnyCircuitElement[] = visibleLines.map((line, lineIndex) =>\n createDirectText(\n `schematic_text_frame_line_altium_${index}_${lineIndex}`,\n line,\n {\n x: textX,\n y: rectangle.maxY - margin - lineIndex * lineHeight,\n },\n fontSize,\n textColor,\n scale,\n 0,\n `top_${horizontalAnchor}` as SchematicText[\"anchor\"],\n ),\n )\n\n const isSolid = record.getBoolean(\"ISSOLID\") === true\n const showBorder = record.getBoolean(\"SHOWBORDER\") === true\n if (isSolid || showBorder) {\n elements.unshift({\n type: \"schematic_rect\",\n schematic_rect_id: `schematic_text_frame_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: scalePoint(\n {\n x: (rectangle.minX + rectangle.maxX) / 2,\n y: (rectangle.minY + rectangle.maxY) / 2,\n },\n scale,\n ),\n width: frameWidth * scale,\n height: frameHeight * scale,\n rotation: 0,\n stroke_width: showBorder ? strokeWidth : 0,\n color: showBorder ? color : \"transparent\",\n is_filled: isSolid,\n fill_color: altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"#ffffff\",\n ),\n is_dashed: false,\n } satisfies SchematicRect)\n }\n\n return elements\n }\n\n return []\n}\n\nfunction convertPin(\n record: AltiumRecord,\n index: number,\n context: SchematicContext,\n options: ConvertAltiumSchDocOptions,\n color: string,\n): AnyCircuitElement[] {\n const location = getLocation(record)\n if (!location) return []\n const pinConglomerate = record.getNumber(\"PINCONGLOMERATE\")\n const hidden =\n record.getBoolean(\"ISHIDDEN\") ||\n (pinConglomerate !== undefined && (pinConglomerate & 0x04) !== 0)\n if (hidden && !options.includeHidden) return []\n const orientation =\n (pinConglomerate ?? Number(record.getCaseInsensitive(\"ORIENTATION\") ?? 0)) &\n 3\n const direction = [\n { x: 1, y: 0 },\n { x: 0, y: 1 },\n { x: -1, y: 0 },\n { x: 0, y: -1 },\n ][orientation] ?? { x: 1, y: 0 }\n const length = Math.max(\n Number(record.getCaseInsensitive(\"PINLENGTH\") ?? 10),\n 1,\n )\n const end = {\n x: location.x + direction.x * length,\n y: location.y + direction.y * length,\n }\n const elements: AnyCircuitElement[] = [\n createLine(index, location, end, color, 0.1, context.scale, \"pin\"),\n ]\n if (options.includeText === false) return elements\n\n const name = record.getDecoded(\"NAME\") ?? \"\"\n const designator = record.getDecoded(\"DESIGNATOR\") ?? \"\"\n const showName =\n pinConglomerate === undefined || (pinConglomerate & 0x08) !== 0\n const showDesignator =\n pinConglomerate === undefined || (pinConglomerate & 0x10) !== 0\n const rotation = orientation === 1 || orientation === 3 ? 90 : 0\n const directionMatchesText = orientation === 0 || orientation === 1\n const nameAnchor = directionMatchesText ? \"right\" : \"left\"\n const designatorAnchor = directionMatchesText ? \"left\" : \"right\"\n const textOffset = 2\n\n if (showName && name) {\n elements.push(\n createDirectText(\n `schematic_pin_name_altium_${index}`,\n name,\n {\n x: location.x - direction.x * textOffset,\n y: location.y - direction.y * textOffset,\n },\n 6,\n color,\n context.scale,\n rotation,\n nameAnchor,\n ),\n )\n }\n if (showDesignator && designator) {\n elements.push(\n createDirectText(\n `schematic_pin_designator_altium_${index}`,\n designator,\n {\n x: location.x + direction.x * textOffset,\n y: location.y + direction.y * textOffset,\n },\n 6,\n color,\n context.scale,\n rotation,\n designatorAnchor,\n ),\n )\n }\n return elements\n}\n\nfunction convertPowerPort(\n record: AltiumRecord,\n index: number,\n context: SchematicContext,\n options: ConvertAltiumSchDocOptions,\n color: string,\n): AnyCircuitElement[] {\n const location = getLocation(record)\n if (!location) return []\n const orientation =\n ((Math.round(record.getNumber(\"ORIENTATION\") ?? 0) % 4) + 4) % 4\n const direction = [\n { x: 1, y: 0 },\n { x: 0, y: 1 },\n { x: -1, y: 0 },\n { x: 0, y: -1 },\n ][orientation] ?? { x: 1, y: 0 }\n const perpendicular = { x: -direction.y, y: direction.x }\n const point = (along: number, across = 0): AltiumPoint => ({\n x: location.x + direction.x * along + perpendicular.x * across,\n y: location.y + direction.y * along + perpendicular.y * across,\n })\n const style = Math.round(Number(record.getCaseInsensitive(\"STYLE\") ?? 2))\n const elements: AnyCircuitElement[] = []\n let labelDistance: number\n\n if (style === 2) {\n elements.push(\n createLine(\n index,\n location,\n point(8),\n color,\n 0.1,\n context.scale,\n \"power_port_stem\",\n ),\n createLine(\n index,\n point(8, -5),\n point(8, 5),\n color,\n 0.1,\n context.scale,\n \"power_port_bar\",\n ),\n )\n labelDistance = 12\n } else if (style === 5) {\n elements.push(\n createLine(\n index,\n location,\n point(4),\n color,\n 0.1,\n context.scale,\n \"power_port_stem\",\n ),\n {\n type: \"schematic_path\",\n schematic_path_id: `schematic_power_port_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n points: [point(4, -7), point(4, 7), point(12)].map((value) =>\n scalePoint(value, context.scale),\n ),\n stroke_width: 0.1,\n stroke_color: color,\n is_filled: false,\n is_dashed: false,\n } satisfies SchematicPath,\n )\n labelDistance = 16\n } else if (style === 4) {\n elements.push(\n createLine(\n index,\n location,\n point(4),\n color,\n 0.1,\n context.scale,\n \"power_port_stem\",\n ),\n ...[\n { along: 4, halfWidth: 7 },\n { along: 8, halfWidth: 4.5 },\n { along: 12, halfWidth: 2 },\n ].map(({ along, halfWidth }, lineIndex) =>\n createLine(\n index,\n point(along, -halfWidth),\n point(along, halfWidth),\n color,\n 0.1,\n context.scale,\n `power_port_ground_${lineIndex}`,\n ),\n ),\n )\n labelDistance = 16\n } else if (style === 6) {\n elements.push(\n createLine(\n index,\n location,\n point(4),\n color,\n 0.1,\n context.scale,\n \"power_port_stem\",\n ),\n createLine(\n index,\n point(4, -7),\n point(4, 7),\n color,\n 0.1,\n context.scale,\n \"power_port_chassis_bar\",\n ),\n ...[\n { from: -7, to: -9 },\n { from: 0, to: -2 },\n { from: 7, to: 5 },\n ].map(({ from, to }, lineIndex) =>\n createLine(\n index,\n point(4, from),\n point(9, to),\n color,\n 0.1,\n context.scale,\n `power_port_chassis_${lineIndex}`,\n ),\n ),\n )\n labelDistance = 14\n } else {\n elements.push({\n type: \"schematic_path\",\n schematic_path_id: `schematic_power_port_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n points: [location, point(10, -5), point(10, 5)].map((value) =>\n scalePoint(value, context.scale),\n ),\n stroke_width: 0.1,\n stroke_color: color,\n fill_color: color,\n is_filled: true,\n is_dashed: false,\n } satisfies SchematicPath)\n labelDistance = 14\n }\n const text = record.getDecoded(\"TEXT\") ?? record.getDecoded(\"NAME\")\n if (\n text &&\n options.includeText !== false &&\n record.getBoolean(\"SHOWNETNAME\") !== false\n ) {\n const vertical = direction.y !== 0\n const anchor: SchematicText[\"anchor\"] = vertical\n ? direction.y > 0\n ? \"bottom_center\"\n : \"top_center\"\n : direction.x > 0\n ? \"center_left\"\n : \"center_right\"\n elements.push(\n createDirectText(\n `schematic_power_port_text_altium_${index}`,\n text,\n point(labelDistance),\n getFontSize(record, context),\n color,\n context.scale,\n 0,\n anchor,\n ),\n )\n }\n return elements\n}\n\nfunction convertPort(\n record: AltiumRecord,\n index: number,\n context: SchematicContext,\n options: ConvertAltiumSchDocOptions,\n color: string,\n): AnyCircuitElement[] {\n const location = getLocation(record)\n if (!location) return []\n const width = Math.max(Number(record.getCaseInsensitive(\"WIDTH\") ?? 16), 10)\n const height = Math.max(Number(record.getCaseInsensitive(\"HEIGHT\") ?? 10), 4)\n const halfHeight = height / 2\n const pointDepth = Math.min(width * 0.22, height)\n const ioType = Number(record.getCaseInsensitive(\"IOTYPE\") ?? 0)\n const points =\n ioType === 1\n ? [\n { x: location.x, y: location.y },\n { x: location.x + pointDepth, y: location.y + halfHeight },\n { x: location.x + width, y: location.y + halfHeight },\n { x: location.x + width, y: location.y - halfHeight },\n { x: location.x + pointDepth, y: location.y - halfHeight },\n ]\n : ioType === 2\n ? [\n { x: location.x, y: location.y + halfHeight },\n {\n x: location.x + width - pointDepth,\n y: location.y + halfHeight,\n },\n { x: location.x + width, y: location.y },\n {\n x: location.x + width - pointDepth,\n y: location.y - halfHeight,\n },\n { x: location.x, y: location.y - halfHeight },\n ]\n : [\n { x: location.x, y: location.y + halfHeight },\n { x: location.x + width, y: location.y + halfHeight },\n { x: location.x + width, y: location.y - halfHeight },\n { x: location.x, y: location.y - halfHeight },\n ]\n const elements: AnyCircuitElement[] = [\n {\n type: \"schematic_path\",\n schematic_path_id: `schematic_port_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n points: points.map((point) => scalePoint(point, context.scale)),\n stroke_width: 0.1,\n stroke_color: color,\n fill_color: altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"#ffffff\",\n ),\n is_filled: true,\n is_dashed: false,\n } satisfies SchematicPath,\n ]\n const name = record.getDecoded(\"NAME\")\n if (name && options.includeText !== false) {\n elements.push(\n createDirectText(\n `schematic_port_text_altium_${index}`,\n name,\n { x: location.x + width / 2, y: location.y },\n getFontSize(record, context),\n altiumColorToCss(record.getCaseInsensitive(\"TEXTCOLOR\"), color),\n context.scale,\n 0,\n \"center\",\n ),\n )\n }\n return elements\n}\n\nfunction createSheetBorder(\n sheetRecord: AltiumRecord | undefined,\n scale: number,\n): SchematicRect {\n const { height, width } = getAltiumSheetDimensions(sheetRecord)\n return {\n type: \"schematic_rect\",\n schematic_rect_id: \"schematic_rect_altium_sheet_border\",\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: { x: (width * scale) / 2, y: (height * scale) / 2 },\n width: width * scale,\n height: height * scale,\n rotation: 0,\n stroke_width: 0.1,\n color: \"#334155\",\n is_filled: false,\n is_dashed: false,\n }\n}\n\nfunction createLine(\n index: number,\n start: AltiumPoint,\n end: AltiumPoint,\n color: string,\n strokeWidth: number,\n scale: number,\n suffix = \"line\",\n): SchematicLine {\n return {\n type: \"schematic_line\",\n schematic_line_id: `schematic_line_altium_${index}_${suffix}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n x1: start.x * scale,\n y1: start.y * scale,\n x2: end.x * scale,\n y2: end.y * scale,\n stroke_width: strokeWidth,\n color,\n is_dashed: false,\n }\n}\n\nfunction createText(\n record: AltiumRecord,\n index: number,\n text: string,\n location: AltiumPoint,\n color: string,\n context: SchematicContext,\n anchorOverride?: SchematicText[\"anchor\"],\n): SchematicText {\n const positioning = getTextPositioning(record)\n return createDirectText(\n `schematic_text_altium_${index}`,\n text,\n location,\n getFontSize(record, context),\n color,\n context.scale,\n positioning.rotation,\n anchorOverride ?? positioning.anchor,\n )\n}\n\nfunction createDirectText(\n id: string,\n text: string,\n location: AltiumPoint,\n fontSize: number,\n color: string,\n scale: number,\n rotation: number,\n anchor: SchematicText[\"anchor\"],\n): SchematicText {\n return {\n type: \"schematic_text\",\n schematic_text_id: id,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n text,\n font_size: Math.max(fontSize * scale, 0.2),\n position: scalePoint(location, scale),\n rotation,\n anchor,\n color,\n }\n}\n\nfunction getFontSize(record: AltiumRecord, context: SchematicContext): number {\n const fontId = Math.max(\n Math.round(Number(record.getCaseInsensitive(\"FONTID\") ?? 1)),\n 1,\n )\n return Math.max(\n Number(context.sheetRecord?.getCaseInsensitive(`SIZE${fontId}`) ?? 9),\n 1,\n )\n}\n\nfunction getFontFamily(\n record: AltiumRecord,\n context: SchematicContext,\n): string {\n const fontId = Math.max(\n Math.round(Number(record.getCaseInsensitive(\"FONTID\") ?? 1)),\n 1,\n )\n return context.sheetRecord?.getDecoded(`FONTNAME${fontId}`) ?? \"Arial\"\n}\n\nfunction getTextPositioning(record: AltiumRecord): {\n anchor: SchematicText[\"anchor\"]\n rotation: number\n} {\n const justification = Math.min(\n Math.max(Math.round(record.getNumber(\"JUSTIFICATION\") ?? 0), 0),\n 8,\n )\n const orientation =\n ((Math.round(record.getNumber(\"ORIENTATION\") ?? 0) % 4) + 4) % 4\n let column = justification % 3\n const row = Math.floor(justification / 3)\n if (orientation === 2 || orientation === 3) column = 2 - column\n const horizontal = [\"left\", \"center\", \"right\"][column] ?? \"left\"\n const vertical = [\"bottom\", \"center\", \"top\"][row] ?? \"bottom\"\n const anchor =\n horizontal === \"center\" && vertical === \"center\"\n ? \"center\"\n : (`${vertical}_${horizontal}` as SchematicText[\"anchor\"])\n return {\n anchor,\n rotation: orientation === 1 || orientation === 3 ? 90 : 0,\n }\n}\n\nfunction shouldRenderSchematicRecord(\n record: AltiumRecord,\n context: SchematicContext,\n): boolean {\n let ownerPartId = record.getNumber(\"OWNERPARTID\")\n let ownerPartDisplayMode = record.getNumber(\"OWNERPARTDISPLAYMODE\")\n let current: AltiumRecord | undefined = record\n const visited = new Set<AltiumRecord>()\n\n while (current && !visited.has(current)) {\n visited.add(current)\n const parent = context.document.getParent(current)\n if (!parent) return true\n\n if (ownerPartId === undefined || ownerPartId <= 0) {\n ownerPartId = current.getNumber(\"OWNERPARTID\")\n }\n if (ownerPartDisplayMode === undefined) {\n ownerPartDisplayMode = current.getNumber(\"OWNERPARTDISPLAYMODE\")\n }\n\n if (parent.recordKind === \"1\") {\n const currentPartId = parent.getNumber(\"CURRENTPARTID\") ?? 1\n return (\n (ownerPartId === undefined ||\n ownerPartId <= 0 ||\n ownerPartId === currentPartId) &&\n (ownerPartDisplayMode === undefined || ownerPartDisplayMode === 0)\n )\n }\n current = parent\n }\n return true\n}\n\nfunction getLocation(record: AltiumRecord): AltiumPoint | undefined {\n if (\n record.getCaseInsensitive(\"LOCATION.X\") === undefined ||\n record.getCaseInsensitive(\"LOCATION.Y\") === undefined\n ) {\n return undefined\n }\n return {\n x: getCoordinate(record, \"LOCATION.X\"),\n y: getCoordinate(record, \"LOCATION.Y\"),\n }\n}\n\nfunction getCorner(record: AltiumRecord): AltiumPoint | undefined {\n if (\n record.getCaseInsensitive(\"CORNER.X\") === undefined ||\n record.getCaseInsensitive(\"CORNER.Y\") === undefined\n ) {\n return undefined\n }\n return {\n x: getCoordinate(record, \"CORNER.X\"),\n y: getCoordinate(record, \"CORNER.Y\"),\n }\n}\n\nfunction getRectangle(\n record: AltiumRecord,\n): { maxX: number; maxY: number; minX: number; minY: number } | undefined {\n const location = getLocation(record)\n const corner = getCorner(record)\n if (!location || !corner) return undefined\n return {\n minX: Math.min(location.x, corner.x),\n minY: Math.min(location.y, corner.y),\n maxX: Math.max(location.x, corner.x),\n maxY: Math.max(location.y, corner.y),\n }\n}\n\nfunction getCoordinate(\n record: AltiumRecord,\n key: string,\n fallback = 0,\n): number {\n const integerPart = Number(record.getCaseInsensitive(key) ?? fallback)\n const fractionRaw = record.getCaseInsensitive(`${key}_FRAC`)\n if (!Number.isFinite(integerPart) || fractionRaw === undefined) {\n return Number.isFinite(integerPart) ? integerPart : fallback\n }\n const fraction = Number(`0.${fractionRaw.replace(/^[+-]/u, \"\")}`)\n if (!Number.isFinite(fraction)) return integerPart\n return integerPart < 0 ? integerPart - fraction : integerPart + fraction\n}\n\nfunction scalePoint(point: AltiumPoint, scale: number): AltiumPoint {\n return { x: point.x * scale, y: point.y * scale }\n}\n\nfunction approximateEllipse(\n center: AltiumPoint,\n radiusX: number,\n radiusY: number,\n): AltiumPoint[] {\n return Array.from({ length: 49 }, (_, index) => {\n const radians = (index / 48) * Math.PI * 2\n return {\n x: center.x + Math.cos(radians) * radiusX,\n y: center.y + Math.sin(radians) * radiusY,\n }\n })\n}\n\nfunction decodeMultilineText(text: string): string {\n return text.replaceAll(\"~1\", \"\\n\").replaceAll(\"\\\\n\", \"\\n\")\n}\n\nfunction wrapSchematicText(\n text: string,\n maximumWidth: number,\n fontSize: number,\n fontFamily: string,\n): string[] {\n return text.split(\"\\n\").flatMap((paragraph) => {\n if (\n estimateSchematicTextWidth(paragraph, fontSize, fontFamily) <=\n maximumWidth\n ) {\n return [paragraph]\n }\n const words = paragraph.split(/\\s+/u)\n const lines: string[] = []\n let line = \"\"\n for (const word of words) {\n if (!line) {\n line = word\n } else if (\n estimateSchematicTextWidth(`${line} ${word}`, fontSize, fontFamily) <=\n maximumWidth\n ) {\n line = `${line} ${word}`\n } else {\n lines.push(line)\n line = word\n }\n }\n if (line) lines.push(line)\n return lines.length > 0 ? lines : [paragraph]\n })\n}\n\nfunction estimateSchematicTextWidth(\n text: string,\n fontSize: number,\n fontFamily: string,\n): number {\n if (/courier|mono/iu.test(fontFamily)) return text.length * fontSize * 0.6\n if (!/times|cambria|serif/iu.test(fontFamily)) {\n return text.length * fontSize * 0.52\n }\n\n return [...text].reduce((width, character) => {\n const emWidth =\n character === \" \"\n ? 0.23\n : /[ilI1.,:;!'`|]/u.test(character)\n ? 0.2\n : /[mwMW@%]/u.test(character)\n ? 0.7\n : /[A-Z0-9]/u.test(character)\n ? 0.5\n : 0.4\n return width + emWidth * fontSize\n }, 0)\n}\n\nfunction altiumColorToCss(raw: string | undefined, fallback: string): string {\n if (raw === undefined) return fallback\n const value = Number(raw)\n if (!Number.isInteger(value) || value < 0) return fallback\n const red = value & 0xff\n const green = (value >>> 8) & 0xff\n const blue = (value >>> 16) & 0xff\n return `#${toHex(red)}${toHex(green)}${toHex(blue)}`\n}\n\nfunction toHex(value: number): string {\n return value.toString(16).padStart(2, \"0\")\n}\n","import {\n type AltiumPoint,\n type AltiumRecord,\n type AltiumSchDoc,\n getSchematicDocumentIndex,\n getSchematicRecordPoints,\n} from \"altiumts\"\nimport {\n type AnyCircuitElement,\n type SchematicComponent,\n type SchematicNetLabel,\n type SchematicPort,\n type SchematicText,\n type SchematicTrace,\n type SourceComponentBase,\n type SourceNet,\n type SourcePort,\n type SourceTrace,\n source_simple_capacitor,\n source_simple_crystal,\n source_simple_inductor,\n source_simple_mosfet,\n source_simple_resistor,\n} from \"circuit-json\"\nimport { parseAndConvertSiUnit } from \"format-si-unit\"\nimport { type SchSymbol, symbols } from \"schematic-symbols\"\n\nexport interface SemanticSchematicOptions {\n includeHidden?: boolean\n includeText?: boolean\n scale: number\n schematicSheetId: string\n}\n\nexport interface SemanticSchematicConversion {\n elements: AnyCircuitElement[]\n handledRecords: Set<AltiumRecord>\n}\n\ninterface ConvertedPort {\n isSchematicVisible: boolean\n point: AltiumPoint\n record: AltiumRecord\n schematicPort: SchematicPort\n sourcePort: SourcePort\n}\n\ninterface SymbolPortAssignment {\n convertedPort: ConvertedPort\n symbolPort: SchSymbol[\"ports\"][number]\n}\n\ninterface SymbolSelection {\n assignments: SymbolPortAssignment[]\n name: string\n symbol: SchSymbol\n}\n\ninterface SemanticNet {\n id: string\n names: string[]\n points: AltiumPoint[]\n records: AltiumRecord[]\n}\n\ninterface SemanticNetGraph {\n getConnectedWiresForRecord(record: AltiumRecord): AltiumRecord[]\n nets: SemanticNet[]\n}\n\ninterface Bounds {\n maxX: number\n maxY: number\n minX: number\n minY: number\n}\n\ntype CardinalDirection = \"up\" | \"down\" | \"left\" | \"right\"\n\nconst DIRECTION_BY_ORIENTATION: readonly CardinalDirection[] = [\n \"right\",\n \"up\",\n \"left\",\n \"down\",\n]\n\nconst VECTOR_BY_DIRECTION: Readonly<Record<CardinalDirection, AltiumPoint>> = {\n down: { x: 0, y: -1 },\n left: { x: -1, y: 0 },\n right: { x: 1, y: 0 },\n up: { x: 0, y: 1 },\n}\n\nconst CARDINAL_DIRECTIONS: readonly CardinalDirection[] = [\n \"right\",\n \"up\",\n \"left\",\n \"down\",\n]\n\nconst SYMBOL_CATALOG = symbols as Record<string, SchSymbol | undefined>\nconst SYMBOL_NAMES = Object.keys(SYMBOL_CATALOG)\n\n/**\n * Converts records that have native Circuit JSON semantics before the\n * primitive fallback runs. This deliberately favors Circuit JSON's component,\n * port, trace, net, and symbol model over reproducing Altium's drawing style.\n */\nexport function convertSemanticSchematic(\n document: AltiumSchDoc,\n options: SemanticSchematicOptions,\n): SemanticSchematicConversion {\n const handledRecords = new Set<AltiumRecord>()\n const elements: AnyCircuitElement[] = []\n const convertedPorts: ConvertedPort[] = []\n\n convertComponents({\n convertedPorts,\n document,\n elements,\n handledRecords,\n options,\n })\n\n const semanticNetGraph = buildSemanticNetGraph(document, convertedPorts)\n\n const connectivity = convertConnectivity({\n convertedPorts,\n document,\n elements,\n handledRecords,\n semanticNetGraph,\n options,\n })\n\n convertNetLabels({\n connectivity,\n document,\n elements,\n handledRecords,\n semanticNetGraph,\n options,\n })\n\n return { elements, handledRecords }\n}\n\nfunction convertComponents(params: {\n convertedPorts: ConvertedPort[]\n document: AltiumSchDoc\n elements: AnyCircuitElement[]\n handledRecords: Set<AltiumRecord>\n options: SemanticSchematicOptions\n}): void {\n const { convertedPorts, document, elements, handledRecords, options } = params\n const documentIndex = getSchematicDocumentIndex(document)\n const sourceComponentIdByDesignator = new Map<string, string>()\n\n for (const [componentIndex, componentRecord] of document.records.entries()) {\n if (componentRecord.recordKind !== \"1\") continue\n handledRecords.add(componentRecord)\n\n const ownedRecords = documentIndex.getOwnedRecords(componentRecord)\n for (const ownedRecord of ownedRecords) handledRecords.add(ownedRecord)\n\n const currentPartId = componentRecord.getNumber(\"CURRENTPARTID\") ?? 1\n const visibleOwnedRecords = ownedRecords.filter((record) =>\n isOwnedRecordVisible(record, currentPartId),\n )\n const pins = visibleOwnedRecords.filter(\n (record) =>\n record.recordKind === \"2\" &&\n (!isPinHidden(record) || options.includeHidden === true),\n )\n if (pins.length === 0) continue\n\n const designator =\n findOwnedText(ownedRecords, \"34\", \"Designator\") ??\n componentRecord.getDecoded(\"DESIGNATOR\") ??\n `U${componentIndex}`\n const value =\n findOwnedText(ownedRecords, \"41\", \"Comment\") ??\n componentRecord.getDecoded(\"COMMENT\") ??\n componentRecord.getDecoded(\"DESIGNITEMID\") ??\n componentRecord.getDecoded(\"LIBREFERENCE\") ??\n \"\"\n const libraryReference =\n componentRecord.getDecoded(\"LIBREFERENCE\") ??\n componentRecord.getDecoded(\"DESIGNITEMID\") ??\n designator\n const manufacturerPartNumber = findOwnedText(\n ownedRecords,\n \"41\",\n \"Mfr_part_number\",\n )\n const normalizedDesignator = designator.trim().toUpperCase()\n const existingSourceComponentId =\n sourceComponentIdByDesignator.get(normalizedDesignator)\n const sourceComponentId =\n existingSourceComponentId ?? `source_component_altium_${componentIndex}`\n const schematicComponentId = `schematic_component_altium_${componentIndex}`\n if (!existingSourceComponentId) {\n sourceComponentIdByDesignator.set(normalizedDesignator, sourceComponentId)\n elements.push(\n createSourceComponent({\n designator,\n libraryReference,\n manufacturerPartNumber,\n pinCount: pins.length,\n sourceComponentId,\n value,\n }),\n )\n }\n\n const componentPorts = pins.map((pin, pinIndex) =>\n convertComponentPin({\n document,\n options,\n pin,\n pinIndex,\n schematicComponentId,\n sourceComponentId,\n }),\n )\n const bodyBounds = getComponentBodyBounds(\n visibleOwnedRecords,\n componentPorts.map(({ point }) => point),\n )\n const symbolSelection = selectCircuitJsonSymbol({\n designator,\n libraryReference,\n ports: componentPorts,\n })\n const center = scalePoint(getBoundsCenter(bodyBounds), options.scale)\n const size = symbolSelection\n ? { ...symbolSelection.symbol.size }\n : {\n height: Math.max(\n (bodyBounds.maxY - bodyBounds.minY) * options.scale,\n 0.4,\n ),\n width: Math.max(\n (bodyBounds.maxX - bodyBounds.minX) * options.scale,\n 0.4,\n ),\n }\n if (symbolSelection) {\n applyNativeSymbolPortGeometry({\n center,\n selection: symbolSelection,\n })\n }\n convertedPorts.push(...componentPorts)\n elements.push(\n ...componentPorts.flatMap(\n ({ isSchematicVisible, sourcePort, schematicPort }) => [\n sourcePort,\n ...(isSchematicVisible ? [schematicPort] : []),\n ],\n ),\n )\n const schematicComponent: SchematicComponent = {\n type: \"schematic_component\",\n center,\n // circuit-to-svg uses this flag as the renderable component gate for\n // both generated boxes and components selected by symbol_name.\n is_box_with_pins: true,\n schematic_component_id: schematicComponentId,\n schematic_sheet_id: options.schematicSheetId,\n size,\n source_component_id: sourceComponentId,\n symbol_display_value: value,\n ...(symbolSelection ? { symbol_name: symbolSelection.name } : {}),\n }\n elements.push(schematicComponent)\n\n if (!symbolSelection && options.includeText !== false) {\n elements.push(\n createComponentText({\n anchor: \"bottom_left\",\n component: schematicComponent,\n id: `schematic_component_designator_altium_${componentIndex}`,\n position: {\n x: center.x - size.width / 2,\n y: center.y + size.height / 2 + 0.13,\n },\n text: designator,\n }),\n )\n if (value) {\n elements.push(\n createComponentText({\n anchor: \"top_left\",\n component: schematicComponent,\n id: `schematic_component_value_altium_${componentIndex}`,\n position: {\n x: center.x - size.width / 2,\n y: center.y - size.height / 2 - 0.13,\n },\n text: value,\n }),\n )\n }\n }\n }\n}\n\nfunction convertComponentPin(params: {\n document: AltiumSchDoc\n options: SemanticSchematicOptions\n pin: AltiumRecord\n pinIndex: number\n schematicComponentId: string\n sourceComponentId: string\n}): ConvertedPort {\n const {\n document,\n options,\n pin,\n pinIndex,\n schematicComponentId,\n sourceComponentId,\n } = params\n const recordIndex = document.records.indexOf(pin)\n const pinConglomerate = pin.getNumber(\"PINCONGLOMERATE\")\n const orientation = (pinConglomerate ?? pin.getNumber(\"ORIENTATION\") ?? 0) & 3\n const direction = DIRECTION_BY_ORIENTATION[orientation] ?? \"right\"\n const directionVector = VECTOR_BY_DIRECTION[direction]\n const location = getLocation(pin) ?? { x: 0, y: 0 }\n const pinLength = Math.max(pin.getNumber(\"PINLENGTH\") ?? 10, 0)\n const terminalPoint = {\n x: location.x + directionVector.x * pinLength,\n y: location.y + directionVector.y * pinLength,\n }\n const designator = pin.getDecoded(\"DESIGNATOR\") ?? `${pinIndex + 1}`\n const pinNumber = parsePinNumber(designator)\n const name = pin.getDecoded(\"NAME\") ?? designator\n const sourcePortId = `source_port_altium_${recordIndex}`\n const schematicPortId = `schematic_port_altium_${recordIndex}`\n const sourcePort: SourcePort = {\n type: \"source_port\",\n name,\n port_hints: uniqueStrings([\n designator,\n name,\n pinNumber === undefined ? undefined : `pin${pinNumber}`,\n ]),\n source_component_id: sourceComponentId,\n source_port_id: sourcePortId,\n ...(pinNumber === undefined ? {} : { pin_number: pinNumber }),\n }\n const electricalType = pin.getNumber(\"ELECTRICAL\")\n const schematicPort: SchematicPort = {\n type: \"schematic_port\",\n center: scalePoint(terminalPoint, options.scale),\n display_pin_label: name,\n distance_from_component_edge: pinLength * options.scale,\n facing_direction: direction,\n is_connected: false,\n schematic_component_id: schematicComponentId,\n schematic_port_id: schematicPortId,\n schematic_sheet_id: options.schematicSheetId,\n side_of_component: directionToSide(direction),\n source_port_id: sourcePortId,\n true_ccw_index: pinIndex,\n ...(pinNumber === undefined ? {} : { pin_number: pinNumber }),\n ...(electricalType === 0 || electricalType === 1\n ? { has_input_arrow: true }\n : {}),\n ...(electricalType === 1 || electricalType === 2\n ? { has_output_arrow: true }\n : {}),\n }\n return {\n isSchematicVisible: true,\n point: terminalPoint,\n record: pin,\n schematicPort,\n sourcePort,\n }\n}\n\nfunction createSourceComponent(params: {\n designator: string\n libraryReference: string\n manufacturerPartNumber?: string\n pinCount: number\n sourceComponentId: string\n value: string\n}): AnyCircuitElement {\n const {\n designator,\n libraryReference,\n manufacturerPartNumber,\n pinCount,\n sourceComponentId,\n value,\n } = params\n const classification = classifyComponent({ designator, libraryReference })\n const primaryValue = getPrimaryComponentValue(value)\n const common = {\n type: \"source_component\" as const,\n display_name: designator,\n display_value: value || undefined,\n manufacturer_part_number: manufacturerPartNumber,\n name: designator,\n source_component_id: sourceComponentId,\n }\n\n if (classification === \"resistor\") {\n const parsed = source_simple_resistor.safeParse({\n ...common,\n display_resistance: value || undefined,\n ftype: \"simple_resistor\",\n resistance: primaryValue || 0,\n })\n if (parsed.success) return parsed.data\n }\n if (classification === \"capacitor\") {\n const parsed = source_simple_capacitor.safeParse({\n ...common,\n display_capacitance: value || undefined,\n ftype: \"simple_capacitor\",\n capacitance: primaryValue || 0,\n })\n if (parsed.success) return parsed.data\n }\n if (classification === \"inductor\") {\n const parsed = source_simple_inductor.safeParse({\n ...common,\n display_inductance: value || undefined,\n ftype: \"simple_inductor\",\n inductance: primaryValue || 0,\n })\n if (parsed.success) return parsed.data\n }\n if (classification === \"crystal\" && (pinCount === 2 || pinCount === 4)) {\n const frequency = parseAndConvertSiUnit(value, \"Hz\").value\n if (typeof frequency === \"number\" && Number.isFinite(frequency)) {\n const parsed = source_simple_crystal.safeParse({\n ...common,\n frequency,\n ftype: \"simple_crystal\",\n pin_variant: pinCount === 4 ? \"four_pin\" : \"two_pin\",\n })\n if (parsed.success) return parsed.data\n }\n }\n if (classification === \"mosfet\" && pinCount >= 3) {\n const parsed = source_simple_mosfet.safeParse({\n ...common,\n ...getMosfetVariant(libraryReference),\n ftype: \"simple_mosfet\",\n })\n if (parsed.success) return parsed.data\n }\n\n const ftype:\n | \"simple_chip\"\n | \"simple_diode\"\n | \"simple_led\"\n | \"simple_test_point\" =\n classification === \"diode\"\n ? \"simple_diode\"\n : classification === \"led\"\n ? \"simple_led\"\n : classification === \"testpoint\"\n ? \"simple_test_point\"\n : \"simple_chip\"\n return {\n ...common,\n ftype,\n } satisfies SourceComponentBase\n}\n\nfunction createComponentText(params: {\n anchor: SchematicText[\"anchor\"]\n component: SchematicComponent\n id: string\n position: AltiumPoint\n text: string\n}): SchematicText {\n const { anchor, component, id, position, text } = params\n return {\n type: \"schematic_text\",\n anchor,\n color: \"#006464\",\n font_size: 0.18,\n position,\n rotation: 0,\n schematic_component_id: component.schematic_component_id,\n schematic_sheet_id: component.schematic_sheet_id,\n schematic_text_id: id,\n text,\n }\n}\n\n/**\n * Altium permits labels and pin hot spots to land anywhere on a wire segment,\n * not only on declared polyline vertices. Build the electrical graph with\n * those geometric joins so Circuit JSON source traces carry the real ports and\n * net names. Mid-segment crossings remain disconnected unless one wire has a\n * vertex there or Altium emits an explicit junction record.\n */\nfunction buildSemanticNetGraph(\n document: AltiumSchDoc,\n convertedPorts: ConvertedPort[],\n): SemanticNetGraph {\n const disjointSet = new PointDisjointSet()\n const pointValues = new Map<string, AltiumPoint>()\n const wireRecords = document.records.filter(\n (record) => record.recordKind === \"27\",\n )\n const segments: Array<{ end: AltiumPoint; start: AltiumPoint }> = []\n\n for (const wire of wireRecords) {\n const points = getSchematicRecordPoints(wire)\n for (const point of points) {\n addGraphPoint(disjointSet, pointValues, point)\n }\n for (let index = 1; index < points.length; index++) {\n const start = points[index - 1]\n const end = points[index]\n if (!start || !end) continue\n disjointSet.union(pointKey(start), pointKey(end))\n segments.push({ end, start })\n }\n }\n\n const positionedRecords = document.records.flatMap((record) => {\n if (![\"4\", \"17\", \"18\", \"25\", \"29\"].includes(record.recordKind ?? \"\")) {\n return []\n }\n const point = getLocation(record)\n return point ? [{ point, record }] : []\n })\n const positionedPins = convertedPorts.map(({ point, record }) => ({\n point,\n record,\n }))\n const joinPoints = [\n ...new Map(\n wireRecords\n .flatMap((wire) => getSchematicRecordPoints(wire))\n .map((point) => [pointKey(point), point]),\n ).values(),\n ...positionedRecords.map(({ point }) => point),\n ...positionedPins.map(({ point }) => point),\n ]\n\n for (const point of joinPoints) {\n addGraphPoint(disjointSet, pointValues, point)\n for (const segment of segments) {\n if (isPointOnSegment(point, segment.start, segment.end)) {\n disjointSet.union(pointKey(point), pointKey(segment.start))\n }\n }\n }\n\n interface MutableSemanticNet {\n id: string\n names: Set<string>\n points: Map<string, AltiumPoint>\n records: Set<AltiumRecord>\n }\n const groupedByRoot = new Map<string, MutableSemanticNet>()\n const getGroup = (point: AltiumPoint): MutableSemanticNet => {\n const root = disjointSet.find(pointKey(point))\n const existing = groupedByRoot.get(root)\n if (existing) return existing\n const created: MutableSemanticNet = {\n id: root,\n names: new Set(),\n points: new Map(),\n records: new Set(),\n }\n groupedByRoot.set(root, created)\n return created\n }\n\n for (const point of pointValues.values()) {\n getGroup(point).points.set(pointKey(point), point)\n }\n for (const wire of wireRecords) {\n const firstPoint = getSchematicRecordPoints(wire)[0]\n if (firstPoint) getGroup(firstPoint).records.add(wire)\n }\n for (const { point, record } of [...positionedRecords, ...positionedPins]) {\n const group = getGroup(point)\n group.records.add(record)\n const name = getElectricalRecordName(record)\n if (name) group.names.add(name)\n }\n\n const connectedWiresByRecord = new Map<AltiumRecord, AltiumRecord[]>()\n for (const group of groupedByRoot.values()) {\n const wires = [...group.records].filter(\n (record) => record.recordKind === \"27\",\n )\n for (const record of group.records) {\n connectedWiresByRecord.set(record, wires)\n }\n }\n\n const mergedGroups: MutableSemanticNet[] = []\n for (const group of groupedByRoot.values()) {\n if (group.records.size === 0) continue\n const normalizedNames = new Set(\n [...group.names].map((name) => name.trim().toUpperCase()),\n )\n const matches = mergedGroups.filter((candidate) =>\n [...candidate.names].some((name) =>\n normalizedNames.has(name.trim().toUpperCase()),\n ),\n )\n if (matches.length === 0 || normalizedNames.size === 0) {\n mergedGroups.push(group)\n continue\n }\n const target = matches[0]\n if (!target) continue\n mergeSemanticNetGroup(target, group)\n for (const duplicate of matches.slice(1)) {\n mergeSemanticNetGroup(target, duplicate)\n const duplicateIndex = mergedGroups.indexOf(duplicate)\n if (duplicateIndex >= 0) mergedGroups.splice(duplicateIndex, 1)\n }\n }\n\n const nets: SemanticNet[] = mergedGroups.map((group) => ({\n id: group.id,\n names: [...group.names],\n points: [...group.points.values()],\n records: [...group.records],\n }))\n return {\n getConnectedWiresForRecord: (record) =>\n connectedWiresByRecord.get(record) ?? [],\n nets,\n }\n}\n\nfunction addGraphPoint(\n disjointSet: PointDisjointSet,\n pointValues: Map<string, AltiumPoint>,\n point: AltiumPoint,\n): void {\n const key = pointKey(point)\n disjointSet.add(key)\n pointValues.set(key, point)\n}\n\nfunction getElectricalRecordName(record: AltiumRecord): string | undefined {\n if (record.recordKind === \"18\") return record.getDecoded(\"NAME\")\n if ([\"4\", \"17\", \"25\"].includes(record.recordKind ?? \"\")) {\n return record.getDecoded(\"TEXT\")\n }\n return undefined\n}\n\nfunction mergeSemanticNetGroup(\n target: {\n names: Set<string>\n points: Map<string, AltiumPoint>\n records: Set<AltiumRecord>\n },\n source: {\n names: Set<string>\n points: Map<string, AltiumPoint>\n records: Set<AltiumRecord>\n },\n): void {\n for (const name of source.names) target.names.add(name)\n for (const [key, point] of source.points) target.points.set(key, point)\n for (const record of source.records) target.records.add(record)\n}\n\nfunction isPointOnSegment(\n point: AltiumPoint,\n start: AltiumPoint,\n end: AltiumPoint,\n): boolean {\n const dx = end.x - start.x\n const dy = end.y - start.y\n const cross = (point.x - start.x) * dy - (point.y - start.y) * dx\n const tolerance = 0.000001 * Math.max(Math.abs(dx), Math.abs(dy), 1)\n if (Math.abs(cross) > tolerance) return false\n const dot = (point.x - start.x) * dx + (point.y - start.y) * dy\n if (dot < -tolerance) return false\n const lengthSquared = dx * dx + dy * dy\n return dot <= lengthSquared + tolerance\n}\n\nfunction splitSegmentAtPoints(\n start: AltiumPoint,\n end: AltiumPoint,\n candidates: AltiumPoint[],\n): AltiumPoint[] {\n const dx = end.x - start.x\n const dy = end.y - start.y\n const lengthSquared = dx * dx + dy * dy\n if (lengthSquared === 0) return [start]\n\n const pointsByKey = new Map<string, AltiumPoint>([\n [pointKey(start), start],\n [pointKey(end), end],\n ])\n for (const candidate of candidates) {\n if (isPointOnSegment(candidate, start, end)) {\n pointsByKey.set(pointKey(candidate), candidate)\n }\n }\n return [...pointsByKey.values()].sort((left, right) => {\n const leftDistance = (left.x - start.x) * dx + (left.y - start.y) * dy\n const rightDistance = (right.x - start.x) * dx + (right.y - start.y) * dy\n return leftDistance - rightDistance\n })\n}\n\nclass PointDisjointSet {\n private readonly parent = new Map<string, string>()\n\n add(value: string): void {\n if (!this.parent.has(value)) this.parent.set(value, value)\n }\n\n find(value: string): string {\n this.add(value)\n const parent = this.parent.get(value) ?? value\n if (parent === value) return value\n const root = this.find(parent)\n this.parent.set(value, root)\n return root\n }\n\n union(left: string, right: string): void {\n const leftRoot = this.find(left)\n const rightRoot = this.find(right)\n if (leftRoot !== rightRoot) this.parent.set(rightRoot, leftRoot)\n }\n}\n\ninterface ConnectivityConversion {\n sourceNetIdByRecord: Map<AltiumRecord, string>\n sourceNetIdByName: Map<string, string>\n schematicTraceIdByRecord: Map<AltiumRecord, string>\n}\n\nfunction convertConnectivity(params: {\n convertedPorts: ConvertedPort[]\n document: AltiumSchDoc\n elements: AnyCircuitElement[]\n handledRecords: Set<AltiumRecord>\n options: SemanticSchematicOptions\n semanticNetGraph: SemanticNetGraph\n}): ConnectivityConversion {\n const {\n convertedPorts,\n document,\n elements,\n handledRecords,\n options,\n semanticNetGraph: graph,\n } = params\n const sourceNetIdByName = new Map<string, string>()\n const sourceNetIdByRecord = new Map<AltiumRecord, string>()\n const schematicTraceIdByRecord = new Map<AltiumRecord, string>()\n const portsByPoint = groupByPoint(convertedPorts)\n\n for (const [netIndex, net] of graph.nets.entries()) {\n const wires = net.records.filter((record) => record.recordKind === \"27\")\n const connectedConvertedPorts = uniqueConvertedPorts(\n net.points.flatMap((point) => portsByPoint.get(pointKey(point)) ?? []),\n )\n const connectedPorts = connectedConvertedPorts.map(\n ({ sourcePort }) => sourcePort.source_port_id,\n )\n if (\n wires.length === 0 &&\n !(\n (net.names.length > 0 && connectedPorts.length > 0) ||\n connectedPorts.length > 1\n )\n ) {\n continue\n }\n const sourceNetIds = net.names.map((name) =>\n getOrCreateSourceNet({\n elements,\n name,\n sourceNetIdByName,\n }),\n )\n for (const record of net.records) {\n const firstSourceNetId = sourceNetIds[0]\n if (firstSourceNetId) sourceNetIdByRecord.set(record, firstSourceNetId)\n }\n\n const sourceTraceId = `source_trace_altium_${netIndex}`\n const sourceTrace: SourceTrace = {\n type: \"source_trace\",\n connected_source_net_ids: sourceNetIds,\n connected_source_port_ids: connectedPorts,\n display_name: net.names[0],\n name: net.names[0],\n source_trace_id: sourceTraceId,\n }\n elements.push(sourceTrace)\n\n const netJunctions = document.records\n .filter(\n (record) =>\n record.recordKind === \"29\" &&\n net.points.some((point) => pointsEqual(point, getLocation(record))),\n )\n .flatMap((record) => {\n handledRecords.add(record)\n const location = getLocation(record)\n return location ? [scalePoint(location, options.scale)] : []\n })\n\n for (const wire of wires) handledRecords.add(wire)\n const prunedSegmentKeys = getEquivalentPortPrunedSegmentKeys({\n convertedPorts: connectedConvertedPorts,\n net,\n wires,\n })\n let renderedWireIndex = 0\n for (const wire of wires) {\n const wireRecordIndex = document.records.indexOf(wire)\n const schematicTraceId = `schematic_trace_altium_${wireRecordIndex}`\n const points = getSchematicRecordPoints(wire)\n const edges: SchematicTrace[\"edges\"] = []\n for (let pointIndex = 1; pointIndex < points.length; pointIndex++) {\n const from = points[pointIndex - 1]\n const to = points[pointIndex]\n if (!from || !to) continue\n const segmentPoints = splitSegmentAtPoints(from, to, net.points)\n for (\n let segmentPointIndex = 1;\n segmentPointIndex < segmentPoints.length;\n segmentPointIndex++\n ) {\n const segmentFrom = segmentPoints[segmentPointIndex - 1]\n const segmentTo = segmentPoints[segmentPointIndex]\n if (!segmentFrom || !segmentTo) continue\n if (prunedSegmentKeys.has(segmentKey(segmentFrom, segmentTo))) {\n continue\n }\n const fromPort = portsByPoint\n .get(pointKey(segmentFrom))\n ?.find((port) => port.isSchematicVisible)\n const toPort = portsByPoint\n .get(pointKey(segmentTo))\n ?.find((port) => port.isSchematicVisible)\n const fromPortId = getPortIdAtElectricalPoint(\n fromPort,\n segmentFrom,\n options.scale,\n )\n const toPortId = getPortIdAtElectricalPoint(\n toPort,\n segmentTo,\n options.scale,\n )\n edges.push({\n from: scalePoint(segmentFrom, options.scale),\n to: scalePoint(segmentTo, options.scale),\n ...(fromPortId ? { from_schematic_port_id: fromPortId } : {}),\n ...(toPortId ? { to_schematic_port_id: toPortId } : {}),\n })\n }\n }\n if (edges.length === 0) continue\n schematicTraceIdByRecord.set(wire, schematicTraceId)\n elements.push({\n type: \"schematic_trace\",\n edges,\n junctions: renderedWireIndex === 0 ? netJunctions : [],\n schematic_sheet_id: options.schematicSheetId,\n schematic_trace_id: schematicTraceId,\n source_trace_id: sourceTraceId,\n } satisfies SchematicTrace)\n renderedWireIndex++\n }\n\n for (const convertedPort of connectedConvertedPorts) {\n if (!convertedPort.isSchematicVisible) continue\n const electricalTerminal = scalePoint(convertedPort.point, options.scale)\n if (pointsEqual(convertedPort.schematicPort.center, electricalTerminal)) {\n continue\n }\n const portRecordIndex = document.records.indexOf(convertedPort.record)\n elements.push({\n type: \"schematic_trace\",\n edges: createPortLeadEdges(convertedPort, electricalTerminal),\n junctions: [],\n schematic_sheet_id: options.schematicSheetId,\n schematic_trace_id: `schematic_trace_altium_port_lead_${portRecordIndex}`,\n source_trace_id: sourceTraceId,\n } satisfies SchematicTrace)\n }\n\n const connectedPortIds = new Set(connectedPorts)\n for (const convertedPort of convertedPorts) {\n if (\n convertedPort.isSchematicVisible &&\n connectedPortIds.has(convertedPort.sourcePort.source_port_id)\n ) {\n convertedPort.schematicPort.is_connected = true\n }\n }\n }\n\n return {\n schematicTraceIdByRecord,\n sourceNetIdByName,\n sourceNetIdByRecord,\n }\n}\n\nfunction getEquivalentPortPrunedSegmentKeys(params: {\n convertedPorts: ConvertedPort[]\n net: SemanticNet\n wires: AltiumRecord[]\n}): Set<string> {\n const { convertedPorts, net, wires } = params\n const hiddenPortPoints = convertedPorts\n .filter((port) => !port.isSchematicVisible)\n .map((port) => port.point)\n if (hiddenPortPoints.length === 0) return new Set()\n\n const protectedPointKeys = new Set(\n convertedPorts\n .filter((port) => port.isSchematicVisible)\n .map((port) => pointKey(port.point)),\n )\n for (const record of net.records) {\n if (![\"4\", \"17\", \"18\", \"25\"].includes(record.recordKind ?? \"\")) continue\n const location = getLocation(record)\n if (location) protectedPointKeys.add(pointKey(location))\n }\n\n interface PrunableSegment {\n endKey: string\n key: string\n startKey: string\n }\n const segments = new Map<string, PrunableSegment>()\n const segmentKeysByPoint = new Map<string, Set<string>>()\n const addIncidentSegment = (point: AltiumPoint, key: string): void => {\n const pointSegments = segmentKeysByPoint.get(pointKey(point))\n if (pointSegments) pointSegments.add(key)\n else segmentKeysByPoint.set(pointKey(point), new Set([key]))\n }\n\n for (const wire of wires) {\n const wirePoints = getSchematicRecordPoints(wire)\n for (let pointIndex = 1; pointIndex < wirePoints.length; pointIndex++) {\n const from = wirePoints[pointIndex - 1]\n const to = wirePoints[pointIndex]\n if (!from || !to) continue\n const segmentPoints = splitSegmentAtPoints(from, to, net.points)\n for (\n let splitIndex = 1;\n splitIndex < segmentPoints.length;\n splitIndex++\n ) {\n const segmentFrom = segmentPoints[splitIndex - 1]\n const segmentTo = segmentPoints[splitIndex]\n if (!segmentFrom || !segmentTo) continue\n const key = segmentKey(segmentFrom, segmentTo)\n segments.set(key, {\n endKey: pointKey(segmentTo),\n key,\n startKey: pointKey(segmentFrom),\n })\n addIncidentSegment(segmentFrom, key)\n addIncidentSegment(segmentTo, key)\n }\n }\n }\n\n const removedSegmentKeys = new Set<string>()\n const pendingPointKeys = hiddenPortPoints.map((point) => pointKey(point))\n while (pendingPointKeys.length > 0) {\n const currentPointKey = pendingPointKeys.shift()\n if (!currentPointKey || protectedPointKeys.has(currentPointKey)) continue\n const activeSegmentKeys = [\n ...(segmentKeysByPoint.get(currentPointKey) ?? []),\n ].filter((key) => !removedSegmentKeys.has(key))\n if (activeSegmentKeys.length !== 1) continue\n const segment = segments.get(activeSegmentKeys[0] ?? \"\")\n if (!segment) continue\n removedSegmentKeys.add(segment.key)\n pendingPointKeys.push(\n segment.startKey === currentPointKey ? segment.endKey : segment.startKey,\n )\n }\n return removedSegmentKeys\n}\n\nfunction segmentKey(start: AltiumPoint, end: AltiumPoint): string {\n const startKey = pointKey(start)\n const endKey = pointKey(end)\n return startKey < endKey ? `${startKey}|${endKey}` : `${endKey}|${startKey}`\n}\n\nfunction createPortLeadEdges(\n convertedPort: ConvertedPort,\n electricalTerminal: AltiumPoint,\n): SchematicTrace[\"edges\"] {\n const portCenter = convertedPort.schematicPort.center\n const facingDirection =\n convertedPort.schematicPort.facing_direction ?? \"right\"\n const elbow =\n facingDirection === \"left\" || facingDirection === \"right\"\n ? { x: electricalTerminal.x, y: portCenter.y }\n : { x: portCenter.x, y: electricalTerminal.y }\n const points = [portCenter, elbow, electricalTerminal].filter(\n (point, index, allPoints) =>\n index === 0 || !pointsEqual(point, allPoints[index - 1]),\n )\n\n return points.slice(1).flatMap((to, index) => {\n const from = points[index]\n if (!from) return []\n return [\n {\n from,\n ...(index === 0\n ? {\n from_schematic_port_id:\n convertedPort.schematicPort.schematic_port_id,\n }\n : {}),\n to,\n },\n ]\n })\n}\n\nfunction convertNetLabels(params: {\n connectivity: ConnectivityConversion\n document: AltiumSchDoc\n elements: AnyCircuitElement[]\n handledRecords: Set<AltiumRecord>\n options: SemanticSchematicOptions\n semanticNetGraph: SemanticNetGraph\n}): void {\n const {\n connectivity,\n document,\n elements,\n handledRecords,\n options,\n semanticNetGraph: graph,\n } = params\n\n for (const [recordIndex, record] of document.records.entries()) {\n const recordKind = record.recordKind\n if (!recordKind || ![\"4\", \"17\", \"18\", \"25\"].includes(recordKind)) {\n continue\n }\n if (record.getBoolean(\"ISHIDDEN\") && options.includeHidden !== true) {\n handledRecords.add(record)\n continue\n }\n const name =\n record.recordKind === \"18\"\n ? record.getDecoded(\"NAME\")\n : record.getDecoded(\"TEXT\")\n const location = getLocation(record)\n if (!name || !location) continue\n const wire = graph.getConnectedWiresForRecord(record)[0]\n // Altium's generic label record is also used for page titles and notes.\n // It is only an electrical net label when it touches a wire.\n if (recordKind === \"4\" && !wire) continue\n handledRecords.add(record)\n\n const sourceNetId =\n connectivity.sourceNetIdByRecord.get(record) ??\n getOrCreateSourceNet({\n elements,\n name,\n sourceNetIdByName: connectivity.sourceNetIdByName,\n })\n const schematicTraceId = wire\n ? connectivity.schematicTraceIdByRecord.get(wire)\n : undefined\n const direction = getRecordDirection(record)\n const symbolName =\n record.recordKind === \"17\"\n ? getPowerPortSymbolName(record, direction)\n : undefined\n const schematicNetLabel: SchematicNetLabel = {\n type: \"schematic_net_label\",\n anchor_position: scalePoint(location, options.scale),\n anchor_side:\n record.recordKind === \"18\" || record.recordKind === \"4\"\n ? \"left\"\n : directionToOppositeSide(direction),\n center: scalePoint(location, options.scale),\n schematic_net_label_id: `schematic_net_label_altium_${recordIndex}`,\n schematic_sheet_id: options.schematicSheetId,\n source_net_id: sourceNetId,\n text: name,\n ...(schematicTraceId ? { schematic_trace_id: schematicTraceId } : {}),\n ...(symbolName ? { symbol_name: symbolName } : {}),\n }\n elements.push(schematicNetLabel)\n }\n}\n\nfunction getOrCreateSourceNet(params: {\n elements: AnyCircuitElement[]\n name: string\n sourceNetIdByName: Map<string, string>\n}): string {\n const { elements, name, sourceNetIdByName } = params\n const normalizedName = name.trim().toUpperCase()\n const existing = sourceNetIdByName.get(normalizedName)\n if (existing) return existing\n\n const sourceNetIdBase = `source_net_altium_${sanitizeId(name)}`\n const existingIds = new Set(\n elements.flatMap((element) =>\n element.type === \"source_net\" ? [element.source_net_id] : [],\n ),\n )\n let sourceNetId = sourceNetIdBase\n let suffix = 2\n while (existingIds.has(sourceNetId)) {\n sourceNetId = `${sourceNetIdBase}_${suffix}`\n suffix++\n }\n const sourceNet: SourceNet = {\n type: \"source_net\",\n is_ground: isGroundNet(name),\n is_power: isPowerNet(name),\n member_source_group_ids: [],\n name,\n source_net_id: sourceNetId,\n }\n elements.push(sourceNet)\n sourceNetIdByName.set(normalizedName, sourceNetId)\n return sourceNetId\n}\n\nfunction selectCircuitJsonSymbol(params: {\n designator: string\n libraryReference: string\n ports: ConvertedPort[]\n}): SymbolSelection | undefined {\n const { designator, libraryReference, ports } = params\n const classification = classifyComponent({ designator, libraryReference })\n let baseName: string | undefined\n let candidateNames: string[] = []\n if (classification === \"testpoint\" && ports.length === 1) {\n baseName = \"testpoint\"\n } else if (classification === \"crystal\" && ports.length === 2) {\n baseName = \"crystal\"\n } else if (classification === \"crystal\" && ports.length === 4) {\n baseName = \"crystal_4pin\"\n } else if (\n classification === \"mosfet\" &&\n ports.length >= 3 &&\n hasCompleteMosfetFunctionalGroups(ports)\n ) {\n const { channel_type, mosfet_mode } = getMosfetVariant(libraryReference)\n const channel = channel_type === \"p\" ? \"p\" : \"n\"\n const mode = mosfet_mode === \"depletion\" ? \"d\" : \"e\"\n const prefix = `${channel}_channel_${mode}_mosfet_transistor_gate_`\n candidateNames = SYMBOL_NAMES.filter((name) => name.startsWith(prefix))\n } else if (ports.length !== 2) {\n return undefined\n } else if (classification === \"resistor\") {\n baseName = \"boxresistor\"\n } else if (classification === \"capacitor\") {\n baseName = isPolarizedCapacitor(libraryReference)\n ? \"capacitor_polarized\"\n : \"capacitor\"\n } else if (classification === \"ferrite_bead\") {\n baseName = \"ferrite_bead\"\n } else if (classification === \"inductor\") {\n baseName = \"inductor\"\n } else if (classification === \"led\") {\n baseName = \"led\"\n }\n if (classification === \"diode\") {\n const lower = libraryReference.toLowerCase()\n baseName = lower.includes(\"schottky\") ? \"schottky_diode\" : \"diode\"\n }\n if (baseName) {\n candidateNames = CARDINAL_DIRECTIONS.map(\n (direction) => `${baseName}_${direction}`,\n )\n }\n if (candidateNames.length === 0) return undefined\n\n const selections = candidateNames.flatMap((name) => {\n const symbol = SYMBOL_CATALOG[name]\n const supportsEquivalentMosfetPads =\n classification === \"mosfet\" && symbol?.ports.length === 3\n if (\n !symbol ||\n (!supportsEquivalentMosfetPads && symbol.ports.length !== ports.length)\n ) {\n return []\n }\n const assignments = assignConvertedPortsToSymbolPorts(ports, symbol, {\n allowFunctionalPortReuse: classification === \"mosfet\",\n geometryInterchangeableLabels:\n classification === \"crystal\" && ports.length === 4\n ? new Set([\"2\", \"4\"])\n : undefined,\n })\n return assignments.length === ports.length\n ? [{ assignments, name, symbol } satisfies SymbolSelection]\n : []\n })\n return selections.sort(\n (left, right) =>\n getSymbolDirectionScore(left) - getSymbolDirectionScore(right),\n )[0]\n}\n\nfunction hasCompleteMosfetFunctionalGroups(ports: ConvertedPort[]): boolean {\n const groups = ports.map((port) =>\n normalizeFunctionalPortLabel(port.sourcePort.name),\n )\n return (\n groups.every((group) => group !== undefined) && new Set(groups).size === 3\n )\n}\n\nfunction assignConvertedPortsToSymbolPorts(\n ports: ConvertedPort[],\n symbol: SchSymbol,\n options: {\n allowFunctionalPortReuse?: boolean\n geometryInterchangeableLabels?: Set<string>\n } = {},\n): SymbolPortAssignment[] {\n const unusedSymbolPorts = new Set(symbol.ports)\n const orderedPorts = [...ports].sort(compareConvertedPorts)\n const assignments: SymbolPortAssignment[] = []\n const convertedCenter = getAveragePoint(ports.map(({ point }) => point))\n\n for (const [portIndex, convertedPort] of orderedPorts.entries()) {\n const rawHints = [\n convertedPort.schematicPort.pin_number?.toString(),\n convertedPort.sourcePort.name,\n ...(convertedPort.sourcePort.port_hints ?? []),\n ].filter((hint): hint is string => Boolean(hint))\n const functionalHints = new Set(\n rawHints.flatMap((hint) => {\n const normalized = normalizeFunctionalPortLabel(hint)\n return normalized ? [normalized] : []\n }),\n )\n const functionalPortCandidates = options.allowFunctionalPortReuse\n ? symbol.ports\n : [...unusedSymbolPorts]\n const functionalSymbolPort = functionalPortCandidates.find((symbolPort) =>\n symbolPort.labels.some((label) => {\n const normalized = normalizeFunctionalPortLabel(label)\n return normalized ? functionalHints.has(normalized) : false\n }),\n )\n const exactHints = new Set(rawHints.map((hint) => hint.toLowerCase()))\n const exactSymbolPort = [...unusedSymbolPorts].find((symbolPort) =>\n symbolPort.labels.some((label) => exactHints.has(label.toLowerCase())),\n )\n const interchangeableLabels = options.geometryInterchangeableLabels\n const isGeometryInterchangeable = rawHints.some((hint) =>\n interchangeableLabels?.has(hint.toLowerCase()),\n )\n const geometrySymbolPort = isGeometryInterchangeable\n ? [...unusedSymbolPorts]\n .filter((symbolPort) =>\n symbolPort.labels.some((label) =>\n interchangeableLabels?.has(label.toLowerCase()),\n ),\n )\n .sort(\n (left, right) =>\n getVectorDifference(\n subtractPoints(convertedPort.point, convertedCenter),\n subtractPoints(left, symbol.center),\n ) -\n getVectorDifference(\n subtractPoints(convertedPort.point, convertedCenter),\n subtractPoints(right, symbol.center),\n ),\n )[0]\n : undefined\n const symbolPort =\n functionalSymbolPort ??\n geometrySymbolPort ??\n exactSymbolPort ??\n symbol.ports[portIndex] ??\n [...unusedSymbolPorts][0]\n if (!symbolPort) continue\n if (!functionalSymbolPort || !options.allowFunctionalPortReuse) {\n unusedSymbolPorts.delete(symbolPort)\n }\n assignments.push({ convertedPort, symbolPort })\n }\n return assignments\n}\n\nfunction getAveragePoint(points: AltiumPoint[]): AltiumPoint {\n if (points.length === 0) return { x: 0, y: 0 }\n return {\n x: points.reduce((sum, point) => sum + point.x, 0) / points.length,\n y: points.reduce((sum, point) => sum + point.y, 0) / points.length,\n }\n}\n\nfunction compareConvertedPorts(\n left: ConvertedPort,\n right: ConvertedPort,\n): number {\n const leftPinNumber = left.schematicPort.pin_number\n const rightPinNumber = right.schematicPort.pin_number\n if (leftPinNumber !== undefined && rightPinNumber !== undefined) {\n return leftPinNumber - rightPinNumber\n }\n return (\n (left.schematicPort.true_ccw_index ?? 0) -\n (right.schematicPort.true_ccw_index ?? 0)\n )\n}\n\nfunction getSymbolDirectionScore(selection: SymbolSelection): number {\n const [first, second] = selection.assignments\n if (!first) return Number.POSITIVE_INFINITY\n if (!second) {\n const expectedDirection =\n VECTOR_BY_DIRECTION[\n first.convertedPort.schematicPort.facing_direction ?? \"right\"\n ]\n return getVectorDifference(\n expectedDirection,\n subtractPoints(first.symbolPort, selection.symbol.center),\n )\n }\n let difference = 0\n let comparisonCount = 0\n for (\n let firstIndex = 0;\n firstIndex < selection.assignments.length;\n firstIndex++\n ) {\n for (\n let secondIndex = firstIndex + 1;\n secondIndex < selection.assignments.length;\n secondIndex++\n ) {\n const firstAssignment = selection.assignments[firstIndex]\n const secondAssignment = selection.assignments[secondIndex]\n if (!firstAssignment || !secondAssignment) continue\n const pairDifference = getVectorDifference(\n subtractPoints(\n secondAssignment.convertedPort.point,\n firstAssignment.convertedPort.point,\n ),\n subtractPoints(secondAssignment.symbolPort, firstAssignment.symbolPort),\n )\n if (!Number.isFinite(pairDifference)) continue\n difference += pairDifference\n comparisonCount++\n }\n }\n return comparisonCount > 0\n ? difference / comparisonCount\n : Number.POSITIVE_INFINITY\n}\n\nfunction normalizeFunctionalPortLabel(value: string): string | undefined {\n const normalized = value.toLowerCase().replace(/[^a-z]/gu, \"\")\n if (normalized === \"g\" || normalized === \"gate\") return \"gate\"\n if (normalized === \"d\" || normalized === \"drain\") return \"drain\"\n if (normalized === \"s\" || normalized === \"source\") return \"source\"\n return undefined\n}\n\nfunction getVectorDifference(left: AltiumPoint, right: AltiumPoint): number {\n const leftLength = Math.hypot(left.x, left.y)\n const rightLength = Math.hypot(right.x, right.y)\n if (leftLength === 0 || rightLength === 0) {\n return Number.POSITIVE_INFINITY\n }\n const cosine =\n (left.x * right.x + left.y * right.y) / (leftLength * rightLength)\n return 1 - Math.max(-1, Math.min(1, cosine))\n}\n\nfunction applyNativeSymbolPortGeometry(params: {\n center: AltiumPoint\n selection: SymbolSelection\n}): void {\n const { center, selection } = params\n const assignmentsBySymbolPort = new Map<\n SchSymbol[\"ports\"][number],\n SymbolPortAssignment[]\n >()\n for (const assignment of selection.assignments) {\n const assignments = assignmentsBySymbolPort.get(assignment.symbolPort)\n if (assignments) assignments.push(assignment)\n else assignmentsBySymbolPort.set(assignment.symbolPort, [assignment])\n }\n\n for (const [symbolPort, assignments] of assignmentsBySymbolPort) {\n const offset = subtractPoints(symbolPort, selection.symbol.center)\n const direction = getDirectionForVector(offset)\n const symbolPortCenter = {\n x: center.x + offset.x,\n y: center.y + offset.y,\n }\n const representative = assignments.sort(\n (left, right) =>\n getPointDistance(\n left.convertedPort.schematicPort.center,\n symbolPortCenter,\n ) -\n getPointDistance(\n right.convertedPort.schematicPort.center,\n symbolPortCenter,\n ),\n )[0]\n for (const { convertedPort } of assignments) {\n convertedPort.isSchematicVisible =\n convertedPort === representative?.convertedPort\n convertedPort.schematicPort.center = symbolPortCenter\n convertedPort.schematicPort.distance_from_component_edge = Math.hypot(\n offset.x,\n offset.y,\n )\n convertedPort.schematicPort.facing_direction = direction\n convertedPort.schematicPort.side_of_component = directionToSide(direction)\n }\n }\n}\n\nfunction getPointDistance(left: AltiumPoint, right: AltiumPoint): number {\n return Math.hypot(left.x - right.x, left.y - right.y)\n}\n\nfunction getDirectionForVector(vector: AltiumPoint): CardinalDirection {\n if (Math.abs(vector.x) >= Math.abs(vector.y)) {\n return vector.x >= 0 ? \"right\" : \"left\"\n }\n return vector.y >= 0 ? \"up\" : \"down\"\n}\n\nfunction subtractPoints(\n left: { x: number; y: number },\n right: { x: number; y: number },\n): AltiumPoint {\n return { x: left.x - right.x, y: left.y - right.y }\n}\n\nfunction classifyComponent(params: {\n designator: string\n libraryReference: string\n}):\n | \"capacitor\"\n | \"crystal\"\n | \"diode\"\n | \"ferrite_bead\"\n | \"inductor\"\n | \"led\"\n | \"mosfet\"\n | \"resistor\"\n | \"testpoint\"\n | \"unknown\" {\n const { designator, libraryReference } = params\n const prefix = designator.match(/^[A-Z]+/iu)?.[0]?.toUpperCase() ?? \"\"\n const lowerReference = libraryReference.toLowerCase()\n if (prefix === \"TP\" || lowerReference.includes(\"testpoint\")) {\n return \"testpoint\"\n }\n if (\n prefix === \"Y\" ||\n lowerReference.includes(\"crystal\") ||\n /(?:^|[_-])cry(?:\\d|[_-]|$)/iu.test(libraryReference)\n ) {\n return \"crystal\"\n }\n if (lowerReference.includes(\"mosfet\")) return \"mosfet\"\n if (\n prefix === \"FB\" ||\n prefix === \"FL\" ||\n lowerReference.includes(\"ferrite\") ||\n lowerReference.includes(\"emifilter_ind\")\n ) {\n return \"ferrite_bead\"\n }\n if (prefix === \"LED\" || lowerReference.includes(\"led\")) return \"led\"\n if (prefix === \"R\" || lowerReference.includes(\"resistor\")) return \"resistor\"\n if (prefix === \"C\" || /(?:^|[_-])cap(?:[_-]|$)/iu.test(libraryReference)) {\n return \"capacitor\"\n }\n if (prefix === \"L\" || lowerReference.includes(\"inductor\")) return \"inductor\"\n if (prefix === \"D\" || lowerReference.includes(\"diode\")) return \"diode\"\n return \"unknown\"\n}\n\nfunction getMosfetVariant(libraryReference: string): {\n channel_type: \"n\" | \"p\"\n mosfet_mode: \"depletion\" | \"enhancement\"\n} {\n const lowerReference = libraryReference.toLowerCase()\n const isPChannel =\n /(?:^|[_-])p(?:channel)?(?:[_-]|$)/iu.test(libraryReference) ||\n lowerReference.includes(\"pmos\") ||\n lowerReference.includes(\"csd25\")\n return {\n channel_type: isPChannel ? \"p\" : \"n\",\n mosfet_mode: lowerReference.includes(\"depletion\")\n ? \"depletion\"\n : \"enhancement\",\n }\n}\n\nfunction isPolarizedCapacitor(libraryReference: string): boolean {\n return /(?:^|[_-])cap(?:acitor)?[_-]?pol(?:arized)?(?:[_-]|$)/iu.test(\n libraryReference,\n )\n}\n\nfunction getPrimaryComponentValue(value: string): string {\n return value.split(/[_/\\s]+/u).find(Boolean) ?? value\n}\n\nfunction getPowerPortSymbolName(\n record: AltiumRecord,\n direction: CardinalDirection,\n): string {\n const style = Math.round(record.getNumber(\"STYLE\") ?? 2)\n if (style === 4) return `digital_ground_${direction}`\n if (style === 5) return `ground_${direction}`\n if (style === 6) return `tilted_ground_${direction}`\n return `vcc_${direction}`\n}\n\nfunction getComponentBodyBounds(\n records: AltiumRecord[],\n portPoints: AltiumPoint[],\n): Bounds {\n const rectangles = records\n .filter((record) => record.recordKind === \"14\")\n .flatMap((record) => {\n const rectangle = getRectangle(record)\n return rectangle ? [rectangle] : []\n })\n if (rectangles.length > 0) return mergeBounds(rectangles)\n\n const points: AltiumPoint[] = []\n for (const record of records) {\n if (record.recordKind === \"2\") continue\n const location = getLocation(record)\n const corner = getCorner(record)\n if (location && corner) points.push(location, corner)\n points.push(...getSchematicRecordPoints(record))\n if (record.recordKind === \"8\" && location) {\n const radiusX = Math.abs(record.getNumber(\"RADIUS\") ?? 0)\n const radiusY = Math.abs(record.getNumber(\"SECONDARYRADIUS\") ?? radiusX)\n points.push(\n { x: location.x - radiusX, y: location.y - radiusY },\n { x: location.x + radiusX, y: location.y + radiusY },\n )\n }\n }\n if (points.length > 0) return getBoundsForPoints(points)\n const bounds = getBoundsForPoints(portPoints)\n if (bounds.minX === bounds.maxX) {\n bounds.minX -= 2\n bounds.maxX += 2\n }\n if (bounds.minY === bounds.maxY) {\n bounds.minY -= 2\n bounds.maxY += 2\n }\n return bounds\n}\n\nfunction findOwnedText(\n records: AltiumRecord[],\n recordKind: string,\n name: string,\n): string | undefined {\n return records\n .find(\n (record) =>\n record.recordKind === recordKind &&\n record.getDecoded(\"NAME\")?.toLowerCase() === name.toLowerCase(),\n )\n ?.getDecoded(\"TEXT\")\n}\n\nfunction isOwnedRecordVisible(\n record: AltiumRecord,\n currentPartId: number,\n): boolean {\n const ownerPartId = record.getNumber(\"OWNERPARTID\")\n const ownerPartDisplayMode = record.getNumber(\"OWNERPARTDISPLAYMODE\")\n return (\n (ownerPartId === undefined ||\n ownerPartId <= 0 ||\n ownerPartId === currentPartId) &&\n (ownerPartDisplayMode === undefined || ownerPartDisplayMode === 0)\n )\n}\n\nfunction isPinHidden(pin: AltiumRecord): boolean {\n const pinConglomerate = pin.getNumber(\"PINCONGLOMERATE\")\n return (\n pin.getBoolean(\"ISHIDDEN\") === true ||\n (pinConglomerate !== undefined && (pinConglomerate & 0x04) !== 0)\n )\n}\n\nfunction getRecordDirection(record: AltiumRecord): CardinalDirection {\n const orientation =\n ((Math.round(record.getNumber(\"ORIENTATION\") ?? 0) % 4) + 4) % 4\n return DIRECTION_BY_ORIENTATION[orientation] ?? \"right\"\n}\n\nfunction directionToSide(\n direction: CardinalDirection,\n): NonNullable<SchematicPort[\"side_of_component\"]> {\n if (direction === \"up\") return \"top\"\n if (direction === \"down\") return \"bottom\"\n return direction\n}\n\nfunction directionToOppositeSide(\n direction: CardinalDirection,\n): SchematicNetLabel[\"anchor_side\"] {\n if (direction === \"up\") return \"bottom\"\n if (direction === \"down\") return \"top\"\n return direction === \"left\" ? \"right\" : \"left\"\n}\n\nfunction groupByPoint(ports: ConvertedPort[]): Map<string, ConvertedPort[]> {\n const grouped = new Map<string, ConvertedPort[]>()\n for (const port of ports) {\n const key = pointKey(port.point)\n const existing = grouped.get(key)\n if (existing) existing.push(port)\n else grouped.set(key, [port])\n }\n return grouped\n}\n\nfunction uniqueConvertedPorts(ports: ConvertedPort[]): ConvertedPort[] {\n const seenSourcePortIds = new Set<string>()\n return ports.filter((port) => {\n const sourcePortId = port.sourcePort.source_port_id\n if (seenSourcePortIds.has(sourcePortId)) return false\n seenSourcePortIds.add(sourcePortId)\n return true\n })\n}\n\nfunction getPortIdAtElectricalPoint(\n port: ConvertedPort | undefined,\n electricalPoint: AltiumPoint,\n scale: number,\n): string | undefined {\n if (!port?.isSchematicVisible) return undefined\n return pointsEqual(\n port.schematicPort.center,\n scalePoint(electricalPoint, scale),\n )\n ? port.schematicPort.schematic_port_id\n : undefined\n}\n\nfunction getBoundsForPoints(points: AltiumPoint[]): Bounds {\n if (points.length === 0) return { maxX: 1, maxY: 1, minX: -1, minY: -1 }\n return {\n maxX: Math.max(...points.map((point) => point.x)),\n maxY: Math.max(...points.map((point) => point.y)),\n minX: Math.min(...points.map((point) => point.x)),\n minY: Math.min(...points.map((point) => point.y)),\n }\n}\n\nfunction mergeBounds(bounds: Bounds[]): Bounds {\n return {\n maxX: Math.max(...bounds.map((bound) => bound.maxX)),\n maxY: Math.max(...bounds.map((bound) => bound.maxY)),\n minX: Math.min(...bounds.map((bound) => bound.minX)),\n minY: Math.min(...bounds.map((bound) => bound.minY)),\n }\n}\n\nfunction getBoundsCenter(bounds: Bounds): AltiumPoint {\n return {\n x: (bounds.minX + bounds.maxX) / 2,\n y: (bounds.minY + bounds.maxY) / 2,\n }\n}\n\nfunction getRectangle(record: AltiumRecord): Bounds | undefined {\n const location = getLocation(record)\n const corner = getCorner(record)\n if (!location || !corner) return undefined\n return {\n maxX: Math.max(location.x, corner.x),\n maxY: Math.max(location.y, corner.y),\n minX: Math.min(location.x, corner.x),\n minY: Math.min(location.y, corner.y),\n }\n}\n\nfunction getLocation(record: AltiumRecord): AltiumPoint | undefined {\n const x = getCoordinate(record, \"LOCATION.X\")\n const y = getCoordinate(record, \"LOCATION.Y\")\n return x === undefined || y === undefined ? undefined : { x, y }\n}\n\nfunction getCorner(record: AltiumRecord): AltiumPoint | undefined {\n const x = getCoordinate(record, \"CORNER.X\")\n const y = getCoordinate(record, \"CORNER.Y\")\n return x === undefined || y === undefined ? undefined : { x, y }\n}\n\nfunction getCoordinate(record: AltiumRecord, key: string): number | undefined {\n const raw = record.getCaseInsensitive(key)\n if (raw === undefined) return undefined\n const integer = Number(raw)\n if (!Number.isFinite(integer)) return undefined\n const fractionRaw = record.getCaseInsensitive(`${key}_FRAC`)\n if (fractionRaw === undefined) return integer\n const fraction = Number(`0.${fractionRaw.replace(/^[+-]/u, \"\")}`)\n if (!Number.isFinite(fraction)) return integer\n return integer < 0 ? integer - fraction : integer + fraction\n}\n\nfunction parsePinNumber(value: string): number | undefined {\n const parsed = Number(value)\n return Number.isInteger(parsed) && parsed >= 0 ? parsed : undefined\n}\n\nfunction scalePoint(point: AltiumPoint, scale: number): AltiumPoint {\n return { x: point.x * scale, y: point.y * scale }\n}\n\nfunction pointKey(point: AltiumPoint): string {\n return `${point.x.toFixed(6)},${point.y.toFixed(6)}`\n}\n\nfunction pointsEqual(\n left: AltiumPoint,\n right: AltiumPoint | undefined,\n): boolean {\n return (\n right !== undefined &&\n Math.abs(left.x - right.x) < 0.000001 &&\n Math.abs(left.y - right.y) < 0.000001\n )\n}\n\nfunction uniqueStrings(values: Array<string | undefined>): string[] {\n return [...new Set(values.filter((value): value is string => Boolean(value)))]\n}\n\nfunction sanitizeId(value: string): string {\n const sanitized = value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/gu, \"_\")\n .replace(/^_+|_+$/gu, \"\")\n return sanitized || \"unnamed\"\n}\n\nfunction isGroundNet(name: string): boolean {\n return /(?:^|[_+-])(?:[adp]?gnd|ground)(?:$|[_+\\d-])/iu.test(name)\n}\n\nfunction isPowerNet(name: string): boolean {\n return (\n isGroundNet(name) ||\n /(?:^|[_+-])(?:vcc|vdd|vss)(?:$|[a-z0-9_+-])/iu.test(name) ||\n /(?:^|[_+-])(?:vin|vout|pwr|power)(?:$|[_+\\d-])/iu.test(name)\n )\n}\n","import {\n AltiumBinaryPcbDoc,\n AltiumPcbDoc,\n type AltiumPcbDocument,\n AltiumSchDoc,\n parseAltiumFile,\n parseAltiumPcbDoc,\n parseAltiumSchDoc,\n} from \"altiumts\"\nimport type { AnyCircuitElement } from \"circuit-json\"\nimport {\n type ConvertAltiumPcbDocOptions,\n convertAltiumPcbDocToCircuitJson,\n} from \"./convert-altium-pcb-doc-to-circuit-json\"\nimport {\n type ConvertAltiumSchDocOptions,\n convertAltiumSchDocToCircuitJson,\n} from \"./convert-altium-sch-doc-to-circuit-json\"\n\nexport type AltiumSourceType = \"auto\" | \"pcb\" | \"schematic\"\n\nexport interface ConvertAltiumToCircuitJsonOptions {\n pcb?: ConvertAltiumPcbDocOptions\n schematic?: ConvertAltiumSchDocOptions\n sourceType?: AltiumSourceType\n}\n\nexport type SupportedAltiumDocument = AltiumPcbDocument | AltiumSchDoc\n\nexport function convertAltiumToCircuitJson(\n source: ArrayBuffer | Uint8Array | string,\n options: ConvertAltiumToCircuitJsonOptions = {},\n): AnyCircuitElement[] {\n const sourceType = options.sourceType ?? \"auto\"\n\n if (sourceType === \"pcb\") {\n if (typeof source === \"string\") {\n return convertAltiumPcbDocToCircuitJson(\n parseAltiumPcbDoc(source),\n options.pcb,\n )\n }\n const { document } = parseAltiumFile(toUint8Array(source))\n if (\n !(document instanceof AltiumPcbDoc) &&\n !(document instanceof AltiumBinaryPcbDoc)\n ) {\n throw new TypeError(\n `Expected an Altium PCB document, got ${document.type}`,\n )\n }\n return convertAltiumPcbDocToCircuitJson(document, options.pcb)\n }\n if (sourceType === \"schematic\") {\n return convertAltiumSchDocToCircuitJson(\n parseAltiumSchDoc(normalizeSchematicSource(source)),\n options.schematic,\n )\n }\n\n const bytes = toUint8Array(source)\n const { document } = parseAltiumFile(bytes)\n return convertAltiumDocumentToCircuitJson(document, options)\n}\n\nexport function convertAltiumDocumentToCircuitJson(\n document: unknown,\n options: ConvertAltiumToCircuitJsonOptions = {},\n): AnyCircuitElement[] {\n if (document instanceof AltiumSchDoc) {\n return convertAltiumSchDocToCircuitJson(document, options.schematic)\n }\n if (\n document instanceof AltiumPcbDoc ||\n document instanceof AltiumBinaryPcbDoc\n ) {\n return convertAltiumPcbDocToCircuitJson(document, options.pcb)\n }\n const type =\n typeof document === \"object\" && document !== null && \"type\" in document\n ? String(document.type)\n : typeof document\n throw new TypeError(`Unsupported Altium document type: ${type}`)\n}\n\nfunction toUint8Array(source: ArrayBuffer | Uint8Array | string): Uint8Array {\n if (typeof source === \"string\") return new TextEncoder().encode(source)\n if (source instanceof Uint8Array) return source\n return new Uint8Array(source)\n}\n\nfunction normalizeSchematicSource(\n source: ArrayBuffer | Uint8Array | string,\n): Uint8Array | string {\n return source instanceof ArrayBuffer ? new Uint8Array(source) : source\n}\n"],"mappings":"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","names":["getSchematicRecordPoints","symbolPort","getSchematicRecordPoints","scalePoint","getLocation","getCorner","getRectangle","getCoordinate","document"]}
1
+ {"version":3,"sources":["../lib/convert-altium-pcb-doc-to-circuit-json.ts","../lib/convert-altium-sch-doc-to-circuit-json.ts","../lib/schematic/convert-semantic-schematic.ts","../lib/convert-altium-to-circuit-json.ts"],"sourcesContent":["import {\n AltiumArcRecord,\n AltiumFillRecord,\n AltiumPadRecord,\n type AltiumPcbDocument,\n type AltiumPoint,\n type AltiumRecord,\n AltiumRegionRecord,\n AltiumTextRecord,\n AltiumTrackRecord,\n AltiumViaRecord,\n getAltiumBounds,\n getPcbLayerStack,\n getPcbRegionGeometry,\n parseAltiumMeasurementToMils,\n} from \"altiumts\"\nimport type {\n AnyCircuitElement,\n LayerRef,\n PcbBoard,\n PcbComponent,\n PcbCourtyardOutline,\n PcbCutout,\n PcbHole,\n PcbPlatedHole,\n PcbSilkscreenLine,\n PcbSilkscreenPath,\n PcbSilkscreenRect,\n PcbSilkscreenText,\n PcbSmtPad,\n PcbTrace,\n PcbVia,\n} from \"circuit-json\"\n\nconst MILS_TO_MILLIMETERS = 0.0254\nconst BOARD_ID = \"pcb_board_altium\"\nconst BOARD_GRAPHICS_COMPONENT_ID = \"pcb_component_altium_board_graphics\"\n\nexport interface ConvertAltiumPcbDocOptions {\n includeBoardOutline?: boolean\n includeComponents?: boolean\n includeCourtyards?: boolean\n includePads?: boolean\n includeSilkscreen?: boolean\n includeTraces?: boolean\n includeVias?: boolean\n}\n\nexport function convertAltiumPcbDocToCircuitJson(\n document: AltiumPcbDocument,\n options: ConvertAltiumPcbDocOptions = {},\n): AnyCircuitElement[] {\n const elements: AnyCircuitElement[] = []\n\n if (options.includeBoardOutline !== false) {\n elements.push(createBoard(document))\n for (const [index, cutout] of document.boardGeometry.cutouts.entries()) {\n if (cutout.outline.points.length < 3) continue\n elements.push({\n type: \"pcb_cutout\",\n pcb_cutout_id: `pcb_cutout_altium_${index}`,\n pcb_board_id: BOARD_ID,\n shape: \"polygon\",\n points: cutout.outline.points.map(toMillimeterPoint),\n } satisfies PcbCutout)\n }\n }\n\n if (options.includeComponents !== false) {\n for (const [index, component] of document.components.entries()) {\n const position = component.position\n if (!position) continue\n const bounds = document.getComponentBounds(component)\n elements.push({\n type: \"pcb_component\",\n pcb_component_id: componentId(index),\n source_component_id: `source_component_altium_${index}`,\n center: toMillimeterPoint(position),\n width: milsToMillimeters(\n bounds ? bounds.maxX - bounds.minX : (component.heightMils ?? 20),\n ),\n height: milsToMillimeters(\n bounds ? bounds.maxY - bounds.minY : (component.heightMils ?? 20),\n ),\n layer: component.side === \"bottom\" ? \"bottom\" : \"top\",\n rotation: component.rotation,\n position_mode: \"none\",\n obstructs_within_bounds: false,\n } satisfies PcbComponent)\n }\n }\n\n if (\n options.includeCourtyards !== false &&\n options.includeComponents !== false\n ) {\n elements.push(...convertCourtyards(document))\n }\n\n for (const [index, record] of document.records.entries()) {\n if (record instanceof AltiumPadRecord && options.includePads !== false) {\n const pad = convertPad(record, index)\n if (pad) elements.push(pad)\n continue\n }\n\n if (record instanceof AltiumTrackRecord) {\n if (isCourtyardLayer(record.layer)) continue\n if (isOverlayLayer(record.layer)) {\n if (options.includeSilkscreen === false) continue\n const line = convertSilkscreenLine(record, index)\n if (line) elements.push(line)\n } else if (options.includeTraces !== false) {\n const trace = convertTrack(record, index)\n if (trace) elements.push(trace)\n }\n continue\n }\n\n if (record instanceof AltiumViaRecord && options.includeVias !== false) {\n const via = convertVia(record, index)\n if (via) elements.push(via)\n continue\n }\n\n if (\n options.includeSilkscreen === false ||\n !isOverlayLayer(getLayer(record))\n ) {\n continue\n }\n\n if (record instanceof AltiumArcRecord) {\n const path = convertSilkscreenArc(record, index)\n if (path) elements.push(path)\n } else if (record instanceof AltiumFillRecord) {\n const rect = convertSilkscreenFill(record, index)\n if (rect) elements.push(rect)\n } else if (record instanceof AltiumTextRecord) {\n const text = convertSilkscreenText(record, index)\n if (text) elements.push(text)\n }\n }\n\n return elements\n}\n\ninterface CourtyardPath {\n componentId: string\n layer: \"top\" | \"bottom\"\n points: AltiumPoint[]\n strokeWidthMils: number\n}\n\nfunction convertCourtyards(document: AltiumPcbDocument): PcbCourtyardOutline[] {\n const componentIds = new Map(\n document.components.flatMap((component, index) =>\n component.position ? [[component, componentId(index)] as const] : [],\n ),\n )\n const paths: CourtyardPath[] = []\n\n for (const record of document.records) {\n const layer = getLayer(record)\n if (!isCourtyardLayer(layer)) continue\n const component = document.getComponentForRecord(record)\n const ownedComponentId = component ? componentIds.get(component) : undefined\n if (!ownedComponentId) continue\n const points = getCourtyardRecordPoints(record)\n if (points.length < 2) continue\n paths.push({\n componentId: ownedComponentId,\n layer: mapCourtyardLayer(layer),\n points,\n strokeWidthMils:\n record instanceof AltiumTrackRecord || record instanceof AltiumArcRecord\n ? (record.widthMils ?? 4)\n : 0,\n })\n }\n\n const courtyards: PcbCourtyardOutline[] = []\n for (const path of stitchCourtyardPaths(paths)) {\n if (!isClosedAltiumPath(path.points)) continue\n const outline = removeClosingPoint(path.points).map(toMillimeterPoint)\n if (outline.length < 3) continue\n courtyards.push({\n type: \"pcb_courtyard_outline\",\n pcb_courtyard_outline_id: `pcb_courtyard_outline_altium_${courtyards.length}`,\n pcb_component_id: path.componentId,\n layer: path.layer,\n outline,\n })\n }\n return courtyards\n}\n\nfunction getCourtyardRecordPoints(record: AltiumRecord): AltiumPoint[] {\n if (record instanceof AltiumTrackRecord) {\n return record.start && record.end ? [record.start, record.end] : []\n }\n if (record instanceof AltiumArcRecord) {\n return record.center && record.radiusMils\n ? approximateArc(\n record.center,\n record.radiusMils,\n record.startAngle,\n record.endAngle,\n )\n : []\n }\n if (record instanceof AltiumRegionRecord) {\n return getPcbRegionGeometry(record).outline.points\n }\n return []\n}\n\nfunction stitchCourtyardPaths(paths: CourtyardPath[]): CourtyardPath[] {\n const groups = new Map<string, CourtyardPath[]>()\n for (const path of deduplicateCourtyardPaths(paths)) {\n const key = [\n path.componentId,\n path.layer,\n path.strokeWidthMils.toFixed(4),\n ].join(\"|\")\n const group = groups.get(key) ?? []\n group.push(path)\n groups.set(key, group)\n }\n return [...groups.values()].flatMap(stitchCourtyardPathGroup)\n}\n\nfunction stitchCourtyardPathGroup(group: CourtyardPath[]): CourtyardPath[] {\n const remaining = [...group]\n const stitched: CourtyardPath[] = []\n while (remaining.length > 0) {\n const first = remaining.shift()\n if (!first) break\n const path = { ...first, points: [...first.points] }\n while (appendConnectedCourtyardPath(path, remaining)) {\n // Continue until no segment can extend either end of this path.\n }\n stitched.push(path)\n }\n return stitched\n}\n\nfunction appendConnectedCourtyardPath(\n stitched: CourtyardPath,\n remaining: CourtyardPath[],\n): boolean {\n const stitchedStart = stitched.points[0]\n const stitchedEnd = stitched.points.at(-1)\n if (!stitchedStart || !stitchedEnd) return false\n\n for (const [index, candidate] of remaining.entries()) {\n const candidateStart = candidate.points[0]\n const candidateEnd = candidate.points.at(-1)\n if (!candidateStart || !candidateEnd) continue\n if (altiumPointsApproximatelyEqual(stitchedEnd, candidateStart)) {\n stitched.points.push(...candidate.points.slice(1))\n } else if (altiumPointsApproximatelyEqual(stitchedEnd, candidateEnd)) {\n stitched.points.push(...candidate.points.toReversed().slice(1))\n } else if (altiumPointsApproximatelyEqual(stitchedStart, candidateEnd)) {\n stitched.points.unshift(...candidate.points.slice(0, -1))\n } else if (altiumPointsApproximatelyEqual(stitchedStart, candidateStart)) {\n stitched.points.unshift(...candidate.points.toReversed().slice(0, -1))\n } else {\n continue\n }\n remaining.splice(index, 1)\n return true\n }\n return false\n}\n\nfunction deduplicateCourtyardPaths(paths: CourtyardPath[]): CourtyardPath[] {\n const signatures = new Set<string>()\n return paths.filter((path) => {\n const forwardPoints = path.points.map(formatAltiumPoint).join(\"|\")\n const reversePoints = path.points\n .toReversed()\n .map(formatAltiumPoint)\n .join(\"|\")\n const pointsSignature =\n forwardPoints < reversePoints ? forwardPoints : reversePoints\n const signature = [\n path.componentId,\n path.layer,\n path.strokeWidthMils.toFixed(4),\n pointsSignature,\n ].join(\"|\")\n if (signatures.has(signature)) return false\n signatures.add(signature)\n return true\n })\n}\n\nfunction formatAltiumPoint(point: AltiumPoint): string {\n return `${point.x.toFixed(4)},${point.y.toFixed(4)}`\n}\n\nfunction isClosedAltiumPath(points: AltiumPoint[]): boolean {\n const first = points[0]\n const last = points.at(-1)\n return Boolean(first && last && altiumPointsApproximatelyEqual(first, last))\n}\n\nfunction removeClosingPoint(points: AltiumPoint[]): AltiumPoint[] {\n const first = points[0]\n const last = points.at(-1)\n return first && last && altiumPointsApproximatelyEqual(first, last)\n ? points.slice(0, -1)\n : points\n}\n\nfunction altiumPointsApproximatelyEqual(\n left: AltiumPoint,\n right: AltiumPoint,\n): boolean {\n return (\n Math.abs(left.x - right.x) <= 0.01 && Math.abs(left.y - right.y) <= 0.01\n )\n}\n\nfunction createBoard(document: AltiumPcbDocument): PcbBoard {\n const outline = document.boardGeometry.outline.points.map(toMillimeterPoint)\n const bounds =\n getAltiumBounds(document.boardGeometry.outline.points) ??\n getFallbackPcbBounds(document.records)\n const width = Math.max(milsToMillimeters(bounds.maxX - bounds.minX), 0.1)\n const height = Math.max(milsToMillimeters(bounds.maxY - bounds.minY), 0.1)\n const numLayers = document.board\n ? Math.max(\n getPcbLayerStack(document.board).entries.filter((entry) =>\n Boolean(mapCopperLayer(entry.name ?? entry.layerId)),\n ).length,\n 2,\n )\n : 2\n\n return {\n type: \"pcb_board\",\n pcb_board_id: BOARD_ID,\n center: {\n x: milsToMillimeters((bounds.minX + bounds.maxX) / 2),\n y: milsToMillimeters((bounds.minY + bounds.maxY) / 2),\n },\n width,\n height,\n ...(outline.length >= 3 ? { shape: \"polygon\" as const, outline } : {}),\n thickness: 1.6,\n num_layers: numLayers,\n material: \"fr4\",\n }\n}\n\nfunction getFallbackPcbBounds(records: AltiumRecord[]): {\n maxX: number\n maxY: number\n minX: number\n minY: number\n} {\n const points: AltiumPoint[] = []\n for (const record of records) {\n if (\n record instanceof AltiumPadRecord ||\n record instanceof AltiumViaRecord\n ) {\n if (record.position) points.push(record.position)\n } else if (record instanceof AltiumTrackRecord) {\n if (record.start) points.push(record.start)\n if (record.end) points.push(record.end)\n }\n }\n return getAltiumBounds(points) ?? { minX: 0, minY: 0, maxX: 1000, maxY: 800 }\n}\n\nfunction convertTrack(\n record: AltiumTrackRecord,\n index: number,\n): PcbTrace | undefined {\n const start = record.start\n const end = record.end\n const layer = mapCopperLayer(record.layer)\n if (!start || !end || !layer) return undefined\n const width = milsToMillimeters(record.widthMils ?? 4)\n return {\n type: \"pcb_trace\",\n pcb_trace_id: `pcb_trace_altium_${index}`,\n should_round_corners: true,\n route: [\n { route_type: \"wire\", ...toMillimeterPoint(start), width, layer },\n { route_type: \"wire\", ...toMillimeterPoint(end), width, layer },\n ],\n }\n}\n\nfunction convertVia(\n record: AltiumViaRecord,\n index: number,\n): PcbVia | undefined {\n if (!record.position) return undefined\n const startLayer = mapCopperLayer(record.startLayer) ?? \"top\"\n const endLayer = mapCopperLayer(record.endLayer) ?? \"bottom\"\n const layers = startLayer === endLayer ? [startLayer] : [startLayer, endLayer]\n const outerDiameter = milsToMillimeters(record.diameterMils ?? 20)\n return {\n type: \"pcb_via\",\n pcb_via_id: `pcb_via_altium_${index}`,\n ...toMillimeterPoint(record.position),\n outer_diameter: outerDiameter,\n hole_diameter: milsToMillimeters(\n record.holeSizeMils ?? (record.diameterMils ?? 20) * 0.45,\n ),\n layers,\n is_tented: record.tentedTop === true && record.tentedBottom === true,\n }\n}\n\nfunction convertPad(\n record: AltiumPadRecord,\n index: number,\n): PcbSmtPad | PcbPlatedHole | PcbHole | undefined {\n const position = record.position\n const size = record.size\n if (!position || !size) return undefined\n const x = milsToMillimeters(position.x)\n const y = milsToMillimeters(position.y)\n const width = milsToMillimeters(size.width)\n const height = milsToMillimeters(size.height)\n const holeDiameter = milsToMillimeters(record.holeSizeMils ?? 0)\n const shape = normalizeShape(record.shape)\n const id = `altium_${index}`\n\n if (record.plated === false && holeDiameter > 0) {\n return {\n type: \"pcb_hole\",\n pcb_hole_id: `pcb_hole_${id}`,\n hole_shape: \"circle\",\n hole_diameter: holeDiameter,\n x,\n y,\n }\n }\n\n if (record.behavior === \"through-hole\" || holeDiameter > 0) {\n const slotLengthMils = getMeasurement(record, \"SLOTLENGTH\")\n const holeWidthMils = record.holeWidthMils ?? record.holeSizeMils\n const isSlot =\n normalizeShape(record.holeType).includes(\"SLOT\") ||\n (slotLengthMils ?? 0) > (record.holeSizeMils ?? 0) ||\n (holeWidthMils ?? 0) > (record.holeSizeMils ?? 0)\n const layers: LayerRef[] = [\"top\", \"bottom\"]\n\n if (isSlot) {\n const holeWidth = milsToMillimeters(\n Math.max(\n slotLengthMils ?? holeWidthMils ?? record.holeSizeMils ?? 1,\n 1,\n ),\n )\n const holeHeight = Math.max(holeDiameter, MILS_TO_MILLIMETERS)\n if (isRectangularShape(shape)) {\n const rotated = record.holeRotation !== 0 || record.rotation !== 0\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: rotated\n ? \"rotated_pill_hole_with_rect_pad\"\n : \"pill_hole_with_rect_pad\",\n hole_shape: rotated ? \"rotated_pill\" : \"pill\",\n pad_shape: \"rect\",\n hole_width: holeWidth,\n hole_height: holeHeight,\n ...(rotated ? { hole_ccw_rotation: record.holeRotation } : {}),\n rect_pad_width: width,\n rect_pad_height: height,\n ...(rotated ? { rect_ccw_rotation: record.rotation } : {}),\n hole_offset_x: 0,\n hole_offset_y: 0,\n x,\n y,\n layers,\n } as PcbPlatedHole\n }\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: \"pill\",\n outer_width: width,\n outer_height: height,\n hole_width: holeWidth,\n hole_height: holeHeight,\n ccw_rotation: record.holeRotation || record.rotation,\n x,\n y,\n layers,\n }\n }\n\n if (isRectangularShape(shape)) {\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: \"circular_hole_with_rect_pad\",\n hole_shape: \"circle\",\n pad_shape: \"rect\",\n hole_diameter: Math.max(holeDiameter, MILS_TO_MILLIMETERS),\n rect_pad_width: width,\n rect_pad_height: height,\n rect_border_radius: shape.includes(\"ROUNDRECT\")\n ? Math.min(width, height) * 0.18\n : 0,\n rect_ccw_rotation: record.rotation,\n hole_offset_x: 0,\n hole_offset_y: 0,\n x,\n y,\n layers,\n }\n }\n\n if (shape.includes(\"OCTAGON\")) {\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: \"hole_with_polygon_pad\",\n hole_shape: \"circle\",\n hole_diameter: Math.max(holeDiameter, MILS_TO_MILLIMETERS),\n pad_outline: createOctagonPoints(x, y, width, height, record.rotation),\n hole_offset_x: 0,\n hole_offset_y: 0,\n x,\n y,\n layers,\n }\n }\n\n if (shape === \"ROUND\" || shape === \"CIRCLE\" || shape === \"OVAL\") {\n if (Math.abs(width - height) >= 0.0001) {\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: \"pill\",\n outer_width: width,\n outer_height: height,\n hole_width: Math.max(holeDiameter, MILS_TO_MILLIMETERS),\n hole_height: Math.max(holeDiameter, MILS_TO_MILLIMETERS),\n ccw_rotation: record.rotation,\n x,\n y,\n layers,\n }\n }\n }\n\n return {\n type: \"pcb_plated_hole\",\n pcb_plated_hole_id: `pcb_plated_hole_${id}`,\n shape: \"circle\",\n outer_diameter: Math.max(width, height),\n hole_diameter: Math.max(holeDiameter, MILS_TO_MILLIMETERS),\n x,\n y,\n layers,\n }\n }\n\n const layer = mapCopperLayer(record.layer)\n if (!layer) return undefined\n const base = {\n type: \"pcb_smtpad\" as const,\n pcb_smtpad_id: `pcb_smtpad_${id}`,\n x,\n y,\n layer,\n soldermask_margin:\n record.solderMaskExpansionMils === undefined\n ? undefined\n : milsToMillimeters(record.solderMaskExpansionMils),\n }\n\n if (shape.includes(\"OCTAGON\")) {\n return {\n ...base,\n shape: \"polygon\",\n points: createOctagonPoints(x, y, width, height, record.rotation),\n }\n }\n if (shape === \"ROUND\" || shape === \"CIRCLE\" || shape === \"OVAL\") {\n if (Math.abs(width - height) < 0.0001) {\n return { ...base, shape: \"circle\", radius: width / 2 }\n }\n return record.rotation === 0\n ? {\n ...base,\n shape: \"pill\",\n width,\n height,\n radius: Math.min(width, height) / 2,\n }\n : {\n ...base,\n shape: \"rotated_pill\",\n width,\n height,\n radius: Math.min(width, height) / 2,\n ccw_rotation: record.rotation,\n }\n }\n\n const cornerRadius = shape.includes(\"ROUNDRECT\")\n ? Math.min(width, height) * 0.18\n : undefined\n return record.rotation === 0\n ? { ...base, shape: \"rect\", width, height, corner_radius: cornerRadius }\n : {\n ...base,\n shape: \"rotated_rect\",\n width,\n height,\n corner_radius: cornerRadius,\n ccw_rotation: record.rotation,\n }\n}\n\nfunction convertSilkscreenLine(\n record: AltiumTrackRecord,\n index: number,\n): PcbSilkscreenLine | undefined {\n if (!record.start || !record.end) return undefined\n return {\n type: \"pcb_silkscreen_line\",\n pcb_silkscreen_line_id: `pcb_silkscreen_line_altium_${index}`,\n pcb_component_id: pcbComponentIdForRecord(record),\n stroke_width: milsToMillimeters(record.widthMils ?? 4),\n ...withNumberedPoints(record.start, record.end),\n layer: mapOverlayLayer(record.layer),\n }\n}\n\nfunction convertSilkscreenArc(\n record: AltiumArcRecord,\n index: number,\n): PcbSilkscreenPath | undefined {\n if (!record.center || !record.radiusMils) return undefined\n const points = approximateArc(\n record.center,\n record.radiusMils,\n record.startAngle,\n record.endAngle,\n )\n return {\n type: \"pcb_silkscreen_path\",\n pcb_silkscreen_path_id: `pcb_silkscreen_path_altium_${index}`,\n pcb_component_id: pcbComponentIdForRecord(record),\n route: points.map(toMillimeterPoint),\n stroke_width: milsToMillimeters(record.widthMils ?? 4),\n layer: mapOverlayLayer(record.layer),\n }\n}\n\nfunction convertSilkscreenFill(\n record: AltiumFillRecord,\n index: number,\n): PcbSilkscreenRect | undefined {\n if (!record.bounds) return undefined\n const width = milsToMillimeters(record.bounds.maxX - record.bounds.minX)\n const height = milsToMillimeters(record.bounds.maxY - record.bounds.minY)\n return {\n type: \"pcb_silkscreen_rect\",\n pcb_silkscreen_rect_id: `pcb_silkscreen_rect_altium_${index}`,\n pcb_component_id: pcbComponentIdForRecord(record),\n center: {\n x: milsToMillimeters((record.bounds.minX + record.bounds.maxX) / 2),\n y: milsToMillimeters((record.bounds.minY + record.bounds.maxY) / 2),\n },\n width,\n height,\n stroke_width: Math.min(width, height),\n is_filled: true,\n has_stroke: false,\n ccw_rotation: record.rotation,\n layer: mapOverlayLayer(record.layer),\n }\n}\n\nfunction convertSilkscreenText(\n record: AltiumTextRecord,\n index: number,\n): PcbSilkscreenText | undefined {\n const text =\n decodeAltiumWideString(record.getDecoded(\"WIDESTRING\")) ||\n record.getDecoded(\"TEXT\") ||\n record.text\n if (!record.position || !text) return undefined\n return {\n type: \"pcb_silkscreen_text\",\n pcb_silkscreen_text_id: `pcb_silkscreen_text_altium_${index}`,\n pcb_component_id: pcbComponentIdForRecord(record),\n text,\n font: \"tscircuit2024\",\n font_size: milsToMillimeters(record.heightMils ?? 30),\n anchor_position: toMillimeterPoint(record.position),\n anchor_alignment: mapTextAnchor(record.justification),\n ccw_rotation: record.rotation,\n layer: mapOverlayLayer(record.layer),\n is_mirrored: record.mirrored,\n }\n}\n\nfunction decodeAltiumWideString(raw: string | undefined): string {\n if (!raw) return \"\"\n if (!/^\\d+(?:,\\d+)*$/u.test(raw)) return raw\n try {\n return String.fromCodePoint(...raw.split(\",\").map(Number))\n } catch {\n return raw\n }\n}\n\nfunction pcbComponentIdForRecord(record: AltiumRecord): string {\n const index = record.getNumber(\"COMPONENT\")\n return index === undefined || index < 0\n ? BOARD_GRAPHICS_COMPONENT_ID\n : componentId(index)\n}\n\nfunction componentId(index: number): string {\n return `pcb_component_altium_${index}`\n}\n\nfunction mapTextAnchor(\n justification: string | undefined,\n): \"bottom_left\" | \"bottom_center\" | \"bottom_right\" | \"center\" {\n const normalized = justification?.replace(/[\\s_-]+/gu, \"\").toUpperCase()\n if (normalized?.includes(\"CENTER\")) return \"bottom_center\"\n if (normalized?.includes(\"RIGHT\")) return \"bottom_right\"\n if (normalized?.includes(\"LEFT\")) return \"bottom_left\"\n return \"center\"\n}\n\nfunction mapCopperLayer(layer: string | undefined): LayerRef | undefined {\n const normalized = normalizeLayer(layer)\n if (normalized === \"TOP\" || normalized === \"TOPLAYER\") return \"top\"\n if (normalized === \"BOTTOM\" || normalized === \"BOTTOMLAYER\") return \"bottom\"\n const innerMatch = /^(?:MID|MIDLAYER|INTERNALPLANE)(\\d+)$/u.exec(normalized)\n if (!innerMatch?.[1]) return undefined\n const innerNumber = Math.min(Math.max(Number(innerMatch[1]), 1), 8)\n return `inner${innerNumber}` as LayerRef\n}\n\nfunction isOverlayLayer(layer: string | undefined): boolean {\n const normalized = normalizeLayer(layer)\n return normalized === \"TOPOVERLAY\" || normalized === \"BOTTOMOVERLAY\"\n}\n\nfunction isCourtyardLayer(layer: string | undefined): boolean {\n const normalized = normalizeLayer(layer)\n return normalized === \"MECHANICAL15\" || normalized === \"MECHANICAL16\"\n}\n\nfunction mapCourtyardLayer(layer: string | undefined): \"top\" | \"bottom\" {\n return normalizeLayer(layer) === \"MECHANICAL16\" ? \"bottom\" : \"top\"\n}\n\nfunction mapOverlayLayer(layer: string | undefined): \"top\" | \"bottom\" {\n return normalizeLayer(layer) === \"BOTTOMOVERLAY\" ? \"bottom\" : \"top\"\n}\n\nfunction getLayer(record: AltiumRecord): string | undefined {\n return record.getDecoded(\"LAYER\")\n}\n\nfunction normalizeLayer(layer: string | undefined): string {\n return (layer ?? \"\").replace(/[\\s_.-]+/gu, \"\").toUpperCase()\n}\n\nfunction normalizeShape(shape: string | undefined): string {\n return (shape ?? \"ROUND\").replace(/[\\s_-]+/gu, \"\").toUpperCase()\n}\n\nfunction isRectangularShape(shape: string): boolean {\n return shape.includes(\"RECT\") || shape === \"SQUARE\"\n}\n\nfunction getMeasurement(record: AltiumRecord, key: string): number | undefined {\n return parseAltiumMeasurementToMils(record.getCaseInsensitive(key))\n}\n\nfunction milsToMillimeters(value: number): number {\n return value * MILS_TO_MILLIMETERS\n}\n\nfunction toMillimeterPoint(point: AltiumPoint): { x: number; y: number } {\n return { x: milsToMillimeters(point.x), y: milsToMillimeters(point.y) }\n}\n\nfunction withNumberedPoints(\n start: AltiumPoint,\n end: AltiumPoint,\n): { x1: number; x2: number; y1: number; y2: number } {\n return {\n x1: milsToMillimeters(start.x),\n y1: milsToMillimeters(start.y),\n x2: milsToMillimeters(end.x),\n y2: milsToMillimeters(end.y),\n }\n}\n\nfunction approximateArc(\n center: AltiumPoint,\n radius: number,\n startAngle: number,\n endAngle: number,\n): AltiumPoint[] {\n const sweep = endAngle - startAngle || 360\n const segments = Math.max(8, Math.ceil(Math.abs(sweep) / 7.5))\n return Array.from({ length: segments + 1 }, (_, index) => {\n const angle = startAngle + (sweep * index) / segments\n const radians = (angle * Math.PI) / 180\n return {\n x: center.x + Math.cos(radians) * radius,\n y: center.y + Math.sin(radians) * radius,\n }\n })\n}\n\nfunction createOctagonPoints(\n x: number,\n y: number,\n width: number,\n height: number,\n rotation: number,\n): Array<{ x: number; y: number }> {\n const halfWidth = width / 2\n const halfHeight = height / 2\n const chamfer = Math.min(width, height) / 4\n const points = [\n { x: -halfWidth + chamfer, y: -halfHeight },\n { x: halfWidth - chamfer, y: -halfHeight },\n { x: halfWidth, y: -halfHeight + chamfer },\n { x: halfWidth, y: halfHeight - chamfer },\n { x: halfWidth - chamfer, y: halfHeight },\n { x: -halfWidth + chamfer, y: halfHeight },\n { x: -halfWidth, y: halfHeight - chamfer },\n { x: -halfWidth, y: -halfHeight + chamfer },\n ]\n const radians = (rotation * Math.PI) / 180\n return points.map((point) => ({\n x: x + point.x * Math.cos(radians) - point.y * Math.sin(radians),\n y: y + point.x * Math.sin(radians) + point.y * Math.cos(radians),\n }))\n}\n","import {\n type AltiumPoint,\n type AltiumRecord,\n type AltiumSchDoc,\n getSchematicRecordPoints,\n} from \"altiumts\"\nimport type {\n AnyCircuitElement,\n Point,\n SchematicArc,\n SchematicCircle,\n SchematicGroup,\n SchematicLine,\n SchematicPath,\n SchematicRect,\n SchematicSheet,\n SchematicText,\n SchematicTrace,\n} from \"circuit-json\"\nimport { convertSemanticSchematic } from \"./schematic/convert-semantic-schematic\"\n\nconst SCHEMATIC_SHEET_ID = \"schematic_sheet_altium\"\n// circuit-to-svg renders schematic_sheet as a centered A4 page. Keep imported\n// coordinates inside the same 5 mm inset used by that renderer.\nconst SCHEMATIC_UNIT_TO_MILLIMETERS = 10.16 / 1.1\nconst SCHEMATIC_SHEET_INSET = 5 / SCHEMATIC_UNIT_TO_MILLIMETERS\nconst SCHEMATIC_SHEET_WIDTH = 297 / SCHEMATIC_UNIT_TO_MILLIMETERS\nconst SCHEMATIC_SHEET_HEIGHT = 210 / SCHEMATIC_UNIT_TO_MILLIMETERS\nconst SCHEMATIC_SHEET_INNER_WIDTH =\n SCHEMATIC_SHEET_WIDTH - SCHEMATIC_SHEET_INSET * 2\nconst SCHEMATIC_SHEET_INNER_HEIGHT =\n SCHEMATIC_SHEET_HEIGHT - SCHEMATIC_SHEET_INSET * 2\n\nexport interface ConvertAltiumSchDocOptions {\n centerOnSchematicSheet?: boolean\n includeHidden?: boolean\n includeSheetBorder?: boolean\n includeText?: boolean\n schematicUnitScale?: number\n sheetName?: string\n}\n\ninterface SchematicContext {\n document: AltiumSchDoc\n records: AltiumRecord[]\n scale: number\n sheetRecord?: AltiumRecord\n}\n\nexport function convertAltiumSchDocToCircuitJson(\n document: AltiumSchDoc,\n options: ConvertAltiumSchDocOptions = {},\n): AnyCircuitElement[] {\n const records = document.records\n const sheetRecord = records.find((record) => record.recordKind === \"31\")\n const sheetDimensions = getAltiumSheetDimensions(sheetRecord)\n const scale = options.schematicUnitScale ?? getPageFitScale(sheetDimensions)\n if (!Number.isFinite(scale) || scale <= 0) {\n throw new RangeError(\"schematicUnitScale must be a positive finite number\")\n }\n\n const context: SchematicContext = { document, records, scale, sheetRecord }\n const elements: AnyCircuitElement[] = [\n {\n type: \"schematic_sheet\",\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n name: options.sheetName ?? \"Altium schematic\",\n outline_color: \"#334155\",\n sheet_index: 0,\n } satisfies SchematicSheet,\n ]\n\n if (options.includeSheetBorder === true) {\n elements.push(createSheetBorder(sheetRecord, scale))\n }\n\n const semanticConversion = convertSemanticSchematic(document, {\n includeHidden: options.includeHidden,\n includeText: options.includeText,\n scale,\n schematicSheetId: SCHEMATIC_SHEET_ID,\n })\n elements.push(...semanticConversion.elements)\n\n for (const [index, record] of records.entries()) {\n if (semanticConversion.handledRecords.has(record)) continue\n if (!shouldRenderSchematicRecord(record, context)) continue\n const converted = convertSchematicRecord(record, index, context, options)\n elements.push(...converted)\n }\n\n const schematicComponentIds = elements\n .filter(\n (\n element,\n ): element is Extract<\n AnyCircuitElement,\n { type: \"schematic_component\" }\n > => element.type === \"schematic_component\",\n )\n .map((element) => element.schematic_component_id)\n if (schematicComponentIds.length > 0) {\n elements.push({\n type: \"schematic_group\",\n schematic_group_id: \"schematic_group_altium\",\n source_group_id: \"source_group_altium\",\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: {\n x: (sheetDimensions.width * scale) / 2,\n y: (sheetDimensions.height * scale) / 2,\n },\n width: sheetDimensions.width * scale,\n height: sheetDimensions.height * scale,\n schematic_component_ids: schematicComponentIds,\n name: options.sheetName ?? \"Altium schematic\",\n } satisfies SchematicGroup)\n }\n\n if (options.centerOnSchematicSheet === false) return elements\n\n const offset = {\n x: (-sheetDimensions.width * scale) / 2,\n y: (-sheetDimensions.height * scale) / 2,\n }\n return elements.map((element) => translateSchematicElement(element, offset))\n}\n\ninterface SheetDimensions {\n height: number\n width: number\n}\n\nfunction getAltiumSheetDimensions(\n sheetRecord: AltiumRecord | undefined,\n): SheetDimensions {\n return {\n width: getPositiveNumber(sheetRecord?.getCaseInsensitive(\"CUSTOMX\"), 1000),\n height: getPositiveNumber(sheetRecord?.getCaseInsensitive(\"CUSTOMY\"), 800),\n }\n}\n\nfunction getPositiveNumber(value: unknown, fallback: number): number {\n const parsed = Number(value)\n return Number.isFinite(parsed) && parsed > 0 ? parsed : fallback\n}\n\nfunction getPageFitScale(sheetDimensions: SheetDimensions): number {\n return Math.min(\n SCHEMATIC_SHEET_INNER_WIDTH / sheetDimensions.width,\n SCHEMATIC_SHEET_INNER_HEIGHT / sheetDimensions.height,\n )\n}\n\nfunction translatePoint(point: Point, offset: Point): Point {\n return { x: point.x + offset.x, y: point.y + offset.y }\n}\n\nfunction translateSchematicElement(\n element: AnyCircuitElement,\n offset: Point,\n): AnyCircuitElement {\n switch (element.type) {\n case \"schematic_component\":\n case \"schematic_port\":\n case \"schematic_rect\":\n case \"schematic_circle\":\n case \"schematic_arc\":\n return { ...element, center: translatePoint(element.center, offset) }\n case \"schematic_net_label\":\n return {\n ...element,\n center: translatePoint(element.center, offset),\n ...(element.anchor_position\n ? {\n anchor_position: translatePoint(element.anchor_position, offset),\n }\n : {}),\n }\n case \"schematic_text\":\n return { ...element, position: translatePoint(element.position, offset) }\n case \"schematic_path\":\n return {\n ...element,\n points: element.points.map((point) => translatePoint(point, offset)),\n }\n case \"schematic_line\":\n return {\n ...element,\n x1: element.x1 + offset.x,\n x2: element.x2 + offset.x,\n y1: element.y1 + offset.y,\n y2: element.y2 + offset.y,\n }\n case \"schematic_trace\":\n return {\n ...element,\n edges: element.edges.map((edge) => ({\n ...edge,\n from: translatePoint(edge.from, offset),\n to: translatePoint(edge.to, offset),\n })),\n junctions: element.junctions.map((junction) =>\n translatePoint(junction, offset),\n ),\n }\n default:\n return element\n }\n}\n\nfunction convertSchematicRecord(\n record: AltiumRecord,\n index: number,\n context: SchematicContext,\n options: ConvertAltiumSchDocOptions,\n): AnyCircuitElement[] {\n const kind = record.recordKind\n const scale = context.scale\n const color = altiumColorToCss(record.getCaseInsensitive(\"COLOR\"), \"#1f2937\")\n const strokeWidth = Math.max(\n Number(record.getCaseInsensitive(\"LINEWIDTH\") ?? 1) * scale,\n 0.05,\n )\n\n if (kind === \"27\") {\n const points = getSchematicRecordPoints(record).map((point) =>\n scalePoint(point, scale),\n )\n if (points.length < 2) return []\n return [\n {\n type: \"schematic_trace\",\n schematic_trace_id: `schematic_trace_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n junctions: [],\n edges: points.slice(1).map((point, pointIndex) => ({\n from: points[pointIndex] ?? point,\n to: point,\n })),\n } satisfies SchematicTrace,\n ]\n }\n\n if (kind === \"6\" || kind === \"7\") {\n const points = getSchematicRecordPoints(record).map((point) =>\n scalePoint(point, scale),\n )\n if (points.length < 2) return []\n return [\n {\n type: \"schematic_path\",\n schematic_path_id: `schematic_path_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n points,\n stroke_width: strokeWidth,\n stroke_color: color,\n fill_color:\n kind === \"7\"\n ? altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"transparent\",\n )\n : undefined,\n is_filled: kind === \"7\",\n is_dashed: false,\n } satisfies SchematicPath,\n ]\n }\n\n if (kind === \"13\") {\n const location = getLocation(record)\n const corner = getCorner(record)\n if (!location || !corner) return []\n return [createLine(index, location, corner, color, strokeWidth, scale)]\n }\n\n if (kind === \"10\" || kind === \"14\") {\n const rectangle = getRectangle(record)\n if (!rectangle) return []\n return [\n {\n type: \"schematic_rect\",\n schematic_rect_id: `schematic_rect_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: scalePoint(\n {\n x: (rectangle.minX + rectangle.maxX) / 2,\n y: (rectangle.minY + rectangle.maxY) / 2,\n },\n scale,\n ),\n width: (rectangle.maxX - rectangle.minX) * scale,\n height: (rectangle.maxY - rectangle.minY) * scale,\n rotation: 0,\n stroke_width: strokeWidth,\n color,\n is_filled: record.getBoolean(\"ISSOLID\") === true,\n fill_color: altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"#ffffff\",\n ),\n is_dashed: false,\n } satisfies SchematicRect,\n ]\n }\n\n if (kind === \"8\") {\n const center = getLocation(record)\n if (!center) return []\n const radiusX = getCoordinate(record, \"RADIUS\", 1)\n const radiusY = getCoordinate(record, \"SECONDARYRADIUS\", radiusX)\n if (Math.abs(radiusX - radiusY) < 0.0001) {\n return [\n {\n type: \"schematic_circle\",\n schematic_circle_id: `schematic_circle_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: scalePoint(center, scale),\n radius: radiusX * scale,\n stroke_width: strokeWidth,\n color,\n is_filled: record.getBoolean(\"ISSOLID\") === true,\n fill_color: altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"#ffffff\",\n ),\n is_dashed: false,\n } satisfies SchematicCircle,\n ]\n }\n return [\n {\n type: \"schematic_path\",\n schematic_path_id: `schematic_ellipse_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n points: approximateEllipse(center, radiusX, radiusY).map((point) =>\n scalePoint(point, scale),\n ),\n stroke_width: strokeWidth,\n stroke_color: color,\n fill_color: altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"#ffffff\",\n ),\n is_filled: record.getBoolean(\"ISSOLID\") === true,\n is_dashed: false,\n } satisfies SchematicPath,\n ]\n }\n\n if (kind === \"11\" || kind === \"12\") {\n const center = getLocation(record)\n if (!center) return []\n return [\n {\n type: \"schematic_arc\",\n schematic_arc_id: `schematic_arc_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: scalePoint(center, scale),\n radius: getCoordinate(record, \"RADIUS\", 1) * scale,\n start_angle_degrees: Number(\n record.getCaseInsensitive(\"STARTANGLE\") ?? 0,\n ),\n end_angle_degrees: Number(record.getCaseInsensitive(\"ENDANGLE\") ?? 360),\n direction: \"counterclockwise\",\n stroke_width: strokeWidth,\n color,\n is_dashed: false,\n } satisfies SchematicArc,\n ]\n }\n\n if (kind === \"2\") {\n return convertPin(record, index, context, options, color)\n }\n\n if (kind === \"29\") {\n const location = getLocation(record)\n if (!location) return []\n return [\n {\n type: \"schematic_circle\",\n schematic_circle_id: `schematic_junction_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: scalePoint(location, scale),\n radius: Math.max(\n Number(record.getCaseInsensitive(\"SIZE\") ?? 1) * 0.18,\n 0.15,\n ),\n color,\n is_filled: true,\n fill_color: color,\n is_dashed: false,\n } satisfies SchematicCircle,\n ]\n }\n\n if (kind === \"22\") {\n const location = getLocation(record)\n if (!location) return []\n // altiumts renders the \"Small Cross\" no-ERC symbol with four Altium\n // coordinate units on either side of its anchor.\n const radius = 4\n const noErcStrokeWidth = Math.max(scale, 0.02)\n return [\n createLine(\n index,\n { x: location.x - radius, y: location.y - radius },\n { x: location.x + radius, y: location.y + radius },\n color,\n noErcStrokeWidth,\n scale,\n \"a\",\n ),\n createLine(\n index,\n { x: location.x + radius, y: location.y - radius },\n { x: location.x - radius, y: location.y + radius },\n color,\n noErcStrokeWidth,\n scale,\n \"b\",\n ),\n ]\n }\n\n if (kind === \"17\") {\n return convertPowerPort(record, index, context, options, color)\n }\n\n if (kind === \"18\") {\n return convertPort(record, index, context, options, color)\n }\n\n if (kind === \"4\" || kind === \"25\" || kind === \"34\" || kind === \"41\") {\n if (options.includeText === false) return []\n if (record.getBoolean(\"ISHIDDEN\") && !options.includeHidden) return []\n const text =\n record.getDecoded(\"TEXT\") ??\n record.getDecoded(\"NAME\") ??\n record.getDecoded(\"DESIGNATOR\")\n const location = getLocation(record)\n if (!text || !location) return []\n return [createText(record, index, text, location, color, context)]\n }\n\n if (kind === \"28\") {\n const rectangle = getRectangle(record)\n const text = decodeMultilineText(record.getDecoded(\"TEXT\") ?? \"\")\n if (!rectangle || !text || options.includeText === false) return []\n const fontSize = getFontSize(record, context)\n const fontFamily = getFontFamily(record, context)\n const margin = Math.max(getCoordinate(record, \"TEXTMARGIN\", 0), 0)\n const frameWidth = rectangle.maxX - rectangle.minX\n const frameHeight = rectangle.maxY - rectangle.minY\n const availableWidth = Math.max(frameWidth - margin * 2, fontSize)\n const availableHeight = Math.max(frameHeight - margin * 2, fontSize)\n const wrappedLines =\n record.getBoolean(\"WORDWRAP\") === false\n ? text.split(\"\\n\")\n : wrapSchematicText(text, availableWidth, fontSize, fontFamily)\n const lineHeight = fontSize\n const visibleLines =\n record.getBoolean(\"CLIPTORECT\") === false\n ? wrappedLines\n : wrappedLines.slice(\n 0,\n Math.max(Math.ceil(availableHeight / lineHeight), 1),\n )\n const alignment = Number(record.getCaseInsensitive(\"ALIGNMENT\") ?? 1)\n const horizontalAnchor =\n alignment === 2 ? \"center\" : alignment === 3 ? \"right\" : \"left\"\n const textX =\n horizontalAnchor === \"center\"\n ? (rectangle.minX + rectangle.maxX) / 2\n : horizontalAnchor === \"right\"\n ? rectangle.maxX - margin\n : rectangle.minX + margin\n const textColor = altiumColorToCss(\n record.getCaseInsensitive(\"TEXTCOLOR\") ??\n record.getCaseInsensitive(\"COLOR\"),\n \"#1f2937\",\n )\n const elements: AnyCircuitElement[] = visibleLines.map((line, lineIndex) =>\n createDirectText(\n `schematic_text_frame_line_altium_${index}_${lineIndex}`,\n line,\n {\n x: textX,\n y: rectangle.maxY - margin - lineIndex * lineHeight,\n },\n fontSize,\n textColor,\n scale,\n 0,\n `top_${horizontalAnchor}` as SchematicText[\"anchor\"],\n ),\n )\n\n const isSolid = record.getBoolean(\"ISSOLID\") === true\n const showBorder = record.getBoolean(\"SHOWBORDER\") === true\n if (isSolid || showBorder) {\n elements.unshift({\n type: \"schematic_rect\",\n schematic_rect_id: `schematic_text_frame_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: scalePoint(\n {\n x: (rectangle.minX + rectangle.maxX) / 2,\n y: (rectangle.minY + rectangle.maxY) / 2,\n },\n scale,\n ),\n width: frameWidth * scale,\n height: frameHeight * scale,\n rotation: 0,\n stroke_width: showBorder ? strokeWidth : 0,\n color: showBorder ? color : \"transparent\",\n is_filled: isSolid,\n fill_color: altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"#ffffff\",\n ),\n is_dashed: false,\n } satisfies SchematicRect)\n }\n\n return elements\n }\n\n return []\n}\n\nfunction convertPin(\n record: AltiumRecord,\n index: number,\n context: SchematicContext,\n options: ConvertAltiumSchDocOptions,\n color: string,\n): AnyCircuitElement[] {\n const location = getLocation(record)\n if (!location) return []\n const pinConglomerate = record.getNumber(\"PINCONGLOMERATE\")\n const hidden =\n record.getBoolean(\"ISHIDDEN\") ||\n (pinConglomerate !== undefined && (pinConglomerate & 0x04) !== 0)\n if (hidden && !options.includeHidden) return []\n const orientation =\n (pinConglomerate ?? Number(record.getCaseInsensitive(\"ORIENTATION\") ?? 0)) &\n 3\n const direction = [\n { x: 1, y: 0 },\n { x: 0, y: 1 },\n { x: -1, y: 0 },\n { x: 0, y: -1 },\n ][orientation] ?? { x: 1, y: 0 }\n const length = Math.max(\n Number(record.getCaseInsensitive(\"PINLENGTH\") ?? 10),\n 1,\n )\n const end = {\n x: location.x + direction.x * length,\n y: location.y + direction.y * length,\n }\n const elements: AnyCircuitElement[] = [\n createLine(index, location, end, color, 0.1, context.scale, \"pin\"),\n ]\n if (options.includeText === false) return elements\n\n const name = record.getDecoded(\"NAME\") ?? \"\"\n const designator = record.getDecoded(\"DESIGNATOR\") ?? \"\"\n const showName =\n pinConglomerate === undefined || (pinConglomerate & 0x08) !== 0\n const showDesignator =\n pinConglomerate === undefined || (pinConglomerate & 0x10) !== 0\n const rotation = orientation === 1 || orientation === 3 ? 90 : 0\n const directionMatchesText = orientation === 0 || orientation === 1\n const nameAnchor = directionMatchesText ? \"right\" : \"left\"\n const designatorAnchor = directionMatchesText ? \"left\" : \"right\"\n const textOffset = 2\n\n if (showName && name) {\n elements.push(\n createDirectText(\n `schematic_pin_name_altium_${index}`,\n name,\n {\n x: location.x - direction.x * textOffset,\n y: location.y - direction.y * textOffset,\n },\n 6,\n color,\n context.scale,\n rotation,\n nameAnchor,\n ),\n )\n }\n if (showDesignator && designator) {\n elements.push(\n createDirectText(\n `schematic_pin_designator_altium_${index}`,\n designator,\n {\n x: location.x + direction.x * textOffset,\n y: location.y + direction.y * textOffset,\n },\n 6,\n color,\n context.scale,\n rotation,\n designatorAnchor,\n ),\n )\n }\n return elements\n}\n\nfunction convertPowerPort(\n record: AltiumRecord,\n index: number,\n context: SchematicContext,\n options: ConvertAltiumSchDocOptions,\n color: string,\n): AnyCircuitElement[] {\n const location = getLocation(record)\n if (!location) return []\n const orientation =\n ((Math.round(record.getNumber(\"ORIENTATION\") ?? 0) % 4) + 4) % 4\n const direction = [\n { x: 1, y: 0 },\n { x: 0, y: 1 },\n { x: -1, y: 0 },\n { x: 0, y: -1 },\n ][orientation] ?? { x: 1, y: 0 }\n const perpendicular = { x: -direction.y, y: direction.x }\n const point = (along: number, across = 0): AltiumPoint => ({\n x: location.x + direction.x * along + perpendicular.x * across,\n y: location.y + direction.y * along + perpendicular.y * across,\n })\n const style = Math.round(Number(record.getCaseInsensitive(\"STYLE\") ?? 2))\n const elements: AnyCircuitElement[] = []\n let labelDistance: number\n\n if (style === 2) {\n elements.push(\n createLine(\n index,\n location,\n point(8),\n color,\n 0.1,\n context.scale,\n \"power_port_stem\",\n ),\n createLine(\n index,\n point(8, -5),\n point(8, 5),\n color,\n 0.1,\n context.scale,\n \"power_port_bar\",\n ),\n )\n labelDistance = 12\n } else if (style === 5) {\n elements.push(\n createLine(\n index,\n location,\n point(4),\n color,\n 0.1,\n context.scale,\n \"power_port_stem\",\n ),\n {\n type: \"schematic_path\",\n schematic_path_id: `schematic_power_port_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n points: [point(4, -7), point(4, 7), point(12)].map((value) =>\n scalePoint(value, context.scale),\n ),\n stroke_width: 0.1,\n stroke_color: color,\n is_filled: false,\n is_dashed: false,\n } satisfies SchematicPath,\n )\n labelDistance = 16\n } else if (style === 4) {\n elements.push(\n createLine(\n index,\n location,\n point(4),\n color,\n 0.1,\n context.scale,\n \"power_port_stem\",\n ),\n ...[\n { along: 4, halfWidth: 7 },\n { along: 8, halfWidth: 4.5 },\n { along: 12, halfWidth: 2 },\n ].map(({ along, halfWidth }, lineIndex) =>\n createLine(\n index,\n point(along, -halfWidth),\n point(along, halfWidth),\n color,\n 0.1,\n context.scale,\n `power_port_ground_${lineIndex}`,\n ),\n ),\n )\n labelDistance = 16\n } else if (style === 6) {\n elements.push(\n createLine(\n index,\n location,\n point(4),\n color,\n 0.1,\n context.scale,\n \"power_port_stem\",\n ),\n createLine(\n index,\n point(4, -7),\n point(4, 7),\n color,\n 0.1,\n context.scale,\n \"power_port_chassis_bar\",\n ),\n ...[\n { from: -7, to: -9 },\n { from: 0, to: -2 },\n { from: 7, to: 5 },\n ].map(({ from, to }, lineIndex) =>\n createLine(\n index,\n point(4, from),\n point(9, to),\n color,\n 0.1,\n context.scale,\n `power_port_chassis_${lineIndex}`,\n ),\n ),\n )\n labelDistance = 14\n } else {\n elements.push({\n type: \"schematic_path\",\n schematic_path_id: `schematic_power_port_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n points: [location, point(10, -5), point(10, 5)].map((value) =>\n scalePoint(value, context.scale),\n ),\n stroke_width: 0.1,\n stroke_color: color,\n fill_color: color,\n is_filled: true,\n is_dashed: false,\n } satisfies SchematicPath)\n labelDistance = 14\n }\n const text = record.getDecoded(\"TEXT\") ?? record.getDecoded(\"NAME\")\n if (\n text &&\n options.includeText !== false &&\n record.getBoolean(\"SHOWNETNAME\") !== false\n ) {\n const vertical = direction.y !== 0\n const anchor: SchematicText[\"anchor\"] = vertical\n ? direction.y > 0\n ? \"bottom_center\"\n : \"top_center\"\n : direction.x > 0\n ? \"center_left\"\n : \"center_right\"\n elements.push(\n createDirectText(\n `schematic_power_port_text_altium_${index}`,\n text,\n point(labelDistance),\n getFontSize(record, context),\n color,\n context.scale,\n 0,\n anchor,\n ),\n )\n }\n return elements\n}\n\nfunction convertPort(\n record: AltiumRecord,\n index: number,\n context: SchematicContext,\n options: ConvertAltiumSchDocOptions,\n color: string,\n): AnyCircuitElement[] {\n const location = getLocation(record)\n if (!location) return []\n const width = Math.max(Number(record.getCaseInsensitive(\"WIDTH\") ?? 16), 10)\n const height = Math.max(Number(record.getCaseInsensitive(\"HEIGHT\") ?? 10), 4)\n const halfHeight = height / 2\n const pointDepth = Math.min(width * 0.22, height)\n const ioType = Number(record.getCaseInsensitive(\"IOTYPE\") ?? 0)\n const points =\n ioType === 1\n ? [\n { x: location.x, y: location.y },\n { x: location.x + pointDepth, y: location.y + halfHeight },\n { x: location.x + width, y: location.y + halfHeight },\n { x: location.x + width, y: location.y - halfHeight },\n { x: location.x + pointDepth, y: location.y - halfHeight },\n ]\n : ioType === 2\n ? [\n { x: location.x, y: location.y + halfHeight },\n {\n x: location.x + width - pointDepth,\n y: location.y + halfHeight,\n },\n { x: location.x + width, y: location.y },\n {\n x: location.x + width - pointDepth,\n y: location.y - halfHeight,\n },\n { x: location.x, y: location.y - halfHeight },\n ]\n : [\n { x: location.x, y: location.y + halfHeight },\n { x: location.x + width, y: location.y + halfHeight },\n { x: location.x + width, y: location.y - halfHeight },\n { x: location.x, y: location.y - halfHeight },\n ]\n const elements: AnyCircuitElement[] = [\n {\n type: \"schematic_path\",\n schematic_path_id: `schematic_port_altium_${index}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n points: points.map((point) => scalePoint(point, context.scale)),\n stroke_width: 0.1,\n stroke_color: color,\n fill_color: altiumColorToCss(\n record.getCaseInsensitive(\"AREACOLOR\"),\n \"#ffffff\",\n ),\n is_filled: true,\n is_dashed: false,\n } satisfies SchematicPath,\n ]\n const name = record.getDecoded(\"NAME\")\n if (name && options.includeText !== false) {\n elements.push(\n createDirectText(\n `schematic_port_text_altium_${index}`,\n name,\n { x: location.x + width / 2, y: location.y },\n getFontSize(record, context),\n altiumColorToCss(record.getCaseInsensitive(\"TEXTCOLOR\"), color),\n context.scale,\n 0,\n \"center\",\n ),\n )\n }\n return elements\n}\n\nfunction createSheetBorder(\n sheetRecord: AltiumRecord | undefined,\n scale: number,\n): SchematicRect {\n const { height, width } = getAltiumSheetDimensions(sheetRecord)\n return {\n type: \"schematic_rect\",\n schematic_rect_id: \"schematic_rect_altium_sheet_border\",\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n center: { x: (width * scale) / 2, y: (height * scale) / 2 },\n width: width * scale,\n height: height * scale,\n rotation: 0,\n stroke_width: 0.1,\n color: \"#334155\",\n is_filled: false,\n is_dashed: false,\n }\n}\n\nfunction createLine(\n index: number,\n start: AltiumPoint,\n end: AltiumPoint,\n color: string,\n strokeWidth: number,\n scale: number,\n suffix = \"line\",\n): SchematicLine {\n return {\n type: \"schematic_line\",\n schematic_line_id: `schematic_line_altium_${index}_${suffix}`,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n x1: start.x * scale,\n y1: start.y * scale,\n x2: end.x * scale,\n y2: end.y * scale,\n stroke_width: strokeWidth,\n color,\n is_dashed: false,\n }\n}\n\nfunction createText(\n record: AltiumRecord,\n index: number,\n text: string,\n location: AltiumPoint,\n color: string,\n context: SchematicContext,\n anchorOverride?: SchematicText[\"anchor\"],\n): SchematicText {\n const positioning = getTextPositioning(record)\n return createDirectText(\n `schematic_text_altium_${index}`,\n text,\n location,\n getFontSize(record, context),\n color,\n context.scale,\n positioning.rotation,\n anchorOverride ?? positioning.anchor,\n )\n}\n\nfunction createDirectText(\n id: string,\n text: string,\n location: AltiumPoint,\n fontSize: number,\n color: string,\n scale: number,\n rotation: number,\n anchor: SchematicText[\"anchor\"],\n): SchematicText {\n return {\n type: \"schematic_text\",\n schematic_text_id: id,\n schematic_sheet_id: SCHEMATIC_SHEET_ID,\n text,\n font_size: Math.max(fontSize * scale, 0.2),\n position: scalePoint(location, scale),\n rotation,\n anchor,\n color,\n }\n}\n\nfunction getFontSize(record: AltiumRecord, context: SchematicContext): number {\n const fontId = Math.max(\n Math.round(Number(record.getCaseInsensitive(\"FONTID\") ?? 1)),\n 1,\n )\n return Math.max(\n Number(context.sheetRecord?.getCaseInsensitive(`SIZE${fontId}`) ?? 9),\n 1,\n )\n}\n\nfunction getFontFamily(\n record: AltiumRecord,\n context: SchematicContext,\n): string {\n const fontId = Math.max(\n Math.round(Number(record.getCaseInsensitive(\"FONTID\") ?? 1)),\n 1,\n )\n return context.sheetRecord?.getDecoded(`FONTNAME${fontId}`) ?? \"Arial\"\n}\n\nfunction getTextPositioning(record: AltiumRecord): {\n anchor: SchematicText[\"anchor\"]\n rotation: number\n} {\n const justification = Math.min(\n Math.max(Math.round(record.getNumber(\"JUSTIFICATION\") ?? 0), 0),\n 8,\n )\n const orientation =\n ((Math.round(record.getNumber(\"ORIENTATION\") ?? 0) % 4) + 4) % 4\n let column = justification % 3\n const row = Math.floor(justification / 3)\n if (orientation === 2 || orientation === 3) column = 2 - column\n const horizontal = [\"left\", \"center\", \"right\"][column] ?? \"left\"\n const vertical = [\"bottom\", \"center\", \"top\"][row] ?? \"bottom\"\n const anchor =\n horizontal === \"center\" && vertical === \"center\"\n ? \"center\"\n : (`${vertical}_${horizontal}` as SchematicText[\"anchor\"])\n return {\n anchor,\n rotation: orientation === 1 || orientation === 3 ? 90 : 0,\n }\n}\n\nfunction shouldRenderSchematicRecord(\n record: AltiumRecord,\n context: SchematicContext,\n): boolean {\n let ownerPartId = record.getNumber(\"OWNERPARTID\")\n let ownerPartDisplayMode = record.getNumber(\"OWNERPARTDISPLAYMODE\")\n let current: AltiumRecord | undefined = record\n const visited = new Set<AltiumRecord>()\n\n while (current && !visited.has(current)) {\n visited.add(current)\n const parent = context.document.getParent(current)\n if (!parent) return true\n\n if (ownerPartId === undefined || ownerPartId <= 0) {\n ownerPartId = current.getNumber(\"OWNERPARTID\")\n }\n if (ownerPartDisplayMode === undefined) {\n ownerPartDisplayMode = current.getNumber(\"OWNERPARTDISPLAYMODE\")\n }\n\n if (parent.recordKind === \"1\") {\n const currentPartId = parent.getNumber(\"CURRENTPARTID\") ?? 1\n return (\n (ownerPartId === undefined ||\n ownerPartId <= 0 ||\n ownerPartId === currentPartId) &&\n (ownerPartDisplayMode === undefined || ownerPartDisplayMode === 0)\n )\n }\n current = parent\n }\n return true\n}\n\nfunction getLocation(record: AltiumRecord): AltiumPoint | undefined {\n if (\n record.getCaseInsensitive(\"LOCATION.X\") === undefined ||\n record.getCaseInsensitive(\"LOCATION.Y\") === undefined\n ) {\n return undefined\n }\n return {\n x: getCoordinate(record, \"LOCATION.X\"),\n y: getCoordinate(record, \"LOCATION.Y\"),\n }\n}\n\nfunction getCorner(record: AltiumRecord): AltiumPoint | undefined {\n if (\n record.getCaseInsensitive(\"CORNER.X\") === undefined ||\n record.getCaseInsensitive(\"CORNER.Y\") === undefined\n ) {\n return undefined\n }\n return {\n x: getCoordinate(record, \"CORNER.X\"),\n y: getCoordinate(record, \"CORNER.Y\"),\n }\n}\n\nfunction getRectangle(\n record: AltiumRecord,\n): { maxX: number; maxY: number; minX: number; minY: number } | undefined {\n const location = getLocation(record)\n const corner = getCorner(record)\n if (!location || !corner) return undefined\n return {\n minX: Math.min(location.x, corner.x),\n minY: Math.min(location.y, corner.y),\n maxX: Math.max(location.x, corner.x),\n maxY: Math.max(location.y, corner.y),\n }\n}\n\nfunction getCoordinate(\n record: AltiumRecord,\n key: string,\n fallback = 0,\n): number {\n const integerPart = Number(record.getCaseInsensitive(key) ?? fallback)\n const fractionRaw = record.getCaseInsensitive(`${key}_FRAC`)\n if (!Number.isFinite(integerPart) || fractionRaw === undefined) {\n return Number.isFinite(integerPart) ? integerPart : fallback\n }\n const fraction = Number(`0.${fractionRaw.replace(/^[+-]/u, \"\")}`)\n if (!Number.isFinite(fraction)) return integerPart\n return integerPart < 0 ? integerPart - fraction : integerPart + fraction\n}\n\nfunction scalePoint(point: AltiumPoint, scale: number): AltiumPoint {\n return { x: point.x * scale, y: point.y * scale }\n}\n\nfunction approximateEllipse(\n center: AltiumPoint,\n radiusX: number,\n radiusY: number,\n): AltiumPoint[] {\n return Array.from({ length: 49 }, (_, index) => {\n const radians = (index / 48) * Math.PI * 2\n return {\n x: center.x + Math.cos(radians) * radiusX,\n y: center.y + Math.sin(radians) * radiusY,\n }\n })\n}\n\nfunction decodeMultilineText(text: string): string {\n return text.replaceAll(\"~1\", \"\\n\").replaceAll(\"\\\\n\", \"\\n\")\n}\n\nfunction wrapSchematicText(\n text: string,\n maximumWidth: number,\n fontSize: number,\n fontFamily: string,\n): string[] {\n return text.split(\"\\n\").flatMap((paragraph) => {\n if (\n estimateSchematicTextWidth(paragraph, fontSize, fontFamily) <=\n maximumWidth\n ) {\n return [paragraph]\n }\n const words = paragraph.split(/\\s+/u)\n const lines: string[] = []\n let line = \"\"\n for (const word of words) {\n if (!line) {\n line = word\n } else if (\n estimateSchematicTextWidth(`${line} ${word}`, fontSize, fontFamily) <=\n maximumWidth\n ) {\n line = `${line} ${word}`\n } else {\n lines.push(line)\n line = word\n }\n }\n if (line) lines.push(line)\n return lines.length > 0 ? lines : [paragraph]\n })\n}\n\nfunction estimateSchematicTextWidth(\n text: string,\n fontSize: number,\n fontFamily: string,\n): number {\n if (/courier|mono/iu.test(fontFamily)) return text.length * fontSize * 0.6\n if (!/times|cambria|serif/iu.test(fontFamily)) {\n return text.length * fontSize * 0.52\n }\n\n return [...text].reduce((width, character) => {\n const emWidth =\n character === \" \"\n ? 0.23\n : /[ilI1.,:;!'`|]/u.test(character)\n ? 0.2\n : /[mwMW@%]/u.test(character)\n ? 0.7\n : /[A-Z0-9]/u.test(character)\n ? 0.5\n : 0.4\n return width + emWidth * fontSize\n }, 0)\n}\n\nfunction altiumColorToCss(raw: string | undefined, fallback: string): string {\n if (raw === undefined) return fallback\n const value = Number(raw)\n if (!Number.isInteger(value) || value < 0) return fallback\n const red = value & 0xff\n const green = (value >>> 8) & 0xff\n const blue = (value >>> 16) & 0xff\n return `#${toHex(red)}${toHex(green)}${toHex(blue)}`\n}\n\nfunction toHex(value: number): string {\n return value.toString(16).padStart(2, \"0\")\n}\n","import {\n type AltiumPoint,\n type AltiumRecord,\n type AltiumSchDoc,\n getSchematicDocumentIndex,\n getSchematicRecordPoints,\n} from \"altiumts\"\nimport {\n type AnyCircuitElement,\n type SchematicComponent,\n type SchematicNetLabel,\n type SchematicPort,\n type SchematicText,\n type SchematicTrace,\n type SourceComponentBase,\n type SourceNet,\n type SourcePort,\n type SourceTrace,\n source_simple_capacitor,\n source_simple_crystal,\n source_simple_inductor,\n source_simple_mosfet,\n source_simple_resistor,\n} from \"circuit-json\"\nimport { parseAndConvertSiUnit } from \"format-si-unit\"\nimport { type SchSymbol, symbols } from \"schematic-symbols\"\n\nexport interface SemanticSchematicOptions {\n includeHidden?: boolean\n includeText?: boolean\n scale: number\n schematicSheetId: string\n}\n\nexport interface SemanticSchematicConversion {\n elements: AnyCircuitElement[]\n handledRecords: Set<AltiumRecord>\n}\n\ninterface ConvertedPort {\n isSchematicVisible: boolean\n point: AltiumPoint\n record: AltiumRecord\n schematicPort: SchematicPort\n sourcePort: SourcePort\n}\n\ninterface SymbolPortAssignment {\n convertedPort: ConvertedPort\n symbolPort: SchSymbol[\"ports\"][number]\n}\n\ninterface SymbolSelection {\n assignments: SymbolPortAssignment[]\n name: string\n symbol: SchSymbol\n}\n\ninterface SemanticNet {\n id: string\n names: string[]\n points: AltiumPoint[]\n records: AltiumRecord[]\n}\n\ninterface SemanticNetGraph {\n getConnectedWiresForRecord(record: AltiumRecord): AltiumRecord[]\n nets: SemanticNet[]\n}\n\ninterface Bounds {\n maxX: number\n maxY: number\n minX: number\n minY: number\n}\n\ntype CardinalDirection = \"up\" | \"down\" | \"left\" | \"right\"\n\nconst DIRECTION_BY_ORIENTATION: readonly CardinalDirection[] = [\n \"right\",\n \"up\",\n \"left\",\n \"down\",\n]\n\nconst VECTOR_BY_DIRECTION: Readonly<Record<CardinalDirection, AltiumPoint>> = {\n down: { x: 0, y: -1 },\n left: { x: -1, y: 0 },\n right: { x: 1, y: 0 },\n up: { x: 0, y: 1 },\n}\n\nconst CARDINAL_DIRECTIONS: readonly CardinalDirection[] = [\n \"right\",\n \"up\",\n \"left\",\n \"down\",\n]\n\nconst SYMBOL_CATALOG = symbols as Record<string, SchSymbol | undefined>\nconst SYMBOL_NAMES = Object.keys(SYMBOL_CATALOG)\nconst INLINE_NET_LABEL_COLOR = \"rgb(132, 0, 0)\"\nconst DEFAULT_INLINE_NET_LABEL_FONT_SIZE = 0.18\nconst MIN_INLINE_NET_LABEL_FONT_SIZE = 0.1\nconst INLINE_NET_LABEL_CHARACTER_WIDTH = 0.12\nconst INLINE_NET_LABEL_HORIZONTAL_PADDING = 0.12\n\n/**\n * Converts records that have native Circuit JSON semantics before the\n * primitive fallback runs. This deliberately favors Circuit JSON's component,\n * port, trace, net, and symbol model over reproducing Altium's drawing style.\n */\nexport function convertSemanticSchematic(\n document: AltiumSchDoc,\n options: SemanticSchematicOptions,\n): SemanticSchematicConversion {\n const handledRecords = new Set<AltiumRecord>()\n const elements: AnyCircuitElement[] = []\n const convertedPorts: ConvertedPort[] = []\n\n convertComponents({\n convertedPorts,\n document,\n elements,\n handledRecords,\n options,\n })\n\n const semanticNetGraph = buildSemanticNetGraph(document, convertedPorts)\n\n const connectivity = convertConnectivity({\n convertedPorts,\n document,\n elements,\n handledRecords,\n semanticNetGraph,\n options,\n })\n\n convertNetLabels({\n connectivity,\n document,\n elements,\n handledRecords,\n semanticNetGraph,\n options,\n })\n\n return { elements, handledRecords }\n}\n\nfunction convertComponents(params: {\n convertedPorts: ConvertedPort[]\n document: AltiumSchDoc\n elements: AnyCircuitElement[]\n handledRecords: Set<AltiumRecord>\n options: SemanticSchematicOptions\n}): void {\n const { convertedPorts, document, elements, handledRecords, options } = params\n const documentIndex = getSchematicDocumentIndex(document)\n const sourceComponentIdByDesignator = new Map<string, string>()\n\n for (const [componentIndex, componentRecord] of document.records.entries()) {\n if (componentRecord.recordKind !== \"1\") continue\n handledRecords.add(componentRecord)\n\n const ownedRecords = documentIndex.getOwnedRecords(componentRecord)\n for (const ownedRecord of ownedRecords) handledRecords.add(ownedRecord)\n\n const currentPartId = componentRecord.getNumber(\"CURRENTPARTID\") ?? 1\n const visibleOwnedRecords = ownedRecords.filter((record) =>\n isOwnedRecordVisible(record, currentPartId),\n )\n const pins = visibleOwnedRecords.filter(\n (record) =>\n record.recordKind === \"2\" &&\n (!isPinHidden(record) || options.includeHidden === true),\n )\n if (pins.length === 0) continue\n const visibleSymbolLabels = new Set(\n visibleOwnedRecords\n .filter((record) => record.recordKind === \"4\")\n .flatMap((record) => {\n const text = record.getDecoded(\"TEXT\")?.trim().toUpperCase()\n return text ? [text] : []\n }),\n )\n\n const designator =\n findOwnedText(ownedRecords, \"34\", \"Designator\") ??\n componentRecord.getDecoded(\"DESIGNATOR\") ??\n `U${componentIndex}`\n const value =\n findOwnedText(ownedRecords, \"41\", \"Comment\") ??\n componentRecord.getDecoded(\"COMMENT\") ??\n componentRecord.getDecoded(\"DESIGNITEMID\") ??\n componentRecord.getDecoded(\"LIBREFERENCE\") ??\n \"\"\n const libraryReference =\n componentRecord.getDecoded(\"LIBREFERENCE\") ??\n componentRecord.getDecoded(\"DESIGNITEMID\") ??\n designator\n const manufacturerPartNumber = findOwnedText(\n ownedRecords,\n \"41\",\n \"Mfr_part_number\",\n )\n const normalizedDesignator = designator.trim().toUpperCase()\n const existingSourceComponentId =\n sourceComponentIdByDesignator.get(normalizedDesignator)\n const sourceComponentId =\n existingSourceComponentId ?? `source_component_altium_${componentIndex}`\n const schematicComponentId = `schematic_component_altium_${componentIndex}`\n if (!existingSourceComponentId) {\n sourceComponentIdByDesignator.set(normalizedDesignator, sourceComponentId)\n elements.push(\n createSourceComponent({\n designator,\n libraryReference,\n manufacturerPartNumber,\n pinCount: pins.length,\n sourceComponentId,\n value,\n }),\n )\n }\n\n const componentPorts = pins.map((pin, pinIndex) =>\n convertComponentPin({\n document,\n options,\n pin,\n pinIndex,\n schematicComponentId,\n sourceComponentId,\n visibleSymbolLabels,\n }),\n )\n const bodyBounds = getComponentBodyBounds(\n visibleOwnedRecords,\n componentPorts.map(({ point }) => point),\n )\n const symbolSelection = selectCircuitJsonSymbol({\n designator,\n libraryReference,\n ports: componentPorts,\n })\n const center = scalePoint(getBoundsCenter(bodyBounds), options.scale)\n const size = symbolSelection\n ? { ...symbolSelection.symbol.size }\n : {\n height: Math.max(\n (bodyBounds.maxY - bodyBounds.minY) * options.scale,\n 0.4,\n ),\n width: Math.max(\n (bodyBounds.maxX - bodyBounds.minX) * options.scale,\n 0.4,\n ),\n }\n if (symbolSelection) {\n applyNativeSymbolPortGeometry({\n center,\n selection: symbolSelection,\n })\n }\n convertedPorts.push(...componentPorts)\n elements.push(\n ...componentPorts.flatMap(\n ({ isSchematicVisible, sourcePort, schematicPort }) => [\n sourcePort,\n ...(isSchematicVisible ? [schematicPort] : []),\n ],\n ),\n )\n const schematicComponent: SchematicComponent = {\n type: \"schematic_component\",\n center,\n // circuit-to-svg uses this flag as the renderable component gate for\n // both generated boxes and components selected by symbol_name.\n is_box_with_pins: true,\n schematic_component_id: schematicComponentId,\n schematic_sheet_id: options.schematicSheetId,\n size,\n source_component_id: sourceComponentId,\n symbol_display_value: value,\n ...(symbolSelection ? { symbol_name: symbolSelection.name } : {}),\n }\n elements.push(schematicComponent)\n\n if (!symbolSelection && options.includeText !== false) {\n elements.push(\n createComponentText({\n anchor: \"bottom_left\",\n component: schematicComponent,\n id: `schematic_component_designator_altium_${componentIndex}`,\n position: {\n x: center.x - size.width / 2,\n y: center.y + size.height / 2 + 0.13,\n },\n text: designator,\n }),\n )\n if (value) {\n elements.push(\n createComponentText({\n anchor: \"top_left\",\n component: schematicComponent,\n id: `schematic_component_value_altium_${componentIndex}`,\n position: {\n x: center.x - size.width / 2,\n y: center.y - size.height / 2 - 0.13,\n },\n text: value,\n }),\n )\n }\n }\n }\n}\n\nfunction convertComponentPin(params: {\n document: AltiumSchDoc\n options: SemanticSchematicOptions\n pin: AltiumRecord\n pinIndex: number\n schematicComponentId: string\n sourceComponentId: string\n visibleSymbolLabels: Set<string>\n}): ConvertedPort {\n const {\n document,\n options,\n pin,\n pinIndex,\n schematicComponentId,\n sourceComponentId,\n visibleSymbolLabels,\n } = params\n const recordIndex = document.records.indexOf(pin)\n const pinConglomerate = pin.getNumber(\"PINCONGLOMERATE\")\n const orientation = (pinConglomerate ?? pin.getNumber(\"ORIENTATION\") ?? 0) & 3\n const direction = DIRECTION_BY_ORIENTATION[orientation] ?? \"right\"\n const directionVector = VECTOR_BY_DIRECTION[direction]\n const location = getLocation(pin) ?? { x: 0, y: 0 }\n const pinLength = Math.max(pin.getNumber(\"PINLENGTH\") ?? 10, 0)\n const terminalPoint = {\n x: location.x + directionVector.x * pinLength,\n y: location.y + directionVector.y * pinLength,\n }\n const designator = pin.getDecoded(\"DESIGNATOR\") ?? `${pinIndex + 1}`\n const pinNumber = parsePinNumber(designator)\n const name = pin.getDecoded(\"NAME\") ?? designator\n const sourcePortId = `source_port_altium_${recordIndex}`\n const schematicPortId = `schematic_port_altium_${recordIndex}`\n const sourcePort: SourcePort = {\n type: \"source_port\",\n name,\n port_hints: uniqueStrings([\n designator,\n name,\n pinNumber === undefined ? undefined : `pin${pinNumber}`,\n ]),\n source_component_id: sourceComponentId,\n source_port_id: sourcePortId,\n ...(pinNumber === undefined ? {} : { pin_number: pinNumber }),\n }\n const electricalType = pin.getNumber(\"ELECTRICAL\")\n const normalizedName = name.trim().toUpperCase()\n const functionalName = normalizedName.replace(/\\d+$/u, \"\")\n const showName =\n pinConglomerate === undefined ||\n (pinConglomerate & 0x08) !== 0 ||\n visibleSymbolLabels.has(normalizedName) ||\n visibleSymbolLabels.has(functionalName)\n const schematicPort: SchematicPort = {\n type: \"schematic_port\",\n center: scalePoint(terminalPoint, options.scale),\n ...(showName && name ? { display_pin_label: name } : {}),\n distance_from_component_edge: pinLength * options.scale,\n facing_direction: direction,\n is_connected: false,\n schematic_component_id: schematicComponentId,\n schematic_port_id: schematicPortId,\n schematic_sheet_id: options.schematicSheetId,\n side_of_component: directionToSide(direction),\n source_port_id: sourcePortId,\n true_ccw_index: pinIndex,\n ...(pinNumber === undefined ? {} : { pin_number: pinNumber }),\n ...(electricalType === 0 || electricalType === 1\n ? { has_input_arrow: true }\n : {}),\n ...(electricalType === 1 || electricalType === 2\n ? { has_output_arrow: true }\n : {}),\n }\n return {\n isSchematicVisible: true,\n point: terminalPoint,\n record: pin,\n schematicPort,\n sourcePort,\n }\n}\n\nfunction createSourceComponent(params: {\n designator: string\n libraryReference: string\n manufacturerPartNumber?: string\n pinCount: number\n sourceComponentId: string\n value: string\n}): AnyCircuitElement {\n const {\n designator,\n libraryReference,\n manufacturerPartNumber,\n pinCount,\n sourceComponentId,\n value,\n } = params\n const classification = classifyComponent({ designator, libraryReference })\n const primaryValue = getPrimaryComponentValue(value)\n const common = {\n type: \"source_component\" as const,\n display_name: designator,\n display_value: value || undefined,\n manufacturer_part_number: manufacturerPartNumber,\n name: designator,\n source_component_id: sourceComponentId,\n }\n\n if (classification === \"resistor\") {\n const parsed = source_simple_resistor.safeParse({\n ...common,\n display_resistance: value || undefined,\n ftype: \"simple_resistor\",\n resistance: primaryValue || 0,\n })\n if (parsed.success) return parsed.data\n }\n if (classification === \"capacitor\") {\n const parsed = source_simple_capacitor.safeParse({\n ...common,\n display_capacitance: value || undefined,\n ftype: \"simple_capacitor\",\n capacitance: primaryValue || 0,\n })\n if (parsed.success) return parsed.data\n }\n if (classification === \"inductor\") {\n const parsed = source_simple_inductor.safeParse({\n ...common,\n display_inductance: value || undefined,\n ftype: \"simple_inductor\",\n inductance: primaryValue || 0,\n })\n if (parsed.success) return parsed.data\n }\n if (classification === \"crystal\" && (pinCount === 2 || pinCount === 4)) {\n const frequency = parseAndConvertSiUnit(value, \"Hz\").value\n if (typeof frequency === \"number\" && Number.isFinite(frequency)) {\n const parsed = source_simple_crystal.safeParse({\n ...common,\n frequency,\n ftype: \"simple_crystal\",\n pin_variant: pinCount === 4 ? \"four_pin\" : \"two_pin\",\n })\n if (parsed.success) return parsed.data\n }\n }\n if (classification === \"mosfet\" && pinCount >= 3) {\n const parsed = source_simple_mosfet.safeParse({\n ...common,\n ...getMosfetVariant(libraryReference),\n ftype: \"simple_mosfet\",\n })\n if (parsed.success) return parsed.data\n }\n\n const ftype:\n | \"simple_chip\"\n | \"simple_diode\"\n | \"simple_led\"\n | \"simple_test_point\" =\n classification === \"diode\"\n ? \"simple_diode\"\n : classification === \"led\"\n ? \"simple_led\"\n : classification === \"testpoint\"\n ? \"simple_test_point\"\n : \"simple_chip\"\n return {\n ...common,\n ftype,\n } satisfies SourceComponentBase\n}\n\nfunction createComponentText(params: {\n anchor: SchematicText[\"anchor\"]\n component: SchematicComponent\n id: string\n position: AltiumPoint\n text: string\n}): SchematicText {\n const { anchor, component, id, position, text } = params\n return {\n type: \"schematic_text\",\n anchor,\n color: \"#006464\",\n font_size: 0.18,\n position,\n rotation: 0,\n schematic_component_id: component.schematic_component_id,\n schematic_sheet_id: component.schematic_sheet_id,\n schematic_text_id: id,\n text,\n }\n}\n\n/**\n * Altium permits labels and pin hot spots to land anywhere on a wire segment,\n * not only on declared polyline vertices. Build the electrical graph with\n * those geometric joins so Circuit JSON source traces carry the real ports and\n * net names. Mid-segment crossings remain disconnected unless one wire has a\n * vertex there or Altium emits an explicit junction record.\n */\nfunction buildSemanticNetGraph(\n document: AltiumSchDoc,\n convertedPorts: ConvertedPort[],\n): SemanticNetGraph {\n const disjointSet = new PointDisjointSet()\n const pointValues = new Map<string, AltiumPoint>()\n const wireRecords = document.records.filter(\n (record) => record.recordKind === \"27\",\n )\n const segments: Array<{ end: AltiumPoint; start: AltiumPoint }> = []\n\n for (const wire of wireRecords) {\n const points = getSchematicRecordPoints(wire)\n for (const point of points) {\n addGraphPoint(disjointSet, pointValues, point)\n }\n for (let index = 1; index < points.length; index++) {\n const start = points[index - 1]\n const end = points[index]\n if (!start || !end) continue\n disjointSet.union(pointKey(start), pointKey(end))\n segments.push({ end, start })\n }\n }\n\n const positionedRecords = document.records.flatMap((record) => {\n if (![\"4\", \"17\", \"18\", \"25\", \"29\"].includes(record.recordKind ?? \"\")) {\n return []\n }\n const point = getLocation(record)\n return point ? [{ point, record }] : []\n })\n const positionedPins = convertedPorts.map(({ point, record }) => ({\n point,\n record,\n }))\n const joinPoints = [\n ...new Map(\n wireRecords\n .flatMap((wire) => getSchematicRecordPoints(wire))\n .map((point) => [pointKey(point), point]),\n ).values(),\n ...positionedRecords.map(({ point }) => point),\n ...positionedPins.map(({ point }) => point),\n ]\n\n for (const point of joinPoints) {\n addGraphPoint(disjointSet, pointValues, point)\n for (const segment of segments) {\n if (isPointOnSegment(point, segment.start, segment.end)) {\n disjointSet.union(pointKey(point), pointKey(segment.start))\n }\n }\n }\n\n interface MutableSemanticNet {\n id: string\n names: Set<string>\n points: Map<string, AltiumPoint>\n records: Set<AltiumRecord>\n }\n const groupedByRoot = new Map<string, MutableSemanticNet>()\n const getGroup = (point: AltiumPoint): MutableSemanticNet => {\n const root = disjointSet.find(pointKey(point))\n const existing = groupedByRoot.get(root)\n if (existing) return existing\n const created: MutableSemanticNet = {\n id: root,\n names: new Set(),\n points: new Map(),\n records: new Set(),\n }\n groupedByRoot.set(root, created)\n return created\n }\n\n for (const point of pointValues.values()) {\n getGroup(point).points.set(pointKey(point), point)\n }\n for (const wire of wireRecords) {\n const firstPoint = getSchematicRecordPoints(wire)[0]\n if (firstPoint) getGroup(firstPoint).records.add(wire)\n }\n for (const { point, record } of [...positionedRecords, ...positionedPins]) {\n const group = getGroup(point)\n group.records.add(record)\n const name = getElectricalRecordName(record)\n if (name) group.names.add(name)\n }\n\n const connectedWiresByRecord = new Map<AltiumRecord, AltiumRecord[]>()\n for (const group of groupedByRoot.values()) {\n const wires = [...group.records].filter(\n (record) => record.recordKind === \"27\",\n )\n for (const record of group.records) {\n connectedWiresByRecord.set(record, wires)\n }\n }\n\n const mergedGroups: MutableSemanticNet[] = []\n for (const group of groupedByRoot.values()) {\n if (group.records.size === 0) continue\n const normalizedNames = new Set(\n [...group.names].map((name) => name.trim().toUpperCase()),\n )\n const matches = mergedGroups.filter((candidate) =>\n [...candidate.names].some((name) =>\n normalizedNames.has(name.trim().toUpperCase()),\n ),\n )\n if (matches.length === 0 || normalizedNames.size === 0) {\n mergedGroups.push(group)\n continue\n }\n const target = matches[0]\n if (!target) continue\n mergeSemanticNetGroup(target, group)\n for (const duplicate of matches.slice(1)) {\n mergeSemanticNetGroup(target, duplicate)\n const duplicateIndex = mergedGroups.indexOf(duplicate)\n if (duplicateIndex >= 0) mergedGroups.splice(duplicateIndex, 1)\n }\n }\n\n const nets: SemanticNet[] = mergedGroups.map((group) => ({\n id: group.id,\n names: [...group.names],\n points: [...group.points.values()],\n records: [...group.records],\n }))\n return {\n getConnectedWiresForRecord: (record) =>\n connectedWiresByRecord.get(record) ?? [],\n nets,\n }\n}\n\nfunction addGraphPoint(\n disjointSet: PointDisjointSet,\n pointValues: Map<string, AltiumPoint>,\n point: AltiumPoint,\n): void {\n const key = pointKey(point)\n disjointSet.add(key)\n pointValues.set(key, point)\n}\n\nfunction getElectricalRecordName(record: AltiumRecord): string | undefined {\n if (record.recordKind === \"18\") return record.getDecoded(\"NAME\")\n if ([\"4\", \"17\", \"25\"].includes(record.recordKind ?? \"\")) {\n return record.getDecoded(\"TEXT\")\n }\n return undefined\n}\n\nfunction mergeSemanticNetGroup(\n target: {\n names: Set<string>\n points: Map<string, AltiumPoint>\n records: Set<AltiumRecord>\n },\n source: {\n names: Set<string>\n points: Map<string, AltiumPoint>\n records: Set<AltiumRecord>\n },\n): void {\n for (const name of source.names) target.names.add(name)\n for (const [key, point] of source.points) target.points.set(key, point)\n for (const record of source.records) target.records.add(record)\n}\n\nfunction isPointOnSegment(\n point: AltiumPoint,\n start: AltiumPoint,\n end: AltiumPoint,\n): boolean {\n const dx = end.x - start.x\n const dy = end.y - start.y\n const cross = (point.x - start.x) * dy - (point.y - start.y) * dx\n const tolerance = 0.000001 * Math.max(Math.abs(dx), Math.abs(dy), 1)\n if (Math.abs(cross) > tolerance) return false\n const dot = (point.x - start.x) * dx + (point.y - start.y) * dy\n if (dot < -tolerance) return false\n const lengthSquared = dx * dx + dy * dy\n return dot <= lengthSquared + tolerance\n}\n\nfunction splitSegmentAtPoints(\n start: AltiumPoint,\n end: AltiumPoint,\n candidates: AltiumPoint[],\n): AltiumPoint[] {\n const dx = end.x - start.x\n const dy = end.y - start.y\n const lengthSquared = dx * dx + dy * dy\n if (lengthSquared === 0) return [start]\n\n const pointsByKey = new Map<string, AltiumPoint>([\n [pointKey(start), start],\n [pointKey(end), end],\n ])\n for (const candidate of candidates) {\n if (isPointOnSegment(candidate, start, end)) {\n pointsByKey.set(pointKey(candidate), candidate)\n }\n }\n return [...pointsByKey.values()].sort((left, right) => {\n const leftDistance = (left.x - start.x) * dx + (left.y - start.y) * dy\n const rightDistance = (right.x - start.x) * dx + (right.y - start.y) * dy\n return leftDistance - rightDistance\n })\n}\n\nclass PointDisjointSet {\n private readonly parent = new Map<string, string>()\n\n add(value: string): void {\n if (!this.parent.has(value)) this.parent.set(value, value)\n }\n\n find(value: string): string {\n this.add(value)\n const parent = this.parent.get(value) ?? value\n if (parent === value) return value\n const root = this.find(parent)\n this.parent.set(value, root)\n return root\n }\n\n union(left: string, right: string): void {\n const leftRoot = this.find(left)\n const rightRoot = this.find(right)\n if (leftRoot !== rightRoot) this.parent.set(rightRoot, leftRoot)\n }\n}\n\ninterface ConnectivityConversion {\n sourceNetIdByRecord: Map<AltiumRecord, string>\n sourceNetIdByName: Map<string, string>\n sourcePortCountByRecord: Map<AltiumRecord, number>\n sourceTraceIdByRecord: Map<AltiumRecord, string>\n schematicTraceIdByRecord: Map<AltiumRecord, string>\n}\n\nfunction convertConnectivity(params: {\n convertedPorts: ConvertedPort[]\n document: AltiumSchDoc\n elements: AnyCircuitElement[]\n handledRecords: Set<AltiumRecord>\n options: SemanticSchematicOptions\n semanticNetGraph: SemanticNetGraph\n}): ConnectivityConversion {\n const {\n convertedPorts,\n document,\n elements,\n handledRecords,\n options,\n semanticNetGraph: graph,\n } = params\n const sourceNetIdByName = new Map<string, string>()\n const sourceNetIdByRecord = new Map<AltiumRecord, string>()\n const sourcePortCountByRecord = new Map<AltiumRecord, number>()\n const sourceTraceIdByRecord = new Map<AltiumRecord, string>()\n const schematicTraceIdByRecord = new Map<AltiumRecord, string>()\n const portsByPoint = groupByPoint(convertedPorts)\n\n for (const [netIndex, net] of graph.nets.entries()) {\n const wires = net.records.filter((record) => record.recordKind === \"27\")\n const connectedConvertedPorts = uniqueConvertedPorts(\n net.points.flatMap((point) => portsByPoint.get(pointKey(point)) ?? []),\n )\n const connectedPorts = connectedConvertedPorts.map(\n ({ sourcePort }) => sourcePort.source_port_id,\n )\n if (\n wires.length === 0 &&\n !(\n (net.names.length > 0 && connectedPorts.length > 0) ||\n connectedPorts.length > 1\n )\n ) {\n continue\n }\n const sourceNetIds = net.names.map((name) =>\n getOrCreateSourceNet({\n elements,\n name,\n sourceNetIdByName,\n }),\n )\n for (const record of net.records) {\n const firstSourceNetId = sourceNetIds[0]\n if (firstSourceNetId) sourceNetIdByRecord.set(record, firstSourceNetId)\n }\n\n const sourceTraceId = `source_trace_altium_${netIndex}`\n for (const record of net.records) {\n sourcePortCountByRecord.set(record, connectedPorts.length)\n sourceTraceIdByRecord.set(record, sourceTraceId)\n }\n const sourceTrace: SourceTrace = {\n type: \"source_trace\",\n connected_source_net_ids: sourceNetIds,\n connected_source_port_ids: connectedPorts,\n display_name: net.names[0],\n name: net.names[0],\n source_trace_id: sourceTraceId,\n }\n elements.push(sourceTrace)\n\n const netJunctions = document.records\n .filter(\n (record) =>\n record.recordKind === \"29\" &&\n net.points.some((point) => pointsEqual(point, getLocation(record))),\n )\n .flatMap((record) => {\n handledRecords.add(record)\n const location = getLocation(record)\n return location ? [scalePoint(location, options.scale)] : []\n })\n\n for (const wire of wires) handledRecords.add(wire)\n const prunedSegmentKeys = getEquivalentPortPrunedSegmentKeys({\n convertedPorts: connectedConvertedPorts,\n net,\n wires,\n })\n let renderedWireIndex = 0\n for (const wire of wires) {\n const wireRecordIndex = document.records.indexOf(wire)\n const schematicTraceId = `schematic_trace_altium_${wireRecordIndex}`\n const points = getSchematicRecordPoints(wire)\n const edges: SchematicTrace[\"edges\"] = []\n for (let pointIndex = 1; pointIndex < points.length; pointIndex++) {\n const from = points[pointIndex - 1]\n const to = points[pointIndex]\n if (!from || !to) continue\n const segmentPoints = splitSegmentAtPoints(from, to, net.points)\n for (\n let segmentPointIndex = 1;\n segmentPointIndex < segmentPoints.length;\n segmentPointIndex++\n ) {\n const segmentFrom = segmentPoints[segmentPointIndex - 1]\n const segmentTo = segmentPoints[segmentPointIndex]\n if (!segmentFrom || !segmentTo) continue\n if (prunedSegmentKeys.has(segmentKey(segmentFrom, segmentTo))) {\n continue\n }\n const fromPort = portsByPoint\n .get(pointKey(segmentFrom))\n ?.find((port) => port.isSchematicVisible)\n const toPort = portsByPoint\n .get(pointKey(segmentTo))\n ?.find((port) => port.isSchematicVisible)\n const fromPortId = getPortIdAtElectricalPoint(\n fromPort,\n segmentFrom,\n options.scale,\n )\n const toPortId = getPortIdAtElectricalPoint(\n toPort,\n segmentTo,\n options.scale,\n )\n edges.push({\n from: scalePoint(segmentFrom, options.scale),\n to: scalePoint(segmentTo, options.scale),\n ...(fromPortId ? { from_schematic_port_id: fromPortId } : {}),\n ...(toPortId ? { to_schematic_port_id: toPortId } : {}),\n })\n }\n }\n if (edges.length === 0) continue\n schematicTraceIdByRecord.set(wire, schematicTraceId)\n elements.push({\n type: \"schematic_trace\",\n edges,\n junctions: renderedWireIndex === 0 ? netJunctions : [],\n schematic_sheet_id: options.schematicSheetId,\n schematic_trace_id: schematicTraceId,\n source_trace_id: sourceTraceId,\n } satisfies SchematicTrace)\n renderedWireIndex++\n }\n\n for (const convertedPort of connectedConvertedPorts) {\n if (!convertedPort.isSchematicVisible) continue\n const electricalTerminal = scalePoint(convertedPort.point, options.scale)\n if (pointsEqual(convertedPort.schematicPort.center, electricalTerminal)) {\n continue\n }\n const portRecordIndex = document.records.indexOf(convertedPort.record)\n elements.push({\n type: \"schematic_trace\",\n edges: createPortLeadEdges(convertedPort, electricalTerminal),\n junctions: [],\n schematic_sheet_id: options.schematicSheetId,\n schematic_trace_id: `schematic_trace_altium_port_lead_${portRecordIndex}`,\n source_trace_id: sourceTraceId,\n } satisfies SchematicTrace)\n }\n\n const connectedPortIds = new Set(connectedPorts)\n for (const convertedPort of convertedPorts) {\n if (\n convertedPort.isSchematicVisible &&\n connectedPortIds.has(convertedPort.sourcePort.source_port_id)\n ) {\n convertedPort.schematicPort.is_connected = true\n }\n }\n }\n\n return {\n schematicTraceIdByRecord,\n sourceNetIdByName,\n sourceNetIdByRecord,\n sourcePortCountByRecord,\n sourceTraceIdByRecord,\n }\n}\n\nfunction getEquivalentPortPrunedSegmentKeys(params: {\n convertedPorts: ConvertedPort[]\n net: SemanticNet\n wires: AltiumRecord[]\n}): Set<string> {\n const { convertedPorts, net, wires } = params\n const hiddenPortPoints = convertedPorts\n .filter((port) => !port.isSchematicVisible)\n .map((port) => port.point)\n if (hiddenPortPoints.length === 0) return new Set()\n\n const protectedPointKeys = new Set(\n convertedPorts\n .filter((port) => port.isSchematicVisible)\n .map((port) => pointKey(port.point)),\n )\n for (const record of net.records) {\n if (![\"4\", \"17\", \"18\", \"25\"].includes(record.recordKind ?? \"\")) continue\n const location = getLocation(record)\n if (location) protectedPointKeys.add(pointKey(location))\n }\n\n interface PrunableSegment {\n endKey: string\n key: string\n startKey: string\n }\n const segments = new Map<string, PrunableSegment>()\n const segmentKeysByPoint = new Map<string, Set<string>>()\n const addIncidentSegment = (point: AltiumPoint, key: string): void => {\n const pointSegments = segmentKeysByPoint.get(pointKey(point))\n if (pointSegments) pointSegments.add(key)\n else segmentKeysByPoint.set(pointKey(point), new Set([key]))\n }\n\n for (const wire of wires) {\n const wirePoints = getSchematicRecordPoints(wire)\n for (let pointIndex = 1; pointIndex < wirePoints.length; pointIndex++) {\n const from = wirePoints[pointIndex - 1]\n const to = wirePoints[pointIndex]\n if (!from || !to) continue\n const segmentPoints = splitSegmentAtPoints(from, to, net.points)\n for (\n let splitIndex = 1;\n splitIndex < segmentPoints.length;\n splitIndex++\n ) {\n const segmentFrom = segmentPoints[splitIndex - 1]\n const segmentTo = segmentPoints[splitIndex]\n if (!segmentFrom || !segmentTo) continue\n const key = segmentKey(segmentFrom, segmentTo)\n segments.set(key, {\n endKey: pointKey(segmentTo),\n key,\n startKey: pointKey(segmentFrom),\n })\n addIncidentSegment(segmentFrom, key)\n addIncidentSegment(segmentTo, key)\n }\n }\n }\n\n const removedSegmentKeys = new Set<string>()\n const pendingPointKeys = hiddenPortPoints.map((point) => pointKey(point))\n while (pendingPointKeys.length > 0) {\n const currentPointKey = pendingPointKeys.shift()\n if (!currentPointKey || protectedPointKeys.has(currentPointKey)) continue\n const activeSegmentKeys = [\n ...(segmentKeysByPoint.get(currentPointKey) ?? []),\n ].filter((key) => !removedSegmentKeys.has(key))\n if (activeSegmentKeys.length !== 1) continue\n const segment = segments.get(activeSegmentKeys[0] ?? \"\")\n if (!segment) continue\n removedSegmentKeys.add(segment.key)\n pendingPointKeys.push(\n segment.startKey === currentPointKey ? segment.endKey : segment.startKey,\n )\n }\n return removedSegmentKeys\n}\n\nfunction segmentKey(start: AltiumPoint, end: AltiumPoint): string {\n const startKey = pointKey(start)\n const endKey = pointKey(end)\n return startKey < endKey ? `${startKey}|${endKey}` : `${endKey}|${startKey}`\n}\n\nfunction createPortLeadEdges(\n convertedPort: ConvertedPort,\n electricalTerminal: AltiumPoint,\n): SchematicTrace[\"edges\"] {\n const portCenter = convertedPort.schematicPort.center\n const facingDirection =\n convertedPort.schematicPort.facing_direction ?? \"right\"\n const elbow =\n facingDirection === \"left\" || facingDirection === \"right\"\n ? { x: electricalTerminal.x, y: portCenter.y }\n : { x: portCenter.x, y: electricalTerminal.y }\n const points = [portCenter, elbow, electricalTerminal].filter(\n (point, index, allPoints) =>\n index === 0 || !pointsEqual(point, allPoints[index - 1]),\n )\n\n return points.slice(1).flatMap((to, index) => {\n const from = points[index]\n if (!from) return []\n return [\n {\n from,\n ...(index === 0\n ? {\n from_schematic_port_id:\n convertedPort.schematicPort.schematic_port_id,\n }\n : {}),\n to,\n },\n ]\n })\n}\n\nfunction convertNetLabels(params: {\n connectivity: ConnectivityConversion\n document: AltiumSchDoc\n elements: AnyCircuitElement[]\n handledRecords: Set<AltiumRecord>\n options: SemanticSchematicOptions\n semanticNetGraph: SemanticNetGraph\n}): void {\n const {\n connectivity,\n document,\n elements,\n handledRecords,\n options,\n semanticNetGraph: graph,\n } = params\n\n for (const [recordIndex, record] of document.records.entries()) {\n const recordKind = record.recordKind\n if (!recordKind || ![\"4\", \"17\", \"18\", \"25\"].includes(recordKind)) {\n continue\n }\n if (record.getBoolean(\"ISHIDDEN\") && options.includeHidden !== true) {\n handledRecords.add(record)\n continue\n }\n const name =\n record.recordKind === \"18\"\n ? record.getDecoded(\"NAME\")\n : record.getDecoded(\"TEXT\")\n const location = getLocation(record)\n if (!name || !location) continue\n const connectedWires = graph.getConnectedWiresForRecord(record)\n const wire = connectedWires[0]\n // Altium's generic label record is also used for page titles and notes.\n // It is only an electrical net label when it touches a wire.\n if (recordKind === \"4\" && !wire) continue\n const sourceTraceId = connectivity.sourceTraceIdByRecord.get(record)\n const shouldRenderInline =\n Boolean(sourceTraceId) &&\n (recordKind === \"25\" ||\n (recordKind === \"18\" &&\n (record.getNumber(\"IOTYPE\") ?? 0) === 0 &&\n connectivity.sourcePortCountByRecord.get(record) === 2 &&\n !isPowerNet(name)))\n if (shouldRenderInline && sourceTraceId) {\n handledRecords.add(record)\n elements.push(\n createInlineNetLabelText({\n connectedWires,\n document,\n location,\n name,\n options,\n record,\n recordIndex,\n sourceTraceId,\n }),\n )\n continue\n }\n handledRecords.add(record)\n\n const sourceNetId =\n connectivity.sourceNetIdByRecord.get(record) ??\n getOrCreateSourceNet({\n elements,\n name,\n sourceNetIdByName: connectivity.sourceNetIdByName,\n })\n const schematicTraceId = wire\n ? connectivity.schematicTraceIdByRecord.get(wire)\n : undefined\n const direction = getRecordDirection(record)\n const symbolName =\n record.recordKind === \"17\"\n ? getPowerPortSymbolName(record, direction)\n : undefined\n const schematicNetLabel: SchematicNetLabel = {\n type: \"schematic_net_label\",\n anchor_position: scalePoint(location, options.scale),\n anchor_side:\n record.recordKind === \"18\" || record.recordKind === \"4\"\n ? \"left\"\n : directionToOppositeSide(direction),\n center: scalePoint(location, options.scale),\n schematic_net_label_id: `schematic_net_label_altium_${recordIndex}`,\n schematic_sheet_id: options.schematicSheetId,\n source_net_id: sourceNetId,\n text: name,\n ...(schematicTraceId ? { schematic_trace_id: schematicTraceId } : {}),\n ...(symbolName ? { symbol_name: symbolName } : {}),\n }\n elements.push(schematicNetLabel)\n }\n}\n\nfunction createInlineNetLabelText(params: {\n connectedWires: AltiumRecord[]\n document: AltiumSchDoc\n location: AltiumPoint\n name: string\n options: SemanticSchematicOptions\n record: AltiumRecord\n recordIndex: number\n sourceTraceId: string\n}): SchematicText {\n const {\n connectedWires,\n document,\n location,\n name,\n options,\n record,\n recordIndex,\n sourceTraceId,\n } = params\n const direction = getInlineNetLabelDirection(record, location, connectedWires)\n const scaledLocation = scalePoint(location, options.scale)\n const fontSize = getInlineNetLabelFontSize(record, document, options.scale)\n const fontScale = fontSize / DEFAULT_INLINE_NET_LABEL_FONT_SIZE\n const textWidth =\n (name.length * INLINE_NET_LABEL_CHARACTER_WIDTH +\n INLINE_NET_LABEL_HORIZONTAL_PADDING) *\n fontScale\n const isVertical = direction === \"up\" || direction === \"down\"\n const directionSign = direction === \"left\" || direction === \"down\" ? -1 : 1\n const isTerminalPort = record.recordKind === \"18\"\n const anchor: SchematicText[\"anchor\"] = isTerminalPort\n ? directionSign > 0\n ? \"left\"\n : \"right\"\n : \"center\"\n const position = isTerminalPort\n ? isVertical\n ? {\n x: scaledLocation.x - fontSize / 2,\n y: scaledLocation.y,\n }\n : {\n x: scaledLocation.x,\n y: scaledLocation.y + fontSize / 2,\n }\n : isVertical\n ? {\n x: scaledLocation.x - fontSize / 2,\n y: scaledLocation.y + (directionSign * textWidth) / 2,\n }\n : {\n x: scaledLocation.x + (directionSign * textWidth) / 2,\n y: scaledLocation.y + fontSize / 2,\n }\n\n return {\n type: \"schematic_text\",\n anchor,\n color: INLINE_NET_LABEL_COLOR,\n font_size: fontSize,\n position,\n rotation: isVertical ? -90 : 0,\n schematic_sheet_id: options.schematicSheetId,\n schematic_text_id: `schematic_inline_net_label_altium_${recordIndex}`,\n source_trace_id: sourceTraceId,\n text: name,\n }\n}\n\nfunction getInlineNetLabelFontSize(\n record: AltiumRecord,\n document: AltiumSchDoc,\n scale: number,\n): number {\n const fontId = Math.max(\n Math.round(Number(record.getCaseInsensitive(\"FONTID\") ?? 1)),\n 1,\n )\n const sheetRecord = document.records.find(\n (candidate) => candidate.recordKind === \"31\",\n )\n const sourceFontSize = Number(\n sheetRecord?.getCaseInsensitive(`SIZE${fontId}`) ??\n DEFAULT_INLINE_NET_LABEL_FONT_SIZE / scale,\n )\n return Math.min(\n DEFAULT_INLINE_NET_LABEL_FONT_SIZE,\n Math.max(MIN_INLINE_NET_LABEL_FONT_SIZE, sourceFontSize * scale),\n )\n}\n\nfunction getInlineNetLabelDirection(\n record: AltiumRecord,\n location: AltiumPoint,\n connectedWires: AltiumRecord[],\n): CardinalDirection {\n if (record.recordKind !== \"18\") return getRecordDirection(record)\n\n for (const wire of connectedWires) {\n const points = getSchematicRecordPoints(wire)\n for (let pointIndex = 1; pointIndex < points.length; pointIndex++) {\n const start = points[pointIndex - 1]\n const end = points[pointIndex]\n if (!start || !end || !isPointOnSegment(location, start, end)) continue\n const other = pointsEqual(location, start)\n ? end\n : pointsEqual(location, end)\n ? start\n : undefined\n if (!other) continue\n // A port's location is at the outer end of its short wire stub. Place\n // its inline text away from the component, matching the side on which\n // Altium drew the port name instead of covering the component body.\n const dx = location.x - other.x\n const dy = location.y - other.y\n if (Math.abs(dx) >= Math.abs(dy)) return dx < 0 ? \"left\" : \"right\"\n return dy < 0 ? \"down\" : \"up\"\n }\n }\n\n return getRecordDirection(record)\n}\n\nfunction getOrCreateSourceNet(params: {\n elements: AnyCircuitElement[]\n name: string\n sourceNetIdByName: Map<string, string>\n}): string {\n const { elements, name, sourceNetIdByName } = params\n const normalizedName = name.trim().toUpperCase()\n const existing = sourceNetIdByName.get(normalizedName)\n if (existing) return existing\n\n const sourceNetIdBase = `source_net_altium_${sanitizeId(name)}`\n const existingIds = new Set(\n elements.flatMap((element) =>\n element.type === \"source_net\" ? [element.source_net_id] : [],\n ),\n )\n let sourceNetId = sourceNetIdBase\n let suffix = 2\n while (existingIds.has(sourceNetId)) {\n sourceNetId = `${sourceNetIdBase}_${suffix}`\n suffix++\n }\n const sourceNet: SourceNet = {\n type: \"source_net\",\n is_ground: isGroundNet(name),\n is_power: isPowerNet(name),\n member_source_group_ids: [],\n name,\n source_net_id: sourceNetId,\n }\n elements.push(sourceNet)\n sourceNetIdByName.set(normalizedName, sourceNetId)\n return sourceNetId\n}\n\nfunction selectCircuitJsonSymbol(params: {\n designator: string\n libraryReference: string\n ports: ConvertedPort[]\n}): SymbolSelection | undefined {\n const { designator, libraryReference, ports } = params\n const classification = classifyComponent({ designator, libraryReference })\n let baseName: string | undefined\n let candidateNames: string[] = []\n if (classification === \"testpoint\" && ports.length === 1) {\n baseName = \"testpoint\"\n } else if (classification === \"crystal\" && ports.length === 2) {\n baseName = \"crystal\"\n } else if (classification === \"crystal\" && ports.length === 4) {\n baseName = \"crystal_4pin\"\n } else if (\n classification === \"mosfet\" &&\n ports.length >= 3 &&\n hasCompleteMosfetFunctionalGroups(ports)\n ) {\n const { channel_type, mosfet_mode } = getMosfetVariant(libraryReference)\n const channel = channel_type === \"p\" ? \"p\" : \"n\"\n const mode = mosfet_mode === \"depletion\" ? \"d\" : \"e\"\n const prefix = `${channel}_channel_${mode}_mosfet_transistor_gate_`\n candidateNames = SYMBOL_NAMES.filter((name) => name.startsWith(prefix))\n } else if (ports.length !== 2) {\n return undefined\n } else if (classification === \"resistor\") {\n baseName = \"boxresistor\"\n } else if (classification === \"capacitor\") {\n baseName = isPolarizedCapacitor(libraryReference)\n ? \"capacitor_polarized\"\n : \"capacitor\"\n } else if (classification === \"ferrite_bead\") {\n baseName = \"ferrite_bead\"\n } else if (classification === \"inductor\") {\n baseName = \"inductor\"\n } else if (classification === \"led\") {\n baseName = \"led\"\n }\n if (classification === \"diode\") {\n const lower = libraryReference.toLowerCase()\n baseName = lower.includes(\"schottky\") ? \"schottky_diode\" : \"diode\"\n }\n if (baseName) {\n candidateNames = CARDINAL_DIRECTIONS.map(\n (direction) => `${baseName}_${direction}`,\n )\n }\n if (candidateNames.length === 0) return undefined\n\n const selections = candidateNames.flatMap((name) => {\n const symbol = SYMBOL_CATALOG[name]\n const supportsEquivalentMosfetPads =\n classification === \"mosfet\" && symbol?.ports.length === 3\n if (\n !symbol ||\n (!supportsEquivalentMosfetPads && symbol.ports.length !== ports.length)\n ) {\n return []\n }\n const assignments = assignConvertedPortsToSymbolPorts(ports, symbol, {\n allowFunctionalPortReuse: classification === \"mosfet\",\n geometryInterchangeableLabels:\n classification === \"crystal\" && ports.length === 4\n ? new Set([\"2\", \"4\"])\n : undefined,\n })\n return assignments.length === ports.length\n ? [{ assignments, name, symbol } satisfies SymbolSelection]\n : []\n })\n return selections.sort(\n (left, right) =>\n getSymbolDirectionScore(left) - getSymbolDirectionScore(right),\n )[0]\n}\n\nfunction hasCompleteMosfetFunctionalGroups(ports: ConvertedPort[]): boolean {\n const groups = ports.map((port) =>\n normalizeFunctionalPortLabel(port.sourcePort.name),\n )\n return (\n groups.every((group) => group !== undefined) && new Set(groups).size === 3\n )\n}\n\nfunction assignConvertedPortsToSymbolPorts(\n ports: ConvertedPort[],\n symbol: SchSymbol,\n options: {\n allowFunctionalPortReuse?: boolean\n geometryInterchangeableLabels?: Set<string>\n } = {},\n): SymbolPortAssignment[] {\n const unusedSymbolPorts = new Set(symbol.ports)\n const orderedPorts = [...ports].sort(compareConvertedPorts)\n const assignments: SymbolPortAssignment[] = []\n const convertedCenter = getAveragePoint(ports.map(({ point }) => point))\n\n for (const [portIndex, convertedPort] of orderedPorts.entries()) {\n const rawHints = [\n convertedPort.schematicPort.pin_number?.toString(),\n convertedPort.sourcePort.name,\n ...(convertedPort.sourcePort.port_hints ?? []),\n ].filter((hint): hint is string => Boolean(hint))\n const functionalHints = new Set(\n rawHints.flatMap((hint) => {\n const normalized = normalizeFunctionalPortLabel(hint)\n return normalized ? [normalized] : []\n }),\n )\n const functionalPortCandidates = options.allowFunctionalPortReuse\n ? symbol.ports\n : [...unusedSymbolPorts]\n const functionalSymbolPort = functionalPortCandidates.find((symbolPort) =>\n symbolPort.labels.some((label) => {\n const normalized = normalizeFunctionalPortLabel(label)\n return normalized ? functionalHints.has(normalized) : false\n }),\n )\n const exactHints = new Set(rawHints.map((hint) => hint.toLowerCase()))\n const exactSymbolPort = [...unusedSymbolPorts].find((symbolPort) =>\n symbolPort.labels.some((label) => exactHints.has(label.toLowerCase())),\n )\n const interchangeableLabels = options.geometryInterchangeableLabels\n const isGeometryInterchangeable = rawHints.some((hint) =>\n interchangeableLabels?.has(hint.toLowerCase()),\n )\n const geometrySymbolPort = isGeometryInterchangeable\n ? [...unusedSymbolPorts]\n .filter((symbolPort) =>\n symbolPort.labels.some((label) =>\n interchangeableLabels?.has(label.toLowerCase()),\n ),\n )\n .sort(\n (left, right) =>\n getVectorDifference(\n subtractPoints(convertedPort.point, convertedCenter),\n subtractPoints(left, symbol.center),\n ) -\n getVectorDifference(\n subtractPoints(convertedPort.point, convertedCenter),\n subtractPoints(right, symbol.center),\n ),\n )[0]\n : undefined\n const symbolPort =\n functionalSymbolPort ??\n geometrySymbolPort ??\n exactSymbolPort ??\n symbol.ports[portIndex] ??\n [...unusedSymbolPorts][0]\n if (!symbolPort) continue\n if (!functionalSymbolPort || !options.allowFunctionalPortReuse) {\n unusedSymbolPorts.delete(symbolPort)\n }\n assignments.push({ convertedPort, symbolPort })\n }\n return assignments\n}\n\nfunction getAveragePoint(points: AltiumPoint[]): AltiumPoint {\n if (points.length === 0) return { x: 0, y: 0 }\n return {\n x: points.reduce((sum, point) => sum + point.x, 0) / points.length,\n y: points.reduce((sum, point) => sum + point.y, 0) / points.length,\n }\n}\n\nfunction compareConvertedPorts(\n left: ConvertedPort,\n right: ConvertedPort,\n): number {\n const leftPinNumber = left.schematicPort.pin_number\n const rightPinNumber = right.schematicPort.pin_number\n if (leftPinNumber !== undefined && rightPinNumber !== undefined) {\n return leftPinNumber - rightPinNumber\n }\n return (\n (left.schematicPort.true_ccw_index ?? 0) -\n (right.schematicPort.true_ccw_index ?? 0)\n )\n}\n\nfunction getSymbolDirectionScore(selection: SymbolSelection): number {\n const [first, second] = selection.assignments\n if (!first) return Number.POSITIVE_INFINITY\n if (!second) {\n const expectedDirection =\n VECTOR_BY_DIRECTION[\n first.convertedPort.schematicPort.facing_direction ?? \"right\"\n ]\n return getVectorDifference(\n expectedDirection,\n subtractPoints(first.symbolPort, selection.symbol.center),\n )\n }\n let difference = 0\n let comparisonCount = 0\n for (\n let firstIndex = 0;\n firstIndex < selection.assignments.length;\n firstIndex++\n ) {\n for (\n let secondIndex = firstIndex + 1;\n secondIndex < selection.assignments.length;\n secondIndex++\n ) {\n const firstAssignment = selection.assignments[firstIndex]\n const secondAssignment = selection.assignments[secondIndex]\n if (!firstAssignment || !secondAssignment) continue\n const pairDifference = getVectorDifference(\n subtractPoints(\n secondAssignment.convertedPort.point,\n firstAssignment.convertedPort.point,\n ),\n subtractPoints(secondAssignment.symbolPort, firstAssignment.symbolPort),\n )\n if (!Number.isFinite(pairDifference)) continue\n difference += pairDifference\n comparisonCount++\n }\n }\n return comparisonCount > 0\n ? difference / comparisonCount\n : Number.POSITIVE_INFINITY\n}\n\nfunction normalizeFunctionalPortLabel(value: string): string | undefined {\n const normalized = value.toLowerCase().replace(/[^a-z]/gu, \"\")\n if (normalized === \"g\" || normalized === \"gate\") return \"gate\"\n if (normalized === \"d\" || normalized === \"drain\") return \"drain\"\n if (normalized === \"s\" || normalized === \"source\") return \"source\"\n return undefined\n}\n\nfunction getVectorDifference(left: AltiumPoint, right: AltiumPoint): number {\n const leftLength = Math.hypot(left.x, left.y)\n const rightLength = Math.hypot(right.x, right.y)\n if (leftLength === 0 || rightLength === 0) {\n return Number.POSITIVE_INFINITY\n }\n const cosine =\n (left.x * right.x + left.y * right.y) / (leftLength * rightLength)\n return 1 - Math.max(-1, Math.min(1, cosine))\n}\n\nfunction applyNativeSymbolPortGeometry(params: {\n center: AltiumPoint\n selection: SymbolSelection\n}): void {\n const { center, selection } = params\n const assignmentsBySymbolPort = new Map<\n SchSymbol[\"ports\"][number],\n SymbolPortAssignment[]\n >()\n for (const assignment of selection.assignments) {\n const assignments = assignmentsBySymbolPort.get(assignment.symbolPort)\n if (assignments) assignments.push(assignment)\n else assignmentsBySymbolPort.set(assignment.symbolPort, [assignment])\n }\n\n for (const [symbolPort, assignments] of assignmentsBySymbolPort) {\n const offset = subtractPoints(symbolPort, selection.symbol.center)\n const direction = getDirectionForVector(offset)\n const symbolPortCenter = {\n x: center.x + offset.x,\n y: center.y + offset.y,\n }\n const representative = assignments.sort(\n (left, right) =>\n getPointDistance(\n left.convertedPort.schematicPort.center,\n symbolPortCenter,\n ) -\n getPointDistance(\n right.convertedPort.schematicPort.center,\n symbolPortCenter,\n ),\n )[0]\n for (const { convertedPort } of assignments) {\n convertedPort.isSchematicVisible =\n convertedPort === representative?.convertedPort\n convertedPort.schematicPort.center = symbolPortCenter\n convertedPort.schematicPort.distance_from_component_edge = Math.hypot(\n offset.x,\n offset.y,\n )\n convertedPort.schematicPort.facing_direction = direction\n convertedPort.schematicPort.side_of_component = directionToSide(direction)\n }\n }\n}\n\nfunction getPointDistance(left: AltiumPoint, right: AltiumPoint): number {\n return Math.hypot(left.x - right.x, left.y - right.y)\n}\n\nfunction getDirectionForVector(vector: AltiumPoint): CardinalDirection {\n if (Math.abs(vector.x) >= Math.abs(vector.y)) {\n return vector.x >= 0 ? \"right\" : \"left\"\n }\n return vector.y >= 0 ? \"up\" : \"down\"\n}\n\nfunction subtractPoints(\n left: { x: number; y: number },\n right: { x: number; y: number },\n): AltiumPoint {\n return { x: left.x - right.x, y: left.y - right.y }\n}\n\nfunction classifyComponent(params: {\n designator: string\n libraryReference: string\n}):\n | \"capacitor\"\n | \"crystal\"\n | \"diode\"\n | \"ferrite_bead\"\n | \"inductor\"\n | \"led\"\n | \"mosfet\"\n | \"resistor\"\n | \"testpoint\"\n | \"unknown\" {\n const { designator, libraryReference } = params\n const prefix = designator.match(/^[A-Z]+/iu)?.[0]?.toUpperCase() ?? \"\"\n const lowerReference = libraryReference.toLowerCase()\n if (prefix === \"TP\" || lowerReference.includes(\"testpoint\")) {\n return \"testpoint\"\n }\n if (\n prefix === \"Y\" ||\n lowerReference.includes(\"crystal\") ||\n /(?:^|[_-])cry(?:\\d|[_-]|$)/iu.test(libraryReference)\n ) {\n return \"crystal\"\n }\n if (lowerReference.includes(\"mosfet\")) return \"mosfet\"\n if (\n prefix === \"FB\" ||\n prefix === \"FL\" ||\n lowerReference.includes(\"ferrite\") ||\n lowerReference.includes(\"emifilter_ind\")\n ) {\n return \"ferrite_bead\"\n }\n if (prefix === \"LED\" || lowerReference.includes(\"led\")) return \"led\"\n if (prefix === \"R\" || lowerReference.includes(\"resistor\")) return \"resistor\"\n if (prefix === \"C\" || /(?:^|[_-])cap(?:[_-]|$)/iu.test(libraryReference)) {\n return \"capacitor\"\n }\n if (prefix === \"L\" || lowerReference.includes(\"inductor\")) return \"inductor\"\n if (prefix === \"D\" || lowerReference.includes(\"diode\")) return \"diode\"\n return \"unknown\"\n}\n\nfunction getMosfetVariant(libraryReference: string): {\n channel_type: \"n\" | \"p\"\n mosfet_mode: \"depletion\" | \"enhancement\"\n} {\n const lowerReference = libraryReference.toLowerCase()\n const isPChannel =\n /(?:^|[_-])p(?:channel)?(?:[_-]|$)/iu.test(libraryReference) ||\n lowerReference.includes(\"pmos\") ||\n lowerReference.includes(\"csd25\")\n return {\n channel_type: isPChannel ? \"p\" : \"n\",\n mosfet_mode: lowerReference.includes(\"depletion\")\n ? \"depletion\"\n : \"enhancement\",\n }\n}\n\nfunction isPolarizedCapacitor(libraryReference: string): boolean {\n return /(?:^|[_-])cap(?:acitor)?[_-]?pol(?:arized)?(?:[_-]|$)/iu.test(\n libraryReference,\n )\n}\n\nfunction getPrimaryComponentValue(value: string): string {\n return value.split(/[_/\\s]+/u).find(Boolean) ?? value\n}\n\nfunction getPowerPortSymbolName(\n record: AltiumRecord,\n direction: CardinalDirection,\n): string {\n const style = Math.round(record.getNumber(\"STYLE\") ?? 2)\n if (style === 4) return `digital_ground_${direction}`\n if (style === 5) return `ground_${direction}`\n if (style === 6) return `tilted_ground_${direction}`\n return `vcc_${direction}`\n}\n\nfunction getComponentBodyBounds(\n records: AltiumRecord[],\n portPoints: AltiumPoint[],\n): Bounds {\n const rectangles = records\n .filter((record) => record.recordKind === \"14\")\n .flatMap((record) => {\n const rectangle = getRectangle(record)\n return rectangle ? [rectangle] : []\n })\n if (rectangles.length > 0) return mergeBounds(rectangles)\n\n const points: AltiumPoint[] = []\n for (const record of records) {\n if (record.recordKind === \"2\") continue\n const location = getLocation(record)\n const corner = getCorner(record)\n if (location && corner) points.push(location, corner)\n points.push(...getSchematicRecordPoints(record))\n if (record.recordKind === \"8\" && location) {\n const radiusX = Math.abs(record.getNumber(\"RADIUS\") ?? 0)\n const radiusY = Math.abs(record.getNumber(\"SECONDARYRADIUS\") ?? radiusX)\n points.push(\n { x: location.x - radiusX, y: location.y - radiusY },\n { x: location.x + radiusX, y: location.y + radiusY },\n )\n }\n }\n if (points.length > 0) return getBoundsForPoints(points)\n const bounds = getBoundsForPoints(portPoints)\n if (bounds.minX === bounds.maxX) {\n bounds.minX -= 2\n bounds.maxX += 2\n }\n if (bounds.minY === bounds.maxY) {\n bounds.minY -= 2\n bounds.maxY += 2\n }\n return bounds\n}\n\nfunction findOwnedText(\n records: AltiumRecord[],\n recordKind: string,\n name: string,\n): string | undefined {\n return records\n .find(\n (record) =>\n record.recordKind === recordKind &&\n record.getDecoded(\"NAME\")?.toLowerCase() === name.toLowerCase(),\n )\n ?.getDecoded(\"TEXT\")\n}\n\nfunction isOwnedRecordVisible(\n record: AltiumRecord,\n currentPartId: number,\n): boolean {\n const ownerPartId = record.getNumber(\"OWNERPARTID\")\n const ownerPartDisplayMode = record.getNumber(\"OWNERPARTDISPLAYMODE\")\n return (\n (ownerPartId === undefined ||\n ownerPartId <= 0 ||\n ownerPartId === currentPartId) &&\n (ownerPartDisplayMode === undefined || ownerPartDisplayMode === 0)\n )\n}\n\nfunction isPinHidden(pin: AltiumRecord): boolean {\n const pinConglomerate = pin.getNumber(\"PINCONGLOMERATE\")\n return (\n pin.getBoolean(\"ISHIDDEN\") === true ||\n (pinConglomerate !== undefined && (pinConglomerate & 0x04) !== 0)\n )\n}\n\nfunction getRecordDirection(record: AltiumRecord): CardinalDirection {\n const orientation =\n ((Math.round(record.getNumber(\"ORIENTATION\") ?? 0) % 4) + 4) % 4\n return DIRECTION_BY_ORIENTATION[orientation] ?? \"right\"\n}\n\nfunction directionToSide(\n direction: CardinalDirection,\n): NonNullable<SchematicPort[\"side_of_component\"]> {\n if (direction === \"up\") return \"top\"\n if (direction === \"down\") return \"bottom\"\n return direction\n}\n\nfunction directionToOppositeSide(\n direction: CardinalDirection,\n): SchematicNetLabel[\"anchor_side\"] {\n if (direction === \"up\") return \"bottom\"\n if (direction === \"down\") return \"top\"\n return direction === \"left\" ? \"right\" : \"left\"\n}\n\nfunction groupByPoint(ports: ConvertedPort[]): Map<string, ConvertedPort[]> {\n const grouped = new Map<string, ConvertedPort[]>()\n for (const port of ports) {\n const key = pointKey(port.point)\n const existing = grouped.get(key)\n if (existing) existing.push(port)\n else grouped.set(key, [port])\n }\n return grouped\n}\n\nfunction uniqueConvertedPorts(ports: ConvertedPort[]): ConvertedPort[] {\n const seenSourcePortIds = new Set<string>()\n return ports.filter((port) => {\n const sourcePortId = port.sourcePort.source_port_id\n if (seenSourcePortIds.has(sourcePortId)) return false\n seenSourcePortIds.add(sourcePortId)\n return true\n })\n}\n\nfunction getPortIdAtElectricalPoint(\n port: ConvertedPort | undefined,\n electricalPoint: AltiumPoint,\n scale: number,\n): string | undefined {\n if (!port?.isSchematicVisible) return undefined\n return pointsEqual(\n port.schematicPort.center,\n scalePoint(electricalPoint, scale),\n )\n ? port.schematicPort.schematic_port_id\n : undefined\n}\n\nfunction getBoundsForPoints(points: AltiumPoint[]): Bounds {\n if (points.length === 0) return { maxX: 1, maxY: 1, minX: -1, minY: -1 }\n return {\n maxX: Math.max(...points.map((point) => point.x)),\n maxY: Math.max(...points.map((point) => point.y)),\n minX: Math.min(...points.map((point) => point.x)),\n minY: Math.min(...points.map((point) => point.y)),\n }\n}\n\nfunction mergeBounds(bounds: Bounds[]): Bounds {\n return {\n maxX: Math.max(...bounds.map((bound) => bound.maxX)),\n maxY: Math.max(...bounds.map((bound) => bound.maxY)),\n minX: Math.min(...bounds.map((bound) => bound.minX)),\n minY: Math.min(...bounds.map((bound) => bound.minY)),\n }\n}\n\nfunction getBoundsCenter(bounds: Bounds): AltiumPoint {\n return {\n x: (bounds.minX + bounds.maxX) / 2,\n y: (bounds.minY + bounds.maxY) / 2,\n }\n}\n\nfunction getRectangle(record: AltiumRecord): Bounds | undefined {\n const location = getLocation(record)\n const corner = getCorner(record)\n if (!location || !corner) return undefined\n return {\n maxX: Math.max(location.x, corner.x),\n maxY: Math.max(location.y, corner.y),\n minX: Math.min(location.x, corner.x),\n minY: Math.min(location.y, corner.y),\n }\n}\n\nfunction getLocation(record: AltiumRecord): AltiumPoint | undefined {\n const x = getCoordinate(record, \"LOCATION.X\")\n const y = getCoordinate(record, \"LOCATION.Y\")\n return x === undefined || y === undefined ? undefined : { x, y }\n}\n\nfunction getCorner(record: AltiumRecord): AltiumPoint | undefined {\n const x = getCoordinate(record, \"CORNER.X\")\n const y = getCoordinate(record, \"CORNER.Y\")\n return x === undefined || y === undefined ? undefined : { x, y }\n}\n\nfunction getCoordinate(record: AltiumRecord, key: string): number | undefined {\n const raw = record.getCaseInsensitive(key)\n if (raw === undefined) return undefined\n const integer = Number(raw)\n if (!Number.isFinite(integer)) return undefined\n const fractionRaw = record.getCaseInsensitive(`${key}_FRAC`)\n if (fractionRaw === undefined) return integer\n const fraction = Number(`0.${fractionRaw.replace(/^[+-]/u, \"\")}`)\n if (!Number.isFinite(fraction)) return integer\n return integer < 0 ? integer - fraction : integer + fraction\n}\n\nfunction parsePinNumber(value: string): number | undefined {\n const parsed = Number(value)\n return Number.isInteger(parsed) && parsed >= 0 ? parsed : undefined\n}\n\nfunction scalePoint(point: AltiumPoint, scale: number): AltiumPoint {\n return { x: point.x * scale, y: point.y * scale }\n}\n\nfunction pointKey(point: AltiumPoint): string {\n return `${point.x.toFixed(6)},${point.y.toFixed(6)}`\n}\n\nfunction pointsEqual(\n left: AltiumPoint,\n right: AltiumPoint | undefined,\n): boolean {\n return (\n right !== undefined &&\n Math.abs(left.x - right.x) < 0.000001 &&\n Math.abs(left.y - right.y) < 0.000001\n )\n}\n\nfunction uniqueStrings(values: Array<string | undefined>): string[] {\n return [...new Set(values.filter((value): value is string => Boolean(value)))]\n}\n\nfunction sanitizeId(value: string): string {\n const sanitized = value\n .trim()\n .toLowerCase()\n .replace(/[^a-z0-9]+/gu, \"_\")\n .replace(/^_+|_+$/gu, \"\")\n return sanitized || \"unnamed\"\n}\n\nfunction isGroundNet(name: string): boolean {\n return /(?:^|[_+-])(?:[adp]?gnd|ground)(?:$|[_+\\d-])/iu.test(name)\n}\n\nfunction isPowerNet(name: string): boolean {\n return (\n isGroundNet(name) ||\n /(?:^|[_+-])(?:vcc|vdd|vss)(?:$|[a-z0-9_+-])/iu.test(name) ||\n /(?:^|[_+-])(?:vin|vout|pwr|power)(?:$|[_+\\d-])/iu.test(name)\n )\n}\n","import {\n AltiumBinaryPcbDoc,\n AltiumPcbDoc,\n type AltiumPcbDocument,\n AltiumSchDoc,\n parseAltiumFile,\n parseAltiumPcbDoc,\n parseAltiumSchDoc,\n} from \"altiumts\"\nimport type { AnyCircuitElement } from \"circuit-json\"\nimport {\n type ConvertAltiumPcbDocOptions,\n convertAltiumPcbDocToCircuitJson,\n} from \"./convert-altium-pcb-doc-to-circuit-json\"\nimport {\n type ConvertAltiumSchDocOptions,\n convertAltiumSchDocToCircuitJson,\n} from \"./convert-altium-sch-doc-to-circuit-json\"\n\nexport type AltiumSourceType = \"auto\" | \"pcb\" | \"schematic\"\n\nexport interface ConvertAltiumToCircuitJsonOptions {\n pcb?: ConvertAltiumPcbDocOptions\n schematic?: ConvertAltiumSchDocOptions\n sourceType?: AltiumSourceType\n}\n\nexport type SupportedAltiumDocument = AltiumPcbDocument | AltiumSchDoc\n\nexport function convertAltiumToCircuitJson(\n source: ArrayBuffer | Uint8Array | string,\n options: ConvertAltiumToCircuitJsonOptions = {},\n): AnyCircuitElement[] {\n const sourceType = options.sourceType ?? \"auto\"\n\n if (sourceType === \"pcb\") {\n if (typeof source === \"string\") {\n return convertAltiumPcbDocToCircuitJson(\n parseAltiumPcbDoc(source),\n options.pcb,\n )\n }\n const { document } = parseAltiumFile(toUint8Array(source))\n if (\n !(document instanceof AltiumPcbDoc) &&\n !(document instanceof AltiumBinaryPcbDoc)\n ) {\n throw new TypeError(\n `Expected an Altium PCB document, got ${document.type}`,\n )\n }\n return convertAltiumPcbDocToCircuitJson(document, options.pcb)\n }\n if (sourceType === \"schematic\") {\n return convertAltiumSchDocToCircuitJson(\n parseAltiumSchDoc(normalizeSchematicSource(source)),\n options.schematic,\n )\n }\n\n const bytes = toUint8Array(source)\n const { document } = parseAltiumFile(bytes)\n return convertAltiumDocumentToCircuitJson(document, options)\n}\n\nexport function convertAltiumDocumentToCircuitJson(\n document: unknown,\n options: ConvertAltiumToCircuitJsonOptions = {},\n): AnyCircuitElement[] {\n if (document instanceof AltiumSchDoc) {\n return convertAltiumSchDocToCircuitJson(document, options.schematic)\n }\n if (\n document instanceof AltiumPcbDoc ||\n document instanceof AltiumBinaryPcbDoc\n ) {\n return convertAltiumPcbDocToCircuitJson(document, options.pcb)\n }\n const type =\n typeof document === \"object\" && document !== null && \"type\" in document\n ? String(document.type)\n : typeof document\n throw new TypeError(`Unsupported Altium document type: ${type}`)\n}\n\nfunction toUint8Array(source: ArrayBuffer | Uint8Array | string): Uint8Array {\n if (typeof source === \"string\") return new TextEncoder().encode(source)\n if (source instanceof Uint8Array) return source\n return new Uint8Array(source)\n}\n\nfunction normalizeSchematicSource(\n source: ArrayBuffer | Uint8Array | string,\n): Uint8Array | string {\n return source instanceof ArrayBuffer ? new Uint8Array(source) : source\n}\n"],"mappings":"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","names":["getSchematicRecordPoints","symbolPort","getSchematicRecordPoints","scalePoint","getLocation","getCorner","getRectangle","getCoordinate","document"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "altium-to-circuit-json",
3
- "version": "0.0.13",
3
+ "version": "0.0.14",
4
4
  "description": "Convert Altium schematic and PCB documents into Circuit JSON",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -44,7 +44,7 @@
44
44
  },
45
45
  "dependencies": {
46
46
  "altiumts": "^0.0.26",
47
- "circuit-json": "^0.0.456",
47
+ "circuit-json": "^0.0.475",
48
48
  "format-si-unit": "^0.0.11",
49
49
  "schematic-symbols": "^0.0.238"
50
50
  },