import type { PhyFile, Node } from "./phy"; import { createId } from "./ids"; import { importKle } from "../io/kleImport"; import { sha256Jcs } from "../io/json"; import { createIdx, type IdxFile } from "./idx"; import { createElc, type ElcFile } from "./elc"; import { createMap, type MapFile } from "./map"; export type MatrixOutputSettings = { rowPins: string[]; colPins: string[]; kind?: "matrix" | "charlieplexing" | "direct"; [key: string]: unknown; }; export type ProjectFile = { format: "beyond-kle-mock-project"; version: string; projectId: string; phy: PhyFile; elc: ElcFile; idx: IdxFile; map: MapFile; output: { variantSelection: Record; matrix?: MatrixOutputSettings; [key: string]: unknown }; ui?: unknown; [key: string]: unknown; }; /** Creates default variant selections from PHY. T-10/T-20. */ export function defaultVariantSelection(phy: PhyFile): Record { const out: Record = {}; const walk = (nodes: Node[]) => nodes.forEach((n) => { if (n.type === "cluster") walk(n.children); if (n.type === "variantGroup") { out[n.id] = n.default; const v = n.children.find((x) => x.id === n.default); if (v) walk(v.children); } }); walk(phy.root); return out; } /** Creates an empty project with default reference values. T-10/T-13. */ export async function createProject(phy: PhyFile, gen?: () => string): Promise { const ref = { source: "project:phy", checksum: await sha256Jcs(phy) }; return { format: "beyond-kle-mock-project", version: "0.1.0", projectId: createId("project-", gen), phy: structuredClone(phy), elc: createElc(ref), idx: createIdx(phy, [], ref), map: createMap(ref), output: { variantSelection: defaultVariantSelection(phy) }, }; } /** Imports KLE as a new project and initializes IDX from occurrence order. T-18. */ export async function createProjectFromKle( input: unknown, options: { idGenerator?: () => string; name?: string; projectIdGenerator?: () => string } = {}, ): Promise { const { phy, keyOrder } = importKle(input, options); const p = await createProject(phy, options.projectIdGenerator); p.idx = createIdx(phy, keyOrder, p.idx.phyReference); return p; }