/* groups.js — busbar (parallel cell group) CRUD. * * A Busbar is { id, name, color, cells: [cellId, …] }. * Cell `assigned` lookup is maintained so the canvas can render colors. */ const Groups = (() => { // Friendly hue palette — rotates as new busbars are added. const COLORS = [ "#f08a24", "#4fa3ff", "#3ecf8e", "#e85aad", "#a78bfa", "#f5d142", "#52d6c6", "#ff6b6b", "#7cb342", "#ba68c8", "#26c6da", "#ffa726", ]; let nextId = 1; let nextNameIdx = 1; function create(state, cellIds) { if (!cellIds || cellIds.length === 0) return null; const id = nextId++; const bb = { id, name: `P${nextNameIdx++}`, color: COLORS[(id - 1) % COLORS.length], shape: "panel", // "panel" (default, production plate) | "wire" cells: [...cellIds], }; state.busbars.push(bb); _reassign(state); return bb; } function remove(state, busbarId) { state.busbars = state.busbars.filter((b) => b.id !== busbarId); _reassign(state); } function rename(state, busbarId, name) { const bb = state.busbars.find((b) => b.id === busbarId); if (bb) bb.name = name; } function recolor(state, busbarId, color) { const bb = state.busbars.find((b) => b.id === busbarId); if (bb) bb.color = color; } function addCells(state, busbarId, cellIds) { const bb = state.busbars.find((b) => b.id === busbarId); if (!bb) return; const set = new Set(bb.cells); for (const id of cellIds) { if (!set.has(id)) { bb.cells.push(id); set.add(id); } } _reassign(state); } function removeCells(state, busbarId, cellIds) { const bb = state.busbars.find((b) => b.id === busbarId); if (!bb) return; const rm = new Set(cellIds); bb.cells = bb.cells.filter((id) => !rm.has(id)); _reassign(state); } function _reassign(state) { state.cellToBusbar = new Map(); for (const bb of state.busbars) { for (const cid of bb.cells) state.cellToBusbar.set(cid, bb.id); } } function findByCell(state, cellId) { return state.cellToBusbar.get(cellId); } function reset() { nextId = 1; nextNameIdx = 1; } return { create, remove, rename, recolor, addCells, removeCells, findByCell, reset }; })();