42 lines
1.7 KiB
TypeScript
42 lines
1.7 KiB
TypeScript
/**
|
|
* Breadboard internal-connectivity helpers.
|
|
*
|
|
* A solderless breadboard electrically joins holes in fixed groups:
|
|
* - each terminal-strip column of 5 holes is one net
|
|
* (full board: rows a-e form the top bank, f-j the bottom bank), and
|
|
* - each power rail (full board only) is one net running the whole length.
|
|
*
|
|
* Pin names follow the Wokwi convention so imported diagram.json wires work
|
|
* verbatim (e.g. "18t.d" = column 18, top bank, row d; "bn.15" = bottom
|
|
* negative rail, hole 15):
|
|
* holes: `${col}t.${a-e}` | `${col}b.${f-j}`
|
|
* rails: `tp.N` / `tn.N` (top +/-) | `bp.N` / `bn.N` (bottom +/-)
|
|
*
|
|
* Consumers (NetlistBuilder union-find, DynamicComponent digital trace) use
|
|
* `breadboardGroupKey` to decide which pins are internally shorted: two pins
|
|
* on the same breadboard belong to the same net iff their group keys match.
|
|
*/
|
|
|
|
const BREADBOARD_IDS = new Set(['breadboard', 'breadboard-mini']);
|
|
|
|
/** True when the metadataId is one of the breadboard parts. */
|
|
export function isBreadboard(metadataId: string): boolean {
|
|
return BREADBOARD_IDS.has(metadataId);
|
|
}
|
|
|
|
const HOLE_RE = /^(\d+)([tb])\.([a-j])$/;
|
|
const RAIL_RE = /^([tb][pn])\.(\d+)$/;
|
|
|
|
/**
|
|
* Group key for a breadboard pin, or null when the pin name is not a valid
|
|
* breadboard hole/rail. Pins with equal keys are internally connected.
|
|
*/
|
|
export function breadboardGroupKey(metadataId: string, pinName: string): string | null {
|
|
if (!isBreadboard(metadataId)) return null;
|
|
const hole = HOLE_RE.exec(pinName);
|
|
if (hole) return `col${hole[1]}${hole[2]}`; // e.g. "col18t" — one 5-hole strip
|
|
const rail = RAIL_RE.exec(pinName);
|
|
if (rail) return `rail${rail[1]}`; // e.g. "railbn" — the whole rail is one net
|
|
return null;
|
|
}
|