@mica-js/editor 0.0.0-stage → 0.2.0
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/LICENSE +21 -0
- package/README.md +176 -2
- package/dist/index.d.ts +413 -0
- package/dist/index.js +7390 -0
- package/dist/index.js.map +1 -0
- package/dist/style.css +104 -0
- package/package.json +44 -3
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.js","names":["SchematicEditor","SchematicEditor","symbols.nextDesignator","wires.connectWireAt","wires.previewWireSegment","createSchematicEditor","_decorate","_decorateParam","_decorate","_decorateParam","_decorate","_decorateParam","createView","snapshot","canvasSnapshot","_decorate","_decorateParam","_decorate","_decorateParam","canvasSnapshot","canvasSnapshot"],"sources":["../src/schematic/model/inspector.ts","../src/schematic/model/reference.ts","../src/schematic/editing/query.ts","../src/schematic/editing/preview.ts","../src/schematic/editing/segment-drag.ts","../src/schematic/model/wires.ts","../src/schematic/model/symbols.ts","../src/schematic/types.ts","../src/schematic/model/clipboard.ts","../src/schematic/model/content.ts","../src/schematic/editing/editor.ts","../src/schematic/model/store.ts","../src/schematic/model/document-model.ts","../src/schematic/model/selection.ts","../src/schematic/render/theme.ts","../src/schematic/render/viewport.ts","../src/schematic/render/canvas-renderer.ts","../src/schematic/render/scene.ts","../src/schematic/editor/clipboard.ts","../src/schematic/editor/snapping/nodes.ts","../src/schematic/editor/snapping/drag.ts","../src/schematic/editor/snapping/wire.ts","../src/schematic/editor/snapping/label.ts","../src/schematic/editor/interactions/placement.ts","../src/schematic/editor/selection-box.ts","../src/schematic/editor/interactions/selection.ts","../src/schematic/editor/interactions/wire.ts","../src/schematic/editor/interactions/keyboard.ts","../src/schematic/editor/interactions/move.ts","../src/schematic/editor/interactions/pointer.ts","../src/schematic/editor/interactions/segment.ts","../src/schematic/editor/interactions/state.ts","../src/schematic/editor/interactions/input.ts","../src/schematic/editor/scene-input.ts","../src/schematic/editor/icons.ts","../src/schematic/editor/shell.ts","../src/schematic/editor/viewport-state.ts","../src/schematic/editor/schematic-editor.ts","../src/snapshot.ts","../src/instantiation.ts","../src/provider-services.ts","../src/libraries.ts","../src/schematic/devices.ts","../src/schematic/document.ts","../src/schematic-editor.ts","../src/commands.ts","../src/canvas/resources.ts","../src/canvas/runtime-factory.ts","../src/canvas/session.ts","../src/canvas/model.ts","../src/canvas/document.ts","../src/canvas/view.ts","../src/canvas-editor.ts"],"sourcesContent":["import {\n DEFAULT_TEXT_CONTENT,\n designatorOf,\n isTextDevice,\n namesNet,\n netNameOf,\n parseDeviceReference,\n propertyValueProblem,\n symbolRole,\n textDeviceContent,\n type DeviceSymbolProvider,\n type PropertyDescriptor,\n type PropertyValue,\n type SchematicDocument,\n type SchematicSymbol,\n type SchematicTopology,\n} from '@mica-js/document/schematic';\nimport type { Inspector, PropertyField, SchematicTarget, ISymbolInspector } from '../types';\n\nexport interface InspectorContext {\n readonly devices: DeviceSymbolProvider | undefined;\n readonly topology: () => SchematicTopology;\n}\n\n/** Builds the property-panel payload for the current selection. */\nexport function buildInspector(\n document: SchematicDocument,\n selection: readonly SchematicTarget[],\n context: InspectorContext,\n): Inspector {\n if (selection.length !== 1) {\n return undefined;\n }\n const [item] = selection;\n if (item === undefined) {\n return undefined;\n }\n if (item.kind === 'wire') {\n const wire = document.sheet.wires.find((candidate) => candidate.id === item.id);\n if (wire === undefined) {\n return undefined;\n }\n const net = context.topology().nets.find((candidate) => candidate.wireIds.includes(wire.id));\n return { kind: 'wire', id: wire.id, netName: net?.name ?? null, points: wire.points };\n }\n if (item.kind !== 'symbol' && item.kind !== 'reference') {\n return undefined;\n }\n const symbolId = item.kind === 'symbol' ? item.id : item.symbolId;\n const symbol = document.sheet.symbols.find((candidate) => candidate.id === symbolId);\n if (symbol === undefined) {\n return undefined;\n }\n return symbolInspector(symbol, context.devices);\n}\n\nfunction symbolInspector(\n symbol: SchematicSymbol,\n devices: DeviceSymbolProvider | undefined,\n): ISymbolInspector {\n const reference = parseDeviceReference(symbol.device);\n const role = symbolRole(symbol.device);\n const designator = designatorOf(symbol);\n const net = netNameOf(symbol);\n return {\n kind: 'symbol',\n id: symbol.id,\n role,\n device: symbol.device,\n name:\n (reference === undefined ? undefined : devices?.getDeviceName(reference)) ??\n builtinName(symbol),\n builtin: role !== 'component',\n ...(designator === undefined ? {} : { designator }),\n ...(net === undefined ? {} : { net }),\n x: symbol.x,\n y: symbol.y,\n rotation: symbol.rotation,\n properties: propertyFields(symbol, devices),\n };\n}\n\nfunction propertyFields(\n symbol: SchematicSymbol,\n devices: DeviceSymbolProvider | undefined,\n): readonly PropertyField[] {\n const overrides = symbol.properties ?? {};\n\n if (isTextDevice(symbol.device)) {\n const override = overrides['text'];\n return [toField(TEXT_DESCRIPTOR, typeof override === 'string' ? override : undefined)];\n }\n\n // Net-naming symbols expose their net name as a dedicated inspector row, not as a property.\n if (namesNet(symbolRole(symbol.device))) {\n return [];\n }\n\n const fields: PropertyField[] = [];\n for (const descriptor of devicePropertyDescriptors(symbol, devices).values()) {\n const override = overrides[descriptor.key];\n const valid =\n override !== undefined && propertyValueProblem(descriptor, override) === undefined;\n fields.push(toField(descriptor, valid ? override : undefined));\n }\n return fields;\n}\n\n/** Moves the declared default to `defaultValue` so hosts can tell it apart from the instance value. */\nfunction toField(descriptor: PropertyDescriptor, value: PropertyValue | undefined): PropertyField {\n const { default: defaultValue, ...rest } = descriptor;\n return {\n ...rest,\n ...(defaultValue === undefined ? {} : { defaultValue }),\n ...(value === undefined ? {} : { value }),\n };\n}\n\nfunction devicePropertyDescriptors(\n symbol: SchematicSymbol,\n devices: DeviceSymbolProvider | undefined,\n): ReadonlyMap<string, PropertyDescriptor> {\n const reference = parseDeviceReference(symbol.device);\n if (reference === undefined) {\n return new Map();\n }\n return devices?.getDevicePropertyDescriptors?.(reference) ?? new Map();\n}\n\nfunction builtinName(symbol: SchematicSymbol): string | undefined {\n if (isTextDevice(symbol.device)) {\n return textDeviceContent(symbol);\n }\n return netNameOf(symbol);\n}\n\n/** `builtin:text` carries its content in one string property, described like any other. */\nconst TEXT_DESCRIPTOR: PropertyDescriptor = {\n key: 'text',\n type: 'string',\n title: '文本',\n default: DEFAULT_TEXT_CONTENT,\n};\n","import {\n referenceAnchor,\n pinsBounds,\n symbolPinPosition,\n type DeviceSymbolDefinition,\n type Point,\n type SchematicSymbol,\n} from '@mica-js/document/schematic';\n\nexport function deviceReferenceAnchor(\n definition: DeviceSymbolDefinition | undefined,\n override: Point | undefined,\n): Point {\n const declared = definition?.annotations?.designator?.position;\n return referenceAnchor(\n definition?.bounds ?? (definition === undefined ? undefined : pinsBounds(definition.pins)),\n override ?? (declared === undefined ? undefined : { x: declared[0], y: declared[1] }),\n );\n}\n\nexport function deviceReferencePosition(\n symbol: Pick<SchematicSymbol, 'x' | 'y' | 'rotation' | 'reference'>,\n definition: DeviceSymbolDefinition | undefined,\n): Point {\n return symbolPinPosition(symbol, deviceReferenceAnchor(definition, symbol.reference));\n}\n","import {\n type Rect,\n type SchematicDocument,\n type Point,\n GROUND_DEVICE,\n POWER_DEVICE,\n designatorOf,\n hasDesignator,\n isLabelDevice,\n isTextDevice,\n netNameOf,\n parseDeviceReference,\n symbolRole,\n textDeviceContent,\n type DeviceSymbolProvider,\n pinSide,\n pinStubEnd,\n pinsBounds,\n DEFAULT_TOLERANCE,\n distanceToSegment,\n pointOnPolyline,\n pointsEqual,\n rotatePoint,\n symbolBounds,\n symbolPinPosition,\n} from '@mica-js/document/schematic';\n\nimport { deviceReferencePosition } from '../model/reference';\n\nexport interface IHitTestOptions {\n readonly devices?: DeviceSymbolProvider;\n /** Coordinate comparison tolerance in page units; defaults to exact matching. */\n readonly tolerance?: number;\n /** Include symbol bodies in the hit search; defaults to true. */\n readonly includeSymbols?: boolean;\n}\n\nexport type SchematicHit =\n | { readonly kind: 'reference'; readonly symbolId: string }\n | { readonly kind: 'junction'; readonly id: string }\n | { readonly kind: 'pin'; readonly symbolId: string; readonly pinId: string }\n | { readonly kind: 'wire'; readonly id: string; readonly segment: number }\n | { readonly kind: 'symbol'; readonly id: string };\n\n/**\n * Returns the topmost element at `point`: reference labels, junctions, pins, wires, then\n * symbol bodies.\n */\nexport function hitTestSchematic(\n document: SchematicDocument,\n point: Point,\n options: IHitTestOptions = {},\n): SchematicHit | undefined {\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const includeSymbols = options.includeSymbols ?? true;\n\n const reference = referenceHit(document, point, options, tolerance);\n if (reference !== undefined) {\n return reference;\n }\n\n const junctions = [...document.sheet.junctions].sort((a, b) => a.id.localeCompare(b.id));\n for (const junction of junctions) {\n if (pointsEqual({ x: junction.x, y: junction.y }, point, tolerance)) {\n return { kind: 'junction', id: junction.id };\n }\n }\n\n if (options.devices !== undefined) {\n const symbols = [...document.sheet.symbols]\n .filter((symbol) => !isLabelDevice(symbol.device))\n .sort((a, b) => a.id.localeCompare(b.id));\n for (const symbol of symbols) {\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices.getDeviceSymbol(reference);\n if (definition === undefined) {\n continue;\n }\n const body = definition.bounds ??\n pinsBounds(definition.pins) ?? { x: -12, y: -12, width: 24, height: 24 };\n const pinIds = Object.keys(definition.pins).sort();\n for (const pinId of pinIds) {\n const anchor = definition.pins[pinId];\n if (anchor === undefined) {\n continue;\n }\n const end = symbolPinPosition(symbol, anchor);\n if (pointsEqual(end, point, tolerance)) {\n return { kind: 'pin', symbolId: symbol.id, pinId };\n }\n // Custom graphics own their pin strokes; only declared anchors are connection targets.\n if (definition.graphics !== undefined) {\n continue;\n }\n // The whole pin stub is grabbable, so clicking the drawn pin starts a wire at its end.\n const side = pinSide(anchor, body);\n if (side === undefined) {\n continue;\n }\n const start = symbolPinPosition(symbol, pinStubEnd(body, anchor, side));\n if (distanceToSegment(point, start, end) <= tolerance) {\n return { kind: 'pin', symbolId: symbol.id, pinId };\n }\n }\n }\n }\n\n const wires = [...document.sheet.wires].sort((a, b) => a.id.localeCompare(b.id));\n for (const wire of wires) {\n for (let index = 1; index < wire.points.length; index += 1) {\n const previous = wire.points[index - 1];\n const current = wire.points[index];\n if (\n previous !== undefined &&\n current !== undefined &&\n distanceToSegment(point, previous, current) <= tolerance\n ) {\n return { kind: 'wire', id: wire.id, segment: index - 1 };\n }\n }\n }\n\n if (!includeSymbols) {\n return undefined;\n }\n\n const symbols = [...document.sheet.symbols].sort((a, b) => a.id.localeCompare(b.id));\n for (const symbol of symbols) {\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices?.getDeviceSymbol(reference);\n const bounds =\n definition === undefined\n ? annotationBounds(symbol)\n : symbolBounds(symbol, definition.bounds, definition.pins);\n if (bounds === undefined) {\n continue;\n }\n const inside =\n point.x >= bounds.x - tolerance &&\n point.x <= bounds.x + bounds.width + tolerance &&\n point.y >= bounds.y - tolerance &&\n point.y <= bounds.y + bounds.height + tolerance;\n if (inside) {\n return { kind: 'symbol', id: symbol.id };\n }\n }\n\n return undefined;\n}\n\n/** Approximate clickable box for symbols without device geometry (labels, text annotations). */\nfunction annotationBounds(symbol: {\n readonly id: string;\n readonly device: string;\n readonly x: number;\n readonly y: number;\n readonly rotation: number;\n readonly net?: string;\n readonly properties?: Readonly<Record<string, unknown>>;\n}): Rect {\n const device = symbol.device;\n if (device === POWER_DEVICE) {\n // Stem, bar and the label above them.\n return rotatedBounds(symbol, {\n x: -POWER_HALF_WIDTH,\n y: -POWER_HEIGHT,\n width: POWER_HALF_WIDTH * 2,\n height: POWER_HEIGHT + ANNOTATION_HEIGHT / 2,\n });\n }\n if (device === GROUND_DEVICE) {\n // Stem, the three bars and the label below them.\n return rotatedBounds(symbol, {\n x: -POWER_HALF_WIDTH,\n y: -ANNOTATION_HEIGHT / 2,\n width: POWER_HALF_WIDTH * 2,\n height: GROUND_HEIGHT,\n });\n }\n const content = isTextDevice(device)\n ? textDeviceContent(symbol)\n : isLabelDevice(device)\n ? (netNameOf(symbol) ?? '')\n : '';\n if (content.length === 0) {\n return { x: symbol.x, y: symbol.y, width: 0, height: 0 };\n }\n const height = ANNOTATION_HEIGHT;\n // Labels anchor at their connection point (left edge); text is drawn from its origin too.\n return rotatedBounds(symbol, {\n x: 0,\n y: -height / 2,\n width: content.length * ANNOTATION_CHAR_WIDTH,\n height,\n });\n}\n\n/** Axis-aligned box of a symbol-local rectangle after applying the symbol's rotation. */\nfunction rotatedBounds(\n symbol: { readonly x: number; readonly y: number; readonly rotation: number },\n local: Rect,\n): Rect {\n if (symbol.rotation % 360 === 0) {\n return {\n x: symbol.x + local.x,\n y: symbol.y + local.y,\n width: local.width,\n height: local.height,\n };\n }\n const corners = [\n { x: local.x, y: local.y },\n { x: local.x + local.width, y: local.y },\n { x: local.x, y: local.y + local.height },\n { x: local.x + local.width, y: local.y + local.height },\n ].map((corner) => {\n const rotated = rotatePoint(corner, symbol.rotation);\n return { x: symbol.x + rotated.x, y: symbol.y + rotated.y };\n });\n const xs = corners.map((corner) => corner.x);\n const ys = corners.map((corner) => corner.y);\n const minX = Math.min(...xs);\n const minY = Math.min(...ys);\n return { x: minX, y: minY, width: Math.max(...xs) - minX, height: Math.max(...ys) - minY };\n}\n\nconst ANNOTATION_CHAR_WIDTH = 6;\nconst ANNOTATION_HEIGHT = 12;\n/** Half width of the power/ground glyph box. */\nconst POWER_HALF_WIDTH = 10;\n/** How far the power symbol (stem + bar + label) reaches above its anchor. */\nconst POWER_HEIGHT = 24;\n/** How far the ground symbol (stem + bars + label) reaches below its anchor. */\nconst GROUND_HEIGHT = 30;\n\n/** Hit box of a reference designator, positioned like the renderer draws it. */\nfunction referenceHit(\n document: SchematicDocument,\n point: Point,\n options: IHitTestOptions,\n tolerance: number,\n): SchematicHit | undefined {\n const symbols = [...document.sheet.symbols]\n .filter((symbol) => hasDesignator(symbolRole(symbol.device)))\n .sort((a, b) => a.id.localeCompare(b.id));\n for (const symbol of symbols) {\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices?.getDeviceSymbol(reference);\n if (definition === undefined) {\n continue;\n }\n const designator = designatorOf(symbol) ?? symbol.id;\n const anchor = deviceReferencePosition(symbol, definition);\n const width = designator.length * ANNOTATION_CHAR_WIDTH;\n const align = definition.annotations?.designator?.align ?? 'left';\n const normalized = (((symbol.rotation % 360) + 540) % 360) - 180;\n const flipped = Math.abs(normalized) === 180;\n const rotation = flipped ? 0 : normalized;\n const textAlign = flipped\n ? align === 'left'\n ? 'right'\n : align === 'right'\n ? 'left'\n : align\n : align;\n const local = rotatePoint({ x: point.x - anchor.x, y: point.y - anchor.y }, -rotation);\n const box: Rect = {\n x: textAlign === 'left' ? 0 : textAlign === 'center' ? -width / 2 : -width,\n y: flipped ? 0 : -ANNOTATION_HEIGHT,\n width,\n height: ANNOTATION_HEIGHT,\n };\n const inside =\n local.x >= box.x - tolerance &&\n local.x <= box.x + box.width + tolerance &&\n local.y >= box.y - tolerance &&\n local.y <= box.y + box.height + tolerance;\n if (inside) {\n return { kind: 'reference', symbolId: symbol.id };\n }\n }\n return undefined;\n}\n\nexport interface IJunctionCandidate {\n readonly point: Point;\n readonly wireIds: readonly string[];\n}\nexport interface IJunctionCandidateOptions {\n readonly tolerance?: number;\n}\n\n/**\n * Finds positions where wires touch or cross without an explicit junction (#6 requires junctions\n * to be created by the user). Existing junctions are excluded.\n */\nexport function findJunctionCandidates(\n document: SchematicDocument,\n options: IJunctionCandidateOptions = {},\n): readonly IJunctionCandidate[] {\n const tolerance = options.tolerance ?? DEFAULT_TOLERANCE;\n const wires = [...document.sheet.wires].sort((a, b) => a.id.localeCompare(b.id));\n const existing = document.sheet.junctions;\n const candidates: { point: Point; wireIds: Set<string> }[] = [];\n\n const add = (point: Point, wireId: string): void => {\n // Points within tolerance describe the same junction handle, so they are merged.\n const entry = candidates.find((candidate) => pointsEqual(candidate.point, point, tolerance));\n if (entry === undefined) {\n candidates.push({ point: { x: point.x, y: point.y }, wireIds: new Set([wireId]) });\n return;\n }\n entry.wireIds.add(wireId);\n };\n\n for (let left = 0; left < wires.length; left += 1) {\n const first = wires[left];\n if (first === undefined) {\n continue;\n }\n for (let right = left + 1; right < wires.length; right += 1) {\n const second = wires[right];\n if (second === undefined) {\n continue;\n }\n const points: Point[] = [...intersections(first.points, second.points, tolerance)];\n const firstPoints = [...first.points];\n const secondPoints = [...second.points];\n for (const point of firstPoints) {\n if (pointOnPolyline(secondPoints, point, tolerance)) {\n points.push(point);\n }\n }\n for (const point of secondPoints) {\n if (pointOnPolyline(firstPoints, point, tolerance)) {\n points.push(point);\n }\n }\n for (const point of points) {\n add(point, first.id);\n add(point, second.id);\n }\n }\n }\n\n const result: IJunctionCandidate[] = [];\n for (const candidate of candidates) {\n if (candidate.wireIds.size < 2) {\n continue;\n }\n const wireIds = [...candidate.wireIds].sort();\n const covered = existing.some(\n (junction) =>\n pointsEqual({ x: junction.x, y: junction.y }, candidate.point, tolerance) &&\n wireIds.every((wireId) => junction.wires.includes(wireId)),\n );\n if (!covered) {\n result.push({ point: candidate.point, wireIds });\n }\n }\n\n return result.sort(\n (a, b) =>\n a.point.x - b.point.x ||\n a.point.y - b.point.y ||\n a.wireIds.join(',').localeCompare(b.wireIds.join(',')),\n );\n}\n\n/** Segment–segment intersection points in the closed-segment sense, within `tolerance`. */\nfunction* intersections(\n first: readonly Point[],\n second: readonly Point[],\n tolerance: number,\n): Generator<Point> {\n for (let a = 1; a < first.length; a += 1) {\n const a1 = first[a - 1];\n const a2 = first[a];\n if (a1 === undefined || a2 === undefined) {\n continue;\n }\n for (let b = 1; b < second.length; b += 1) {\n const b1 = second[b - 1];\n const b2 = second[b];\n if (b1 === undefined || b2 === undefined) {\n continue;\n }\n const point = segmentIntersection(a1, a2, b1, b2, tolerance);\n if (point !== undefined) {\n yield point;\n }\n }\n }\n}\n\nfunction segmentIntersection(\n a1: Point,\n a2: Point,\n b1: Point,\n b2: Point,\n tolerance: number,\n): Point | undefined {\n const r = { x: a2.x - a1.x, y: a2.y - a1.y };\n const s = { x: b2.x - b1.x, y: b2.y - b1.y };\n const denominator = r.x * s.y - r.y * s.x;\n const qp = { x: b1.x - a1.x, y: b1.y - a1.y };\n if (Math.abs(denominator) < Number.EPSILON) {\n // Parallel or collinear: overlap points are covered by the endpoint checks in the caller.\n return undefined;\n }\n const t = (qp.x * s.y - qp.y * s.x) / denominator;\n const u = (qp.x * r.y - qp.y * r.x) / denominator;\n const slackT = tolerance === 0 ? 0 : tolerance / Math.hypot(r.x, r.y);\n const slackU = tolerance === 0 ? 0 : tolerance / Math.hypot(s.x, s.y);\n if (t < -slackT || t > 1 + slackT || u < -slackU || u > 1 + slackU) {\n return undefined;\n }\n return { x: a1.x + t * r.x, y: a1.y + t * r.y };\n}\n","import {\n namesNet,\n symbolRole,\n type DeviceSymbolProvider,\n type Placement,\n type SchematicDocument,\n type Point,\n symbolPinPosition,\n nearestPointOnPolyline,\n pointOnPolyline,\n pointOnPolylineAt,\n samePoint,\n rerouteWireEndpoint,\n stretchWireEndpoint,\n} from '@mica-js/document/schematic';\n\nexport interface ISymbolDragPreview {\n /** New point lists for wires whose endpoint is attached to a moving pin. */\n readonly wires: ReadonlyMap<string, readonly Point[]>;\n /** New positions for junctions sitting on a moving pin. */\n readonly junctions: ReadonlyMap<string, Point>;\n /** New positions for anchors (power / ground / label) attached to a moving pin. */\n readonly symbols: ReadonlyMap<string, Point>;\n}\n\n/**\n * Geometry of a symbol being dragged or rotated: which wires, junctions and anchors follow.\n * Shared by the editor controller (commit) and the renderer (live preview).\n */\nexport function previewSymbolDrag(\n document: SchematicDocument,\n devices: DeviceSymbolProvider | undefined,\n symbolId: string,\n next: Placement,\n): ISymbolDragPreview | undefined {\n const symbol = document.sheet.symbols.find((candidate) => candidate.id === symbolId);\n if (symbol === undefined) {\n return undefined;\n }\n\n // Net labels and ports stretch their wire; component pins keep the run attached to the pin.\n const stretches = isNetAnchor(symbol.device);\n const definition = connectionAnchors(devices, symbol.device);\n const moves: { readonly from: Point; readonly to: Point }[] = [];\n for (const anchor of Object.values(definition)) {\n const from = symbolPinPosition(symbol, anchor);\n const to = symbolPinPosition(next, anchor);\n if (from.x !== to.x || from.y !== to.y) {\n moves.push({ from, to });\n }\n }\n\n const wires = new Map<string, readonly Point[]>();\n const junctions = new Map<string, Point>();\n const symbols = new Map<string, Point>();\n if (moves.length === 0) {\n return { wires, junctions, symbols };\n }\n\n const pointMoves = [...moves];\n for (const wire of document.sheet.wires) {\n for (const move of moves) {\n const rerouted = stretches\n ? stretchWireEndpoint(wire, move.from, move.to)\n : rerouteWireEndpoint(wire, move.from, move.to);\n if (rerouted === undefined) {\n continue;\n }\n wires.set(wire.id, rerouted.points);\n for (const extra of rerouted.moves) {\n if (!pointMoves.some((candidate) => samePoint(candidate.from, extra.from))) {\n pointMoves.push(extra);\n }\n }\n break;\n }\n }\n\n // Junctions that still lie on their (rerouted) wires stay put; only detached ones are re-placed.\n for (const junction of document.sheet.junctions) {\n const point = { x: junction.x, y: junction.y };\n const attached = junction.wires.every((wireId) => {\n const points = wires.get(wireId) ?? document.sheet.wires.find((w) => w.id === wireId)?.points;\n return points !== undefined && pointOnPolyline(points, point, ON_WIRE_EPSILON);\n });\n if (attached) {\n continue;\n }\n for (const wireId of junction.wires) {\n const before = document.sheet.wires.find((candidate) => candidate.id === wireId);\n const after = wires.get(wireId);\n if (before === undefined || after === undefined) {\n continue;\n }\n const projected = nearestPointOnPolyline(before.points, point);\n const moved =\n projected === undefined\n ? undefined\n : pointOnPolylineAt(after, projected.segment, projected.t);\n if (moved === undefined) {\n continue;\n }\n junctions.set(junction.id, moved);\n break;\n }\n }\n\n for (const move of pointMoves) {\n for (const junction of document.sheet.junctions) {\n if (samePoint({ x: junction.x, y: junction.y }, move.from)) {\n junctions.set(junction.id, move.to);\n }\n }\n for (const other of document.sheet.symbols) {\n if (other.id !== symbolId && samePoint({ x: other.x, y: other.y }, move.from)) {\n symbols.set(other.id, move.to);\n }\n }\n }\n\n return { wires, junctions, symbols };\n}\n\n/** True for the builtin anchors that name a net: net labels, power and ground. */\nfunction isNetAnchor(device: string): boolean {\n return namesNet(symbolRole(device));\n}\n\n/**\n * Connection points of a device in symbol-local space. Net labels, power and ground symbols connect\n * at their own anchor, so they report one at the origin and drag their wire end like a pin does.\n */\nfunction connectionAnchors(\n devices: DeviceSymbolProvider | undefined,\n device: string,\n): Readonly<Record<string, Point>> {\n if (isNetAnchor(device)) {\n return { net: { x: 0, y: 0 } };\n }\n if (symbolRole(device) !== 'component') {\n // Text symbols connect nowhere.\n return {};\n }\n const separator = device.indexOf(':');\n if (separator <= 0 || devices === undefined) {\n return {};\n }\n const packageId = device.slice(0, separator);\n const deviceId = device.slice(separator + 1);\n return devices.getDeviceSymbol({ raw: device, packageId, deviceId })?.pins ?? {};\n}\n\nconst ON_WIRE_EPSILON = 1e-6;\n","import {\n parseDeviceReference,\n symbolRole,\n type DeviceSymbolProvider,\n type SchematicDocument,\n type SchematicWire,\n type Point,\n symbolPinPosition,\n} from '@mica-js/document/schematic';\n\nexport interface ISegmentDragOptions {\n readonly devices?: DeviceSymbolProvider;\n}\n\n/**\n * Wire points produced by sliding one segment by `delta` along its normal.\n *\n * The whole run of segments parallel to the dragged one moves along, so no neighbour is left\n * diagonal. Where that run ends at a pin, an anchor, a junction or another wire, the vertex stays\n * put and the wire gains a dogleg. Pure geometry: the caller decides how to apply it.\n */\nexport function planSegmentDrag(\n document: SchematicDocument,\n wireId: string,\n segment: number,\n delta: Point,\n options: ISegmentDragOptions = {},\n): readonly Point[] | undefined {\n const wire = document.sheet.wires.find((candidate) => candidate.id === wireId);\n return wire === undefined\n ? undefined\n : planWireSegmentDrag(document, wire, segment, delta, options);\n}\n\nfunction planWireSegmentDrag(\n document: SchematicDocument,\n wire: SchematicWire,\n segment: number,\n delta: Point,\n options: ISegmentDragOptions,\n): readonly Point[] | undefined {\n const points = wire.points;\n const start = points[segment];\n const end = points[segment + 1];\n if (start === undefined || end === undefined || (delta.x === 0 && delta.y === 0)) {\n return undefined;\n }\n if (start.x === end.x && start.y === end.y) {\n return undefined;\n }\n // Dragging a horizontal segment moves its run vertically; the run only breaks at a segment\n // pointing the other way (it just stretches) or at a connected vertex (it needs a dogleg).\n const horizontal = start.y === end.y;\n const isParallel = (from: Point, to: Point): boolean =>\n horizontal ? from.y === to.y : from.x === to.x;\n const connected = (point: Point): boolean => isConnectedVertex(document, point, wire.id, options);\n\n let first = segment;\n while (first > 0) {\n const previous = points[first - 1];\n const current = points[first];\n if (\n previous === undefined ||\n current === undefined ||\n !isParallel(previous, current) ||\n connected(current)\n ) {\n break;\n }\n first -= 1;\n }\n let last = segment + 1;\n while (last < points.length - 1) {\n const current = points[last];\n const next = points[last + 1];\n if (\n current === undefined ||\n next === undefined ||\n !isParallel(current, next) ||\n connected(current)\n ) {\n break;\n }\n last += 1;\n }\n\n const firstPoint = points[first];\n const lastPoint = points[last];\n if (firstPoint === undefined || lastPoint === undefined) {\n return undefined;\n }\n const shift = (point: Point): Point => ({ x: point.x + delta.x, y: point.y + delta.y });\n const moved: Point[] = [];\n for (let index = first; index <= last; index += 1) {\n const point = points[index];\n if (point !== undefined) {\n moved.push(shift(point));\n }\n }\n if (connected(firstPoint)) {\n moved.unshift(firstPoint);\n }\n if (connected(lastPoint)) {\n moved.push(lastPoint);\n }\n return [...points.slice(0, first), ...moved, ...points.slice(last + 1)];\n}\n\n/** True when something other than the wire itself is attached at `point`. */\nexport function isConnectedVertex(\n document: SchematicDocument,\n point: Point,\n wireId: string,\n options: ISegmentDragOptions = {},\n): boolean {\n const same = (candidate: Point): boolean => candidate.x === point.x && candidate.y === point.y;\n for (const junction of document.sheet.junctions) {\n if (same(junction)) {\n return true;\n }\n }\n for (const wire of document.sheet.wires) {\n if (wire.id !== wireId && wire.points.some(same)) {\n return true;\n }\n }\n for (const symbol of document.sheet.symbols) {\n const role = symbolRole(symbol.device);\n if (role !== 'component') {\n if (same({ x: symbol.x, y: symbol.y })) {\n return true;\n }\n continue;\n }\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : options.devices?.getDeviceSymbol(reference);\n if (definition === undefined) {\n continue;\n }\n for (const anchor of Object.values(definition.pins)) {\n if (same(symbolPinPosition(symbol, anchor))) {\n return true;\n }\n }\n }\n return false;\n}\n","import {\n SchematicError,\n joinJunctionAt,\n planJunctionRelease,\n pointOnPolyline,\n samePoint,\n splitWireAt,\n type Point,\n} from '@mica-js/document/schematic';\nimport { planSegmentDrag } from '../editing/segment-drag';\nimport type { DocumentStore } from './store';\n\n/**\n * Appends a wire. Endpoints that land inside another wire split it and create a junction, and\n * endpoints that land on an existing junction join it, so the new wire is electrically connected.\n */\nexport function addWire(store: DocumentStore, points: readonly Point[]): void {\n if (points.length < 2) {\n store.reject(\n new SchematicError([\n { severity: 'error', code: 'wire/invalid-points', message: 'A wire needs two points.' },\n ]),\n );\n }\n store.mutate(\n () => {\n const id = store.createId('wire', store.document);\n store.editor.dispatch({ type: 'add-wire', id, points });\n for (const point of [points[0], points[points.length - 1]]) {\n if (point === undefined) {\n continue;\n }\n const host = hitTestWire(store, point, id);\n if (host !== undefined) {\n splitInto(store, id, host.wireId, point);\n continue;\n }\n const join = joinJunctionAt(store.document, id, point);\n if (join !== undefined) {\n store.editor.dispatch({ type: 'update-junction', id: join.id, wires: join.wires });\n }\n }\n },\n { reconcile: false },\n );\n}\n\n/** Splits `wireId` at `point` and creates a junction there. */\nexport function connectWireAt(\n store: DocumentStore,\n wireId: string,\n point: Point,\n otherWireId?: string,\n): string {\n let junctionId = '';\n store.mutate(\n () => {\n junctionId = splitInto(store, otherWireId, wireId, point, { strict: true });\n },\n { reconcile: false },\n );\n return junctionId;\n}\n\n/**\n * Slides one wire segment by `delta` along its normal. The whole run of segments parallel to it\n * moves along; junctions left behind on the old geometry let go of this wire.\n */\nexport function moveWireSegment(\n store: DocumentStore,\n wireId: string,\n segment: number,\n delta: Point,\n): void {\n const points = previewWireSegment(store, wireId, segment, delta);\n if (points === undefined) {\n return;\n }\n store.mutate(() => {\n for (const release of planJunctionRelease(store.document, wireId, points)) {\n store.editor.dispatch(\n release.wires === undefined\n ? { type: 'remove-junction', id: release.id }\n : { type: 'update-junction', id: release.id, wires: release.wires },\n );\n }\n store.editor.dispatch({ type: 'set-wire-points', id: wireId, points });\n });\n}\n\n/** Wire points a segment drag would produce; the renderer previews them before the commit. */\nexport function previewWireSegment(\n store: DocumentStore,\n wireId: string,\n segment: number,\n delta: Point,\n): readonly Point[] | undefined {\n return planSegmentDrag(store.document, wireId, segment, delta, store.options);\n}\n\n/** Removes a wire while keeping its junctions for the merge pass to collapse. */\nexport function removeWire(store: DocumentStore, wireId: string): void {\n const attached = store.document.sheet.junctions.filter((junction) =>\n junction.wires.includes(wireId),\n );\n for (const junction of attached) {\n const remaining = junction.wires.filter((id) => id !== wireId);\n if (remaining.length >= 2) {\n store.editor.dispatch({ type: 'update-junction', id: junction.id, wires: remaining });\n } else {\n store.editor.dispatch({ type: 'remove-junction', id: junction.id });\n }\n }\n store.editor.dispatch({ type: 'remove-wire', id: wireId });\n}\n\n/** Wire whose interior (not its ends) passes through `point`, excluding `excludeWireId`. */\nfunction hitTestWire(\n store: DocumentStore,\n point: Point,\n excludeWireId: string,\n): { wireId: string } | undefined {\n // Scanned directly instead of through `hitTest`: the point sits on both the new wire and the\n // host, and which one a plain hit reports depends on element order.\n for (const wire of store.document.sheet.wires) {\n if (wire.id === excludeWireId || !pointOnPolyline(wire.points, point, store.tolerance ?? 0)) {\n continue;\n }\n const [first, last] = [wire.points[0], wire.points[wire.points.length - 1]];\n if (first === undefined || last === undefined) {\n continue;\n }\n if (samePoint(first, point) || samePoint(last, point)) {\n continue;\n }\n return { wireId: wire.id };\n }\n return undefined;\n}\n\n/** Splits `hostWireId` at `point` and joins `newWireId` to the junction it creates. */\nfunction splitInto(\n store: DocumentStore,\n newWireId: string | undefined,\n hostWireId: string,\n point: Point,\n options: { strict?: boolean } = {},\n): string {\n const document = store.document;\n if (!options.strict) {\n const wire = store.findWire(hostWireId);\n const [first, last] = [wire?.points[0], wire?.points[wire.points.length - 1]];\n if (\n wire === undefined ||\n first === undefined ||\n last === undefined ||\n samePoint(first, point) ||\n samePoint(last, point)\n ) {\n return '';\n }\n }\n const split = splitWireAt(document, hostWireId, point, {\n ...(store.tolerance === undefined ? {} : { tolerance: store.tolerance }),\n createId: store.createId,\n });\n const junctionId = store.createId('junction', split.document);\n const wires = [split.firstWireId, split.secondWireId];\n if (newWireId !== undefined && newWireId.length > 0 && !wires.includes(newWireId)) {\n wires.push(newWireId);\n }\n const junctions = [\n ...split.document.sheet.junctions,\n { id: junctionId, x: point.x, y: point.y, wires },\n ];\n store.editor.replace({\n ...split.document,\n sheet: { ...split.document.sheet, junctions },\n });\n return junctionId;\n}\n","import {\n SchematicError,\n designatorOf,\n hasDesignator,\n namesNet,\n netNameOf,\n parseDeviceReference,\n rotatePoint,\n symbolRole,\n type PropertyValue,\n type SchematicSymbol,\n} from '@mica-js/document/schematic';\nimport { previewSymbolDrag } from '../editing/preview';\nimport type { SchematicTarget } from '../types';\nimport type { DocumentStore } from './store';\nimport { removeWire } from './wires';\nimport { deviceReferenceAnchor } from './reference';\n\n/** Reference designator the next placed component gets, per the host's policy. */\nexport function nextDesignator(store: DocumentStore, device: string): string {\n return store.createDesignator(device, store.document);\n}\n\nexport function moveTargets(\n store: DocumentStore,\n targets: readonly SchematicTarget[],\n dx: number,\n dy: number,\n): void {\n if (targets.length === 0 || (dx === 0 && dy === 0)) {\n return;\n }\n store.mutate(() => {\n for (const item of targets) {\n switch (item.kind) {\n case 'symbol': {\n const symbol = store.findSymbol(item.id);\n if (symbol !== undefined) {\n repositionSymbol(store, symbol, { ...symbol, x: symbol.x + dx, y: symbol.y + dy });\n }\n break;\n }\n case 'vertex': {\n const wire = store.findWire(item.wireId);\n const target = wire?.points[item.index];\n if (wire !== undefined && target !== undefined) {\n store.editor.dispatch({\n type: 'set-wire-points',\n id: wire.id,\n points: wire.points.map((point, index) =>\n index === item.index ? { x: point.x + dx, y: point.y + dy } : point,\n ),\n });\n }\n break;\n }\n case 'reference':\n moveReferenceBy(store, item.symbolId, dx, dy);\n break;\n case 'junction':\n // Junctions are derived from wire geometry; moving one would break orthogonality.\n break;\n default:\n break;\n }\n }\n });\n}\n\nexport function rotateTargets(\n store: DocumentStore,\n targets: readonly SchematicTarget[],\n degrees: number,\n): void {\n if (targets.length === 0 || degrees === 0) {\n return;\n }\n store.mutate(() => {\n for (const item of targets) {\n if (item.kind !== 'symbol') {\n continue;\n }\n const symbol = store.findSymbol(item.id);\n if (symbol === undefined) {\n continue;\n }\n repositionSymbol(store, symbol, {\n ...symbol,\n rotation: normalizeRotation(symbol.rotation + degrees),\n });\n }\n });\n}\n\n/**\n * Replaces a symbol's placement and drags everything anchored to its pins: wire ends keep\n * orthogonal routing, junctions and attached builtin anchors follow.\n */\nexport function repositionSymbol(\n store: DocumentStore,\n symbol: SchematicSymbol,\n next: SchematicSymbol,\n): void {\n const document = store.document;\n const preview = previewSymbolDrag(document, store.devices, symbol.id, next);\n if (preview === undefined) {\n return;\n }\n const symbols = document.sheet.symbols.map((item) => {\n if (item.id === symbol.id) {\n return next;\n }\n const target = preview.symbols.get(item.id);\n return target === undefined ? item : { ...item, x: target.x, y: target.y };\n });\n const wires = document.sheet.wires.map((wire) => {\n const points = preview.wires.get(wire.id);\n return points === undefined ? wire : { ...wire, points };\n });\n const junctions = document.sheet.junctions.map((junction) => {\n const target = preview.junctions.get(junction.id);\n return target === undefined ? junction : { ...junction, x: target.x, y: target.y };\n });\n\n store.editor.replace({\n ...document,\n sheet: { ...document.sheet, symbols, wires, junctions },\n });\n}\n\nexport function removeTargets(store: DocumentStore, targets: readonly SchematicTarget[]): void {\n if (targets.length === 0) {\n return;\n }\n store.mutate(() => {\n for (const item of targets) {\n switch (item.kind) {\n case 'symbol':\n store.editor.dispatch({ type: 'remove-symbol', id: item.id });\n break;\n case 'wire':\n removeWire(store, item.id);\n break;\n case 'junction':\n // Removing a wire already drops junctions it leaves with fewer than two wires, so a\n // rubber-band selection around a T connection contains junction ids that are gone.\n if (store.document.sheet.junctions.some((junction) => junction.id === item.id)) {\n store.editor.dispatch({ type: 'remove-junction', id: item.id });\n }\n break;\n case 'vertex': {\n const wire = store.findWire(item.wireId);\n if (wire === undefined) {\n break;\n }\n const points = wire.points.filter((_, index) => index !== item.index);\n if (points.length < 2) {\n removeWire(store, wire.id);\n } else {\n store.editor.dispatch({ type: 'set-wire-points', id: wire.id, points });\n }\n break;\n }\n default:\n break;\n }\n }\n });\n}\n\n/** Moves a reference designator by a world-space delta; the offset is stored locally. */\nexport function moveReferenceBy(\n store: DocumentStore,\n symbolId: string,\n dx: number,\n dy: number,\n): void {\n const symbol = store.findSymbol(symbolId);\n if (symbol === undefined || (dx === 0 && dy === 0)) {\n return;\n }\n store.mutate(() => {\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : store.devices?.getDeviceSymbol(reference);\n const anchor = deviceReferenceAnchor(definition, symbol.reference);\n // Offsets live in symbol-local space, so undo the rotation before moving.\n const local = rotatePoint({ x: dx, y: dy }, -symbol.rotation);\n store.editor.dispatch({\n type: 'update-symbol',\n id: symbol.id,\n reference: { x: anchor.x + local.x, y: anchor.y + local.y },\n });\n });\n}\n\nexport function setSymbolProperty(\n store: DocumentStore,\n symbolId: string,\n key: string,\n value: PropertyValue,\n): void {\n store.mutate(() => {\n store.editor.dispatch({ type: 'set-symbol-property', id: symbolId, key, value });\n });\n}\n\nexport function removeSymbolProperty(store: DocumentStore, symbolId: string, key: string): void {\n store.mutate(() => {\n store.editor.dispatch({ type: 'remove-symbol-property', id: symbolId, key });\n });\n}\n\n/**\n * Sets a component's reference designator. The symbol id stays untouched, so selections and\n * stable ids keep references pointing at the same element.\n */\nexport function renameDesignator(\n store: DocumentStore,\n symbolId: string,\n nextDesignator: string,\n): void {\n const trimmed = nextDesignator.trim();\n const symbol = store.requireSymbol(symbolId);\n const role = symbolRole(symbol.device);\n if (!hasDesignator(role)) {\n store.reject(\n new SchematicError([\n {\n severity: 'error',\n code: 'symbol/unsupported-field',\n message: `Symbols of role \"${role}\" carry no reference designator.`,\n entity: { kind: 'symbol', id: symbolId },\n },\n ]),\n );\n }\n if (trimmed.length === 0) {\n store.reject(\n new SchematicError([\n {\n severity: 'error',\n code: 'schema/invalid-value',\n message: 'Reference designator must not be empty.',\n },\n ]),\n );\n }\n if (trimmed === designatorOf(symbol)) {\n return;\n }\n const duplicate = store.document.sheet.symbols.find(\n (candidate) => candidate.id !== symbolId && designatorOf(candidate) === trimmed,\n );\n if (duplicate !== undefined) {\n store.reject(\n new SchematicError([\n {\n severity: 'error',\n code: 'symbol/designator-duplicate',\n message: `Reference designator ${JSON.stringify(trimmed)} is already used.`,\n entity: { kind: 'symbol', id: duplicate.id },\n },\n ]),\n );\n }\n store.mutate(() => {\n store.editor.dispatch({ type: 'update-symbol', id: symbolId, designator: trimmed });\n });\n}\n\n/**\n * Sets the net name of a label / power / ground symbol. Same-named ports are one net, so\n * duplicates are allowed.\n */\nexport function renameNet(store: DocumentStore, symbolId: string, nextNet: string): void {\n const trimmed = nextNet.trim();\n const symbol = store.requireSymbol(symbolId);\n const role = symbolRole(symbol.device);\n if (!namesNet(role)) {\n store.reject(\n new SchematicError([\n {\n severity: 'error',\n code: 'symbol/unsupported-field',\n message: `Symbols of role \"${role}\" name no net.`,\n entity: { kind: 'symbol', id: symbolId },\n },\n ]),\n );\n }\n if (trimmed.length === 0) {\n store.reject(\n new SchematicError([\n {\n severity: 'error',\n code: 'schema/invalid-value',\n message: 'Net name must not be empty.',\n },\n ]),\n );\n }\n if (trimmed === netNameOf(symbol)) {\n return;\n }\n store.mutate(() => {\n store.editor.dispatch({ type: 'update-symbol', id: symbolId, net: trimmed });\n });\n}\n\nfunction normalizeRotation(degrees: number): number {\n return ((degrees % 360) + 360) % 360;\n}\n","import type {\n Point,\n PropertyDescriptor,\n PropertyValue,\n SchematicDocument,\n SchematicError,\n SymbolRole,\n} from '@mica-js/document/schematic';\n\nexport type EditorTool = 'select' | 'wire' | 'power' | 'ground' | 'label' | 'text';\n\n/** One addressable element of the document that an editor can select or edit. */\nexport type SchematicTarget =\n | { readonly kind: 'symbol'; readonly id: string }\n | { readonly kind: 'pin'; readonly symbolId: string; readonly pinId: string }\n | { readonly kind: 'reference'; readonly symbolId: string }\n | { readonly kind: 'wire'; readonly id: string }\n | { readonly kind: 'junction'; readonly id: string }\n | { readonly kind: 'vertex'; readonly wireId: string; readonly index: number };\n\n/** Selection entry of the canvas editor; the same shape a document model edits. */\nexport type EditorSelection = SchematicTarget;\n\nexport interface IDisplayOptions {\n readonly grid: boolean;\n readonly snap: boolean;\n readonly labels: boolean;\n /** Snap step in page units. */\n readonly gridSize: number;\n /** Fine grid lines per snap cell; symbol dragging snaps to this finer spacing. */\n readonly gridSubdivisions: number;\n}\n\nexport const DEFAULT_DISPLAY_OPTIONS: IDisplayOptions = {\n grid: true,\n snap: true,\n labels: true,\n gridSize: 10,\n gridSubdivisions: 2,\n};\n\n/**\n * One editable property of the selected symbol, described by its device.\n *\n * `type` selects the control a host renders; the remaining constraint fields (`options`, `min`,\n * `max`, `step`, `unit`, `maxLength`, `alpha`, `maxBytes`, `maxPixels`) come from the declaration.\n */\nexport type PropertyField = Omit<PropertyDescriptor, 'default'> & {\n /** Declared default; absent when the device declares none. */\n readonly defaultValue?: PropertyValue;\n /** Instance override; absent when the instance inherits the default, `null` when cleared. */\n readonly value?: PropertyValue;\n};\n\nexport interface ISymbolInspector {\n readonly kind: 'symbol';\n readonly id: string;\n /** What the symbol is for; drives which fields the panel shows. */\n readonly role: SymbolRole;\n readonly device: string;\n readonly name: string | undefined;\n /** True for the builtin symbols (`label` / `power` / `ground` / `text`). */\n readonly builtin: boolean;\n /** Reference designator; absent for symbols that carry none. */\n readonly designator?: string;\n /** Net name; absent for symbols that name no net. */\n readonly net?: string;\n readonly x: number;\n readonly y: number;\n readonly rotation: number;\n readonly properties: readonly PropertyField[];\n}\n\nexport interface IWireInspector {\n readonly kind: 'wire';\n readonly id: string;\n /** Net name derived from the topology; `null` for anonymous nets. */\n readonly netName: string | null;\n readonly points: readonly Point[];\n}\n\nexport type Inspector = ISymbolInspector | IWireInspector | undefined;\n\n/**\n * Field subset the canvas needs. Reading it never builds the inspector, so a repaint (pointer\n * hover, drag preview) stays cheap.\n */\nexport interface IEditorRenderState {\n readonly document: SchematicDocument;\n readonly selection: readonly SchematicTarget[];\n readonly tool: EditorTool;\n readonly display: IDisplayOptions;\n}\n\nexport interface IEditorState {\n readonly document: SchematicDocument;\n readonly selection: readonly SchematicTarget[];\n readonly tool: EditorTool;\n /** Device armed for placement by the host's device list; `undefined` when idle. */\n readonly placingDevice: string | undefined;\n readonly display: IDisplayOptions;\n readonly canUndo: boolean;\n readonly canRedo: boolean;\n readonly inspector: Inspector;\n /** Last captured edit error; cleared by the next successful edit. */\n readonly lastError: SchematicError | undefined;\n}\n","import {\n SCHEMATIC_VERSION,\n SchematicError,\n hasDesignator,\n parseSchematic,\n symbolRole,\n type DiagnosticCode,\n type Point,\n type SchematicDocument,\n type SchematicJunction,\n type SchematicSymbol,\n type SchematicWire,\n} from '@mica-js/document/schematic';\nimport { DEFAULT_DISPLAY_OPTIONS, type SchematicTarget } from '../types';\nimport type { DocumentStore } from './store';\n\n/** Identifies a payload produced by this editor; anything else is a foreign clipboard. */\nexport const SCHEMATIC_CLIPBOARD_FORMAT = 'mica-schematic/selection';\n/** Payload schema version; older payloads are rejected instead of migrated. */\nexport const SCHEMATIC_CLIPBOARD_VERSION = 1;\n/** Custom MIME type written next to `text/plain`. */\nexport const SCHEMATIC_CLIPBOARD_MIME = 'application/x-mica-schematic+json';\n\n/** Element budget and coordinate bound that keep a hostile payload from building a huge document. */\nconst MAX_CLIPBOARD_ELEMENTS = 10_000;\nconst MAX_CLIPBOARD_COORDINATE = 1_000_000;\n\n/**\n * Copied schematic elements, ready to serialize.\n *\n * Element ids stay as they were copied: they only resolve junction → wire references, and every\n * pasted element gets a fresh id. Geometry lives in page coordinates, so pasting rebuilds it from\n * the payload bounds instead of storing an origin.\n */\nexport interface ISchematicClipboard {\n readonly format: typeof SCHEMATIC_CLIPBOARD_FORMAT;\n readonly version: typeof SCHEMATIC_CLIPBOARD_VERSION;\n readonly symbols: readonly SchematicSymbol[];\n readonly wires: readonly SchematicWire[];\n readonly junctions: readonly SchematicJunction[];\n}\n\nexport interface IPasteOptions {\n /** Page coordinate the top-left corner of the copied content lands on. */\n readonly at?: Point;\n /** Translation used without `at`; defaults to one grid step (`DEFAULT_DISPLAY_OPTIONS.gridSize`). */\n readonly offset?: Point;\n}\n\n/**\n * Collects the selected elements into a payload. Reference targets copy their whole symbol and\n * vertex targets their whole wire; targets that no longer exist are skipped.\n *\n * Junctions come along only when every wire they join is copied, so a pasted selection never\n * starts with a dangling junction. Reading never edits the document or its history.\n */\nexport function createSchematicClipboard(\n document: SchematicDocument,\n targets: readonly SchematicTarget[],\n): ISchematicClipboard | undefined {\n const symbolIds = new Set<string>();\n const wireIds = new Set<string>();\n for (const target of targets) {\n switch (target.kind) {\n case 'symbol':\n symbolIds.add(target.id);\n break;\n case 'reference':\n symbolIds.add(target.symbolId);\n break;\n case 'wire':\n wireIds.add(target.id);\n break;\n case 'vertex':\n wireIds.add(target.wireId);\n break;\n default:\n break;\n }\n }\n\n const symbols = document.sheet.symbols.filter((symbol) => symbolIds.has(symbol.id));\n const wires = document.sheet.wires.filter((wire) => wireIds.has(wire.id));\n const copiedWireIds = new Set(wires.map((wire) => wire.id));\n const junctions = document.sheet.junctions.filter(\n (junction) => junction.wires.length >= 2 && junction.wires.every((id) => copiedWireIds.has(id)),\n );\n if (symbols.length === 0 && wires.length === 0 && junctions.length === 0) {\n return undefined;\n }\n return {\n format: SCHEMATIC_CLIPBOARD_FORMAT,\n version: SCHEMATIC_CLIPBOARD_VERSION,\n symbols,\n wires,\n junctions,\n };\n}\n\nexport function serializeSchematicClipboard(clipboard: ISchematicClipboard): string {\n return JSON.stringify(clipboard);\n}\n\n/**\n * Parses and normalizes a clipboard payload.\n *\n * @throws {SchematicError} when the text is not JSON, not a selection payload, uses another\n * version or exceeds the element / coordinate budget; the document is never touched.\n */\nexport function parseSchematicClipboard(text: string): ISchematicClipboard {\n const value = parseClipboardJson(text);\n if (!isRecord(value)) {\n fail('schema/invalid-type', 'Clipboard payload must be a JSON object.');\n }\n if (value['format'] !== SCHEMATIC_CLIPBOARD_FORMAT) {\n fail('schema/invalid-value', 'Clipboard payload is not a schematic selection.');\n }\n if (value['version'] !== SCHEMATIC_CLIPBOARD_VERSION) {\n fail(\n 'schema/unsupported-version',\n `Unsupported clipboard version; expected ${SCHEMATIC_CLIPBOARD_VERSION}.`,\n );\n }\n const symbols = readElementArray(value, 'symbols');\n const wires = readElementArray(value, 'wires');\n const junctions = readElementArray(value, 'junctions');\n checkLimits(symbols, wires, junctions);\n // Re-validation through the `.sch` contract normalizes the payload and rejects unknown fields.\n const parsed = parseSchematic({\n version: SCHEMATIC_VERSION,\n sheet: { symbols, wires, junctions },\n });\n return {\n format: SCHEMATIC_CLIPBOARD_FORMAT,\n version: SCHEMATIC_CLIPBOARD_VERSION,\n symbols: parsed.sheet.symbols,\n wires: parsed.sheet.wires,\n junctions: parsed.sheet.junctions,\n };\n}\n\n/**\n * Inserts a payload as one undoable edit and returns the pasted symbols and wires.\n *\n * Every new element is merged into the working document before the next id is generated, so a\n * batch never reuses an id. Components get fresh designators and junctions follow their new wires.\n */\nexport function pasteClipboard(\n store: DocumentStore,\n clipboard: ISchematicClipboard,\n options: IPasteOptions = {},\n): readonly SchematicTarget[] {\n // Junctions only attach to wires; without copied wires there is nothing to insert or to record.\n if (clipboard.symbols.length === 0 && clipboard.wires.length === 0) {\n return [];\n }\n\n const document = store.document;\n const delta = pasteDelta(clipboard, options);\n const symbols = [...document.sheet.symbols];\n const wires = [...document.sheet.wires];\n const junctions = [...document.sheet.junctions];\n const targets: SchematicTarget[] = [];\n let working: SchematicDocument = document;\n const rebuild = (): void => {\n working = { ...document, sheet: { ...document.sheet, symbols, wires, junctions } };\n };\n\n for (const source of clipboard.symbols) {\n const id = store.createId('symbol', working);\n symbols.push(translateSymbol(store, source, id, delta, working));\n rebuild();\n targets.push({ kind: 'symbol', id });\n }\n\n const wireIds = new Map<string, string>();\n for (const source of clipboard.wires) {\n const id = store.createId('wire', working);\n wireIds.set(source.id, id);\n wires.push({\n id,\n points: source.points.map((point) => ({ x: point.x + delta.x, y: point.y + delta.y })),\n });\n rebuild();\n targets.push({ kind: 'wire', id });\n }\n\n for (const source of clipboard.junctions) {\n const mapped = source.wires\n .map((wireId) => wireIds.get(wireId))\n .filter((wireId): wireId is string => wireId !== undefined);\n if (mapped.length < 2) {\n continue;\n }\n const id = store.createId('junction', working);\n junctions.push({ id, x: source.x + delta.x, y: source.y + delta.y, wires: mapped });\n rebuild();\n }\n\n // Reconciling would rewrite the geometry the user copied; the payload is already consistent.\n store.mutate(() => store.editor.replace(working), { reconcile: false });\n return targets;\n}\n\nfunction translateSymbol(\n store: DocumentStore,\n source: SchematicSymbol,\n id: string,\n delta: Point,\n working: SchematicDocument,\n): SchematicSymbol {\n const role = symbolRole(source.device);\n return {\n id,\n device: source.device,\n x: source.x + delta.x,\n y: source.y + delta.y,\n rotation: source.rotation,\n ...(source.properties === undefined ? {} : { properties: source.properties }),\n // Pasted components are new instances, so they must not reuse the copied designator.\n ...(hasDesignator(role) ? { designator: store.createDesignator(source.device, working) } : {}),\n ...(source.net === undefined ? {} : { net: source.net }),\n ...(source.reference === undefined ? {} : { reference: source.reference }),\n };\n}\n\nfunction pasteDelta(clipboard: ISchematicClipboard, options: IPasteOptions): Point {\n if (options.at !== undefined) {\n const topLeft = clipboardTopLeft(clipboard);\n return { x: options.at.x - topLeft.x, y: options.at.y - topLeft.y };\n }\n return (\n options.offset ?? {\n x: DEFAULT_DISPLAY_OPTIONS.gridSize,\n y: DEFAULT_DISPLAY_OPTIONS.gridSize,\n }\n );\n}\n\nfunction clipboardTopLeft(clipboard: ISchematicClipboard): Point {\n let x = Number.POSITIVE_INFINITY;\n let y = Number.POSITIVE_INFINITY;\n const visit = (point: Point): void => {\n x = Math.min(x, point.x);\n y = Math.min(y, point.y);\n };\n for (const symbol of clipboard.symbols) {\n visit(symbol);\n }\n for (const wire of clipboard.wires) {\n for (const point of wire.points) {\n visit(point);\n }\n }\n for (const junction of clipboard.junctions) {\n visit(junction);\n }\n return { x: Number.isFinite(x) ? x : 0, y: Number.isFinite(y) ? y : 0 };\n}\n\nfunction parseClipboardJson(text: string): unknown {\n try {\n return JSON.parse(text) as unknown;\n } catch {\n fail('json/invalid', 'Clipboard payload is not valid JSON.');\n }\n}\n\nfunction readElementArray(value: Record<string, unknown>, field: string): readonly unknown[] {\n const items = value[field];\n if (!Array.isArray(items)) {\n fail('schema/invalid-type', `Field \"${field}\" must be an array.`);\n }\n return items;\n}\n\nfunction checkLimits(\n symbols: readonly unknown[],\n wires: readonly unknown[],\n junctions: readonly unknown[],\n): void {\n if (symbols.length + wires.length + junctions.length > MAX_CLIPBOARD_ELEMENTS) {\n fail('schema/invalid-value', `Clipboard selection exceeds ${MAX_CLIPBOARD_ELEMENTS} elements.`);\n }\n for (const symbol of symbols) {\n checkCoordinates(symbol, ['x', 'y']);\n }\n for (const wire of wires) {\n if (!isRecord(wire)) {\n continue;\n }\n const points = wire['points'];\n if (!Array.isArray(points)) {\n continue;\n }\n for (const point of points) {\n checkCoordinates(point, ['x', 'y']);\n }\n }\n for (const junction of junctions) {\n checkCoordinates(junction, ['x', 'y']);\n }\n}\n\nfunction checkCoordinates(value: unknown, fields: readonly string[]): void {\n if (!isRecord(value)) {\n return;\n }\n for (const field of fields) {\n const coordinate = value[field];\n if (\n typeof coordinate === 'number' &&\n (!Number.isFinite(coordinate) || Math.abs(coordinate) > MAX_CLIPBOARD_COORDINATE)\n ) {\n fail(\n 'schema/invalid-value',\n `Coordinate \"${field}\" is outside ±${MAX_CLIPBOARD_COORDINATE}.`,\n );\n }\n }\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return typeof value === 'object' && value !== null && !Array.isArray(value);\n}\n\nfunction fail(code: DiagnosticCode, message: string): never {\n throw new SchematicError([{ severity: 'error', code, message }]);\n}\n","import {\n SCHEMATIC_VERSION,\n parseSchematic,\n type SchematicDocument,\n} from '@mica-js/document/schematic';\n\n/** Content a model or editor accepts: a parsed `.sch` document, or the `.sch` JSON text itself. */\nexport type SchematicContent = SchematicDocument | string;\n\n/** An empty sheet, the content of a model created without `value`. */\nexport function createEmptySchematicDocument(): SchematicDocument {\n return { version: SCHEMATIC_VERSION, sheet: { symbols: [], wires: [], junctions: [] } };\n}\n\n/**\n * Resolves accepted content into a document: text is parsed as `.sch` JSON, documents pass through\n * unchanged and `undefined` yields an empty sheet.\n *\n * @throws {SchematicError} when the text is not a valid `.sch` document.\n */\nexport function resolveSchematicContent(value: SchematicContent | undefined): SchematicDocument {\n if (value === undefined) {\n return createEmptySchematicDocument();\n }\n return typeof value === 'string' ? parseSchematic(value) : value;\n}\n","import {\n type SchematicDocument,\n parseSchematic,\n pointOnPolyline,\n serializeSchematic,\n deriveSchematicTopology,\n type SchematicTopology,\n applySchematicCommand,\n type SchematicCommand,\n type SchematicEditOptions,\n} from '@mica-js/document/schematic';\n\nexport interface ISchematicEditorOptions extends SchematicEditOptions {\n /** Maximum number of undo steps kept; defaults to 200. */\n readonly historyLimit?: number;\n}\n\nconst DEFAULT_HISTORY_LIMIT = 200;\n\n/**\n * Stateful editor over a schematic document with undo/redo.\n * Every mutation goes through {@link applySchematicCommand}; failures leave the state untouched.\n */\nexport class SchematicEditor {\n readonly #options: ISchematicEditorOptions;\n readonly #historyLimit: number;\n #past: SchematicDocument[] = [];\n #future: SchematicDocument[] = [];\n #document: SchematicDocument;\n #depth = 0;\n\n constructor(document: SchematicDocument, options: ISchematicEditorOptions = {}) {\n this.#document = document;\n this.#options = options;\n this.#historyLimit = options.historyLimit ?? DEFAULT_HISTORY_LIMIT;\n }\n\n get document(): SchematicDocument {\n return this.#document;\n }\n\n get canUndo(): boolean {\n return this.#past.length > 0;\n }\n\n get canRedo(): boolean {\n return this.#future.length > 0;\n }\n\n /** @throws {SchematicError} leaving the current document and history untouched. */\n dispatch(command: SchematicCommand): void {\n const next = applySchematicCommand(this.#document, command, this.#options);\n this.#record(next);\n }\n\n /**\n * Records an already-derived document (for example a wire split) as one history step.\n * Junctions that no longer lie on their wires are dropped, keeping the document consistent.\n *\n * @throws {SchematicError} when the document is invalid; the state stays untouched.\n */\n replace(document: SchematicDocument): void {\n const parsed = parseSchematic(document);\n const tolerance = this.#options.tolerance ?? 0;\n const wireById = new Map(parsed.sheet.wires.map((wire) => [wire.id, wire]));\n const junctions = parsed.sheet.junctions.filter((junction) =>\n junction.wires.every((wireId) => {\n const wire = wireById.get(wireId);\n return (\n wire !== undefined &&\n pointOnPolyline(wire.points, { x: junction.x, y: junction.y }, tolerance)\n );\n }),\n );\n this.#record(\n junctions.length === parsed.sheet.junctions.length\n ? parsed\n : { ...parsed, sheet: { ...parsed.sheet, junctions } },\n );\n }\n\n /** Applies several edits atomically; a failure rolls back every command in the block. */\n transaction(edit: (editor: SchematicEditor) => void): void {\n if (this.#depth > 0) {\n edit(this);\n return;\n }\n const document = this.#document;\n const future = this.#future;\n this.#past.push(document);\n this.#future = [];\n this.#depth = 1;\n try {\n edit(this);\n } catch (error) {\n this.#document = document;\n this.#past.pop();\n this.#future = future;\n throw error;\n } finally {\n this.#depth = 0;\n }\n if (this.#document === document) {\n this.#past.pop();\n this.#future = future;\n return;\n }\n this.#trimHistory();\n }\n\n undo(): void {\n const previous = this.#past.pop();\n if (previous === undefined) {\n return;\n }\n if (this.#depth === 0) {\n this.#future.push(this.#document);\n }\n this.#document = previous;\n }\n\n redo(): void {\n const next = this.#future.pop();\n if (next === undefined) {\n return;\n }\n if (this.#depth === 0) {\n this.#past.push(this.#document);\n }\n this.#document = next;\n }\n\n topology(): SchematicTopology {\n return deriveSchematicTopology(this.#document, this.#options);\n }\n\n toJSON(): string {\n return serializeSchematic(this.#document);\n }\n\n #record(next: SchematicDocument): void {\n const previous = this.#document;\n this.#document = next;\n if (this.#depth > 0) {\n return;\n }\n this.#past.push(previous);\n this.#future = [];\n this.#trimHistory();\n }\n\n #trimHistory(): void {\n if (this.#past.length > this.#historyLimit) {\n this.#past.shift();\n }\n }\n}\n","import { SchematicEditor } from '../editing/editor';\nimport {\n SchematicError,\n createDesignatorFactory,\n defaultElementIdFactory,\n deriveSchematicTopology,\n mergeWiresAtJunction,\n type DesignatorFactory,\n type DeviceSymbolProvider,\n type Diagnostic,\n type ElementIdFactory,\n type SchematicDocument,\n type SchematicSymbol,\n type SchematicTopology,\n type SchematicWire,\n} from '@mica-js/document/schematic';\nimport { hitTestSchematic, type IHitTestOptions, type SchematicHit } from '../editing/query';\nimport { Emitter, type Event } from '@mica-js/core/lifecycle';\n\nconst MAX_MERGE_PASSES = 64;\n\nexport interface IDocumentStoreOptions {\n readonly document: SchematicDocument;\n readonly devices?: DeviceSymbolProvider;\n readonly tolerance?: number;\n readonly historyLimit?: number;\n readonly createId?: ElementIdFactory;\n /** Designator policy; defaults to the device's `designatorPrefix` (`U` when it declares none). */\n readonly createDesignator?: DesignatorFactory;\n}\n\n/**\n * Internal document state behind `DocumentModel`: the core editor (document + history), the\n * junction reconciliation pass and the caches derived from the document. Canvas state such as\n * selection, tool and display options lives in the editor.\n */\nexport class DocumentStore {\n editor: SchematicEditor;\n readonly devices: DeviceSymbolProvider | undefined;\n readonly tolerance: number | undefined;\n readonly createId: ElementIdFactory;\n readonly createDesignator: DesignatorFactory;\n readonly #content = new Emitter<DocumentStore>();\n readonly #rejections = new Emitter<SchematicError>();\n readonly #historyLimit: number | undefined;\n #topology:\n { readonly document: SchematicDocument; readonly value: SchematicTopology } | undefined;\n #lastError: SchematicError | undefined;\n #mutationDepth = 0;\n\n /** Fires after every commit: an edit, undo/redo or a document swap. */\n readonly onDidChangeContent: Event<DocumentStore> = this.#content.event;\n /** Fires instead of {@link onDidChangeContent} when an edit is rejected. */\n readonly onDidRejectEdit: Event<SchematicError> = this.#rejections.event;\n\n constructor(options: IDocumentStoreOptions) {\n this.#historyLimit = options.historyLimit;\n this.editor = createEditor(options);\n this.devices = options.devices;\n this.tolerance = options.tolerance;\n this.createId = options.createId ?? defaultElementIdFactory;\n this.createDesignator = options.createDesignator ?? createDesignatorFactory(options.devices);\n }\n\n get document(): SchematicDocument {\n return this.editor.document;\n }\n\n get lastError(): SchematicError | undefined {\n return this.#lastError;\n }\n\n /** Editing options for core calls (`exactOptionalPropertyTypes` friendly). */\n get options(): { devices?: DeviceSymbolProvider; tolerance?: number } {\n return deriveOptions(this.devices, this.tolerance);\n }\n\n /**\n * Runs `run` as one undoable edit, then reconciles junctions. Failures are recorded in\n * `lastError`, reported through `onDidRejectEdit` and rethrown; the content stays untouched.\n */\n mutate(run: () => void, options: { reconcile?: boolean } = {}): void {\n const outermost = this.#mutationDepth === 0;\n this.#mutationDepth += 1;\n try {\n this.editor.transaction(() => {\n run();\n if (outermost && options.reconcile !== false) {\n this.mergeDegenerateJunctions();\n }\n });\n } catch (error) {\n if (outermost) {\n this.#lastError = toSchematicError(error);\n this.#rejections.fire(this.#lastError);\n }\n throw error;\n } finally {\n this.#mutationDepth -= 1;\n }\n if (outermost) {\n this.#lastError = undefined;\n this.#content.fire(this);\n }\n }\n\n afterHistoryChange(): void {\n this.#lastError = undefined;\n this.#content.fire(this);\n }\n\n /** Records a rejected edit in `lastError`, notifies listeners, then rethrows. */\n reject(error: SchematicError): never {\n if (this.#mutationDepth === 0) {\n this.#lastError = error;\n this.#rejections.fire(error);\n }\n throw error;\n }\n\n undo(): void {\n if (!this.editor.canUndo) {\n return;\n }\n this.editor.undo();\n this.afterHistoryChange();\n }\n\n redo(): void {\n if (!this.editor.canRedo) {\n return;\n }\n this.editor.redo();\n this.afterHistoryChange();\n }\n\n /** Swaps the edited document and clears history and errors. */\n reset(document: SchematicDocument): void {\n this.editor = createEditor({\n document,\n ...deriveOptions(this.devices, this.tolerance),\n ...(this.#historyLimit === undefined ? {} : { historyLimit: this.#historyLimit }),\n createId: this.createId,\n createDesignator: this.createDesignator,\n });\n this.#lastError = undefined;\n this.#topology = undefined;\n this.#content.fire(this);\n }\n\n /** Swaps the whole document as one undoable edit. */\n replace(document: SchematicDocument): void {\n this.mutate(() => {\n this.editor.replace(document);\n });\n }\n\n topology(): SchematicTopology {\n const document = this.editor.document;\n if (this.#topology?.document !== document) {\n this.#topology = {\n document,\n value: deriveSchematicTopology(document, this.options),\n };\n }\n return this.#topology.value;\n }\n\n hitTest(\n point: { readonly x: number; readonly y: number },\n options: IHitTestOptions = {},\n ): SchematicHit | undefined {\n return hitTestSchematic(this.editor.document, point, { ...this.options, ...options });\n }\n\n findSymbol(id: string): SchematicSymbol | undefined {\n return this.editor.document.sheet.symbols.find((symbol) => symbol.id === id);\n }\n\n findWire(id: string): SchematicWire | undefined {\n return this.editor.document.sheet.wires.find((wire) => wire.id === id);\n }\n\n /** @throws {SchematicError} when the symbol is unknown. */\n requireSymbol(symbolId: string): SchematicSymbol {\n const symbol = this.findSymbol(symbolId);\n if (symbol === undefined) {\n this.reject(\n new SchematicError([\n {\n severity: 'error',\n code: 'edit/unknown-entity',\n message: `Unknown symbol \"${symbolId}\".`,\n entity: { kind: 'symbol', id: symbolId },\n },\n ]),\n );\n }\n return symbol;\n }\n\n /** Device outline in symbol-local coordinates, used as the reference-designator default. */\n outlineOf(\n symbol: SchematicSymbol,\n ): { x: number; y: number; width: number; height: number } | undefined {\n const separator = symbol.device.indexOf(':');\n if (separator <= 0) {\n return undefined;\n }\n return this.devices?.getDeviceSymbol({\n raw: symbol.device,\n packageId: symbol.device.slice(0, separator),\n deviceId: symbol.device.slice(separator + 1),\n })?.bounds;\n }\n\n /** A junction that only splices two collinear wires collapses back into a single wire. */\n mergeDegenerateJunctions(): void {\n for (let pass = 0; pass < MAX_MERGE_PASSES; pass += 1) {\n const junctions = this.editor.document.sheet.junctions;\n let merged = false;\n for (const junction of junctions) {\n const result = mergeWiresAtJunction(this.editor.document, junction.id, {\n ...deriveOptions(undefined, this.tolerance),\n createId: this.createId,\n });\n if (result === undefined) {\n continue;\n }\n this.editor.replace(result.document);\n merged = true;\n break;\n }\n if (!merged) {\n return;\n }\n }\n }\n}\n\nfunction createEditor(options: IDocumentStoreOptions): SchematicEditor {\n return new SchematicEditor(options.document, {\n ...deriveOptions(options.devices, options.tolerance),\n ...(options.historyLimit === undefined ? {} : { historyLimit: options.historyLimit }),\n ...(options.createId === undefined ? {} : { createId: options.createId }),\n });\n}\n\n/** Builds provider options without `undefined` values (`exactOptionalPropertyTypes`). */\nexport function deriveOptions(\n devices: DeviceSymbolProvider | undefined,\n tolerance: number | undefined,\n): { devices?: DeviceSymbolProvider; tolerance?: number } {\n const options: { devices?: DeviceSymbolProvider; tolerance?: number } = {};\n if (devices !== undefined) {\n options.devices = devices;\n }\n if (tolerance !== undefined) {\n options.tolerance = tolerance;\n }\n return options;\n}\n\nexport function toSchematicError(error: unknown): SchematicError {\n if (error instanceof SchematicError) {\n return error;\n }\n const message = error instanceof Error ? error.message : String(error);\n const diagnostics: readonly Diagnostic[] = [\n { severity: 'error', code: 'edit/invalid-command', message },\n ];\n return new SchematicError(diagnostics);\n}\n","import type {\n DesignatorFactory,\n DeviceSymbolProvider,\n ElementIdFactory,\n Point,\n PropertyValue,\n SchematicCommand,\n SchematicDocument,\n SchematicError,\n SchematicTopology,\n} from '@mica-js/document/schematic';\nimport type { IHitTestOptions, SchematicHit } from '../editing/query';\nimport * as symbols from './symbols';\nimport * as wires from './wires';\nimport {\n createSchematicClipboard,\n pasteClipboard,\n type IPasteOptions,\n type ISchematicClipboard,\n} from './clipboard';\nimport { resolveSchematicContent, type SchematicContent } from './content';\nimport { DocumentStore } from './store';\nimport type { SchematicTarget } from '../types';\nimport { DisposableStore, Emitter, type Event } from '@mica-js/core/lifecycle';\n\nexport interface IDocumentModelOptions {\n /** Initial content: a `.sch` document or its JSON text; defaults to an empty sheet. */\n readonly value?: SchematicContent;\n /** Device provider used for drag geometry, designator prefixes and property declarations. */\n readonly devices?: DeviceSymbolProvider;\n /** Hit / geometry tolerance in page units. */\n readonly tolerance?: number;\n /** Maximum number of undo steps kept; defaults to 200. */\n readonly historyLimit?: number;\n /** Element id factory; defaults to the core UUID factory. */\n readonly createId?: ElementIdFactory;\n /** Designator policy; defaults to the device's `designatorPrefix` (`U` when it declares none). */\n readonly createDesignator?: DesignatorFactory;\n}\n\nexport interface IDocumentUpdateOptions {\n /** Records the swap as one undoable edit instead of starting a new history. */\n readonly keepHistory?: boolean;\n}\n\n/**\n * Owns a `.sch` document and its undo history, independent of any DOM.\n *\n * The model is the single writer for document content: every mutation runs as one undoable edit,\n * rejects without touching the content, and notifies subscribers exactly once. Canvas state —\n * selection, active tool, display options and viewport — belongs to {@link SchematicEditor}.\n */\nexport class DocumentModel {\n readonly #store: DocumentStore;\n readonly #subscriptions = new DisposableStore();\n readonly #content = new Emitter<SchematicDocument>();\n readonly #rejections = new Emitter<SchematicError>();\n\n /** Fires after every committed change with the new content; rejected edits do not fire it. */\n readonly onDidChangeContent: Event<SchematicDocument> = this.#content.event;\n /** Fires when an edit is rejected, with the error the model recorded; the content stays. */\n readonly onDidRejectEdit: Event<SchematicError> = this.#rejections.event;\n\n constructor(options: IDocumentModelOptions = {}) {\n const { value, ...rest } = options;\n this.#store = new DocumentStore({ ...rest, document: resolveSchematicContent(value) });\n this.#subscriptions.add(\n this.#store.onDidChangeContent(() => {\n this.#content.fire(this.#store.document);\n }),\n );\n this.#subscriptions.add(\n this.#store.onDidRejectEdit((error) => {\n this.#rejections.fire(error);\n }),\n );\n }\n\n /** Current content; the same reference until an edit replaces it. */\n getValue(): SchematicDocument {\n return this.#store.document;\n }\n\n /** Device provider the editor renders symbols from; the model uses it for drag geometry. */\n getDevices(): DeviceSymbolProvider | undefined {\n return this.#store.devices;\n }\n\n getCanUndo(): boolean {\n return this.#store.editor.canUndo;\n }\n\n getCanRedo(): boolean {\n return this.#store.editor.canRedo;\n }\n\n /** Last rejected edit; cleared by the next successful edit or undo/redo. */\n getLastError(): SchematicError | undefined {\n return this.#store.lastError;\n }\n\n /** Derived connectivity of the current document, cached until the document changes. */\n getTopology(): SchematicTopology {\n return this.#store.topology();\n }\n\n /** Serializes the current document as `.sch` JSON. */\n toJSON(): string {\n return this.#store.editor.toJSON();\n }\n\n /**\n * Applies one core command as one undoable edit. A command the document rejects is reported\n * through {@link DocumentModel.getLastError} and rethrown; the document stays untouched.\n */\n applyCommand(command: SchematicCommand): void {\n this.#store.mutate(() => {\n this.#store.editor.dispatch(command);\n });\n }\n\n /**\n * Replaces the content, accepting a document or its `.sch` JSON text. By default history and\n * errors start over; `keepHistory` records the swap as one undoable edit instead.\n *\n * @throws {SchematicError} when the text is invalid, or the document is rejected (`keepHistory`).\n */\n setValue(value: SchematicContent, options: IDocumentUpdateOptions = {}): void {\n const document = resolveSchematicContent(value);\n if (options.keepHistory === true) {\n this.#store.replace(document);\n return;\n }\n this.#store.reset(document);\n }\n\n undo(): void {\n this.#store.undo();\n }\n\n redo(): void {\n this.#store.redo();\n }\n\n /** Runs several edits as one history step; a failure rolls all of them back. */\n transaction(run: (model: DocumentModel) => void): void {\n this.#store.mutate(() => {\n run(this);\n });\n }\n\n /**\n * Releases the model's events; an editor that created the model disposes it with itself. Further\n * edits still apply, but nobody is notified.\n */\n dispose(): void {\n this.#subscriptions.dispose();\n this.#content.dispose();\n this.#rejections.dispose();\n }\n\n /** Reference designator the next placed component gets, per the model's policy. */\n nextDesignator(device: string): string {\n return symbols.nextDesignator(this.#store, device);\n }\n\n /** Moves document elements by a page-space delta. */\n moveTargets(targets: readonly SchematicTarget[], dx: number, dy: number): void {\n symbols.moveTargets(this.#store, targets, dx, dy);\n }\n\n /** Rotates symbols clockwise by `degrees`. */\n rotateTargets(targets: readonly SchematicTarget[], degrees: number): void {\n symbols.rotateTargets(this.#store, targets, degrees);\n }\n\n /** Removes symbols, wires, junctions and wire vertices. */\n removeTargets(targets: readonly SchematicTarget[]): void {\n symbols.removeTargets(this.#store, targets);\n }\n\n /**\n * Extracts the selected elements as a clipboard payload. Pure read: no history step.\n * Reference targets copy their symbol, vertex targets their whole wire.\n */\n copy(targets: readonly SchematicTarget[]): ISchematicClipboard | undefined {\n return createSchematicClipboard(this.#store.document, targets);\n }\n\n /** Copies then deletes the selected elements as one undoable edit. */\n cut(targets: readonly SchematicTarget[]): ISchematicClipboard | undefined {\n const clipboard = createSchematicClipboard(this.#store.document, targets);\n if (clipboard === undefined) {\n return undefined;\n }\n symbols.removeTargets(this.#store, targets);\n return clipboard;\n }\n\n /** Inserts a payload as one undoable edit; returns the pasted symbols and wires. */\n paste(clipboard: ISchematicClipboard, options?: IPasteOptions): readonly SchematicTarget[] {\n return pasteClipboard(this.#store, clipboard, options);\n }\n\n /** Copies and re-inserts the selected elements offset by one grid step, as one undoable edit. */\n duplicate(\n targets: readonly SchematicTarget[],\n options?: IPasteOptions,\n ): readonly SchematicTarget[] {\n const clipboard = createSchematicClipboard(this.#store.document, targets);\n return clipboard === undefined ? [] : pasteClipboard(this.#store, clipboard, options);\n }\n\n /** Moves a reference designator by a world-space delta. */\n moveReferenceBy(symbolId: string, dx: number, dy: number): void {\n symbols.moveReferenceBy(this.#store, symbolId, dx, dy);\n }\n\n setSymbolProperty(symbolId: string, key: string, value: PropertyValue): void {\n symbols.setSymbolProperty(this.#store, symbolId, key, value);\n }\n\n removeSymbolProperty(symbolId: string, key: string): void {\n symbols.removeSymbolProperty(this.#store, symbolId, key);\n }\n\n renameDesignator(symbolId: string, nextDesignator: string): void {\n symbols.renameDesignator(this.#store, symbolId, nextDesignator);\n }\n\n renameNet(symbolId: string, nextNet: string): void {\n symbols.renameNet(this.#store, symbolId, nextNet);\n }\n\n addWire(points: readonly Point[]): void {\n wires.addWire(this.#store, points);\n }\n\n connectWireAt(wireId: string, point: Point, otherWireId?: string): string {\n return wires.connectWireAt(this.#store, wireId, point, otherWireId);\n }\n\n moveWireSegment(wireId: string, segment: number, delta: Point): void {\n wires.moveWireSegment(this.#store, wireId, segment, delta);\n }\n\n /** Wire points a segment drag would produce, for previews; commits nothing. */\n previewWireSegment(wireId: string, segment: number, delta: Point): readonly Point[] | undefined {\n return wires.previewWireSegment(this.#store, wireId, segment, delta);\n }\n\n hitTest(point: Point, options: IHitTestOptions = {}): SchematicHit | undefined {\n return this.#store.hitTest(point, options);\n }\n}\n","import {\n parseDeviceReference,\n type DeviceSymbolProvider,\n type SchematicDocument,\n} from '@mica-js/document/schematic';\nimport type { SchematicTarget } from '../types';\n\nexport function sameTarget(left: SchematicTarget, right: SchematicTarget): boolean {\n if (left.kind !== right.kind) {\n return false;\n }\n if (left.kind === 'vertex' && right.kind === 'vertex') {\n return left.wireId === right.wireId && left.index === right.index;\n }\n if (left.kind === 'pin' && right.kind === 'pin') {\n return left.symbolId === right.symbolId && left.pinId === right.pinId;\n }\n if (left.kind === 'reference' && right.kind === 'reference') {\n return left.symbolId === right.symbolId;\n }\n return 'id' in left && 'id' in right ? left.id === right.id : false;\n}\n\nexport function sameSelection(\n left: readonly SchematicTarget[],\n right: readonly SchematicTarget[],\n): boolean {\n return (\n left.length === right.length &&\n left.every((item, index) => {\n const other = right[index];\n return other !== undefined && sameTarget(item, other);\n })\n );\n}\n\n/** Drops entries whose target disappeared from the document. */\nexport function pruneSelection(\n selection: readonly SchematicTarget[],\n document: SchematicDocument,\n devices?: DeviceSymbolProvider,\n): readonly SchematicTarget[] {\n if (selection.length === 0) {\n return selection;\n }\n const symbols = new Set(document.sheet.symbols.map((symbol) => symbol.id));\n const wires = new Map(document.sheet.wires.map((wire) => [wire.id, wire]));\n const junctions = new Set(document.sheet.junctions.map((junction) => junction.id));\n const kept = selection.filter((item) => {\n switch (item.kind) {\n case 'symbol':\n return symbols.has(item.id);\n case 'reference':\n return symbols.has(item.symbolId);\n case 'pin': {\n const symbol = document.sheet.symbols.find((candidate) => candidate.id === item.symbolId);\n if (symbol === undefined) return false;\n if (devices === undefined) return true;\n const reference = parseDeviceReference(symbol.device);\n return (\n reference !== undefined &&\n devices.getDeviceSymbol(reference)?.pins[item.pinId] !== undefined\n );\n }\n case 'wire':\n return wires.has(item.id);\n case 'junction':\n return junctions.has(item.id);\n case 'vertex': {\n const wire = wires.get(item.wireId);\n return (\n wire !== undefined &&\n Number.isInteger(item.index) &&\n item.index >= 0 &&\n item.index < wire.points.length\n );\n }\n default:\n return false;\n }\n });\n return kept.length === selection.length ? selection : kept;\n}\n","/** Any CSS color string; Canvas and CSS parse it. */\nexport type ThemeColor = string;\n\n/**\n * Rendering and chrome tokens. The renderer never hard-codes colors: every visible\n * value comes from a theme.\n */\nexport interface ISchematicTheme {\n background: ThemeColor;\n grid: ThemeColor;\n gridMajor: ThemeColor;\n\n wire: ThemeColor;\n wireSelected: ThemeColor;\n junction: ThemeColor;\n junctionSelected: ThemeColor;\n pendingWire: ThemeColor;\n\n symbolFill: ThemeColor;\n symbolStroke: ThemeColor;\n symbolText: ThemeColor;\n symbolPlaceholder: ThemeColor;\n pin: ThemeColor;\n pinText: ThemeColor;\n pinOpen: ThemeColor;\n\n labelAnchor: ThemeColor;\n labelText: ThemeColor;\n\n selection: ThemeColor;\n hover: ThemeColor;\n\n uiBackground: ThemeColor;\n uiSurface: ThemeColor;\n uiBorder: ThemeColor;\n uiText: ThemeColor;\n uiMutedText: ThemeColor;\n uiAccent: ThemeColor;\n uiAccentText: ThemeColor;\n focusRing: ThemeColor;\n\n fontFamily: string;\n fontSize: number;\n /** Pin name text; smaller than `fontSize` so labels stay inside the body. */\n pinFontSize: number;\n /** Device name drawn in the symbol centre. */\n symbolFontSize: number;\n gridSize: number;\n}\n\n/**\n * Default dark theme: neutral greys on near-black, matching the reference palette\n * (background `#0a0a0a`, foreground `#fafafa`, muted `#a1a1a1`, ring `#737373`).\n */\nexport const DARK_SCHEMATIC_THEME: ISchematicTheme = {\n background: '#0a0a0a',\n grid: 'rgba(250, 250, 250, 0.06)',\n gridMajor: 'rgba(250, 250, 250, 0.12)',\n\n wire: '#a1a1a1',\n wireSelected: '#fafafa',\n junction: '#e5e5e5',\n junctionSelected: '#fafafa',\n pendingWire: '#fafafa',\n\n symbolFill: '#171717',\n symbolStroke: '#737373',\n /** Device name in the symbol centre: quiet until the symbol is hovered or selected. */\n symbolText: '#a1a1a1',\n symbolPlaceholder: 'rgba(250, 250, 250, 0.28)',\n pin: '#737373',\n pinText: '#a1a1a1',\n pinOpen: '#e5e5e5',\n\n labelAnchor: '#737373',\n labelText: '#a1a1a1',\n\n selection: '#fafafa',\n hover: '#a1a1a1',\n\n uiBackground: '#0a0a0a',\n uiSurface: '#171717',\n uiBorder: 'rgba(250, 250, 250, 0.1)',\n uiText: '#fafafa',\n uiMutedText: '#a1a1a1',\n uiAccent: '#e5e5e5',\n uiAccentText: '#171717',\n focusRing: '#737373',\n\n fontFamily: 'ui-sans-serif, system-ui, -apple-system, \"Segoe UI\", sans-serif',\n fontSize: 9,\n pinFontSize: 7,\n symbolFontSize: 9,\n gridSize: 10,\n};\n\nexport const LIGHT_SCHEMATIC_THEME: ISchematicTheme = {\n background: '#ffffff',\n grid: 'rgba(10, 10, 10, 0.05)',\n gridMajor: 'rgba(10, 10, 10, 0.1)',\n\n wire: '#525252',\n wireSelected: '#0a0a0a',\n junction: '#262626',\n junctionSelected: '#0a0a0a',\n pendingWire: '#0a0a0a',\n\n symbolFill: '#fafafa',\n symbolStroke: '#a1a1a1',\n /** Device name in the symbol centre: quiet until the symbol is hovered or selected. */\n symbolText: '#525252',\n symbolPlaceholder: 'rgba(10, 10, 10, 0.3)',\n pin: '#a1a1a1',\n pinText: '#525252',\n pinOpen: '#262626',\n\n labelAnchor: '#a1a1a1',\n labelText: '#525252',\n\n selection: '#0a0a0a',\n hover: '#525252',\n\n uiBackground: '#ffffff',\n uiSurface: '#f5f5f5',\n uiBorder: 'rgba(10, 10, 10, 0.1)',\n uiText: '#0a0a0a',\n uiMutedText: '#525252',\n uiAccent: '#171717',\n uiAccentText: '#fafafa',\n focusRing: '#a1a1a1',\n\n fontFamily: DARK_SCHEMATIC_THEME.fontFamily,\n fontSize: DARK_SCHEMATIC_THEME.fontSize,\n pinFontSize: DARK_SCHEMATIC_THEME.pinFontSize,\n symbolFontSize: DARK_SCHEMATIC_THEME.symbolFontSize,\n gridSize: DARK_SCHEMATIC_THEME.gridSize,\n};\n\n/** Merges overrides onto the dark baseline, so partial themes stay readable. */\nexport function resolveSchematicTheme(overrides: Partial<ISchematicTheme> = {}): ISchematicTheme {\n const resolved: ISchematicTheme = { ...DARK_SCHEMATIC_THEME };\n for (const key of Object.keys(overrides) as (keyof ISchematicTheme)[]) {\n const value = overrides[key];\n if (value !== undefined) {\n Object.assign(resolved, { [key]: value });\n }\n }\n return resolved;\n}\n\n/** Maps the theme onto `--mica-schematic-*` CSS variables for light-DOM chrome. */\nexport function themeToCssVariables(theme: ISchematicTheme): Readonly<Record<string, string>> {\n const variables: Record<string, string> = {};\n for (const [key, value] of Object.entries(theme)) {\n variables[`--mica-schematic-${kebabCase(key)}`] = String(value);\n }\n return variables;\n}\n\nfunction kebabCase(value: string): string {\n return value.replace(/[A-Z]/g, (letter) => `-${letter.toLowerCase()}`);\n}\n","import type { Point, Rect } from '@mica-js/document/schematic';\n\nexport interface IViewportState {\n readonly scale: number;\n readonly offsetX: number;\n readonly offsetY: number;\n}\n\nexport interface IViewportLimits {\n readonly minScale: number;\n readonly maxScale: number;\n}\n\nexport const DEFAULT_VIEWPORT_LIMITS: IViewportLimits = { minScale: 0.25, maxScale: 4 };\n\n/** Merges partial overrides onto the defaults; rejects non-positive and inverted ranges. */\nexport function resolveViewportLimits(limits?: Partial<IViewportLimits>): IViewportLimits {\n const minScale = limits?.minScale;\n const maxScale = limits?.maxScale;\n const resolved: IViewportLimits = {\n minScale:\n minScale !== undefined && Number.isFinite(minScale) && minScale > 0\n ? minScale\n : DEFAULT_VIEWPORT_LIMITS.minScale,\n maxScale:\n maxScale !== undefined && Number.isFinite(maxScale) && maxScale > 0\n ? maxScale\n : DEFAULT_VIEWPORT_LIMITS.maxScale,\n };\n if (resolved.minScale > resolved.maxScale) {\n return { minScale: resolved.maxScale, maxScale: resolved.minScale };\n }\n return resolved;\n}\n\nexport const IDENTITY_VIEWPORT: IViewportState = { scale: 1, offsetX: 0, offsetY: 0 };\n\nexport function screenToPage(viewport: IViewportState, point: Point): Point {\n return {\n x: (point.x - viewport.offsetX) / viewport.scale,\n y: (point.y - viewport.offsetY) / viewport.scale,\n };\n}\n\nexport function pageToScreen(viewport: IViewportState, point: Point): Point {\n return {\n x: point.x * viewport.scale + viewport.offsetX,\n y: point.y * viewport.scale + viewport.offsetY,\n };\n}\n\nexport function clampScale(\n scale: number,\n limits: IViewportLimits = DEFAULT_VIEWPORT_LIMITS,\n): number {\n return Math.min(limits.maxScale, Math.max(limits.minScale, scale));\n}\n\n/**\n * Clamps a viewport to `limits` while keeping the page point at the centre of `size` in place,\n * so restoring a saved view can never jump the content off screen.\n */\nexport function clampViewport(\n viewport: IViewportState,\n size: { readonly width: number; readonly height: number },\n limits: IViewportLimits = DEFAULT_VIEWPORT_LIMITS,\n): IViewportState {\n const scale = clampScale(\n Number.isFinite(viewport.scale) && viewport.scale > 0 ? viewport.scale : limits.minScale,\n limits,\n );\n if (scale === viewport.scale) {\n return viewport;\n }\n const center = { x: size.width / 2, y: size.height / 2 };\n const anchor = screenToPage(viewport, center);\n return {\n scale,\n offsetX: center.x - anchor.x * scale,\n offsetY: center.y - anchor.y * scale,\n };\n}\n\n/** Zooms around a screen-space point so the page point under the cursor stays fixed. */ export function zoomAt(\n viewport: IViewportState,\n screenPoint: Point,\n factor: number,\n limits: IViewportLimits = DEFAULT_VIEWPORT_LIMITS,\n): IViewportState {\n const scale = clampScale(viewport.scale * factor, limits);\n if (scale === viewport.scale) {\n return viewport;\n }\n const anchor = screenToPage(viewport, screenPoint);\n return {\n scale,\n offsetX: screenPoint.x - anchor.x * scale,\n offsetY: screenPoint.y - anchor.y * scale,\n };\n}\n\nexport function panBy(viewport: IViewportState, dx: number, dy: number): IViewportState {\n return { ...viewport, offsetX: viewport.offsetX + dx, offsetY: viewport.offsetY + dy };\n}\n\n/** Fits `bounds` into `size` with padding, centering the content. */\nexport function fitBounds(\n bounds: Rect,\n size: { readonly width: number; readonly height: number },\n padding = 32,\n limits: IViewportLimits = DEFAULT_VIEWPORT_LIMITS,\n): IViewportState {\n const availableWidth = Math.max(1, size.width - padding * 2);\n const availableHeight = Math.max(1, size.height - padding * 2);\n const width = Math.max(bounds.width, 1e-6);\n const height = Math.max(bounds.height, 1e-6);\n const scale = clampScale(Math.min(availableWidth / width, availableHeight / height), limits);\n const centerX = bounds.x + bounds.width / 2;\n const centerY = bounds.y + bounds.height / 2;\n return {\n scale,\n offsetX: size.width / 2 - centerX * scale,\n offsetY: size.height / 2 - centerY * scale,\n };\n}\n","import type { Point } from '@mica-js/document/schematic';\nimport type { ISchematicScene, SceneItem } from './scene';\nimport { resolveSchematicTheme, type ISchematicTheme } from './theme';\nimport { pageToScreen, type IViewportState } from './viewport';\n\nexport interface ICanvasRendererOptions {\n readonly theme?: Partial<ISchematicTheme>;\n}\n\nconst MAJOR_GRID_INTERVAL = 5;\n/** Sub-grid lines are hidden once they get closer together than this (CSS pixels). */\nconst MIN_GRID_PIXELS = 4;\n/** Emphasised lines are stretched to stay at least this far apart (CSS pixels). */\nconst MIN_MAJOR_GRID_PIXELS = 20;\n\n/** Draws a {@link ISchematicScene} onto a canvas, honoring device pixel ratio. */\nexport class CanvasSchematicRenderer {\n #canvas: HTMLCanvasElement;\n #context: CanvasRenderingContext2D | null;\n #theme: ISchematicTheme;\n #width = 0;\n #height = 0;\n #pixelRatio = 1;\n\n constructor(canvas: HTMLCanvasElement, options: ICanvasRendererOptions = {}) {\n this.#canvas = canvas;\n this.#context = canvas.getContext('2d');\n this.#theme = resolveSchematicTheme(options.theme);\n }\n\n get theme(): ISchematicTheme {\n return this.#theme;\n }\n\n setTheme(theme: ISchematicTheme): void {\n this.#theme = theme;\n }\n\n resize(width: number, height: number, pixelRatio = 1): void {\n this.#width = width;\n this.#height = height;\n this.#pixelRatio = pixelRatio;\n // Only the bitmap size is set here; CSS keeps ownership of the display size.\n this.#canvas.width = Math.max(1, Math.round(width * pixelRatio));\n this.#canvas.height = Math.max(1, Math.round(height * pixelRatio));\n }\n\n render(scene: ISchematicScene, viewport: IViewportState): void {\n const context = this.#context;\n if (context === null) {\n return;\n }\n context.setTransform(this.#pixelRatio, 0, 0, this.#pixelRatio, 0, 0);\n context.clearRect(0, 0, this.#width, this.#height);\n\n context.fillStyle = scene.background;\n context.fillRect(0, 0, this.#width, this.#height);\n\n if (scene.grid !== undefined) {\n this.#drawGrid(context, scene, viewport);\n }\n\n for (const item of scene.items) {\n this.#drawItem(context, item, viewport);\n }\n }\n\n destroy(): void {\n this.#context = null;\n }\n\n #drawGrid(\n context: CanvasRenderingContext2D,\n scene: ISchematicScene,\n viewport: IViewportState,\n ): void {\n const grid = scene.grid;\n if (grid === undefined) {\n return;\n }\n const cell = grid.size * viewport.scale;\n if (!Number.isFinite(cell) || cell <= 0) {\n return;\n }\n // Too fine to read at this zoom: drop subdivisions, then fall back to emphasised lines only.\n let subdivisions = grid.subdivisions;\n while (subdivisions > 1 && cell / subdivisions < MIN_GRID_PIXELS) {\n subdivisions = Math.max(1, Math.round(subdivisions / 2));\n }\n let step = cell / subdivisions;\n if (step < MIN_GRID_PIXELS) {\n step = cell;\n }\n let majorSpacing = cell * MAJOR_GRID_INTERVAL;\n while (majorSpacing < MIN_MAJOR_GRID_PIXELS) {\n majorSpacing *= 2;\n }\n const majorOnly = step < MIN_GRID_PIXELS;\n if (majorOnly) {\n step = majorSpacing;\n }\n\n const origin = pageToScreen(viewport, { x: 0, y: 0 });\n const startX = origin.x - Math.ceil(origin.x / step) * step;\n const startY = origin.y - Math.ceil(origin.y / step) * step;\n\n context.lineWidth = 1;\n for (let x = startX; x <= this.#width; x += step) {\n if (x < 0) {\n continue;\n }\n const major = majorOnly || isMajorGridLine(x - origin.x, majorSpacing);\n context.strokeStyle = major ? grid.major : grid.minor;\n strokeLine(\n context,\n { x: Math.round(x) + 0.5, y: 0 },\n { x: Math.round(x) + 0.5, y: this.#height },\n );\n }\n for (let y = startY; y <= this.#height; y += step) {\n if (y < 0) {\n continue;\n }\n const major = majorOnly || isMajorGridLine(y - origin.y, majorSpacing);\n context.strokeStyle = major ? grid.major : grid.minor;\n strokeLine(\n context,\n { x: 0, y: Math.round(y) + 0.5 },\n { x: this.#width, y: Math.round(y) + 0.5 },\n );\n }\n }\n\n #drawItem(context: CanvasRenderingContext2D, item: SceneItem, viewport: IViewportState): void {\n switch (item.kind) {\n case 'line': {\n context.strokeStyle = item.color;\n context.lineWidth = item.width;\n context.setLineDash(item.dash === undefined ? [] : [...item.dash]);\n strokeLine(context, pageToScreen(viewport, item.from), pageToScreen(viewport, item.to));\n context.setLineDash([]);\n break;\n }\n case 'polyline': {\n context.strokeStyle = item.color;\n context.lineWidth = item.width;\n context.lineJoin = 'round';\n context.lineCap = 'round';\n context.setLineDash(item.dash === undefined ? [] : [...item.dash]);\n context.beginPath();\n item.points.forEach((point, index) => {\n const screen = pageToScreen(viewport, point);\n if (index === 0) {\n context.moveTo(screen.x, screen.y);\n } else {\n context.lineTo(screen.x, screen.y);\n }\n });\n if (item.closed) context.closePath();\n if (item.fill !== undefined) {\n context.fillStyle = item.fill;\n context.fill();\n }\n context.stroke();\n context.setLineDash([]);\n break;\n }\n case 'rect': {\n const topLeft = pageToScreen(viewport, { x: item.bounds.x, y: item.bounds.y });\n const width = item.bounds.width * viewport.scale;\n const height = item.bounds.height * viewport.scale;\n context.setLineDash(item.dash === undefined ? [] : [...item.dash]);\n if (item.fill !== undefined) {\n context.fillStyle = item.fill;\n context.fillRect(topLeft.x, topLeft.y, width, height);\n }\n if (item.stroke !== undefined) {\n context.strokeStyle = item.stroke;\n context.lineWidth = item.width;\n context.strokeRect(topLeft.x, topLeft.y, width, height);\n }\n context.setLineDash([]);\n break;\n }\n case 'circle': {\n const center = pageToScreen(viewport, item.center);\n context.beginPath();\n context.arc(\n center.x,\n center.y,\n Math.max(0.5, item.radius * viewport.scale),\n 0,\n Math.PI * 2,\n );\n if (item.fill !== undefined) {\n context.fillStyle = item.fill;\n context.fill();\n }\n if (item.stroke !== undefined) {\n context.strokeStyle = item.stroke;\n context.lineWidth = item.width;\n context.stroke();\n }\n break;\n }\n case 'arc': {\n const center = pageToScreen(viewport, item.center);\n context.beginPath();\n context.arc(\n center.x,\n center.y,\n item.radius * viewport.scale,\n (item.startAngle * Math.PI) / 180,\n ((item.startAngle + item.sweepAngle) * Math.PI) / 180,\n item.sweepAngle < 0,\n );\n if (item.fill !== undefined) {\n context.fillStyle = item.fill;\n context.fill();\n }\n context.strokeStyle = item.stroke;\n context.lineWidth = item.width;\n context.stroke();\n break;\n }\n case 'text': {\n const position = pageToScreen(viewport, item.position);\n context.fillStyle = item.color;\n context.font = scaleFont(item.font, viewport.scale);\n context.textAlign = item.align;\n context.textBaseline = item.baseline;\n if (item.rotation === undefined || item.rotation === 0) {\n context.fillText(item.text, position.x, position.y);\n break;\n }\n context.save();\n context.translate(position.x, position.y);\n context.rotate((item.rotation * Math.PI) / 180);\n context.fillText(item.text, 0, 0);\n context.restore();\n break;\n }\n default:\n break;\n }\n }\n}\n\nfunction strokeLine(context: CanvasRenderingContext2D, from: Point, to: Point): void {\n context.beginPath();\n context.moveTo(from.x, from.y);\n context.lineTo(to.x, to.y);\n context.stroke();\n}\n\nfunction isMajorGridLine(offset: number, spacing: number): boolean {\n if (!Number.isFinite(spacing) || spacing <= 0) {\n return false;\n }\n const remainder = Math.abs(offset % spacing);\n return remainder < 0.5 || spacing - remainder < 0.5;\n}\n\nfunction scaleFont(font: string, scale: number): string {\n const match = /^(\\d+(?:\\.\\d+)?)px(.*)$/.exec(font);\n if (match === null) {\n return font;\n }\n return `${(Number(match[1]) * Math.max(scale, 0.01)).toFixed(1)}px${match[2]}`;\n}\n","import {\n DEFAULT_TEXT_CONTENT,\n builtinSymbolKind,\n designatorOf,\n isTextDevice,\n netNameOf,\n parseDeviceReference,\n pinSide,\n pinStubEnd,\n pinsBounds,\n pointOnPolyline,\n samePoint,\n referencePosition,\n rotatePoint,\n symbolBounds,\n symbolPinPosition,\n textDeviceContent,\n type DeviceSymbolDefinition,\n type DeviceSymbolProvider,\n type Placement,\n type Point,\n type Rect,\n type SchematicDocument,\n type SchematicSymbol,\n} from '@mica-js/document/schematic';\nimport { previewSymbolDrag } from '../editing/preview';\nimport { type SchematicHit } from '../editing/query';\nimport type { ISchematicTheme } from './theme';\nimport { deviceReferencePosition } from '../model/reference';\nexport type SceneTool = 'select' | 'wire' | 'power' | 'ground' | 'label' | 'text';\n\nexport interface ISceneSelection {\n readonly symbols?: ReadonlySet<string>;\n readonly wires?: ReadonlySet<string>;\n readonly junctions?: ReadonlySet<string>;\n readonly vertices?: readonly { readonly wireId: string; readonly index: number }[];\n /** Preview offset applied to the selected symbols while dragging. */\n readonly offset?: Point;\n}\n\nexport interface ISceneDisplayOptions {\n readonly grid: boolean;\n readonly gridSize?: number;\n /** Visible grid lines per snap cell; `1` draws only the snap grid. */\n readonly gridSubdivisions?: number;\n readonly labels: boolean;\n}\n\nexport type SceneItem =\n | {\n readonly kind: 'line';\n readonly from: Point;\n readonly to: Point;\n readonly color: string;\n readonly width: number;\n readonly dash?: readonly number[];\n }\n | {\n readonly kind: 'polyline';\n readonly points: readonly Point[];\n readonly closed?: boolean;\n readonly fill?: string;\n readonly color: string;\n readonly width: number;\n readonly dash?: readonly number[];\n }\n | {\n readonly kind: 'rect';\n readonly bounds: Rect;\n readonly fill?: string;\n readonly stroke?: string;\n readonly width: number;\n readonly dash?: readonly number[];\n }\n | {\n readonly kind: 'circle';\n readonly center: Point;\n readonly radius: number;\n readonly fill?: string;\n readonly stroke?: string;\n readonly width: number;\n }\n | {\n readonly kind: 'arc';\n readonly center: Point;\n readonly radius: number;\n readonly startAngle: number;\n readonly sweepAngle: number;\n readonly fill?: string;\n readonly stroke: string;\n readonly width: number;\n }\n | {\n readonly kind: 'text';\n readonly position: Point;\n readonly text: string;\n readonly color: string;\n readonly align: 'left' | 'center' | 'right';\n readonly baseline: 'top' | 'middle' | 'bottom';\n readonly font: string;\n /** Degrees, clockwise around `position`. */\n readonly rotation?: number;\n };\n\nexport interface ISchematicScene {\n readonly background: string;\n readonly grid:\n | {\n readonly size: number;\n /** Minor lines drawn per snap cell; `1` means the cell size is the only step. */\n readonly subdivisions: number;\n readonly minor: string;\n readonly major: string;\n }\n | undefined;\n readonly items: readonly SceneItem[];\n}\n\nexport interface IRenderInput {\n readonly document: SchematicDocument;\n readonly devices?: DeviceSymbolProvider;\n readonly theme: ISchematicTheme;\n readonly selection?: ISceneSelection;\n readonly hover?: SchematicHit;\n readonly tool?: SceneTool;\n readonly display?: ISceneDisplayOptions;\n readonly pendingWire?: readonly Point[];\n /** Rubber-band selection rectangle in page units. */\n readonly marquee?: Rect;\n /** Ghost of the symbol the current placement tool would insert. */\n readonly placementPreview?: {\n readonly device: string;\n readonly position: Point;\n readonly rotation: number;\n /** Stub wire the placement will add, e.g. when a label lands on a pin. */\n readonly wire?: readonly Point[];\n };\n /** Reference designator being dragged; drawn at this world position instead. */\n readonly referencePreview?: { readonly symbolId: string; readonly position: Point };\n /** Wire being reshaped by a segment drag; drawn with these points instead of the document's. */\n readonly wirePreview?: { readonly wireId: string; readonly points: readonly Point[] };\n}\n\nconst WIRE_WIDTH = 1.5;\nconst SELECTED_WIDTH = 2.5;\nconst JUNCTION_RADIUS = 3;\nconst VERTEX_SIZE = 5;\n\n/** Visible grid lines per snap cell; anything unset or invalid falls back to the snap grid. */\nfunction gridSubdivisions(value: number | undefined): number {\n return value !== undefined && Number.isFinite(value) && value >= 1 ? Math.round(value) : 1;\n}\n\ninterface ITextPlacement {\n readonly align: 'left' | 'center' | 'right';\n readonly baseline: 'top' | 'middle' | 'bottom';\n readonly rotation: number;\n}\n\nconst ALIGN_MIRROR: Readonly<Record<ITextPlacement['align'], ITextPlacement['align']>> = {\n left: 'right',\n center: 'center',\n right: 'left',\n};\n\nconst BASELINE_MIRROR: Readonly<Record<ITextPlacement['baseline'], ITextPlacement['baseline']>> = {\n top: 'bottom',\n middle: 'middle',\n bottom: 'top',\n};\n\n/**\n * Text turns with the symbol, except at half turns where it would read upside down: those flip\n * back and mirror the anchor alignment so the glyphs stay on the same side of the anchor.\n */\nfunction uprightText(\n rotation: number,\n align: ITextPlacement['align'],\n baseline: ITextPlacement['baseline'],\n): ITextPlacement {\n const normalized = (((rotation % 360) + 540) % 360) - 180;\n if (Math.abs(normalized) === 180) {\n return { align: ALIGN_MIRROR[align], baseline: BASELINE_MIRROR[baseline], rotation: 0 };\n }\n return { align, baseline, rotation: normalized };\n}\n\ninterface IPreviewDrag {\n readonly wires: ReadonlyMap<string, readonly Point[]>;\n readonly junctions: ReadonlyMap<string, Point>;\n readonly symbols: ReadonlyMap<string, Point>;\n}\n\nconst NO_PREVIEW: IPreviewDrag = { wires: new Map(), junctions: new Map(), symbols: new Map() };\n\n/** Live preview of the dragged symbols: wires, junctions and anchors follow their pins. */\nfunction previewDrag(\n document: SchematicDocument,\n devices: DeviceSymbolProvider | undefined,\n selection: ISceneSelection,\n): IPreviewDrag {\n const offset = selection.offset;\n if (offset === undefined || selection.symbols === undefined) {\n return NO_PREVIEW;\n }\n const wires = new Map<string, readonly Point[]>();\n const junctions = new Map<string, Point>();\n const symbols = new Map<string, Point>();\n for (const symbol of document.sheet.symbols) {\n if (!selection.symbols.has(symbol.id)) {\n continue;\n }\n const placed = { x: symbol.x, y: symbol.y, rotation: symbol.rotation };\n const preview = previewSymbolDrag(document, devices, symbol.id, {\n ...placed,\n x: placed.x + offset.x,\n y: placed.y + offset.y,\n });\n if (preview === undefined) {\n continue;\n }\n for (const [id, points] of preview.wires) {\n wires.set(id, points);\n }\n for (const [id, point] of preview.junctions) {\n junctions.set(id, point);\n }\n for (const [id, point] of preview.symbols) {\n symbols.set(id, point);\n }\n symbols.set(symbol.id, { x: placed.x + offset.x, y: placed.y + offset.y });\n }\n return { wires, junctions, symbols };\n}\n\n/** Builds a flat, drawable scene. Every color comes from `theme`. */\nexport function buildSchematicScene(input: IRenderInput): ISchematicScene {\n const { document, devices, theme } = input;\n const selection = input.selection ?? {};\n const tool = input.tool ?? 'select';\n const display = input.display ?? { grid: true, labels: true };\n const font = `${theme.fontSize}px ${theme.fontFamily}`;\n const pinFont = `${theme.pinFontSize}px ${theme.fontFamily}`;\n const symbolFont = `${theme.symbolFontSize}px ${theme.fontFamily}`;\n const items: SceneItem[] = [];\n const drag = previewDrag(document, devices, selection);\n const wirePaths: (readonly Point[])[] = [];\n const junctionPoints = new Set<string>();\n\n for (const wire of document.sheet.wires) {\n const selected = selection.wires?.has(wire.id) ?? false;\n const hovered = input.hover?.kind === 'wire' && input.hover.id === wire.id;\n const preview = input.wirePreview;\n const points =\n preview !== undefined && preview.wireId === wire.id\n ? preview.points\n : (drag.wires.get(wire.id) ?? wire.points);\n wirePaths.push(points);\n items.push({\n kind: 'polyline',\n points,\n color: selected ? theme.wireSelected : hovered ? theme.hover : theme.wire,\n width: selected ? SELECTED_WIDTH : WIRE_WIDTH,\n });\n }\n\n for (const junction of document.sheet.junctions) {\n const selected = selection.junctions?.has(junction.id) ?? false;\n const hovered = input.hover?.kind === 'junction' && input.hover.id === junction.id;\n const center = drag.junctions.get(junction.id) ?? { x: junction.x, y: junction.y };\n junctionPoints.add(`${center.x},${center.y}`);\n items.push({\n kind: 'circle',\n center,\n radius: JUNCTION_RADIUS,\n fill: selected ? theme.junctionSelected : hovered ? theme.hover : theme.junction,\n width: 0,\n });\n }\n\n for (const symbol of document.sheet.symbols) {\n const selected = selection.symbols?.has(symbol.id) ?? false;\n const hovered =\n (input.hover?.kind === 'symbol' && input.hover.id === symbol.id) ||\n (input.hover?.kind === 'reference' && input.hover.symbolId === symbol.id);\n const placed = { x: symbol.x, y: symbol.y, rotation: symbol.rotation };\n const dragged = drag.symbols.get(symbol.id);\n const placement = dragged === undefined ? placed : { ...placed, x: dragged.x, y: dragged.y };\n drawSymbol(items, {\n symbol,\n placement,\n theme,\n devices,\n labels: display.labels,\n fonts: { font, pinFont, symbolFont },\n selected,\n hovered,\n ...(input.referencePreview?.symbolId === symbol.id\n ? { referenceOverride: input.referencePreview.position }\n : {}),\n });\n const reference = parseDeviceReference(symbol.device);\n const definition = reference === undefined ? undefined : devices?.getDeviceSymbol(reference);\n for (const pin of Object.values(definition?.pins ?? {})) {\n const center = symbolPinPosition(placement, pin);\n const key = `${center.x},${center.y}`;\n if (junctionPoints.has(key)) continue;\n let branches = 1;\n for (const points of wirePaths) {\n if (!pointOnPolyline(points, center)) continue;\n branches +=\n samePoint(center, points[0]!) || samePoint(center, points[points.length - 1]!) ? 1 : 2;\n }\n if (branches <= 2) continue;\n junctionPoints.add(key);\n items.push({\n kind: 'circle',\n center,\n radius: JUNCTION_RADIUS,\n fill: selected ? theme.junctionSelected : hovered ? theme.hover : theme.junction,\n width: 0,\n });\n }\n }\n for (const vertex of selection.vertices ?? []) {\n const wire = document.sheet.wires.find((candidate) => candidate.id === vertex.wireId);\n const point = wire?.points[vertex.index];\n if (point === undefined) {\n continue;\n }\n const center = point;\n items.push({\n kind: 'rect',\n bounds: {\n x: center.x - VERTEX_SIZE / 2,\n y: center.y - VERTEX_SIZE / 2,\n width: VERTEX_SIZE,\n height: VERTEX_SIZE,\n },\n fill: theme.selection,\n width: 0,\n });\n }\n\n if (input.marquee !== undefined) {\n items.push({\n kind: 'rect',\n bounds: input.marquee,\n stroke: theme.selection,\n width: 1,\n dash: [4, 3],\n });\n }\n\n if (input.placementPreview !== undefined) {\n const { device, position, rotation, wire } = input.placementPreview;\n if (wire !== undefined) {\n items.push({ kind: 'polyline', points: wire, color: theme.hover, width: WIRE_WIDTH });\n }\n drawSymbol(items, {\n symbol: previewSymbol(device, position),\n placement: { ...position, rotation },\n theme,\n devices,\n labels: display.labels,\n fonts: { font, pinFont, symbolFont },\n selected: false,\n hovered: false,\n ghost: true,\n });\n }\n\n if (tool === 'wire' && input.pendingWire !== undefined && input.pendingWire.length > 0) {\n items.push({\n kind: 'polyline',\n points: input.pendingWire,\n color: theme.pendingWire,\n width: WIRE_WIDTH,\n dash: [5, 4],\n });\n const last = input.pendingWire[input.pendingWire.length - 1];\n if (last !== undefined) {\n items.push({ kind: 'circle', center: last, radius: 2.5, fill: theme.pendingWire, width: 0 });\n }\n }\n\n return {\n background: theme.background,\n grid:\n display.grid === false\n ? undefined\n : {\n size: display.gridSize ?? theme.gridSize,\n subdivisions: gridSubdivisions(display.gridSubdivisions),\n minor: theme.grid,\n major: theme.gridMajor,\n },\n items,\n };\n}\n\ninterface ISymbolFonts {\n readonly font: string;\n readonly pinFont: string;\n readonly symbolFont: string;\n}\n\ninterface IDrawSymbolOptions {\n readonly symbol: SchematicSymbol;\n readonly placement: Placement;\n readonly theme: ISchematicTheme;\n readonly devices: DeviceSymbolProvider | undefined;\n readonly labels: boolean;\n readonly fonts: ISymbolFonts;\n readonly selected: boolean;\n readonly hovered: boolean;\n /** Drawn as a placement ghost (hover color, no reference override). */\n readonly ghost?: boolean;\n readonly referenceOverride?: Point;\n}\n\n/**\n * Draws one symbol: the single code path shared by placed symbols and the placement preview,\n * so what follows the cursor is exactly what will be inserted.\n */\nfunction drawSymbol(items: SceneItem[], options: IDrawSymbolOptions): void {\n const { symbol, placement, theme, devices, fonts, selected, hovered } = options;\n const ghost = options.ghost ?? false;\n const highlight = selected ? theme.selection : hovered || ghost ? theme.hover : undefined;\n const stroke = highlight ?? theme.symbolStroke;\n const annotation = highlight ?? theme.labelText;\n\n if (isTextDevice(symbol.device)) {\n items.push({\n kind: 'text',\n position: placement,\n text: textDeviceContent(symbol),\n color: annotation,\n ...uprightText(placement.rotation, 'left', 'middle'),\n font: fonts.symbolFont,\n });\n return;\n }\n\n const builtin = builtinSymbolKind(symbol.device);\n if (builtin !== undefined) {\n drawBuiltin(items, {\n kind: builtin,\n placement,\n text: netNameOf(symbol) ?? symbol.id,\n color: annotation,\n anchorColor: highlight ?? theme.labelAnchor,\n font: builtin === 'label' ? fonts.font : fonts.pinFont,\n });\n return;\n }\n\n const reference = parseDeviceReference(symbol.device);\n const definition = reference === undefined ? undefined : devices?.getDeviceSymbol(reference);\n\n if (definition === undefined) {\n const half = 12;\n items.push({\n kind: 'rect',\n bounds: { x: placement.x - half, y: placement.y - half, width: half * 2, height: half * 2 },\n stroke: theme.symbolPlaceholder,\n width: 1,\n dash: [4, 3],\n });\n items.push({\n kind: 'text',\n position: { x: placement.x, y: placement.y },\n text: (reference === undefined ? undefined : devices?.getDeviceName(reference)) ?? symbol.id,\n color: theme.symbolPlaceholder,\n align: 'center',\n baseline: 'middle',\n font: fonts.symbolFont,\n });\n return;\n }\n\n const localBody = definition.bounds ??\n pinsBounds(definition.pins) ?? { x: -12, y: -12, width: 24, height: 24 };\n if (definition.graphics !== undefined) {\n drawCustomSymbol(items, options, definition, localBody);\n return;\n }\n\n const body = symbolBounds(placement, localBody, {}) ?? fallbackBounds(placement);\n\n items.push({ kind: 'rect', bounds: body, fill: theme.symbolFill, stroke, width: 1.5 });\n items.push({\n kind: 'text',\n position:\n options.referenceOverride ?? referencePosition(placement, localBody, symbol.reference),\n text: designatorOf(symbol) ?? symbol.id,\n color: options.referenceOverride === undefined ? annotation : theme.selection,\n ...uprightText(placement.rotation, 'left', 'bottom'),\n font: fonts.pinFont,\n });\n items.push({\n kind: 'text',\n position: { x: body.x + body.width / 2, y: body.y + body.height / 2 },\n text: definition.name,\n // Inverted on purpose: the name is quiet by default and lights up on hover / selection.\n color: selected || hovered ? theme.selection : theme.symbolText,\n ...uprightText(placement.rotation, 'center', 'middle'),\n font: fonts.symbolFont,\n });\n\n for (const anchor of Object.values(definition.pins)) {\n const side = pinSide(anchor, localBody) ?? 'left';\n const pinPosition = symbolPinPosition(placement, anchor);\n const edge = symbolPinPosition(placement, pinStubEnd(localBody, anchor, side));\n items.push({\n kind: 'line',\n from: edge,\n to: pinPosition,\n color: highlight ?? theme.pin,\n width: 1.2,\n });\n }\n drawPinLabels(items, options, definition, localBody);\n}\n\nfunction drawCustomSymbol(\n items: SceneItem[],\n options: IDrawSymbolOptions,\n definition: DeviceSymbolDefinition,\n localBody: Rect,\n): void {\n const { placement, theme, symbol, selected, hovered, fonts } = options;\n const highlight = selected ? theme.selection : hovered || options.ghost ? theme.hover : undefined;\n const stroke = highlight ?? theme.symbolStroke;\n const at = (point: readonly [number, number]): Point =>\n symbolPinPosition(placement, { x: point[0], y: point[1] });\n for (const graphic of definition.graphics ?? []) {\n const fill =\n graphic.fill === 'foreground'\n ? stroke\n : graphic.fill === 'background'\n ? theme.symbolFill\n : undefined;\n const style = { ...(fill === undefined ? {} : { fill }), width: graphic.strokeWidth ?? 1.5 };\n switch (graphic.type) {\n case 'line':\n items.push({\n kind: 'line',\n from: at(graphic.from),\n to: at(graphic.to),\n color: stroke,\n width: style.width,\n });\n break;\n case 'polyline':\n items.push({\n kind: 'polyline',\n points: graphic.points.map(at),\n closed: graphic.closed ?? false,\n color: stroke,\n ...style,\n });\n break;\n case 'rect':\n items.push({\n kind: 'polyline',\n points: [\n at([graphic.x, graphic.y]),\n at([graphic.x + graphic.width, graphic.y]),\n at([graphic.x + graphic.width, graphic.y + graphic.height]),\n at([graphic.x, graphic.y + graphic.height]),\n ],\n closed: true,\n color: stroke,\n ...style,\n });\n break;\n case 'circle':\n items.push({\n kind: 'circle',\n center: at(graphic.center),\n radius: graphic.radius,\n stroke,\n ...style,\n });\n break;\n case 'arc':\n items.push({\n kind: 'arc',\n center: at(graphic.center),\n radius: graphic.radius,\n startAngle: graphic.startAngle + placement.rotation,\n sweepAngle: graphic.sweepAngle,\n stroke,\n ...style,\n });\n break;\n case 'text':\n items.push({\n kind: 'text',\n position: at(graphic.position),\n text: graphic.text,\n color: stroke,\n ...uprightText(placement.rotation, graphic.align ?? 'left', 'middle'),\n font:\n graphic.fontSize === undefined\n ? fonts.symbolFont\n : `${graphic.fontSize}px ${theme.fontFamily}`,\n });\n break;\n }\n }\n const annotation = definition.annotations?.designator;\n items.push({\n kind: 'text',\n position:\n options.referenceOverride ??\n deviceReferencePosition(\n {\n ...placement,\n ...(symbol.reference === undefined ? {} : { reference: symbol.reference }),\n },\n definition,\n ),\n text: designatorOf(symbol) ?? symbol.id,\n color:\n options.referenceOverride === undefined ? (highlight ?? theme.labelText) : theme.selection,\n ...uprightText(placement.rotation, annotation?.align ?? 'left', 'bottom'),\n font: fonts.pinFont,\n });\n drawPinLabels(items, options, definition, localBody);\n}\n\nfunction drawPinLabels(\n items: SceneItem[],\n options: IDrawSymbolOptions,\n definition: DeviceSymbolDefinition,\n localBody: Rect,\n): void {\n if (!options.labels) return;\n const { placement, theme, fonts, selected, hovered } = options;\n const highlight = selected ? theme.selection : hovered || options.ghost ? theme.hover : undefined;\n for (const [pinId, pin] of Object.entries(definition.pins)) {\n if (pin.label?.visible === false) continue;\n const explicit = pin.label?.position;\n const label =\n explicit === undefined\n ? pinLabel(localBody, pinSide(pin, localBody) ?? 'left', pin)\n : {\n position: { x: explicit[0], y: explicit[1] },\n align: 'left' as const,\n baseline: 'middle' as const,\n rotation: 0,\n };\n items.push({\n kind: 'text',\n position: symbolPinPosition(placement, label.position),\n text: pin.displayName ?? pinId,\n color: highlight ?? theme.pinText,\n ...uprightText(\n placement.rotation + label.rotation,\n pin.label?.align ?? label.align,\n label.baseline,\n ),\n font: fonts.pinFont,\n });\n }\n}\n\n/** Synthetic symbol used to preview the current placement tool. */\nfunction previewSymbol(device: string, position: Point): SchematicSymbol {\n const base: SchematicSymbol = { id: 'N', device, x: position.x, y: position.y, rotation: 0 };\n if (isTextDevice(device)) {\n return { ...base, properties: { text: DEFAULT_TEXT_CONTENT } };\n }\n return base;\n}\n\nfunction fallbackBounds(placement: { readonly x: number; readonly y: number }): Rect {\n return { x: placement.x - 12, y: placement.y - 12, width: 24, height: 24 };\n}\n\nfunction pinLabel(\n body: Rect,\n side: 'left' | 'right' | 'top' | 'bottom',\n anchor: { readonly x: number; readonly y: number },\n): {\n position: Point;\n align: 'left' | 'center' | 'right';\n baseline: 'top' | 'middle' | 'bottom';\n rotation: number;\n} {\n const centerX = body.x + body.width / 2;\n const centerY = body.y + body.height / 2;\n const clampX = Math.min(Math.max(anchor.x, body.x), body.x + body.width);\n const clampY = Math.min(Math.max(anchor.y, body.y), body.y + body.height);\n switch (side) {\n case 'left':\n return {\n position: { x: body.x + 2, y: clampY },\n align: 'left',\n baseline: 'middle',\n rotation: 0,\n };\n case 'right':\n return {\n position: { x: body.x + body.width - 2, y: clampY },\n align: 'right',\n baseline: 'middle',\n rotation: 0,\n };\n case 'top':\n return {\n position: { x: clampX, y: body.y + 5 },\n align: 'center',\n baseline: 'middle',\n rotation: -90,\n };\n case 'bottom':\n return {\n position: { x: clampX, y: body.y + body.height - 5 },\n align: 'center',\n baseline: 'middle',\n rotation: -90,\n };\n default:\n return {\n position: { x: centerX, y: centerY },\n align: 'center',\n baseline: 'middle',\n rotation: 0,\n };\n }\n}\n\nfunction drawBuiltin(\n items: SceneItem[],\n input: {\n readonly kind: 'label' | 'power' | 'ground';\n readonly placement: Placement;\n readonly text: string;\n readonly color: string;\n readonly anchorColor: string;\n readonly font: string;\n },\n): void {\n const { placement, color, anchorColor, font } = input;\n const at = (x: number, y: number): Point => symbolPinPosition(placement, { x, y });\n // Annotation text keeps its orientation and grows away from the glyph, so it stays readable\n // whatever the rotation.\n const push = (x: number, y: number): void => {\n const rotated = rotatePoint({ x, y }, placement.rotation);\n items.push({\n kind: 'text',\n position: { x: placement.x + rotated.x, y: placement.y + rotated.y },\n text: input.text,\n color,\n ...outwardLabel(rotated),\n font,\n });\n };\n\n // Power and ground mark their connection point with the stem itself; only free-standing\n // labels need a marker, drawn as a small cross.\n if (input.kind === 'label') {\n items.push({ kind: 'line', from: at(-3, 0), to: at(3, 0), color: anchorColor, width: 1.2 });\n items.push({ kind: 'line', from: at(0, -3), to: at(0, 3), color: anchorColor, width: 1.2 });\n // The name sits beside the cross, off the wire it names, so the wire never crosses the text.\n const layout = LABEL_TEXT_LAYOUTS[quarterTurns(placement.rotation)];\n items.push({\n kind: 'text',\n position: { x: placement.x + layout.offset.x, y: placement.y + layout.offset.y },\n text: input.text,\n color,\n align: layout.align,\n baseline: layout.baseline,\n font,\n });\n return;\n }\n\n if (input.kind === 'power') {\n items.push({ kind: 'line', from: at(0, 0), to: at(0, -10), color, width: 1.5 });\n items.push({ kind: 'line', from: at(-6, -10), to: at(6, -10), color, width: 1.5 });\n push(0, -13);\n return;\n }\n\n if (input.kind === 'ground') {\n items.push({ kind: 'line', from: at(0, 0), to: at(0, 6), color, width: 1.5 });\n for (const [offset, width] of [\n [6, 12],\n [9, 8],\n [12, 4],\n ] as const) {\n items.push({\n kind: 'line',\n from: at(-width / 2, offset),\n to: at(width / 2, offset),\n color,\n width: 1.5,\n });\n }\n push(0, 16);\n }\n}\n\n/** Rotation snapped to the 90° steps builtin glyphs support. */\nfunction quarterTurns(rotation: number): 0 | 90 | 180 | 270 {\n const normalized = ((((rotation % 360) + 360) % 360) + 45) % 360;\n return (Math.floor(normalized / 90) * 90) as 0 | 90 | 180 | 270;\n}\n\n/** Distance between a label's name and the wire it names. */\nconst LABEL_TEXT_GAP = 1;\n/** Clearance from the anchor cross, so the name starts just past its arms. */\nconst LABEL_TEXT_INSET = 4;\n\n/**\n * Where a label's name goes for each rotation: right above the wire for horizontal labels and\n * just past its tip for vertical ones, clear of the anchor cross.\n */\nconst LABEL_TEXT_LAYOUTS: Readonly<\n Record<\n 0 | 90 | 180 | 270,\n {\n readonly offset: Point;\n readonly align: ITextPlacement['align'];\n readonly baseline: ITextPlacement['baseline'];\n }\n >\n> = {\n 0: {\n offset: { x: LABEL_TEXT_INSET, y: -LABEL_TEXT_GAP },\n align: 'left',\n baseline: 'bottom',\n },\n 90: { offset: { x: LABEL_TEXT_INSET, y: 0 }, align: 'left', baseline: 'middle' },\n 180: {\n offset: { x: -LABEL_TEXT_INSET, y: -LABEL_TEXT_GAP },\n align: 'right',\n baseline: 'bottom',\n },\n 270: { offset: { x: LABEL_TEXT_INSET, y: 0 }, align: 'left', baseline: 'middle' },\n};\n\n/** Horizontal text starting at `offset` (already rotated) and growing away from the origin. */\nfunction outwardLabel(offset: Point): ITextPlacement {\n if (Math.abs(offset.x) >= Math.abs(offset.y)) {\n return { align: offset.x >= 0 ? 'left' : 'right', baseline: 'middle', rotation: 0 };\n }\n return { align: 'center', baseline: offset.y >= 0 ? 'top' : 'bottom', rotation: 0 };\n}\n","import { SCHEMATIC_CLIPBOARD_MIME } from '../model/clipboard';\n\n/**\n * Bridge to the host clipboard. The editor keeps its own in-memory payload, so a port that throws\n * (no permission, no secure context) only costs system-clipboard interop.\n */\nexport interface IClipboardPort {\n /** Payload text, or `undefined` when the clipboard is empty or unreadable. */\n read(): Promise<string | undefined>;\n /** Replaces the clipboard with `text`; rejects when the host denies the write. */\n write(text: string): Promise<void>;\n}\n\ntype BrowserClipboard = Pick<Clipboard, 'read' | 'readText' | 'write' | 'writeText'>;\n\n/**\n * Asynchronous Clipboard API, preferring the editor MIME type and degrading to `text/plain`.\n * Reads resolve to `undefined` and writes reject when the API is missing, so callers fall back to\n * the editor's own buffer.\n */\nexport function createBrowserClipboardPort(): IClipboardPort {\n return {\n async read() {\n const clipboard = browserClipboard();\n if (clipboard === undefined) {\n return undefined;\n }\n if (typeof clipboard.read === 'function') {\n try {\n const items = await clipboard.read();\n for (const item of items) {\n const text = await readItemText(item);\n if (text !== undefined) {\n return text;\n }\n }\n } catch {\n // Custom MIME reads are permission-gated in some browsers; try plain text next.\n }\n }\n try {\n const text = await clipboard.readText();\n return text.length > 0 ? text : undefined;\n } catch {\n return undefined;\n }\n },\n async write(text) {\n const clipboard = browserClipboard();\n if (clipboard === undefined) {\n throw new Error('The Clipboard API is unavailable.');\n }\n if (typeof ClipboardItem !== 'undefined' && typeof clipboard.write === 'function') {\n try {\n await clipboard.write([\n new ClipboardItem({\n [SCHEMATIC_CLIPBOARD_MIME]: new Blob([text], { type: SCHEMATIC_CLIPBOARD_MIME }),\n 'text/plain': new Blob([text], { type: 'text/plain' }),\n }),\n ]);\n return;\n } catch {\n // Some browsers reject custom MIME types; fall back to plain text.\n }\n }\n await clipboard.writeText(text);\n },\n };\n}\n\n/** Clipboard kept in memory: tests, Electron shells and hosts without clipboard permissions. */\nexport class MemoryClipboardPort implements IClipboardPort {\n #text: string | undefined;\n\n constructor(text?: string) {\n this.#text = text;\n }\n\n read(): Promise<string | undefined> {\n return Promise.resolve(this.#text);\n }\n\n write(text: string): Promise<void> {\n this.#text = text;\n return Promise.resolve();\n }\n}\n\n/** Reads the editor MIME type from a DOM clipboard event, falling back to `text/plain`. */\nexport function readClipboardEvent(event: ClipboardEvent): string | undefined {\n const data = event.clipboardData;\n if (data === null) {\n return undefined;\n }\n const custom = data.getData(SCHEMATIC_CLIPBOARD_MIME);\n if (custom.length > 0) {\n return custom;\n }\n const plain = data.getData('text/plain');\n return plain.length > 0 ? plain : undefined;\n}\n\n/** Writes `text` under the editor MIME type and `text/plain`, for DOM copy / cut events. */\nexport function writeClipboardEvent(event: ClipboardEvent, text: string): void {\n const data = event.clipboardData;\n if (data === null) {\n return;\n }\n data.setData(SCHEMATIC_CLIPBOARD_MIME, text);\n data.setData('text/plain', text);\n}\n\nfunction browserClipboard(): BrowserClipboard | undefined {\n const navigatorLike = (globalThis as { navigator?: { clipboard?: unknown } }).navigator;\n const clipboard = navigatorLike?.clipboard;\n return typeof clipboard === 'object' && clipboard !== null\n ? (clipboard as BrowserClipboard)\n : undefined;\n}\n\nasync function readItemText(item: ClipboardItem): Promise<string | undefined> {\n for (const type of [SCHEMATIC_CLIPBOARD_MIME, 'text/plain']) {\n if (!item.types.includes(type)) {\n continue;\n }\n const text = await (await item.getType(type)).text();\n if (text.length > 0) {\n return text;\n }\n }\n return undefined;\n}\n","import {\n GROUND_DEVICE,\n LABEL_DEVICE,\n POWER_DEVICE,\n parseDeviceReference,\n symbolPinPosition,\n type DeviceSymbolProvider,\n type Point,\n type SchematicDocument,\n} from '@mica-js/document/schematic';\nimport { type IHitTestOptions, type SchematicHit } from '../../editing/query';\nimport type { IDisplayOptions } from '../../types';\n\n/** Screen-space hit radius; callers divide by the viewport scale. */\nexport const MIN_HIT_PIXELS = 6;\n\nexport interface ISnapContext {\n readonly document: SchematicDocument;\n readonly display: IDisplayOptions;\n readonly devices: DeviceSymbolProvider | undefined;\n /** Hit tolerance in page units. */\n readonly tolerance: number;\n readonly hitTest: (point: Point, options?: IHitTestOptions) => SchematicHit | undefined;\n}\n\n/** World position of a pin / label / power / ground anchor under `point`. */\nexport function connectionNodeAt(context: ISnapContext, point: Point): Point | undefined {\n const hit = context.hitTest(point, {\n tolerance: context.tolerance * 2,\n includeSymbols: false,\n });\n if (hit?.kind === 'pin') {\n return pinPosition(context, hit);\n }\n const anchor = anchorSymbolAt(context, point);\n if (anchor !== undefined) {\n return { x: anchor.x, y: anchor.y };\n }\n return wireEndpointAt(context, point);\n}\n\n/** Endpoint of an existing wire under `point`; used to close a connection. */\nexport function wireEndpointAt(context: ISnapContext, point: Point): Point | undefined {\n for (const wire of context.document.sheet.wires) {\n for (const endpoint of [wire.points[0], wire.points[wire.points.length - 1]]) {\n if (\n endpoint !== undefined &&\n Math.abs(endpoint.x - point.x) <= context.tolerance * 2 &&\n Math.abs(endpoint.y - point.y) <= context.tolerance * 2\n ) {\n return { x: endpoint.x, y: endpoint.y };\n }\n }\n }\n return undefined;\n}\n\n/** Builtin connection symbol (label / power / ground) anchored under `point`. */\nexport function anchorSymbolAt(\n context: ISnapContext,\n point: Point,\n): { readonly x: number; readonly y: number } | undefined {\n // Anchors sit on wire endpoints, where `hitTest` reports the wire first, so scan directly.\n for (const symbol of context.document.sheet.symbols) {\n const device = symbol.device;\n if (device !== LABEL_DEVICE && device !== POWER_DEVICE && device !== GROUND_DEVICE) {\n continue;\n }\n if (\n Math.abs(symbol.x - point.x) <= context.tolerance &&\n Math.abs(symbol.y - point.y) <= context.tolerance\n ) {\n return symbol;\n }\n }\n return undefined;\n}\n\nexport function pinPosition(\n context: ISnapContext,\n hit: { readonly symbolId: string; readonly pinId: string },\n): Point | undefined {\n const symbol = context.document.sheet.symbols.find((item) => item.id === hit.symbolId);\n if (symbol === undefined) {\n return undefined;\n }\n const reference = parseDeviceReference(symbol.device);\n const anchor =\n reference === undefined\n ? undefined\n : context.devices?.getDeviceSymbol(reference)?.pins[hit.pinId];\n return anchor === undefined ? undefined : symbolPinPosition(symbol, anchor);\n}\n","import type { Point } from '@mica-js/document/schematic';\nimport type { IDisplayOptions } from '../../types';\n\nexport function snapToGrid(point: Point, display: IDisplayOptions): Point {\n if (!display.snap || !(display.gridSize > 0)) {\n return point;\n }\n const size = display.gridSize;\n return { x: Math.round(point.x / size) * size, y: Math.round(point.y / size) * size };\n}\n\n/**\n * Offset for dragging something anchored at `anchor` from `from` to `to`: the result is snapped,\n * not the raw pointer delta, so an off-grid symbol lands on the grid.\n *\n * Dragging uses the fine grid spacing (`gridSize / gridSubdivisions`).\n * A drag that stays within half a fine grid cell on one axis does not move that axis at all, so an\n * anchor that started off-grid keeps its column/row instead of jittering sideways.\n */\nexport function snapDragOffset(\n anchor: Point,\n from: Point,\n to: Point,\n display: IDisplayOptions,\n): Point {\n const dx = to.x - from.x;\n const dy = to.y - from.y;\n if (!display.snap || !(display.gridSize > 0)) {\n return { x: dx, y: dy };\n }\n const subdivisions =\n Number.isFinite(display.gridSubdivisions) && display.gridSubdivisions >= 1\n ? Math.round(display.gridSubdivisions)\n : 1;\n const size = display.gridSize / subdivisions;\n const target = snapToGrid({ x: anchor.x + dx, y: anchor.y + dy }, { ...display, gridSize: size });\n const lock = size / 2;\n return {\n x: (Math.abs(dx) < lock ? anchor.x : target.x) - anchor.x,\n y: (Math.abs(dy) < lock ? anchor.y : target.y) - anchor.y,\n };\n}\n","import { projectOnSegment, type Point } from '@mica-js/document/schematic';\nimport type { IDisplayOptions } from '../../types';\nimport type { ISnapContext } from './nodes';\nimport { connectionNodeAt } from './nodes';\nimport { snapToGrid } from './drag';\n\n/**\n * Waypoints needed to reach `to` from `from` with horizontal/vertical segments only.\n * Returns `[to]` when already aligned, otherwise an elbow plus `to` (long axis first).\n */\nexport function orthogonalWaypoints(from: Point, to: Point): readonly Point[] {\n if (from.x === to.x || from.y === to.y) {\n return [to];\n }\n const elbow =\n Math.abs(to.x - from.x) >= Math.abs(to.y - from.y)\n ? { x: to.x, y: from.y }\n : { x: from.x, y: to.y };\n return [elbow, to];\n}\n\nexport type WireAxis = 'horizontal' | 'vertical';\n\n/**\n * Waypoints for one new wire leg. When the target lands on an existing wire the last leg runs\n * perpendicular to it, so the branch taps into a T instead of doubling back along the host.\n */\nexport function wireWaypoints(\n from: Point,\n to: Point,\n host: WireAxis | undefined,\n): readonly Point[] {\n if (host === undefined || from.x === to.x || from.y === to.y) {\n return orthogonalWaypoints(from, to);\n }\n return host === 'vertical' ? [{ x: from.x, y: to.y }, to] : [{ x: to.x, y: from.y }, to];\n}\n\n/** Extends a routed path, folding retraced collinear legs instead of leaving dangling branches. */\nexport function extendWirePath(\n points: readonly Point[],\n to: Point,\n host: WireAxis | undefined,\n): Point[] {\n const from = points[points.length - 1];\n const candidates = from === undefined ? [to] : [...points, ...wireWaypoints(from, to, host)];\n const path: Point[] = [];\n for (const point of candidates) {\n while (path.length >= 2) {\n const a = path[path.length - 2]!;\n const b = path[path.length - 1]!;\n if ((a.x === b.x && b.x === point.x) || (a.y === b.y && b.y === point.y)) {\n path.pop();\n } else {\n break;\n }\n }\n const previous = path[path.length - 1];\n if (previous === undefined || previous.x !== point.x || previous.y !== point.y) {\n path.push(point);\n }\n }\n return path;\n}\n\n/** Snaps to a nearby connection node, then to a nearby wire, otherwise to the grid. */\nexport function snapForWire(context: ISnapContext, point: Point): Point {\n return (\n connectionNodeAt(context, point) ??\n wireBodyPointAt(context, point) ??\n snapToGrid(point, context.display)\n );\n}\n\n/**\n * Closest point on an existing wire's run when `point` is within the snap radius. Lets the wire\n * tool land exactly on another wire, which is what turns the run into a T junction. Only the\n * offset beside the host is absorbed: the position along it still follows the grid.\n */\nexport function wireBodyPointAt(context: ISnapContext, point: Point): Point | undefined {\n const radius = context.tolerance * 2;\n const display = context.display;\n let best: { readonly point: Point; readonly distance: number } | undefined;\n for (const wire of context.document.sheet.wires) {\n for (let index = 1; index < wire.points.length; index += 1) {\n const a = wire.points[index - 1];\n const b = wire.points[index];\n if (a === undefined || b === undefined) {\n continue;\n }\n const projected = projectOnSegment(point, a, b);\n const distance = Math.hypot(projected.x - point.x, projected.y - point.y);\n if (distance > radius || (best !== undefined && distance >= best.distance)) {\n continue;\n }\n best = { point: gridAlongHost(projected, a, b, display), distance };\n }\n }\n return best?.point;\n}\n\nfunction gridAlongHost(projected: Point, a: Point, b: Point, display: IDisplayOptions): Point {\n // The axis normal to the host keeps the run's own coordinate so the tap stays on it; the axis\n // along the run follows the pointer, so it still has to honour the grid.\n if (a.y === b.y && a.x !== b.x) {\n const x = snapToGrid(projected, display).x;\n return x >= Math.min(a.x, b.x) && x <= Math.max(a.x, b.x)\n ? { x, y: a.y }\n : { x: projected.x, y: a.y };\n }\n if (a.x === b.x && a.y !== b.y) {\n const y = snapToGrid(projected, display).y;\n return y >= Math.min(a.y, b.y) && y <= Math.max(a.y, b.y)\n ? { x: a.x, y }\n : { x: a.x, y: projected.y };\n }\n return { x: projected.x, y: projected.y };\n}\n","import {\n DEFAULT_TEXT_CONTENT,\n GROUND_DEVICE,\n LABEL_DEVICE,\n POWER_DEVICE,\n TEXT_DEVICE,\n isTextDevice,\n netNameOf,\n parseDeviceReference,\n pinSide,\n pinsBounds,\n rotatePoint,\n type Point,\n type SchematicDocument,\n} from '@mica-js/document/schematic';\nimport type { EditorTool } from '../../types';\nimport { pinPosition, type ISnapContext } from './nodes';\n\nexport function isPlacementTool(tool: EditorTool): boolean {\n return tool === 'power' || tool === 'ground' || tool === 'label' || tool === 'text';\n}\n\nexport function toolDevice(tool: EditorTool): string {\n switch (tool) {\n case 'power':\n return POWER_DEVICE;\n case 'ground':\n return GROUND_DEVICE;\n case 'label':\n return LABEL_DEVICE;\n default:\n return TEXT_DEVICE;\n }\n}\n\n/** Smallest unused `N<n>` net name for a freshly placed net label. */\nexport function nextNetName(document: SchematicDocument): string {\n const used = new Set(\n document.sheet.symbols\n .map((symbol) => netNameOf(symbol))\n .filter((name): name is string => name !== undefined),\n );\n for (let index = 1; index < Number.MAX_SAFE_INTEGER; index += 1) {\n const candidate = `N${index}`;\n if (!used.has(candidate)) {\n return candidate;\n }\n }\n return 'N';\n}\n\n/** Length of the lead added when a label is dropped straight onto a pin. */\nexport const LABEL_STUB_LENGTH = 20;\n\nexport interface ILabelStub {\n /** Pin connection point. */\n readonly pin: Point;\n /** Where the label anchor goes: one lead away from the pin. */\n readonly anchor: Point;\n /** Rotation that draws the net name away from the symbol. */\n readonly rotation: number;\n /** Lead to insert; absent when an existing wire already reaches the anchor. */\n readonly wire?: readonly Point[];\n}\n\n/**\n * Lead used when a label is placed directly on a pin: labels hang off a short wire in the pin's\n * outward direction instead of sitting on the pin itself.\n */\nexport function labelStubAt(context: ISnapContext, point: Point): ILabelStub | undefined {\n const hit = context.hitTest(point, {\n tolerance: context.tolerance * 2,\n includeSymbols: false,\n });\n if (hit?.kind !== 'pin') {\n return undefined;\n }\n const pin = pinPosition(context, hit);\n const direction = pinOutward(context, hit);\n if (pin === undefined || direction === undefined) {\n return undefined;\n }\n // Directions are axis aligned, so rounding removes the rotation's floating point noise.\n const dx = Math.round(direction.x);\n const dy = Math.round(direction.y);\n const anchor = {\n x: pin.x + dx * LABEL_STUB_LENGTH,\n y: pin.y + dy * LABEL_STUB_LENGTH,\n };\n const rotation = dx > 0 ? 0 : dx < 0 ? 180 : dy > 0 ? 90 : 270;\n return { pin, anchor, rotation, ...stubWire(context, pin, anchor) };\n}\n\n/** The lead only has to be drawn where no wire already runs; labels bind to any wire they touch. */\nfunction stubWire(\n context: ISnapContext,\n pin: Point,\n anchor: Point,\n): { readonly wire?: readonly Point[] } {\n const host = context.hitTest(anchor, {\n includeSymbols: false,\n tolerance: context.tolerance,\n });\n return host?.kind === 'wire' ? {} : { wire: [pin, anchor] };\n}\n\n/** Unit vector, in world space, pointing away from the symbol body at a pin. */\nfunction pinOutward(\n context: ISnapContext,\n hit: { readonly symbolId: string; readonly pinId: string },\n): Point | undefined {\n const symbol = context.document.sheet.symbols.find((item) => item.id === hit.symbolId);\n const reference = symbol === undefined ? undefined : parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : context.devices?.getDeviceSymbol(reference);\n const anchor = definition?.pins[hit.pinId];\n if (symbol === undefined || definition === undefined || anchor === undefined) {\n return undefined;\n }\n const side = pinSide(anchor, definition.bounds ?? pinsBounds(definition.pins));\n const local =\n side === 'left'\n ? { x: -1, y: 0 }\n : side === 'right'\n ? { x: 1, y: 0 }\n : side === 'top'\n ? { x: 0, y: -1 }\n : side === 'bottom'\n ? { x: 0, y: 1 }\n : undefined;\n return local === undefined ? undefined : rotatePoint(local, symbol.rotation);\n}\n\n/** Extra properties written when a placement inserts a builtin symbol. */\nexport function placementProperties(device: string): Record<string, string> | undefined {\n return isTextDevice(device) ? { text: DEFAULT_TEXT_CONTENT } : undefined;\n}\n","import { LABEL_DEVICE, symbolRole, type Point } from '@mica-js/document/schematic';\nimport {\n isPlacementTool,\n labelStubAt,\n nextNetName,\n placementProperties,\n snapToGrid,\n toolDevice,\n type ILabelStub,\n} from '../snapping';\nimport type { InteractionContext } from './context';\n\n/** Device the next click inserts: the host's armed device wins over the toolbar tool. */\nexport function placementDevice(context: InteractionContext): string | undefined {\n const armed = context.deps.editor.getPlacingDevice();\n if (armed !== undefined) {\n return armed;\n }\n const tool = context.deps.editor.getTool();\n return isPlacementTool(tool) ? toolDevice(tool) : undefined;\n}\n\n/** Lead a label placement adds when the pointer is on a pin. */\nexport function labelStub(\n context: InteractionContext,\n device: string,\n point: Point,\n): ILabelStub | undefined {\n return device === LABEL_DEVICE ? labelStubAt(context.pointer.snapContext(), point) : undefined;\n}\n\n/** Ghost rotation: the pin lead picks a readable angle unless the user rotated it. */\nexport function placeRotation(context: InteractionContext, stub: ILabelStub | undefined): number {\n return context.state.placementRotation === 0 && stub !== undefined\n ? stub.rotation\n : context.state.placementRotation;\n}\n\n/** Ghost shown while a placement tool or armed device follows the pointer. */\nexport function placementPreview(context: InteractionContext):\n | {\n readonly device: string;\n readonly position: Point;\n readonly rotation: number;\n readonly wire?: readonly Point[];\n }\n | undefined {\n const device = placementDevice(context);\n const cursor = context.state.cursorPoint;\n if (cursor === undefined || device === undefined) {\n return undefined;\n }\n const stub = labelStub(context, device, cursor);\n return {\n device,\n position: stub?.anchor ?? cursor,\n rotation: placeRotation(context, stub),\n ...(stub?.wire === undefined ? {} : { wire: stub.wire }),\n };\n}\n\n/** Rotates the ghost while a placement tool is active. */\nexport function rotatePlacement(context: InteractionContext, degrees: number): boolean {\n if (placementDevice(context) === undefined) {\n return false;\n }\n context.state.placementRotation =\n (((context.state.placementRotation + degrees) % 360) + 360) % 360;\n context.deps.onChange();\n return true;\n}\n\n/** Places the armed device at `page`. */\nexport function place(context: InteractionContext, page: Point): void {\n const editor = context.deps.editor;\n const device = placementDevice(context);\n if (device === undefined || context.deps.readOnly) {\n return;\n }\n const role = symbolRole(device);\n // Connection points snap to pins and wire ends; components only snap to the grid.\n const snapped =\n role === 'component' ? snapToGrid(page, editor.getDisplay()) : context.pointer.snapWire(page);\n // A label dropped on a pin hangs off a short lead instead of sitting on the pin.\n const stub = labelStub(context, device, snapped);\n const point = stub?.anchor ?? snapped;\n const properties = placementProperties(device);\n const designator = role === 'component' ? editor.nextDesignator(device) : undefined;\n context.deps.run(() =>\n editor.transaction(() => {\n if (stub?.wire !== undefined) {\n editor.addWire(stub.wire);\n }\n editor.applyCommand({\n type: 'add-symbol',\n ...(device === LABEL_DEVICE ? { net: nextNetName(editor.getValue()) } : {}),\n ...(designator === undefined ? {} : { designator }),\n device,\n x: point.x,\n y: point.y,\n rotation: placeRotation(context, stub),\n ...(properties === undefined ? {} : { properties }),\n });\n }),\n );\n editor.setTool('select');\n context.state.cursorPoint = undefined;\n context.state.placementRotation = 0;\n}\n\n/** Snapping applied to the placement ghost so it matches where the click will land. */\nexport function snapPlacementPoint(\n context: InteractionContext,\n page: Point,\n device: string,\n): Point {\n return symbolRole(device) === 'component'\n ? snapToGrid(page, context.deps.editor.getDisplay())\n : context.pointer.snapWire(page);\n}\n","import {\n parseDeviceReference,\n symbolBounds,\n type DeviceSymbolProvider,\n type Point,\n type Rect,\n type SchematicDocument,\n} from '@mica-js/document/schematic';\nimport type { EditorSelection } from '../types';\n\nexport function rectOf(from: Point, to: Point): Rect {\n return {\n x: Math.min(from.x, to.x),\n y: Math.min(from.y, to.y),\n width: Math.abs(to.x - from.x),\n height: Math.abs(to.y - from.y),\n };\n}\n\nexport function pointInRect(point: Point, rect: Rect): boolean {\n return (\n point.x >= rect.x &&\n point.x <= rect.x + rect.width &&\n point.y >= rect.y &&\n point.y <= rect.y + rect.height\n );\n}\n\nexport function rectsIntersect(left: Rect, right: Rect): boolean {\n return (\n left.x + left.width >= right.x &&\n left.x <= right.x + right.width &&\n left.y + left.height >= right.y &&\n left.y <= right.y + right.height\n );\n}\n\n/** Everything touched by the rubber-band rectangle. */\nexport function marqueeSelection(\n document: SchematicDocument,\n rect: Rect,\n devices: DeviceSymbolProvider | undefined,\n): readonly EditorSelection[] {\n if (rect.width === 0 && rect.height === 0) {\n return [];\n }\n const result: EditorSelection[] = [];\n for (const symbol of document.sheet.symbols) {\n if (rectsIntersect(symbolRect(symbol, devices), rect)) {\n result.push({ kind: 'symbol', id: symbol.id });\n }\n }\n for (const wire of document.sheet.wires) {\n if (wire.points.some((point) => pointInRect(point, rect))) {\n result.push({ kind: 'wire', id: wire.id });\n }\n }\n for (const junction of document.sheet.junctions) {\n if (pointInRect({ x: junction.x, y: junction.y }, rect)) {\n result.push({ kind: 'junction', id: junction.id });\n }\n }\n return result;\n}\n\nfunction symbolRect(\n symbol: {\n readonly id: string;\n readonly device: string;\n readonly x: number;\n readonly y: number;\n readonly rotation: number;\n },\n devices: DeviceSymbolProvider | undefined,\n): Rect {\n const reference = parseDeviceReference(symbol.device);\n const definition = reference === undefined ? undefined : devices?.getDeviceSymbol(reference);\n return (\n (definition === undefined\n ? undefined\n : symbolBounds(symbol, definition.bounds, definition.pins)) ?? {\n x: symbol.x,\n y: symbol.y,\n width: 0,\n height: 0,\n }\n );\n}\n","import { symbolRole, type Point } from '@mica-js/document/schematic';\nimport { type SchematicHit } from '../../editing/query';\nimport { sameTarget } from '../../model/selection';\nimport type { EditorSelection } from '../../types';\nimport { marqueeSelection, rectOf } from '../selection-box';\nimport type { InteractionContext } from './context';\n\n/** Selection under the pointer: vertices win over wire bodies, then pins/anchors/symbols. */\nexport function selectionAt(context: InteractionContext, page: Point): EditorSelection | undefined {\n const vertex = vertexAt(context, page);\n if (vertex !== undefined) {\n return vertex;\n }\n const hit = context.deps.editor.hitTest(page, { tolerance: context.pointer.tolerance() });\n return hit === undefined ? undefined : selectionFromHit(hit);\n}\n\nexport function vertexAt(context: InteractionContext, page: Point): EditorSelection | undefined {\n const tolerance = context.pointer.tolerance();\n for (const wire of context.deps.editor.getValue().sheet.wires) {\n for (let index = 0; index < wire.points.length; index += 1) {\n const point = wire.points[index];\n if (point === undefined) {\n continue;\n }\n if (Math.abs(point.x - page.x) <= tolerance && Math.abs(point.y - page.y) <= tolerance) {\n return { kind: 'vertex', wireId: wire.id, index };\n }\n }\n }\n return undefined;\n}\n\n/** True when the pointer is over a builtin annotation (label / power / ground / text). */\nexport function annotationSymbolAt(context: InteractionContext, page: Point): boolean {\n const hit = context.deps.editor.hitTest(page, { tolerance: context.pointer.tolerance() });\n if (hit?.kind !== 'symbol') {\n return false;\n }\n const symbol = context.deps.editor.getValue().sheet.symbols.find((item) => item.id === hit.id);\n return symbol !== undefined && symbolRole(symbol.device) !== 'component';\n}\n\n/** Applies a click selection, honouring additive (shift) clicks. */\nexport function selectItem(\n context: InteractionContext,\n selection: EditorSelection | undefined,\n additive: boolean,\n): void {\n const editor = context.deps.editor;\n if (selection === undefined) {\n editor.setSelection(additive ? editor.getSelection() : []);\n return;\n }\n const current = editor.getSelection();\n const exists = current.some((item) => sameTarget(item, selection));\n if (!additive) {\n editor.setSelection([selection]);\n return;\n }\n editor.setSelection(\n exists ? current.filter((item) => !sameTarget(item, selection)) : [...current, selection],\n );\n}\n\n/** Commits a rubber-band selection. */\nexport function finishMarquee(context: InteractionContext, origin: Point, current: Point): void {\n context.deps.editor.setSelection(\n marqueeSelection(context.deps.editor.getValue(), rectOf(origin, current), context.deps.devices),\n );\n}\n\nexport function selectionFromHit(hit: SchematicHit): EditorSelection | undefined {\n switch (hit.kind) {\n case 'symbol':\n return { kind: 'symbol', id: hit.id };\n case 'reference':\n return { kind: 'reference', symbolId: hit.symbolId };\n case 'wire':\n return { kind: 'wire', id: hit.id };\n case 'junction':\n return { kind: 'junction', id: hit.id };\n case 'pin':\n return { kind: 'symbol', id: hit.symbolId };\n default:\n return undefined;\n }\n}\n\nexport function sameHit(left: SchematicHit | undefined, right: SchematicHit | undefined): boolean {\n if (left === undefined || right === undefined) {\n return left === right;\n }\n return JSON.stringify(left) === JSON.stringify(right);\n}\n","import type { Point } from '@mica-js/document/schematic';\nimport { connectionNodeAt, extendWirePath } from '../snapping';\nimport { annotationSymbolAt } from './selection';\nimport type { InteractionContext } from './context';\n\n/** Adds the next waypoint of the wire being drawn, closing the run on a connection. */\nexport function addWirePoint(context: InteractionContext, page: Point): void {\n const state = context.state;\n const point = context.pointer.snapWire(page);\n state.pendingWire = extendWirePath(state.pendingWire, point, context.pointer.hostAxisAt(point));\n state.cursorPoint = point;\n // Landing on another endpoint (pin, anchor, wire end) or an existing wire closes the run.\n const node = connectionNodeAt(context.pointer.snapContext(), point);\n const host = context.deps.editor.hitTest(point, {\n includeSymbols: false,\n tolerance: context.pointer.tolerance(),\n });\n const closes = node !== undefined || host?.kind === 'wire';\n if (closes && state.pendingWire.length >= 2) {\n finishWire(context);\n context.deps.editor.setTool('select');\n return;\n }\n context.deps.onChange();\n}\n\n/** Commits the pending wire as one edit; nothing is written in read-only mode. */\nexport function finishWire(context: InteractionContext): void {\n const points = context.state.pendingWire;\n context.state.pendingWire = [];\n context.state.cursorPoint = undefined;\n context.state.hover = undefined;\n if (points.length < 2 || context.deps.readOnly) {\n context.deps.onChange();\n return;\n }\n context.deps.run(() => context.deps.editor.addWire(points));\n}\n\n/** Pending wire plus the live cursor leg, for the dashed preview. */\nexport function pendingWireWithCursor(context: InteractionContext): readonly Point[] {\n const state = context.state;\n const cursor = state.cursorPoint;\n if (cursor === undefined) {\n return state.pendingWire;\n }\n return extendWirePath(state.pendingWire, cursor, context.pointer.hostAxisAt(cursor));\n}\n\n/** Clicking a pin or wire end in select mode starts a wire from there. */\nexport function startWireAtNode(context: InteractionContext, page: Point): boolean {\n const editor = context.deps.editor;\n if (editor.getTool() !== 'select' || context.deps.readOnly) {\n return false;\n }\n // Net labels, ports and text are selection/drag targets, so a tap on their body must not be\n // eaten by a new wire; the wire tool still connects to their anchors by snapping to them.\n if (annotationSymbolAt(context, page)) {\n return false;\n }\n const node = connectionNodeAt(context.pointer.snapContext(), page);\n if (node === undefined) {\n return false;\n }\n // Switch the tool first: the tool change resets transient state, which must not eat the anchor.\n editor.setTool('wire');\n context.state.pendingWire = [node];\n context.state.cursorPoint = node;\n context.deps.onChange();\n return true;\n}\n","import type { Point } from '@mica-js/document/schematic';\nimport type { InteractionContext } from './context';\nimport { rotatePlacement } from './placement';\nimport { finishWire } from './wire';\n\n/**\n * Cancels whatever interaction is pending: placement, the wire being drawn, a drag or the active\n * tool, and clears the selection. Returns whether there was anything to cancel.\n */\nexport function cancelInteraction(context: InteractionContext): boolean {\n const editor = context.deps.editor;\n const active =\n editor.getPlacingDevice() !== undefined ||\n editor.getTool() !== 'select' ||\n editor.getSelection().length > 0 ||\n context.state.pendingWire.length > 0 ||\n context.state.drag !== undefined;\n if (!active) {\n return false;\n }\n if (editor.getPlacingDevice() !== undefined) {\n editor.cancelPlacement();\n }\n context.state.reset();\n editor.setSelection([]);\n editor.setTool('select');\n context.deps.onChange();\n return true;\n}\n\n/** Keyboard shortcuts; the canvas keeps focus, so the root element owns the listener. */\nexport function handleKeyDown(context: InteractionContext, event: KeyboardEvent): void {\n const editor = context.deps.editor;\n const readOnly = context.deps.readOnly;\n\n // Host controls (property fields, search boxes) bubble their keys here; leave them alone.\n if (isEditableTarget(event.target)) {\n return;\n }\n\n if (event.key === ' ') {\n event.preventDefault();\n if (rotatePlacement(context, 90)) {\n return;\n }\n if (!readOnly) {\n context.deps.run(() => editor.rotateSelection(90));\n }\n return;\n }\n if (event.key === 'Escape') {\n cancelInteraction(context);\n return;\n }\n if (event.key === 'Enter') {\n if (editor.getTool() === 'wire') {\n finishWire(context);\n }\n return;\n }\n if (\n event.key === 'Backspace' &&\n editor.getTool() === 'wire' &&\n context.state.pendingWire.length > 0\n ) {\n event.preventDefault();\n context.state.pendingWire = context.state.pendingWire.slice(0, -1);\n context.deps.onChange();\n return;\n }\n if (event.key === 'Delete' || event.key === 'Backspace') {\n event.preventDefault();\n if (!readOnly) {\n context.deps.run(() => editor.deleteSelection());\n }\n return;\n }\n if (event.key === 'r' || event.key === 'R') {\n if (!readOnly) {\n context.deps.run(() => editor.rotateSelection(90));\n }\n return;\n }\n if (event.key === 'f' || event.key === 'F') {\n context.deps.onFit();\n return;\n }\n if ((event.ctrlKey || event.metaKey) && (event.key === 'z' || event.key === 'Z')) {\n event.preventDefault();\n if (readOnly) {\n return;\n }\n if (event.shiftKey) {\n editor.redo();\n } else {\n editor.undo();\n }\n return;\n }\n if ((event.ctrlKey || event.metaKey) && (event.key === 'y' || event.key === 'Y')) {\n event.preventDefault();\n if (readOnly) {\n return;\n }\n editor.redo();\n return;\n }\n if ((event.ctrlKey || event.metaKey) && (event.key === 'a' || event.key === 'A')) {\n event.preventDefault();\n editor.selectAll();\n return;\n }\n if ((event.ctrlKey || event.metaKey) && (event.key === 'd' || event.key === 'D')) {\n // The browser would bookmark the page; the editor duplicates the selection instead.\n event.preventDefault();\n if (!readOnly) {\n editor.duplicateSelection();\n }\n return;\n }\n if (readOnly) {\n return;\n }\n const step = editor.getDisplay().gridSize > 0 ? editor.getDisplay().gridSize : 1;\n const distance = event.shiftKey ? step * 10 : step;\n const deltas: Readonly<Record<string, Point>> = {\n ArrowLeft: { x: -distance, y: 0 },\n ArrowRight: { x: distance, y: 0 },\n ArrowUp: { x: 0, y: -distance },\n ArrowDown: { x: 0, y: distance },\n };\n const delta = deltas[event.key];\n if (delta !== undefined) {\n event.preventDefault();\n context.deps.run(() => editor.moveSelectionBy(delta.x, delta.y));\n }\n}\n\n/** Text fields and contenteditable hosts keep their own shortcuts. */\nfunction isEditableTarget(target: EventTarget | null): boolean {\n if (target === null || typeof target !== 'object') {\n return false;\n }\n const element = target as { readonly tagName?: unknown; readonly isContentEditable?: unknown };\n const tagName = typeof element.tagName === 'string' ? element.tagName.toLowerCase() : '';\n return tagName === 'input' || tagName === 'textarea' || element.isContentEditable === true;\n}\n","import { parseDeviceReference, type Point } from '@mica-js/document/schematic';\nimport { deviceReferencePosition } from '../../model/reference';\nimport { snapDragOffset } from '../snapping';\nimport type { InteractionContext } from './context';\n\n/** Starts dragging a symbol; the grid is applied where it lands, not to the pointer delta. */\nexport function beginMoveDrag(context: InteractionContext, page: Point, symbolId: string): boolean {\n const symbol = context.deps.editor.getValue().sheet.symbols.find((item) => item.id === symbolId);\n context.state.drag = {\n mode: 'move',\n origin: page,\n anchor: symbol === undefined ? page : { x: symbol.x, y: symbol.y },\n offset: { x: 0, y: 0 },\n };\n return true;\n}\n\nexport function beginReferenceDrag(\n context: InteractionContext,\n page: Point,\n symbolId: string,\n): boolean {\n const symbol = context.deps.editor.getValue().sheet.symbols.find((item) => item.id === symbolId);\n if (symbol === undefined) {\n return false;\n }\n const start = referenceWorldPosition(context, symbol);\n context.state.drag = {\n mode: 'reference',\n symbolId: symbol.id,\n start,\n origin: page,\n position: start,\n };\n return true;\n}\n\n/** Updates an in-flight move drag; returns `true` when this drag is the active one. */\nexport function updateMoveDrag(context: InteractionContext, page: Point): boolean {\n const drag = context.state.drag;\n if (drag?.mode !== 'move') {\n return false;\n }\n const next = snapDragOffset(drag.anchor, drag.origin, page, context.deps.editor.getDisplay());\n if (next.x !== drag.offset.x || next.y !== drag.offset.y) {\n context.state.drag = { ...drag, offset: next };\n context.deps.onChange();\n }\n return true;\n}\n\nexport function updateReferenceDrag(context: InteractionContext, page: Point): boolean {\n const drag = context.state.drag;\n if (drag?.mode !== 'reference') {\n return false;\n }\n context.state.drag = {\n ...drag,\n position: {\n x: drag.start.x + (page.x - drag.origin.x),\n y: drag.start.y + (page.y - drag.origin.y),\n },\n };\n context.deps.onChange();\n return true;\n}\n\n/** Commits a finished move drag; returns whether an edit was recorded. */\nexport function finishMoveDrag(\n context: InteractionContext,\n drag: { readonly offset: Point },\n): boolean {\n if (drag.offset.x === 0 && drag.offset.y === 0) {\n return false;\n }\n const { offset } = drag;\n context.deps.run(() => context.deps.editor.moveSelectionBy(offset.x, offset.y));\n return true;\n}\n\nexport function finishReferenceDrag(\n context: InteractionContext,\n drag: {\n readonly symbolId: string;\n readonly start: Point;\n readonly position: Point;\n },\n): boolean {\n const dx = drag.position.x - drag.start.x;\n const dy = drag.position.y - drag.start.y;\n if (dx === 0 && dy === 0) {\n return false;\n }\n context.deps.run(() => context.deps.editor.moveReferenceBy(drag.symbolId, dx, dy));\n return true;\n}\n\n/** World position of the reference designator of `symbol`, used as the drag anchor. */\nexport function referenceWorldPosition(\n context: InteractionContext,\n symbol: {\n readonly id: string;\n readonly device: string;\n readonly x: number;\n readonly y: number;\n readonly rotation: number;\n readonly reference?: Point;\n },\n): Point {\n const reference = parseDeviceReference(symbol.device);\n const definition =\n reference === undefined ? undefined : context.deps.devices?.getDeviceSymbol(reference);\n return deviceReferencePosition(symbol, definition);\n}\n","import type { DeviceSymbolProvider, Point } from '@mica-js/document/schematic';\nimport { screenToPage, type IViewportState } from '../../render/viewport';\nimport { MIN_HIT_PIXELS, snapForWire, type ISnapContext, type WireAxis } from '../snapping';\nimport type { IEditorSurface } from '../surface';\nimport type { EditorViewport } from '../viewport-state';\n\nexport interface IPointerDeps {\n readonly editor: IEditorSurface;\n readonly devices: DeviceSymbolProvider | undefined;\n readonly viewport: EditorViewport;\n readonly canvas: HTMLCanvasElement;\n}\n\n/** Screen-space geometry of the canvas: event → page coordinates, hit tolerance and snapping. */\nexport class Pointer {\n readonly #deps: IPointerDeps;\n\n constructor(deps: IPointerDeps) {\n this.#deps = deps;\n }\n\n viewport(): IViewportState {\n return this.#deps.viewport.state;\n }\n\n screen(event: PointerEvent | MouseEvent | WheelEvent): Point {\n const rect = this.#deps.canvas.getBoundingClientRect();\n return { x: event.clientX - rect.left, y: event.clientY - rect.top };\n }\n\n page(event: PointerEvent | MouseEvent | WheelEvent): Point {\n return screenToPage(this.viewport(), this.screen(event));\n }\n\n /** Hit tolerance in page units, so it stays constant on screen while zooming. */\n tolerance(): number {\n return MIN_HIT_PIXELS / this.viewport().scale;\n }\n\n snapContext(): ISnapContext {\n return {\n document: this.#deps.editor.getValue(),\n display: this.#deps.editor.getDisplay(),\n devices: this.#deps.devices,\n tolerance: this.tolerance(),\n hitTest: (point, options) => this.#deps.editor.hitTest(point, options),\n };\n }\n\n snapWire(point: Point): Point {\n return snapForWire(this.snapContext(), point);\n }\n\n /** Orientation of the existing wire under `point`, so a branch can approach it perpendicularly. */\n hostAxisAt(point: Point): WireAxis | undefined {\n const hit = this.#deps.editor.hitTest(point, {\n includeSymbols: false,\n tolerance: this.tolerance(),\n });\n if (hit?.kind !== 'wire') {\n return undefined;\n }\n const wire = this.#deps.editor.getValue().sheet.wires.find((item) => item.id === hit.id);\n const a = wire?.points[hit.segment];\n const b = wire?.points[hit.segment + 1];\n if (a === undefined || b === undefined) {\n return undefined;\n }\n return a.y === b.y ? 'horizontal' : a.x === b.x ? 'vertical' : undefined;\n }\n}\n","import type { Point } from '@mica-js/document/schematic';\nimport { snapToGrid, type WireAxis } from '../snapping';\nimport type { InteractionContext } from './context';\n\n/** Starts dragging a wire segment; the moved run is snapped so it lands on grid lines. */\nexport function beginSegmentDrag(\n context: InteractionContext,\n page: Point,\n wireId: string,\n): boolean {\n const hit = context.deps.editor.hitTest(page, {\n includeSymbols: false,\n tolerance: context.pointer.tolerance(),\n });\n if (hit?.kind !== 'wire' || hit.id !== wireId) {\n return false;\n }\n context.state.drag = {\n mode: 'segment',\n wireId: hit.id,\n segment: hit.segment,\n origin: page,\n delta: { x: 0, y: 0 },\n };\n return true;\n}\n\n/** Updates an in-flight segment drag; returns `true` when this drag is the active one. */\nexport function updateSegmentDrag(context: InteractionContext, page: Point): boolean {\n const drag = context.state.drag;\n if (drag?.mode !== 'segment') {\n return false;\n }\n const wire = context.deps.editor.getValue().sheet.wires.find((item) => item.id === drag.wireId);\n const start = wire?.points[drag.segment];\n const end = wire?.points[drag.segment + 1];\n if (wire === undefined || start === undefined || end === undefined) {\n return true;\n }\n // Segments only slide along their normal, so the wire stays orthogonal; the moved vertex is\n // snapped (not the delta) so the run lands on grid lines.\n const horizontal = start.y === end.y;\n const target = snapToGrid(\n horizontal\n ? { x: start.x, y: start.y + (page.y - drag.origin.y) }\n : { x: start.x + (page.x - drag.origin.x), y: start.y },\n context.deps.editor.getDisplay(),\n );\n const candidate = horizontal ? { x: 0, y: target.y - start.y } : { x: target.x - start.x, y: 0 };\n if (candidate.x !== drag.delta.x || candidate.y !== drag.delta.y) {\n context.state.drag = { ...drag, delta: candidate };\n context.deps.onChange();\n }\n return true;\n}\n\n/** Commits a finished segment drag; returns whether an edit was recorded. */\nexport function finishSegmentDrag(\n context: InteractionContext,\n drag: { readonly wireId: string; readonly segment: number; readonly delta: Point },\n): boolean {\n if (drag.delta.x === 0 && drag.delta.y === 0) {\n return false;\n }\n context.deps.run(() =>\n context.deps.editor.moveWireSegment(drag.wireId, drag.segment, drag.delta),\n );\n return true;\n}\n\n/** Wire preview for the renderer, plus the orientation helper used by the wire tool. */\nexport function wirePreview(\n context: InteractionContext,\n): { readonly wireId: string; readonly points: readonly Point[] } | undefined {\n const drag = context.state.drag;\n if (drag?.mode !== 'segment') {\n return undefined;\n }\n const points = context.deps.editor.previewWireSegment(drag.wireId, drag.segment, drag.delta);\n return points === undefined ? undefined : { wireId: drag.wireId, points };\n}\n\nexport type { WireAxis };\n","import type { Point, Rect } from '@mica-js/document/schematic';\nimport type { SchematicHit } from '../../editing/query';\nimport { rectOf } from '../selection-box';\n\nexport type DragInteraction =\n | { readonly mode: 'pan'; readonly lastX: number; readonly lastY: number }\n | { readonly mode: 'marquee'; readonly origin: Point; readonly current: Point }\n | {\n readonly mode: 'move';\n readonly origin: Point;\n /** World position of the dragged symbol when the drag started. */\n readonly anchor: Point;\n readonly offset: Point;\n }\n | {\n readonly mode: 'reference';\n readonly symbolId: string;\n /** Reference anchor when the drag started. */\n readonly start: Point;\n readonly origin: Point;\n readonly position: Point;\n }\n | {\n readonly mode: 'segment';\n readonly wireId: string;\n readonly segment: number;\n readonly origin: Point;\n readonly delta: Point;\n }\n | undefined;\n\n/**\n * Transient interaction state owned by the canvas. Nothing here belongs in the document, so the\n * document model never sees hovers, in-progress wires or previews.\n */\nexport class InteractionState {\n hover: SchematicHit | undefined;\n drag: DragInteraction;\n pendingWire: Point[] = [];\n cursorPoint: Point | undefined;\n /** Last pointer position in page space; anchors a paste that has no explicit target. */\n pointerPage: Point | undefined;\n placementRotation = 0;\n\n get marquee(): Rect | undefined {\n return this.drag?.mode === 'marquee' ? rectOf(this.drag.origin, this.drag.current) : undefined;\n }\n\n /** Live offset of the symbols being dragged. */\n get dragOffset(): Point | undefined {\n if (this.drag?.mode !== 'move') {\n return undefined;\n }\n const { offset } = this.drag;\n return offset.x === 0 && offset.y === 0 ? undefined : offset;\n }\n\n /** Reference designator being dragged, in world coordinates. */\n get referencePreview(): { readonly symbolId: string; readonly position: Point } | undefined {\n return this.drag?.mode === 'reference'\n ? { symbolId: this.drag.symbolId, position: this.drag.position }\n : undefined;\n }\n\n /** Drops the interaction in progress; called when the tool changes or an edit is cancelled. */\n reset(): void {\n this.pendingWire = [];\n this.cursorPoint = undefined;\n this.placementRotation = 0;\n this.drag = undefined;\n }\n}\n","import type { Point, Rect } from '@mica-js/document/schematic';\nimport type { SchematicHit } from '../../editing/query';\nimport { serializeSchematicClipboard } from '../../model/clipboard';\nimport type { EditorSelection } from '../../types';\nimport { readClipboardEvent, writeClipboardEvent } from '../clipboard';\nimport type { IEditorInputDeps, InteractionContext } from './context';\nimport { cancelInteraction, handleKeyDown } from './keyboard';\nimport {\n beginMoveDrag,\n beginReferenceDrag,\n finishMoveDrag,\n finishReferenceDrag,\n updateMoveDrag,\n updateReferenceDrag,\n} from './move';\nimport {\n place,\n placementDevice,\n placementPreview,\n rotatePlacement,\n snapPlacementPoint,\n} from './placement';\nimport { Pointer } from './pointer';\nimport { finishMarquee, sameHit, selectItem, selectionAt, selectionFromHit } from './selection';\nimport { beginSegmentDrag, finishSegmentDrag, updateSegmentDrag, wirePreview } from './segment';\nimport { InteractionState } from './state';\nimport { addWirePoint, finishWire, pendingWireWithCursor, startWireAtNode } from './wire';\n\nexport type { IEditorInputDeps } from './context';\n\n/**\n * Pointer and keyboard state machine: panning, rubber-band selection, wire drawing, placement\n * previews and shortcuts. It owns the transient interaction state and delegates to the modules\n * under `interactions/`, which never touch the DOM directly.\n */\nexport class EditorInput {\n readonly #context: InteractionContext;\n #detached = false;\n #clickStart:\n | { readonly pointerId: number; readonly x: number; readonly y: number; moved: boolean }\n | undefined;\n\n constructor(deps: IEditorInputDeps) {\n this.#context = {\n deps,\n state: new InteractionState(),\n pointer: new Pointer({\n editor: deps.editor,\n devices: deps.devices,\n viewport: deps.viewport,\n canvas: deps.canvas,\n }),\n };\n }\n\n get hover(): SchematicHit | undefined {\n return this.#context.state.hover;\n }\n\n get pendingWire(): readonly Point[] {\n return this.#context.state.pendingWire;\n }\n\n get cursorPoint(): Point | undefined {\n return this.#context.state.cursorPoint;\n }\n\n /** Last pointer position over the canvas in page space; `undefined` once it leaves. */\n get lastPointerPage(): Point | undefined {\n return this.#context.state.pointerPage;\n }\n\n get marquee(): Rect | undefined {\n return this.#context.state.marquee;\n }\n\n /** Live offset of the symbols being dragged. */\n get dragOffset(): Point | undefined {\n return this.#context.state.dragOffset;\n }\n\n /** Wire being reshaped by a segment drag, so the renderer can show it before the commit. */\n get wirePreview(): { readonly wireId: string; readonly points: readonly Point[] } | undefined {\n return wirePreview(this.#context);\n }\n\n /** Reference designator being dragged, in world coordinates. */\n get referencePreview(): { readonly symbolId: string; readonly position: Point } | undefined {\n return this.#context.state.referencePreview;\n }\n\n /** Placement ghost for the current tool or armed device, if the pointer is inside the canvas. */\n get placementPreview(): ReturnType<typeof placementPreview> {\n return placementPreview(this.#context);\n }\n\n get pendingWireWithCursor(): readonly Point[] {\n return pendingWireWithCursor(this.#context);\n }\n\n /** Rotates the ghost while a placement tool is active. */\n rotatePlacement(degrees: number): boolean {\n return rotatePlacement(this.#context, degrees);\n }\n\n /** Drops the in-progress wire; called when the tool changes. */\n resetTransient(): void {\n this.#context.state.reset();\n }\n\n attach(): void {\n const { canvas, root } = this.#context.deps;\n canvas.addEventListener('pointerdown', this.#onPointerDown);\n canvas.addEventListener('pointermove', this.#onPointerMove);\n canvas.addEventListener('pointerup', this.#onPointerUp);\n canvas.addEventListener('pointercancel', this.#onPointerCancel);\n canvas.addEventListener('pointerleave', this.#onPointerLeave);\n canvas.addEventListener('wheel', this.#onWheel, { passive: false });\n canvas.addEventListener('dblclick', this.#onDoubleClick);\n canvas.addEventListener('contextmenu', this.#onContextMenu);\n root.addEventListener('keydown', this.#onKeyDown);\n root.addEventListener('keyup', this.#onKeyUp);\n root.addEventListener('copy', this.#onCopy);\n root.addEventListener('cut', this.#onCut);\n root.addEventListener('paste', this.#onPaste);\n root.ownerDocument.addEventListener('keydown', this.#onDocumentKeyDown);\n }\n\n detach(): void {\n if (this.#detached) {\n return;\n }\n this.#detached = true;\n const { canvas, root } = this.#context.deps;\n canvas.removeEventListener('pointerdown', this.#onPointerDown);\n canvas.removeEventListener('pointermove', this.#onPointerMove);\n canvas.removeEventListener('pointerup', this.#onPointerUp);\n canvas.removeEventListener('pointercancel', this.#onPointerCancel);\n canvas.removeEventListener('pointerleave', this.#onPointerLeave);\n canvas.removeEventListener('wheel', this.#onWheel);\n canvas.removeEventListener('dblclick', this.#onDoubleClick);\n canvas.removeEventListener('contextmenu', this.#onContextMenu);\n root.removeEventListener('keydown', this.#onKeyDown);\n root.removeEventListener('keyup', this.#onKeyUp);\n root.removeEventListener('copy', this.#onCopy);\n root.removeEventListener('cut', this.#onCut);\n root.removeEventListener('paste', this.#onPaste);\n root.ownerDocument.removeEventListener('keydown', this.#onDocumentKeyDown);\n }\n\n #onPointerDown = (event: PointerEvent): void => {\n this.#clickStart =\n event.button === 0\n ? { pointerId: event.pointerId, x: event.clientX, y: event.clientY, moved: false }\n : undefined;\n const { deps, state, pointer } = this.#context;\n deps.root.focus();\n const screen = pointer.screen(event);\n const page = pointer.page(event);\n state.pointerPage = page;\n\n if (event.button === 1) {\n event.preventDefault();\n state.drag = { mode: 'pan', lastX: screen.x, lastY: screen.y };\n deps.canvas.setPointerCapture(event.pointerId);\n return;\n }\n if (event.button !== 0) {\n return;\n }\n\n if (deps.editor.getTool() === 'wire' && !deps.readOnly) {\n addWirePoint(this.#context, page);\n return;\n }\n if (!deps.readOnly && placementDevice(this.#context) !== undefined) {\n place(this.#context, page);\n return;\n }\n if (startWireAtNode(this.#context, page)) {\n return;\n }\n\n const selection = selectionAt(this.#context, page);\n if (selection === undefined) {\n selectItem(this.#context, undefined, event.shiftKey);\n state.drag = { mode: 'marquee', origin: page, current: page };\n deps.canvas.setPointerCapture(event.pointerId);\n deps.onChange();\n return;\n }\n selectItem(this.#context, selection, event.shiftKey);\n if (!deps.readOnly) {\n const started = beginDragFor(this.#context, page, selection);\n if (started) {\n deps.canvas.setPointerCapture(event.pointerId);\n }\n }\n deps.onChange();\n };\n\n #onPointerMove = (event: PointerEvent): void => {\n const start = this.#clickStart;\n if (\n start?.pointerId === event.pointerId &&\n Math.hypot(event.clientX - start.x, event.clientY - start.y) >= 3\n )\n start.moved = true;\n const { deps, state, pointer } = this.#context;\n const screen = pointer.screen(event);\n const page = pointer.page(event);\n state.pointerPage = page;\n\n if (state.drag?.mode === 'pan') {\n deps.viewport.pan(screen.x - state.drag.lastX, screen.y - state.drag.lastY);\n state.drag = { mode: 'pan', lastX: screen.x, lastY: screen.y };\n deps.onChange();\n return;\n }\n if (state.drag?.mode === 'marquee') {\n state.drag = { mode: 'marquee', origin: state.drag.origin, current: page };\n deps.onChange();\n return;\n }\n if (updateMoveDrag(this.#context, page)) {\n return;\n }\n if (updateReferenceDrag(this.#context, page)) {\n return;\n }\n if (updateSegmentDrag(this.#context, page)) {\n return;\n }\n\n const device = placementDevice(this.#context);\n if (deps.editor.getTool() === 'wire') {\n state.cursorPoint = pointer.snapWire(page);\n deps.onChange();\n return;\n }\n if (device !== undefined) {\n // Same snapping as the click so the ghost already shows where the symbol will land.\n state.cursorPoint = snapPlacementPoint(this.#context, page, device);\n deps.onChange();\n return;\n }\n\n const next = deps.editor.hitTest(page, { tolerance: pointer.tolerance() });\n if (!sameHit(next, state.hover)) {\n state.hover = next;\n deps.onChange();\n }\n };\n\n #onPointerUp = (event: PointerEvent): void => {\n const start = this.#clickStart;\n this.#clickStart = undefined;\n const drag = this.#context.state.drag;\n const dragged =\n drag?.mode === 'pan' ||\n (drag?.mode === 'move' && (drag.offset.x !== 0 || drag.offset.y !== 0)) ||\n (drag?.mode === 'segment' && (drag.delta.x !== 0 || drag.delta.y !== 0)) ||\n (drag?.mode === 'reference' &&\n (drag.position.x !== drag.start.x || drag.position.y !== drag.start.y)) ||\n (drag?.mode === 'marquee' &&\n (drag.current.x !== drag.origin.x || drag.current.y !== drag.origin.y));\n this.#finishPointerUp(event);\n if (\n start?.pointerId === event.pointerId &&\n event.button === 0 &&\n !dragged &&\n !start.moved &&\n Math.hypot(event.clientX - start.x, event.clientY - start.y) < 3\n ) {\n this.#emitPointer('click', event);\n }\n };\n\n #onPointerCancel = (event: PointerEvent): void => {\n this.#clickStart = undefined;\n this.#context.state.reset();\n if (this.#context.deps.canvas.hasPointerCapture(event.pointerId))\n this.#context.deps.canvas.releasePointerCapture(event.pointerId);\n this.#context.deps.onChange();\n };\n\n #finishPointerUp = (event: PointerEvent): void => {\n const { deps, state } = this.#context;\n const drag = state.drag;\n state.drag = undefined;\n if (deps.canvas.hasPointerCapture(event.pointerId)) {\n deps.canvas.releasePointerCapture(event.pointerId);\n }\n if (drag?.mode === 'marquee') {\n finishMarquee(this.#context, drag.origin, drag.current);\n return;\n }\n if (drag?.mode === 'move') {\n if (!finishMoveDrag(this.#context, drag)) {\n deps.onChange();\n }\n return;\n }\n if (drag?.mode === 'reference') {\n if (!finishReferenceDrag(this.#context, drag)) {\n deps.onChange();\n }\n return;\n }\n if (drag?.mode === 'segment') {\n if (!finishSegmentDrag(this.#context, drag)) {\n deps.onChange();\n }\n return;\n }\n if (drag !== undefined) {\n deps.onChange();\n }\n };\n\n #onPointerLeave = (): void => {\n const { deps, state } = this.#context;\n state.pointerPage = undefined;\n if (state.hover !== undefined && state.drag === undefined) {\n state.hover = undefined;\n deps.onChange();\n }\n };\n\n #onWheel = (event: WheelEvent): void => {\n const { deps, pointer } = this.#context;\n event.preventDefault();\n deps.viewport.zoomAt(pointer.screen(event), event.deltaY < 0 ? 1.1 : 1 / 1.1);\n deps.onChange();\n };\n\n #onDoubleClick = (event: MouseEvent): void => {\n const { deps, pointer } = this.#context;\n if (deps.editor.getTool() === 'wire' && !deps.readOnly) {\n finishWire(this.#context);\n this.#emitPointer('doubleClick', event);\n return;\n }\n const page = pointer.page(event);\n const hit = deps.editor.hitTest(page, { tolerance: pointer.tolerance() });\n const selection = hit === undefined ? undefined : selectionFromHit(hit);\n if (selection !== undefined) {\n deps.editor.setSelection([selection]);\n }\n this.#emitPointer('doubleClick', event);\n };\n\n #onContextMenu = (event: MouseEvent): void => {\n event.preventDefault();\n this.#emitPointer('contextMenu', event);\n };\n\n #emitPointer(kind: 'click' | 'doubleClick' | 'contextMenu', event: MouseEvent): void {\n const { deps, pointer } = this.#context;\n if (deps.onPointerEvent === undefined) return;\n const position = pointer.page(event);\n const hit = deps.editor.hitTest(position, { tolerance: pointer.tolerance() });\n const target =\n hit?.kind === 'pin'\n ? { kind: 'pin' as const, symbolId: hit.symbolId, pinId: hit.pinId }\n : hit === undefined\n ? null\n : (selectionFromHit(hit) ?? null);\n deps.onPointerEvent(kind, {\n target,\n position,\n clientPosition: { x: event.clientX, y: event.clientY },\n button: event.button,\n altKey: event.altKey ?? false,\n ctrlKey: event.ctrlKey ?? false,\n metaKey: event.metaKey ?? false,\n shiftKey: event.shiftKey ?? false,\n mode: 'edit',\n });\n }\n\n #onKeyDown = (event: KeyboardEvent): void => {\n handleKeyDown(this.#context, event);\n };\n\n #onKeyUp = (): void => {\n // No key-up handling: Space now rotates instead of acting as a pan modifier.\n };\n\n /**\n * Copy and cut rely on the browser's clipboard events instead of `Ctrl+C` / `Ctrl+X` keydown, so\n * the browser menu, keyboard shortcuts and host gestures all take the same path. The event itself\n * carries the payload, so the editor must not write the system clipboard a second time.\n */\n #onCopy = (event: ClipboardEvent): void => {\n const clipboard = this.#context.deps.editor.copySelection({ system: false });\n if (clipboard === undefined) {\n return;\n }\n event.preventDefault();\n writeClipboardEvent(event, serializeSchematicClipboard(clipboard));\n };\n\n #onCut = (event: ClipboardEvent): void => {\n if (this.#context.deps.readOnly) {\n return;\n }\n const clipboard = this.#context.deps.editor.cutSelection({ system: false });\n if (clipboard === undefined) {\n return;\n }\n event.preventDefault();\n writeClipboardEvent(event, serializeSchematicClipboard(clipboard));\n };\n\n #onPaste = (event: ClipboardEvent): void => {\n if (this.#context.deps.readOnly) {\n return;\n }\n const text = readClipboardEvent(event);\n if (text === undefined) {\n return;\n }\n event.preventDefault();\n void this.#context.deps.editor.pasteSelection({ text });\n };\n\n /**\n * Esc fallback for hosts that arm placement from their own UI: the event may never reach the\n * editor root, so listen on the document while an interaction is pending.\n */\n #onDocumentKeyDown = (event: KeyboardEvent): void => {\n const { deps } = this.#context;\n if (event.key !== 'Escape' || event.defaultPrevented) {\n return;\n }\n if (deps.root.contains(event.target as Node | null)) {\n return;\n }\n if (cancelInteraction(this.#context)) {\n event.preventDefault();\n }\n };\n}\n\nfunction beginDragFor(\n context: InteractionContext,\n page: Point,\n selection: EditorSelection,\n): boolean {\n switch (selection.kind) {\n case 'symbol':\n return beginMoveDrag(context, page, selection.id);\n case 'reference':\n return beginReferenceDrag(context, page, selection.symbolId);\n case 'wire':\n return beginSegmentDrag(context, page, selection.id);\n default:\n return false;\n }\n}\n","import type { Point } from '@mica-js/document/schematic';\nimport type { EditorSelection } from '../types';\n\nexport interface ISceneHighlight {\n readonly symbols: ReadonlySet<string>;\n readonly wires: ReadonlySet<string>;\n readonly junctions: ReadonlySet<string>;\n readonly vertices: readonly { readonly wireId: string; readonly index: number }[];\n}\n\n/** Translates editor selections into the flat sets the scene builder expects. */\nexport function toSceneHighlight(selection: readonly EditorSelection[]): ISceneHighlight {\n const symbols = new Set<string>();\n const wires = new Set<string>();\n const junctions = new Set<string>();\n const vertices: { wireId: string; index: number }[] = [];\n for (const item of selection) {\n switch (item.kind) {\n case 'symbol':\n symbols.add(item.id);\n break;\n case 'wire':\n wires.add(item.id);\n break;\n case 'junction':\n junctions.add(item.id);\n break;\n case 'vertex':\n wires.add(item.wireId);\n vertices.push({ wireId: item.wireId, index: item.index });\n break;\n default:\n break;\n }\n }\n return { symbols, wires, junctions, vertices };\n}\n\n/** Appends the cursor to a pending wire so it rubber-bands to the pointer. */\nexport function withCursor(pending: readonly Point[], cursor: Point | undefined): readonly Point[] {\n return cursor === undefined ? pending : [...pending, cursor];\n}\n","import type { EditorTool } from '../types';\n\nexport interface IToolIcon {\n readonly tool: EditorTool;\n readonly label: string;\n /** 16×16 figure drawn with `currentColor`: stroked segments plus terminal dots. */\n readonly segments: readonly string[];\n readonly dots: readonly (readonly [number, number])[];\n}\n\n/** Toolbar entries, in display order. */\nexport const TOOL_ICONS: readonly IToolIcon[] = [\n {\n // Classic pointer arrow: the select tool the other tools fall back to.\n tool: 'select',\n label: '选择',\n segments: ['M4 2.5 L4 12.5 L6.6 10.1 L8.4 13.5 L10 12.7 L8.2 9.4 L11.8 9.4 Z'],\n dots: [],\n },\n {\n tool: 'wire',\n label: '导线',\n segments: ['M3.5 12.5 L12.5 3.5'],\n dots: [\n [3.5, 12.5],\n [12.5, 3.5],\n ],\n },\n {\n tool: 'power',\n label: '电源',\n segments: ['M8 14 V6', 'M4 6 H12'],\n dots: [[8, 14]],\n },\n {\n tool: 'ground',\n label: '地',\n segments: ['M8 3 V8', 'M3.5 8 H12.5', 'M5.5 11 H10.5', 'M7 14 H9'],\n dots: [[8, 3]],\n },\n {\n tool: 'label',\n label: '网络标签',\n segments: ['M8 4 V12', 'M4.5 8 L8 4 L11.5 8'],\n dots: [[8, 12]],\n },\n {\n tool: 'text',\n label: '文本',\n segments: ['M4 4 H12', 'M8 4 V12'],\n dots: [],\n },\n];\n\nconst SVG_NAMESPACE = 'http://www.w3.org/2000/svg';\n\nexport function createToolIcon(doc: Document, icon: IToolIcon): SVGSVGElement {\n const svg = doc.createElementNS(SVG_NAMESPACE, 'svg');\n svg.setAttribute('viewBox', '0 0 16 16');\n svg.setAttribute('width', '16');\n svg.setAttribute('height', '16');\n svg.setAttribute('fill', 'none');\n svg.setAttribute('stroke', 'currentColor');\n svg.setAttribute('stroke-width', '1.4');\n svg.setAttribute('stroke-linecap', 'round');\n svg.setAttribute('stroke-linejoin', 'round');\n svg.setAttribute('aria-hidden', 'true');\n for (const d of icon.segments) {\n const path = doc.createElementNS(SVG_NAMESPACE, 'path');\n path.setAttribute('d', d);\n svg.append(path);\n }\n for (const [cx, cy] of icon.dots) {\n const circle = doc.createElementNS(SVG_NAMESPACE, 'circle');\n circle.setAttribute('cx', String(cx));\n circle.setAttribute('cy', String(cy));\n circle.setAttribute('r', '1.5');\n circle.setAttribute('fill', 'currentColor');\n circle.setAttribute('stroke', 'none');\n svg.append(circle);\n }\n return svg;\n}\n","import type { EditorTool } from '../types';\nimport { TOOL_ICONS, createToolIcon } from './icons';\n\nexport interface IEditorShell {\n readonly root: HTMLElement;\n readonly canvasHost: HTMLElement;\n readonly canvas: HTMLCanvasElement;\n readonly toolButtons: ReadonlyMap<EditorTool, HTMLButtonElement>;\n setToolActive(tool: EditorTool): void;\n}\n\nexport interface IShellOptions {\n readonly document: Document;\n readonly readOnly: boolean;\n readonly toolbar: boolean;\n readonly onToolClick: (tool: EditorTool) => void;\n}\n\n/** Builds the canvas surface and the floating tool strip; it owns no behaviour beyond wiring. */\nexport function createShell(options: IShellOptions): IEditorShell {\n const doc = options.document;\n const root = doc.createElement('div');\n root.className = 'mica-schematic';\n root.tabIndex = 0;\n\n const canvasHost = doc.createElement('div');\n canvasHost.className = 'mica-schematic__canvas-host';\n\n const canvas = doc.createElement('canvas');\n canvas.className = 'mica-schematic__canvas';\n canvasHost.append(canvas);\n\n root.append(canvasHost);\n\n const toolButtons = new Map<EditorTool, HTMLButtonElement>();\n if (options.toolbar) {\n const toolbar = doc.createElement('div');\n toolbar.className = 'mica-schematic__toolbar';\n for (const icon of TOOL_ICONS) {\n const button = doc.createElement('button');\n button.type = 'button';\n button.className = 'mica-schematic__tool';\n button.title = icon.label;\n button.setAttribute('aria-label', icon.label);\n button.disabled = options.readOnly;\n button.append(createToolIcon(doc, icon));\n button.addEventListener('click', () => options.onToolClick(icon.tool));\n toolButtons.set(icon.tool, button);\n toolbar.append(button);\n }\n root.append(toolbar);\n } else {\n root.classList.add('mica-schematic--no-toolbar');\n }\n\n return {\n root,\n canvasHost,\n canvas,\n toolButtons,\n setToolActive(tool) {\n for (const [candidate, button] of toolButtons) {\n button.setAttribute('aria-pressed', String(candidate === tool));\n }\n },\n };\n}\n","import type { Point, Rect } from '@mica-js/document/schematic';\nimport {\n DEFAULT_VIEWPORT_LIMITS,\n IDENTITY_VIEWPORT,\n fitBounds,\n panBy,\n resolveViewportLimits,\n zoomAt,\n type IViewportLimits,\n type IViewportState,\n} from '../render/viewport';\n\n/**\n * Owns the viewport and the \"auto fit until the user takes over\" rule.\n * An empty canvas keeps refitting while the container resizes.\n */\nexport class EditorViewport {\n #state: IViewportState = IDENTITY_VIEWPORT;\n #autoFit = true;\n readonly #limits: IViewportLimits;\n\n constructor(limits: IViewportLimits = DEFAULT_VIEWPORT_LIMITS) {\n this.#limits = resolveViewportLimits(limits);\n }\n\n get state(): IViewportState {\n return this.#state;\n }\n\n get limits(): IViewportLimits {\n return this.#limits;\n }\n\n get autoFit(): boolean {\n return this.#autoFit;\n }\n\n /** Fits `bounds` into the given viewport size and re-enables auto fit. */\n fit(bounds: Rect | undefined, size: { readonly width: number; readonly height: number }): void {\n if (size.width === 0 || size.height === 0) {\n return;\n }\n this.#state = fitBounds(\n bounds ?? { x: -50, y: -50, width: 100, height: 100 },\n size,\n 48,\n this.#limits,\n );\n this.#autoFit = true;\n }\n\n pan(dx: number, dy: number): void {\n this.#autoFit = false;\n this.#state = panBy(this.#state, dx, dy);\n }\n\n zoomAt(screenPoint: Point, factor: number): void {\n this.#autoFit = false;\n this.#state = zoomAt(this.#state, screenPoint, factor, this.#limits);\n }\n\n zoomTo(scale: number, center: Point): void {\n if (scale <= 0 || !Number.isFinite(scale)) {\n return;\n }\n this.#autoFit = false;\n this.#state = zoomAt(this.#state, center, scale / this.#state.scale, this.#limits);\n }\n\n /** Restores a saved viewport (already clamped by the caller); turns auto fit off. */\n setState(state: IViewportState): void {\n this.#autoFit = false;\n this.#state = state;\n }\n\n /** Turns off auto fit when the user interacts with the view. */\n takeOver(): void {\n this.#autoFit = false;\n }\n}\n","import {\n SchematicError,\n parseDeviceReference,\n type Point,\n type SchematicCommand,\n type SchematicDocument,\n type SchematicTopology,\n} from '@mica-js/document/schematic';\nimport { type IHitTestOptions, type SchematicHit } from '../editing/query';\nimport {\n DocumentModel,\n type IDocumentModelOptions,\n type IDocumentUpdateOptions,\n} from '../model/document-model';\nimport { resolveSchematicContent, type SchematicContent } from '../model/content';\nimport {\n parseSchematicClipboard,\n serializeSchematicClipboard,\n type IPasteOptions,\n type ISchematicClipboard,\n} from '../model/clipboard';\nimport { buildInspector } from '../model/inspector';\nimport { pruneSelection, sameSelection } from '../model/selection';\nimport { CanvasSchematicRenderer } from '../render/canvas-renderer';\nimport { buildSchematicScene } from '../render/scene';\nimport { resolveSchematicTheme, themeToCssVariables, type ISchematicTheme } from '../render/theme';\nimport {\n clampViewport,\n pageToScreen,\n resolveViewportLimits,\n screenToPage,\n type IViewportLimits,\n type IViewportState,\n} from '../render/viewport';\nimport {\n DEFAULT_DISPLAY_OPTIONS,\n type IDisplayOptions,\n type IEditorRenderState,\n type EditorSelection,\n type IEditorState,\n type EditorTool,\n} from '../types';\nimport { DisposableStore, Emitter, type Event } from '@mica-js/core/lifecycle';\nimport { createBrowserClipboardPort, type IClipboardPort } from './clipboard';\nimport { EditorInput } from './interactions/input';\nimport { toSceneHighlight } from './scene-input';\nimport { snapToGrid } from './snapping';\nimport { createShell, type IEditorShell } from './shell';\nimport type { IEditorSurface } from './surface';\nimport type { IEditorInputDeps } from './interactions/context';\nimport { EditorViewport } from './viewport-state';\n\n/** Model construction options exposed by {@link ISchematicEditorOptions} (`value` is separate). */\nexport type SchematicEditorModelOptions = Omit<IDocumentModelOptions, 'value'>;\n\n/** Paste options of the editor API: a caller-provided payload skips the system clipboard. */\nexport interface IEditorPasteOptions extends IPasteOptions {\n /** Serialized payload; when present the system clipboard is not read. */\n readonly text?: string;\n}\n\n/** Copy and cut options: DOM clipboard events write their own payload and skip the port. */\nexport interface IClipboardWriteOptions {\n /** Also write the system clipboard; defaults to true. */\n readonly system?: boolean;\n}\n\n/**\n * Options shared by {@link SchematicEditor} and {@link createSchematicEditor}.\n *\n * The editor displays one {@link DocumentModel} and leaves document content to it. Pass `model` to\n * hand in an existing one, or `value` (plus the model options below) to have the editor create and\n * own the model: `model` wins, then `value`, then an empty sheet.\n */\nexport interface ISchematicEditorOptions extends SchematicEditorModelOptions {\n /** Caller-provided container; the editor only appends and removes its own root. */\n readonly container: HTMLElement;\n /** Model the editor draws and edits; when given, `value` and the model options are ignored. */\n readonly model?: DocumentModel;\n /** Initial content of the editor's own model: a `.sch` document or its JSON text. */\n readonly value?: SchematicContent;\n readonly theme?: Partial<ISchematicTheme>;\n readonly display?: Partial<IDisplayOptions>;\n /** Zoom range for wheel, fit and `zoomTo`; defaults to 0.25×–4×. */\n readonly zoomLimits?: Partial<IViewportLimits>;\n /** Disables the built-in interactions; the editor and model stay writable through their APIs. */\n readonly readOnly?: boolean;\n /** Renders the floating tool strip in the canvas corner; defaults to true. */\n readonly toolbar?: boolean;\n /** System clipboard bridge; defaults to the browser Clipboard API. */\n readonly clipboard?: IClipboardPort;\n readonly prepareDevices?: (ids: readonly string[]) => Promise<void>;\n readonly onPointerEvent?: IEditorInputDeps['onPointerEvent'];\n}\n\n/**\n * Canvas surface over a {@link DocumentModel}: rendering, input handling, selection, viewport and\n * tool state. Construction is synchronous and only touches `options.container`.\n *\n * Document edits go through the model, so every path — a gesture, a host call or the model's own\n * methods — commits one undoable step, fires `onDidChangeContent` and `onDidChangeState` once and\n * can be undone.\n */\nexport class SchematicEditor implements IEditorSurface {\n readonly root: HTMLElement;\n readonly canvas: HTMLCanvasElement;\n\n readonly #contentChanged = new Emitter<SchematicDocument>();\n readonly #stateChanged = new Emitter<IEditorState>();\n readonly #selectionChanged = new Emitter<readonly EditorSelection[]>();\n readonly #toolChanged = new Emitter<EditorTool>();\n readonly #errorChanged = new Emitter<SchematicError | undefined>();\n readonly #viewportChanged = new Emitter<IViewportState>();\n\n /** Fires after every committed content change with the new document. */\n readonly onDidChangeContent: Event<SchematicDocument> = this.#contentChanged.event;\n /** Fires after every editor or document change with the new state. */\n readonly onDidChangeState: Event<IEditorState> = this.#stateChanged.event;\n /** Fires when the selection changes. */\n readonly onDidChangeSelection: Event<readonly EditorSelection[]> = this.#selectionChanged.event;\n /** Fires when the active tool or the armed placement changes. */\n readonly onDidChangeTool: Event<EditorTool> = this.#toolChanged.event;\n /** Fires when the reported edit error changes; `undefined` once an edit succeeds. */\n readonly onDidChangeError: Event<SchematicError | undefined> = this.#errorChanged.event;\n /** Fires on wheel/pan/fit/`zoomTo`/`setViewport` and when auto fit re-runs. */\n readonly onDidChangeViewport: Event<IViewportState> = this.#viewportChanged.event;\n\n readonly #subscriptions = new DisposableStore();\n readonly #model: DocumentModel;\n readonly #ownsModel: boolean;\n readonly #container: HTMLElement;\n readonly #shell: IEditorShell;\n readonly #viewport: EditorViewport;\n readonly #renderer: CanvasSchematicRenderer;\n readonly #input: EditorInput;\n readonly #readOnly: boolean;\n readonly #clipboardPort: IClipboardPort;\n readonly #prepareDevices: ((ids: readonly string[]) => Promise<void>) | undefined;\n #clipboard: ISchematicClipboard | undefined;\n #theme: ISchematicTheme;\n #display: IDisplayOptions;\n #selection: readonly EditorSelection[] = [];\n #tool: EditorTool = 'select';\n #placingDevice: string | undefined;\n /** Last edit or placement error; the model reports document failures, the editor placement ones. */\n #error: SchematicError | undefined;\n #lastContent: SchematicDocument;\n #lastSelection: readonly EditorSelection[] = [];\n #lastTool: EditorTool = 'select';\n #lastPlacing: string | undefined;\n #reportedError: SchematicError | undefined;\n #lastViewport: IViewportState | undefined;\n #disposed = false;\n readonly #resizeObserver: ResizeObserver;\n\n constructor(options: ISchematicEditorOptions) {\n this.#ownsModel = options.model === undefined;\n this.#model = options.model ?? createOwnedModel(options);\n this.#lastContent = this.#model.getValue();\n this.#container = options.container;\n this.#readOnly = options.readOnly ?? false;\n this.#clipboardPort = options.clipboard ?? createBrowserClipboardPort();\n this.#prepareDevices = options.prepareDevices;\n this.#display = { ...DEFAULT_DISPLAY_OPTIONS, ...options.display };\n this.#theme = resolveSchematicTheme(options.theme);\n this.#error = this.#model.getLastError();\n\n this.#shell = createShell({\n document: options.container.ownerDocument,\n readOnly: this.#readOnly,\n toolbar: options.toolbar !== false,\n onToolClick: (tool) => {\n this.setTool(this.getTool() === tool ? 'select' : tool);\n this.root.focus();\n },\n });\n this.root = this.#shell.root;\n this.canvas = this.#shell.canvas;\n\n this.#viewport = new EditorViewport(resolveViewportLimits(options.zoomLimits));\n this.#renderer = new CanvasSchematicRenderer(this.canvas, { theme: this.#theme });\n this.#input = new EditorInput({\n editor: this,\n devices: this.#model.getDevices(),\n viewport: this.#viewport,\n root: this.root,\n canvas: this.canvas,\n readOnly: this.#readOnly,\n ...(options.onPointerEvent === undefined ? {} : { onPointerEvent: options.onPointerEvent }),\n onChange: () => this.#render(),\n onFit: () => this.fitToContent(),\n run: (edit) => this.#run(edit),\n });\n this.#resizeObserver = new ResizeObserver(() => this.resize());\n\n this.#subscriptions.add(this.#model.onDidChangeContent(() => this.#onModelChanged()));\n this.#subscriptions.add(this.#model.onDidRejectEdit(() => this.#onModelChanged()));\n\n try {\n this.#applyTheme();\n this.#input.attach();\n this.#sync();\n this.#resizeObserver.observe(this.#shell.canvasHost);\n this.#container.append(this.root);\n this.resize();\n } catch (error) {\n try {\n this.dispose();\n } catch (cleanupError) {\n throw new AggregateError(\n [error, cleanupError],\n 'Schematic view initialization and cleanup failed.',\n { cause: cleanupError },\n );\n }\n throw error;\n }\n }\n\n /** Model the editor draws; the same reference for the lifetime of the editor. */\n getModel(): DocumentModel {\n return this.#model;\n }\n\n /** Current content; the same shape `DocumentModel.getValue()` returns. */\n getValue(): SchematicDocument {\n return this.#model.getValue();\n }\n\n getSelection(): readonly EditorSelection[] {\n return this.#selection;\n }\n\n /** Replaces the selection; targets the document does not contain are dropped. */\n setSelection(selection: readonly EditorSelection[]): void {\n if (this.#disposed) {\n return;\n }\n this.#selection = pruneSelection(selection, this.#model.getValue(), this.#model.getDevices());\n this.#sync();\n }\n\n getTool(): EditorTool {\n return this.#tool;\n }\n\n /** Switches the active tool and disarms any pending device placement. */\n setTool(tool: EditorTool): void {\n if (this.#disposed) {\n return;\n }\n if (this.#tool === tool && this.#placingDevice === undefined) {\n return;\n }\n this.#tool = tool;\n this.#placingDevice = undefined;\n this.#sync();\n }\n\n getDisplay(): IDisplayOptions {\n return this.#display;\n }\n\n setDisplayOptions(patch: Partial<IDisplayOptions>): void {\n if (this.#disposed) {\n return;\n }\n this.#display = { ...this.#display, ...patch };\n this.#sync();\n }\n\n getCanUndo(): boolean {\n return this.#model.getCanUndo();\n }\n\n getCanRedo(): boolean {\n return this.#model.getCanRedo();\n }\n\n /** Device armed for placement by the host's device list; `undefined` when idle. */\n getPlacingDevice(): string | undefined {\n return this.#placingDevice;\n }\n\n /**\n * Arms placement of `device`: the next canvas click inserts it and disarms again.\n *\n * @throws {SchematicError} when the device reference is malformed.\n */\n placeDevice(device: string): void {\n if (this.#disposed || this.#readOnly) {\n return;\n }\n if (parseDeviceReference(device) === undefined) {\n const error = new SchematicError([\n {\n severity: 'error',\n code: 'device/invalid-reference',\n message: `Invalid device reference ${JSON.stringify(device)}.`,\n },\n ]);\n this.#error = error;\n this.#sync();\n throw error;\n }\n this.#placingDevice = device;\n this.#tool = 'select';\n this.#sync();\n this.root.focus();\n }\n\n /** Disarms a pending placement without touching the document. */\n cancelPlacement(): void {\n if (this.#disposed || this.#placingDevice === undefined) {\n return;\n }\n this.#placingDevice = undefined;\n this.#sync();\n }\n\n /** Reference designator the next placed component gets, per the model's policy. */\n nextDesignator(device: string): string {\n return this.#model.nextDesignator(device);\n }\n\n /** Applies one core command through the model, like a gesture that just finished. */\n applyCommand(command: SchematicCommand): void {\n if (this.#disposed) {\n return;\n }\n this.#model.applyCommand(command);\n }\n\n /**\n * Replaces the content. By default selection and placement start over and the view fits the new\n * content; `keepHistory` records the swap as one undoable edit instead.\n *\n * @throws {SchematicError} when the text is not a valid `.sch` document, or the model rejects the\n * swap (`keepHistory`); the editor keeps its previous content, selection and placement.\n */\n setValue(value: SchematicContent, options: IDocumentUpdateOptions = {}): void {\n if (this.#disposed) {\n return;\n }\n // Resolve first: invalid text throws before the editor drops selection or placement.\n const content = resolveSchematicContent(value);\n this.cancelInteraction();\n if (options.keepHistory === true) {\n this.#model.setValue(content, options);\n return;\n }\n this.#placingDevice = undefined;\n this.#selection = [];\n this.#model.setValue(content);\n this.fitToContent();\n }\n\n undo(): void {\n if (this.#disposed) {\n return;\n }\n this.#model.undo();\n }\n\n redo(): void {\n if (this.#disposed) {\n return;\n }\n this.#model.redo();\n }\n\n /** Runs several edits as one history step; a failure rolls all of them back. */\n transaction(run: () => void): void {\n if (this.#disposed) {\n return;\n }\n this.#model.transaction(() => {\n run();\n });\n }\n\n addWire(points: readonly Point[]): void {\n if (this.#disposed) {\n return;\n }\n this.#model.addWire(points);\n }\n\n connectWireAt(wireId: string, point: Point, otherWireId?: string): string {\n if (this.#disposed) {\n return '';\n }\n return this.#model.connectWireAt(wireId, point, otherWireId);\n }\n\n moveWireSegment(wireId: string, segment: number, delta: Point): void {\n if (this.#disposed) {\n return;\n }\n this.#model.moveWireSegment(wireId, segment, delta);\n }\n\n previewWireSegment(wireId: string, segment: number, delta: Point): readonly Point[] | undefined {\n return this.#model.previewWireSegment(wireId, segment, delta);\n }\n\n moveSelectionBy(dx: number, dy: number): void {\n if (this.#disposed) {\n return;\n }\n this.#model.moveTargets(this.#selection, dx, dy);\n }\n\n rotateSelection(degrees: number): void {\n if (this.#disposed) {\n return;\n }\n this.#model.rotateTargets(this.#selection, degrees);\n }\n\n /** Deletes the selected elements; the selection empties once the edit commits. */\n deleteSelection(): void {\n if (this.#disposed || this.#selection.length === 0) {\n return;\n }\n this.#model.removeTargets(this.#selection);\n if (this.#selection.length > 0) {\n this.#selection = [];\n this.#sync();\n }\n }\n\n /**\n * Copies the selection into the editor's own buffer and, best-effort, into the system clipboard.\n * Allowed in read-only editors because it changes nothing. DOM copy events pass\n * `{ system: false }`: they write `clipboardData` themselves.\n */\n copySelection(options: IClipboardWriteOptions = {}): ISchematicClipboard | undefined {\n if (this.#disposed) {\n return undefined;\n }\n const clipboard = this.#model.copy(this.#selection);\n if (clipboard === undefined) {\n return undefined;\n }\n this.#clipboard = clipboard;\n if (options.system !== false) {\n void this.#writeClipboard(clipboard);\n }\n return clipboard;\n }\n\n /** Cuts the selection as one undoable edit, then mirrors the payload to the system clipboard. */\n cutSelection(options: IClipboardWriteOptions = {}): ISchematicClipboard | undefined {\n if (this.#disposed || this.#readOnly) {\n return undefined;\n }\n const clipboard = this.#model.cut(this.#selection);\n if (clipboard === undefined) {\n return undefined;\n }\n this.#clipboard = clipboard;\n if (options.system !== false) {\n void this.#writeClipboard(clipboard);\n }\n return clipboard;\n }\n\n /**\n * Pastes a payload as one undoable edit and selects the new elements. The payload comes from\n * `options.text`, then the clipboard port, then the editor's own buffer.\n */\n async pasteSelection(options: IEditorPasteOptions = {}): Promise<boolean> {\n if (this.#disposed || this.#readOnly) {\n return false;\n }\n const clipboard =\n options.text === undefined ? await this.#readClipboard() : this.#parseClipboard(options.text);\n if (clipboard === undefined || this.#disposed) {\n return false;\n }\n try {\n if (this.#prepareDevices)\n await this.#prepareDevices(clipboard.symbols.map((symbol) => symbol.device));\n if (this.#disposed) return false;\n const targets = this.#model.paste(clipboard, this.#pasteOptions(options));\n if (targets.length === 0) {\n return false;\n }\n this.setSelection(targets);\n this.root.focus();\n return true;\n } catch {\n // The model recorded the failure and notified the editor through onDidChangeError.\n return false;\n }\n }\n\n /** Copies and re-inserts the selection one grid step away as one undoable edit. */\n duplicateSelection(): readonly EditorSelection[] {\n if (this.#disposed || this.#readOnly) {\n return [];\n }\n const targets = this.#model.duplicate(this.#selection, { offset: this.#gridStep() });\n if (targets.length > 0) {\n this.setSelection(targets);\n this.root.focus();\n }\n return targets;\n }\n\n /** Selects every symbol, wire and junction; reference designators stay part of their symbol. */\n selectAll(): void {\n if (this.#disposed) {\n return;\n }\n const { symbols, wires, junctions } = this.#model.getValue().sheet;\n this.setSelection([\n ...symbols.map((symbol): EditorSelection => ({ kind: 'symbol', id: symbol.id })),\n ...wires.map((wire): EditorSelection => ({ kind: 'wire', id: wire.id })),\n ...junctions.map((junction): EditorSelection => ({ kind: 'junction', id: junction.id })),\n ]);\n }\n\n moveReferenceBy(symbolId: string, dx: number, dy: number): void {\n if (this.#disposed) {\n return;\n }\n this.#model.moveReferenceBy(symbolId, dx, dy);\n }\n\n hitTest(point: Point, options: IHitTestOptions = {}): SchematicHit | undefined {\n return this.#model.hitTest(point, options);\n }\n\n getTopology(): SchematicTopology {\n return this.#model.getTopology();\n }\n\n /** Everything the canvas draws from; reading it never builds the inspector. */\n getRenderState(): IEditorRenderState {\n return {\n document: this.#model.getValue(),\n selection: this.#selection,\n tool: this.#tool,\n display: this.#display,\n };\n }\n\n /** Selection, tool and the inspector payload for the current document. */\n getState(): IEditorState {\n return this.#state();\n }\n\n setTheme(theme: Partial<ISchematicTheme>): void {\n if (this.#disposed) {\n return;\n }\n this.#theme = resolveSchematicTheme(theme);\n this.#applyTheme();\n this.#render();\n }\n\n getTheme(): ISchematicTheme {\n return this.#theme;\n }\n\n fitToContent(): void {\n if (this.#disposed) {\n return;\n }\n this.#viewport.fit(this.#model.getTopology().bounds, {\n width: this.#shell.canvasHost.clientWidth,\n height: this.#shell.canvasHost.clientHeight,\n });\n this.#render();\n }\n\n zoomTo(scale: number): void {\n if (this.#disposed) {\n return;\n }\n this.#viewport.zoomTo(scale, {\n x: this.#shell.canvasHost.clientWidth / 2,\n y: this.#shell.canvasHost.clientHeight / 2,\n });\n this.#render();\n }\n\n /** Current zoom/pan; safe to persist and hand back to {@link setViewport}. */\n getViewport(): IViewportState {\n return this.#viewport.state;\n }\n\n /** Restores a saved viewport; the scale is clamped to `zoomLimits` around the canvas centre. */\n setViewport(viewport: IViewportState): void {\n if (this.#disposed) {\n return;\n }\n this.#viewport.setState(\n clampViewport(\n viewport,\n { width: this.#shell.canvasHost.clientWidth, height: this.#shell.canvasHost.clientHeight },\n this.#viewport.limits,\n ),\n );\n this.#render();\n }\n\n /** Serializes the current document as `.sch` JSON. */\n toJSON(): string {\n return this.#model.toJSON();\n }\n\n /** Moves keyboard focus to the canvas surface; call after host toolbar interactions. */\n focus(): void {\n if (this.#disposed) {\n return;\n }\n this.root.focus();\n }\n\n /** Canvas-relative client coordinates → page coordinates (for host overlays). */\n toPage(clientPoint: Point): Point {\n const rect = this.canvas.getBoundingClientRect();\n return screenToPage(this.#viewport.state, {\n x: clientPoint.x - rect.left,\n y: clientPoint.y - rect.top,\n });\n }\n\n /** Page coordinates → canvas-relative CSS pixels (for host overlays). */\n toScreen(pagePoint: Point): Point {\n return pageToScreen(this.#viewport.state, pagePoint);\n }\n\n /** Cancels the pending wire, drag or marquee; selection and tool stay as they are. */\n cancelInteraction(): void {\n if (this.#disposed) {\n return;\n }\n this.#input.resetTransient();\n this.#render();\n }\n\n /** Re-measures the container; call after showing a previously hidden editor. */\n resize(): void {\n if (this.#disposed) {\n return;\n }\n const width = this.#shell.canvasHost.clientWidth;\n const height = this.#shell.canvasHost.clientHeight;\n if (width === 0 || height === 0) {\n return;\n }\n const pixelRatio = this.#container.ownerDocument.defaultView?.devicePixelRatio ?? 1;\n this.#renderer.resize(width, height, Math.max(1, pixelRatio));\n if (this.#viewport.autoFit) {\n this.fitToContent();\n return;\n }\n this.#render();\n }\n\n /** Repaints without touching layout (e.g. after a device-pixel-ratio change). */\n invalidate(): void {\n this.#render();\n }\n\n /** Removes the DOM and listeners created by the editor, keeping the container contents. */\n dispose(): void {\n if (this.#disposed) {\n return;\n }\n this.#disposed = true;\n this.#subscriptions.dispose();\n this.#resizeObserver.disconnect();\n this.#input.detach();\n this.#renderer.destroy();\n this.root.remove();\n this.#contentChanged.dispose();\n this.#stateChanged.dispose();\n this.#selectionChanged.dispose();\n this.#toolChanged.dispose();\n this.#errorChanged.dispose();\n this.#viewportChanged.dispose();\n if (this.#ownsModel) {\n this.#model.dispose();\n }\n }\n\n /** Runs a gesture edit; errors surface through `state.lastError` / `onDidChangeError`. */\n #run(edit: () => void): void {\n try {\n edit();\n } catch {\n // The model already recorded the failure and notified the editor.\n }\n }\n\n async #writeClipboard(clipboard: ISchematicClipboard): Promise<void> {\n try {\n await this.#clipboardPort.write(serializeSchematicClipboard(clipboard));\n } catch {\n // The editor's own buffer keeps paste working without clipboard permissions.\n }\n }\n\n /** Payload from the system clipboard, falling back to the last copied or cut selection. */\n async #readClipboard(): Promise<ISchematicClipboard | undefined> {\n let text: string | undefined;\n try {\n text = await this.#clipboardPort.read();\n } catch {\n return this.#clipboard;\n }\n if (text === undefined) {\n return this.#clipboard;\n }\n try {\n return parseSchematicClipboard(text);\n } catch {\n // Foreign clipboard content: keep pasting what the editor itself copied.\n return this.#clipboard;\n }\n }\n\n #parseClipboard(text: string): ISchematicClipboard | undefined {\n try {\n return parseSchematicClipboard(text);\n } catch {\n // Foreign or corrupted clipboard text stays silent: the document is simply left alone.\n return undefined;\n }\n }\n\n /** Explicit target first, then the pointer position, then a plain grid offset. */\n #pasteOptions(options: IPasteOptions): IPasteOptions {\n if (options.at !== undefined) {\n return { at: options.at };\n }\n if (options.offset !== undefined) {\n return { offset: options.offset };\n }\n const page = this.#input.lastPointerPage;\n if (page === undefined) {\n return { offset: this.#gridStep() };\n }\n return { at: this.#display.snap ? snapToGrid(page, this.#display) : page };\n }\n\n #gridStep(): Point {\n const size = this.#display.gridSize;\n return size > 0 ? { x: size, y: size } : { x: 1, y: 1 };\n }\n\n #onModelChanged(): void {\n // A rejected model edit records its error; every committed edit clears it.\n this.#error = this.#model.getLastError();\n this.#sync();\n }\n\n #state(): IEditorState {\n const document = this.#model.getValue();\n return {\n document,\n selection: this.#selection,\n tool: this.#tool,\n placingDevice: this.#placingDevice,\n display: this.#display,\n canUndo: this.#model.getCanUndo(),\n canRedo: this.#model.getCanRedo(),\n inspector: buildInspector(document, this.#selection, {\n devices: this.#model.getDevices(),\n topology: () => this.#model.getTopology(),\n }),\n lastError: this.#error,\n };\n }\n\n #applyTheme(): void {\n for (const [name, value] of Object.entries(themeToCssVariables(this.#theme))) {\n this.root.style.setProperty(name, value);\n }\n this.#renderer.setTheme(this.#theme);\n }\n\n #sync(): void {\n if (this.#disposed) {\n return;\n }\n this.#selection = pruneSelection(\n this.#selection,\n this.#model.getValue(),\n this.#model.getDevices(),\n );\n const state = this.#state();\n this.#shell.setToolActive(state.tool);\n this.canvas.style.cursor =\n state.tool === 'select' && state.placingDevice === undefined ? 'default' : 'crosshair';\n if (state.document !== this.#lastContent) {\n this.#lastContent = state.document;\n this.#contentChanged.fire(state.document);\n }\n if (state.lastError !== this.#reportedError) {\n this.#reportedError = state.lastError;\n this.#errorChanged.fire(state.lastError);\n }\n if (state.tool !== this.#lastTool || state.placingDevice !== this.#lastPlacing) {\n this.#lastTool = state.tool;\n this.#lastPlacing = state.placingDevice;\n this.#input.resetTransient();\n this.#toolChanged.fire(state.tool);\n }\n if (!sameSelection(state.selection, this.#lastSelection)) {\n this.#lastSelection = state.selection;\n this.#selectionChanged.fire(state.selection);\n }\n this.#stateChanged.fire(state);\n // The state came from this emit: reuse it instead of building another one for the repaint.\n this.#render(state);\n }\n\n #render(state: IEditorRenderState = this.getRenderState()): void {\n if (this.#disposed) {\n return;\n }\n const devices = this.#model.getDevices();\n const scene = buildSchematicScene({\n document: state.document,\n ...(devices === undefined ? {} : { devices }),\n theme: this.#theme,\n selection: {\n ...toSceneHighlight(state.selection),\n ...(this.#input.dragOffset === undefined ? {} : { offset: this.#input.dragOffset }),\n },\n ...(this.#input.hover === undefined ? {} : { hover: this.#input.hover }),\n tool: state.tool,\n display: {\n grid: state.display.grid,\n labels: state.display.labels,\n gridSize: state.display.gridSize,\n gridSubdivisions: state.display.gridSubdivisions,\n },\n ...(this.#input.pendingWire.length === 0\n ? {}\n : { pendingWire: this.#input.pendingWireWithCursor }),\n ...(this.#input.marquee === undefined ? {} : { marquee: this.#input.marquee }),\n ...(this.#input.placementPreview === undefined\n ? {}\n : { placementPreview: this.#input.placementPreview }),\n ...(this.#input.referencePreview === undefined\n ? {}\n : { referencePreview: this.#input.referencePreview }),\n ...(this.#input.wirePreview === undefined ? {} : { wirePreview: this.#input.wirePreview }),\n });\n this.#renderer.render(scene, this.#viewport.state);\n if (!sameViewport(this.#viewport.state, this.#lastViewport)) {\n this.#lastViewport = this.#viewport.state;\n this.#viewportChanged.fire(this.#viewport.state);\n }\n }\n}\n\n/** Creates a canvas schematic editor over `options.model`, or over a model it builds from `value`. */\nexport function createSchematicEditor(options: ISchematicEditorOptions): SchematicEditor {\n return new SchematicEditor(options);\n}\n\n/** Builds the model an editor owns when the host passes content instead of a model. */\nfunction createOwnedModel(options: ISchematicEditorOptions): DocumentModel {\n return new DocumentModel({\n ...(options.value === undefined ? {} : { value: options.value }),\n ...(options.devices === undefined ? {} : { devices: options.devices }),\n ...(options.tolerance === undefined ? {} : { tolerance: options.tolerance }),\n ...(options.historyLimit === undefined ? {} : { historyLimit: options.historyLimit }),\n ...(options.createId === undefined ? {} : { createId: options.createId }),\n ...(options.createDesignator === undefined\n ? {}\n : { createDesignator: options.createDesignator }),\n });\n}\n\nfunction sameViewport(left: IViewportState, right: IViewportState | undefined): boolean {\n return (\n right !== undefined &&\n left.scale === right.scale &&\n left.offsetX === right.offsetX &&\n left.offsetY === right.offsetY\n );\n}\n","/** Detaches public data and freezes JSON objects; binary views remain writable private copies. */\nexport function editorSnapshot<T>(value: T): T {\n const copy = structuredClone(value);\n const seen = new WeakSet<object>();\n const freeze = (entry: unknown): void => {\n if (entry === null || typeof entry !== 'object' || seen.has(entry)) return;\n seen.add(entry);\n if (ArrayBuffer.isView(entry)) return;\n for (const child of Object.values(entry)) freeze(child);\n Object.freeze(entry);\n };\n freeze(copy);\n return copy;\n}\n","import type { IDisposable } from '@mica-js/core/lifecycle';\n\nexport interface IServiceIdentifier<T> {\n (target: object, propertyKey: string | symbol | undefined, parameterIndex: number): void;\n readonly type: T;\n toString(): string;\n}\n\n// `unknown[]` would reject constructors with narrower explicit and injected parameters.\n// eslint-disable-next-line @typescript-eslint/no-explicit-any\nexport type Constructor<T> = new (...args: any[]) => T;\n\ntype Dependency = { readonly id: IServiceIdentifier<unknown>; readonly index: number };\nconst identifiers = new Map<string, IServiceIdentifier<unknown>>();\nconst dependencies = new WeakMap<object, Dependency[]>();\n\nexport function createDecorator<T>(id: string): IServiceIdentifier<T> {\n const existing = identifiers.get(id);\n if (existing) return existing as IServiceIdentifier<T>;\n const identifier = ((target: object, propertyKey: string | symbol | undefined, index: number) => {\n if (typeof target !== 'function' || propertyKey !== undefined) {\n throw new TypeError('Service decorators can only decorate constructor parameters');\n }\n const entries = dependencies.get(target) ?? [];\n if (entries.some((entry) => entry.index === index)) {\n throw new Error(`Duplicate service decorator at parameter ${index}`);\n }\n entries.push({ id: identifier, index });\n dependencies.set(target, entries);\n }) as IServiceIdentifier<T>;\n identifier.toString = () => id;\n identifiers.set(id, identifier);\n return identifier;\n}\n\nexport class SyncDescriptor<T> {\n constructor(\n readonly ctor: Constructor<T>,\n readonly staticArguments: readonly unknown[] = [],\n ) {}\n}\n\ntype ServiceEntry<T> = T | SyncDescriptor<T>;\n\nexport class ServiceCollection {\n private readonly entries = new Map<IServiceIdentifier<unknown>, unknown>();\n\n constructor(...entries: readonly (readonly [IServiceIdentifier<unknown>, unknown])[]) {\n for (const [id, value] of entries) this.entries.set(id, value);\n }\n\n set<T>(id: IServiceIdentifier<T>, value: ServiceEntry<T>): ServiceEntry<T> | undefined {\n const previous = this.get(id);\n this.entries.set(id, value);\n return previous;\n }\n\n get<T>(id: IServiceIdentifier<T>): ServiceEntry<T> | undefined {\n return this.entries.get(id) as ServiceEntry<T> | undefined;\n }\n\n has<T>(id: IServiceIdentifier<T>): boolean {\n return this.entries.has(id);\n }\n}\n\nexport class InstantiationService implements IDisposable {\n private readonly resolving: IServiceIdentifier<unknown>[] = [];\n private readonly owned: unknown[] = [];\n private readonly children = new Set<InstantiationService>();\n private disposed = false;\n private disposal: Promise<void> | undefined;\n\n constructor(\n private readonly services = new ServiceCollection(),\n private readonly parent?: InstantiationService,\n ) {\n parent?.assertAlive();\n parent?.children.add(this);\n }\n\n createChild(services = new ServiceCollection()): InstantiationService {\n this.assertAlive();\n return new InstantiationService(services, this);\n }\n\n get<T>(id: IServiceIdentifier<T>): T {\n this.assertAlive();\n if (!this.services.has(id)) {\n if (this.parent) return this.parent.get(id);\n throw new Error(`Missing service: ${id}`);\n }\n const entry = this.services.get(id);\n if (!(entry instanceof SyncDescriptor)) return entry as T;\n if (this.resolving.includes(id)) {\n throw new Error(`Circular service dependency: ${[...this.resolving, id].join(' -> ')}`);\n }\n this.resolving.push(id);\n try {\n const instance = this.createInstance(entry.ctor, ...entry.staticArguments);\n this.owned.push(instance);\n this.assertAlive();\n if (this.services.get(id) === entry) this.services.set(id, instance);\n return instance;\n } finally {\n this.resolving.pop();\n }\n }\n\n /** Instances returned here belong to the caller, not to this service scope. */\n createInstance<T>(ctor: Constructor<T>, ...args: unknown[]): T {\n this.assertAlive();\n let target: object | null = ctor;\n let injections: readonly Dependency[] = [];\n while (target) {\n const entries = dependencies.get(target);\n if (entries) {\n injections = entries;\n break;\n }\n target = Object.getPrototypeOf(target) as object | null;\n }\n const byIndex = new Map(injections.map((entry) => [entry.index, entry.id]));\n const count = Math.max(\n ctor.length,\n args.length + injections.length,\n ...injections.map((d) => d.index + 1),\n );\n const parameters: unknown[] = [];\n let explicitIndex = 0;\n for (let index = 0; index < count; index++) {\n const id = byIndex.get(index);\n parameters.push(id ? this.get(id) : args[explicitIndex++]);\n }\n this.assertAlive();\n return new ctor(...parameters);\n }\n\n dispose(): Promise<void> {\n if (this.disposal) return this.disposal;\n this.disposed = true;\n // Schedule cleanup after publishing the promise, making reentrant disposal idempotent.\n this.disposal = Promise.resolve().then(async () => {\n const errors: unknown[] = [];\n for (const child of [...this.children].reverse()) {\n try {\n await child.dispose();\n } catch (error) {\n errors.push(error);\n }\n }\n this.children.clear();\n const instances = [...new Set(this.owned)].reverse();\n this.owned.length = 0;\n for (const instance of instances) {\n try {\n if (instance && typeof (instance as IDisposable).dispose === 'function') {\n await (instance as IDisposable).dispose();\n }\n } catch (error) {\n errors.push(error);\n }\n }\n this.parent?.children.delete(this);\n if (errors.length) throw new AggregateError(errors, 'Failed to dispose services');\n });\n return this.disposal;\n }\n\n private assertAlive(): void {\n if (this.disposed) throw new Error('InstantiationService is disposed');\n this.parent?.assertAlive();\n }\n}\n","import { createDecorator } from './instantiation';\nimport type {\n IDeviceLibrary as IDeviceLibraryContract,\n IFileSystemProvider as IFileSystemProviderContract,\n IWidgetLibrary as IWidgetLibraryContract,\n} from './providers';\n\nexport type IDeviceLibrary = IDeviceLibraryContract;\nexport const IDeviceLibrary = createDecorator<IDeviceLibrary>('editor.deviceLibrary');\n\nexport type IWidgetLibrary = IWidgetLibraryContract;\nexport const IWidgetLibrary = createDecorator<IWidgetLibrary>('editor.widgetLibrary');\n\nexport type IFileSystemProvider = IFileSystemProviderContract;\nexport const IFileSystemProvider = createDecorator<IFileSystemProvider>(\n 'editor.fileSystemProvider',\n);\n","import type { IDisposable } from '@mica-js/core/lifecycle';\nimport { createDecorator } from './instantiation';\nimport { IDeviceLibrary, IWidgetLibrary } from './provider-services';\nimport type { IDeviceDescription, IWidgetDescription } from './providers';\n\nclass LibraryResolver<T> implements IDisposable {\n readonly #cache = new Map<string, Promise<T | undefined>>();\n #disposed = false;\n\n constructor(private readonly library: { resolve(id: string): Promise<T | undefined> }) {}\n\n resolve(id: string): Promise<T | undefined> {\n if (this.#disposed) return Promise.reject(new Error('Library resolver is disposed.'));\n const cached = this.#cache.get(id);\n if (cached) return cached;\n const pending = Promise.resolve()\n .then(() => {\n if (this.#disposed) throw new Error('Library resolver is disposed.');\n return this.library.resolve(id);\n })\n .then(\n (description) => {\n if (description === undefined) this.#cache.delete(id);\n return description;\n },\n (error: unknown) => {\n this.#cache.delete(id);\n throw error;\n },\n );\n this.#cache.set(id, pending);\n return pending;\n }\n\n dispose(): void {\n this.#disposed = true;\n this.#cache.clear();\n }\n}\n\nexport const IDeviceLibraryResolver = createDecorator<IDeviceLibrary>(\n 'editor.deviceLibraryResolver',\n);\n\nexport class DeviceLibraryResolver extends LibraryResolver<IDeviceDescription> {\n constructor(@IDeviceLibrary library: IDeviceLibrary) {\n super(library);\n }\n}\n\nexport const IWidgetLibraryResolver = createDecorator<IWidgetLibrary>(\n 'editor.widgetLibraryResolver',\n);\n\nexport class WidgetLibraryResolver extends LibraryResolver<IWidgetDescription> {\n constructor(@IWidgetLibrary library: IWidgetLibrary) {\n super(library);\n }\n}\n","import {\n createDeviceRegistry,\n formatDeviceReference,\n parseDeviceReference,\n type DeviceReference,\n type DeviceRegistry,\n type DeviceSymbolProvider,\n} from '@mica-js/document/schematic';\nimport type { IDisposable } from '@mica-js/core/lifecycle';\nimport { createDecorator } from '../instantiation';\nimport { IDeviceLibraryResolver } from '../libraries';\nimport type { IDeviceLibrary } from '../providers';\n\nexport interface ISchematicDevices extends DeviceSymbolProvider, IDisposable {\n prepare(ids: readonly string[]): Promise<void>;\n}\n\nexport const ISchematicDevices = createDecorator<ISchematicDevices>('editor.schematicDevices');\n\nexport class SchematicDevices implements ISchematicDevices {\n readonly #registries = new Map<string, DeviceRegistry>();\n readonly #pending = new Map<string, Promise<void>>();\n #disposed = false;\n\n constructor(@IDeviceLibraryResolver private readonly library: IDeviceLibrary) {}\n\n async prepare(ids: readonly string[]): Promise<void> {\n this.#assertActive();\n await Promise.all([...new Set(ids)].map((id) => this.#prepare(id)));\n }\n\n getDeviceSymbol(reference: DeviceReference) {\n return this.#registry(reference)?.getDeviceSymbol(reference);\n }\n\n getDeviceName(reference: DeviceReference) {\n return this.#registry(reference)?.getDeviceName(reference);\n }\n\n getDeviceDesignatorPrefix(reference: DeviceReference) {\n return this.#registry(reference)?.getDeviceDesignatorPrefix?.(reference);\n }\n\n getDevicePropertyDescriptors(reference: DeviceReference) {\n return this.#registry(reference)?.getDevicePropertyDescriptors?.(reference);\n }\n\n dispose(): void {\n this.#disposed = true;\n this.#registries.clear();\n this.#pending.clear();\n }\n\n #registry(reference: DeviceReference): DeviceRegistry | undefined {\n return this.#registries.get(formatDeviceReference(reference.packageId, reference.deviceId));\n }\n\n #assertActive(): void {\n if (this.#disposed) throw new Error('Schematic devices service is disposed.');\n }\n\n #prepare(id: string): Promise<void> {\n const reference = parseDeviceReference(id);\n if (!reference) return Promise.reject(new Error(`Invalid device ID ${JSON.stringify(id)}.`));\n if (reference.packageId === 'builtin' || this.#registries.has(id)) return Promise.resolve();\n const existing = this.#pending.get(id);\n if (existing) return existing;\n\n const pending = Promise.resolve()\n .then(() => {\n this.#assertActive();\n return this.library.resolve(id);\n })\n .then((description) => {\n this.#assertActive();\n if (!description) throw new Error(`Device ${JSON.stringify(id)} was not found.`);\n const definition = description.definition;\n const registry = createDeviceRegistry([\n {\n packageId: reference.packageId,\n devices: [\n {\n id: reference.deviceId,\n ...(definition.displayName === undefined\n ? {}\n : { displayName: definition.displayName }),\n ...(definition.description === undefined\n ? {}\n : { description: definition.description }),\n ...(definition.designatorPrefix === undefined\n ? {}\n : { designatorPrefix: definition.designatorPrefix }),\n raw: { ...definition },\n },\n ],\n },\n ]);\n this.#registries.set(id, registry);\n })\n .finally(() => {\n this.#pending.delete(id);\n });\n this.#pending.set(id, pending);\n return pending;\n }\n}\n","import {\n parseSchematic,\n type SchematicCommand,\n type SchematicDocument,\n} from '@mica-js/document/schematic';\nimport { type Event } from '@mica-js/core/lifecycle';\nimport { DocumentModel } from './model/document-model';\nimport { createDecorator } from '../instantiation';\nimport { IFileSystemProvider } from '../provider-services';\nimport { ISchematicDevices } from './devices';\n\nexport interface ISchematicConfiguration {\n readonly uri: string;\n}\nexport const ISchematicConfiguration = createDecorator<ISchematicConfiguration>(\n 'editor.schematicConfiguration',\n);\n\nexport class SchematicDocumentService {\n #model: DocumentModel | undefined;\n #disposed = false;\n #queue: Promise<void> = Promise.resolve();\n\n constructor(\n @ISchematicConfiguration private readonly configuration: ISchematicConfiguration,\n @IFileSystemProvider private readonly files: IFileSystemProvider,\n @ISchematicDevices private readonly devices: ISchematicDevices,\n ) {}\n\n async initialize(): Promise<void> {\n this.#assertAlive();\n const bytes = await this.files.read(this.configuration.uri);\n this.#assertAlive();\n const document = parseSchematic(new TextDecoder('utf-8', { fatal: true }).decode(bytes));\n await this.devices.prepare(document.sheet.symbols.map((symbol) => symbol.device));\n this.#assertAlive();\n this.#model = new DocumentModel({ value: document, devices: this.devices });\n }\n\n get model(): DocumentModel {\n this.#assertAlive();\n if (!this.#model) throw new Error('Schematic document is not initialized.');\n return this.#model;\n }\n\n get onDidChangeContent(): Event<SchematicDocument> {\n return this.model.onDidChangeContent;\n }\n\n apply(command: SchematicCommand): Promise<void> {\n return this.#enqueue(async () => {\n if ((command.type === 'add-symbol' || command.type === 'update-symbol') && command.device) {\n await this.devices.prepare([command.device]);\n }\n this.model.applyCommand(command);\n });\n }\n\n undo(): Promise<void> {\n return this.#enqueue(() => this.model.undo());\n }\n\n redo(): Promise<void> {\n return this.#enqueue(() => this.model.redo());\n }\n\n #enqueue(run: () => void | Promise<void>): Promise<void> {\n const pending = this.#queue.then(() => {\n this.#assertAlive();\n return run();\n });\n this.#queue = pending.catch(() => undefined);\n return pending;\n }\n\n dispose(): void {\n this.#disposed = true;\n this.#model?.dispose();\n this.#model = undefined;\n }\n\n #assertAlive(): void {\n if (this.#disposed) throw new Error('Schematic document is disposed.');\n }\n}\n\nexport const ISchematicDocumentService = createDecorator<SchematicDocumentService>(\n 'editor.schematicDocument',\n);\n","import { DisposableStore, Emitter, type Event } from '@mica-js/core/lifecycle';\nimport type { SchematicDocument } from '@mica-js/document/schematic';\nimport type {\n EditorCommandArgs,\n IEditorErrorEvent,\n IEditorIntegrationState,\n IEditorPointerEvent,\n IEditorProperty,\n} from './host';\nimport type { ISchematicCommandMap } from './schematic-commands';\nimport type { SchematicTarget } from './schematic/types';\nimport { buildInspector } from './schematic/model/inspector';\nexport type { ISchematicCommandMap } from './schematic-commands';\nexport type { SchematicTarget } from './schematic/types';\nimport { createSchematicEditor as createView } from './schematic/editor/schematic-editor';\nimport type { ISchematicTheme } from './schematic/render/theme';\nimport './schematic/styles/editor.css';\nimport type { EditorState } from './editor';\nimport { editorSnapshot as snapshot } from './snapshot';\nimport { InstantiationService, ServiceCollection, SyncDescriptor } from './instantiation';\nimport { DeviceLibraryResolver, IDeviceLibraryResolver } from './libraries';\nimport { IDeviceLibrary, IFileSystemProvider } from './provider-services';\nimport { SchematicDevices, ISchematicDevices } from './schematic/devices';\nimport {\n ISchematicConfiguration,\n ISchematicDocumentService,\n SchematicDocumentService,\n} from './schematic/document';\n\nexport interface ISchematicEditorOptions {\n readonly container: HTMLElement;\n readonly uri: string;\n readonly fileSystem: IFileSystemProvider;\n readonly deviceLibrary: IDeviceLibrary;\n readonly readOnly?: boolean;\n readonly theme?: Partial<ISchematicTheme>;\n}\n\nexport interface ISchematicEditor {\n readonly uri: string;\n readonly state: EditorState;\n readonly onDidChangeContent: Event<SchematicDocument>;\n readonly onDidChangeSelection: Event<readonly SchematicTarget[]>;\n readonly onDidClick: Event<IEditorPointerEvent<SchematicTarget>>;\n readonly onDidDoubleClick: Event<IEditorPointerEvent<SchematicTarget>>;\n readonly onDidContextMenu: Event<IEditorPointerEvent<SchematicTarget>>;\n readonly onDidChangeState: Event<IEditorIntegrationState>;\n readonly onDidError: Event<IEditorErrorEvent>;\n getDocument(): SchematicDocument;\n getSelection(): readonly SchematicTarget[];\n setSelection(selection: readonly SchematicTarget[]): void;\n getProperties(symbolId: string): readonly IEditorProperty[];\n getState(): IEditorIntegrationState;\n executeCommand<K extends keyof ISchematicCommandMap>(\n id: K,\n ...args: EditorCommandArgs<ISchematicCommandMap[K]>\n ): Promise<ISchematicCommandMap[K]['result']>;\n dispose(): Promise<void>;\n}\n\n/** Loads one document and mounts one schematic view; the returned instance owns all internal services. */\nexport async function createSchematicEditor(\n options: ISchematicEditorOptions,\n): Promise<ISchematicEditor> {\n const uri = new URL(options.uri).href;\n const readOnly = options.readOnly ?? false;\n const services = new ServiceCollection();\n services.set(IFileSystemProvider, options.fileSystem);\n services.set(IDeviceLibrary, options.deviceLibrary);\n services.set(ISchematicConfiguration, { uri });\n services.set(IDeviceLibraryResolver, new SyncDescriptor(DeviceLibraryResolver));\n services.set(ISchematicDevices, new SyncDescriptor(SchematicDevices));\n services.set(ISchematicDocumentService, new SyncDescriptor(SchematicDocumentService));\n const scope = new InstantiationService(services);\n let view: ReturnType<typeof createView> | undefined;\n const subscriptions = new DisposableStore();\n const content = subscriptions.add(new Emitter<SchematicDocument>());\n const selection = subscriptions.add(new Emitter<readonly SchematicTarget[]>());\n const click = subscriptions.add(new Emitter<IEditorPointerEvent<SchematicTarget>>());\n const doubleClick = subscriptions.add(new Emitter<IEditorPointerEvent<SchematicTarget>>());\n const contextMenu = subscriptions.add(new Emitter<IEditorPointerEvent<SchematicTarget>>());\n const stateChanged = subscriptions.add(new Emitter<IEditorIntegrationState>());\n const errors = subscriptions.add(new Emitter<IEditorErrorEvent>());\n try {\n const document = scope.get(ISchematicDocumentService);\n await document.initialize();\n view = createView({\n container: options.container,\n model: document.model,\n prepareDevices: (ids) => scope.get(ISchematicDevices).prepare(ids),\n readOnly,\n onPointerEvent: (kind, event) => {\n const emitter =\n kind === 'click' ? click : kind === 'doubleClick' ? doubleClick : contextMenu;\n emitter.fire(snapshot(event));\n },\n ...(options.theme === undefined ? {} : { theme: options.theme }),\n });\n const mountedView = view;\n const model = document.model;\n let state: EditorState = 'ready';\n let disposal: Promise<void> | undefined;\n let queue: Promise<unknown> = Promise.resolve();\n let executing = false;\n function assertReady(): void {\n if (state !== 'ready') throw new Error('Schematic editor is disposed.');\n }\n const prepare = async (deviceId: string) => {\n await scope.get(ISchematicDevices).prepare([deviceId]);\n assertReady();\n };\n type Handlers = {\n [K in keyof ISchematicCommandMap]: (\n params: ISchematicCommandMap[K]['params'],\n ) => ISchematicCommandMap[K]['result'];\n };\n const handlers: Handlers = {\n 'schematic.setProperty': ({ symbolId, key, value }) =>\n model.setSymbolProperty(symbolId, key, value),\n 'schematic.removeProperty': ({ symbolId, key }) => model.removeSymbolProperty(symbolId, key),\n 'schematic.setProperties': ({ symbolId, values, remove = [] }) =>\n model.transaction(() => {\n for (const key of remove) model.removeSymbolProperty(symbolId, key);\n for (const [key, value] of Object.entries(values))\n model.setSymbolProperty(symbolId, key, value);\n }),\n 'schematic.addDevice': ({ deviceId, ...params }) => {\n const before = new Set(model.getValue().sheet.symbols.map((symbol) => symbol.id));\n model.applyCommand({ type: 'add-symbol', ...params, device: deviceId });\n return model.getValue().sheet.symbols.find((symbol) => !before.has(symbol.id))!.id;\n },\n 'schematic.removeDevice': ({ symbolId }) =>\n model.removeTargets([{ kind: 'symbol', id: symbolId }]),\n 'schematic.updateDevice': ({ symbolId, deviceId, ...params }) => {\n model.applyCommand({\n type: 'update-symbol',\n ...params,\n id: symbolId,\n ...(deviceId === undefined ? {} : { device: deviceId }),\n });\n },\n 'schematic.addWire': (params) => {\n const before = new Set(model.getValue().sheet.wires.map((wire) => wire.id));\n model.applyCommand({ type: 'add-wire', ...params });\n return model.getValue().sheet.wires.find((wire) => !before.has(wire.id))!.id;\n },\n 'schematic.removeWire': ({ wireId }) => model.removeTargets([{ kind: 'wire', id: wireId }]),\n 'schematic.setWirePoints': ({ wireId, points }) =>\n model.applyCommand({ type: 'set-wire-points', id: wireId, points }),\n 'schematic.deleteSelection': () => mountedView.deleteSelection(),\n 'schematic.moveSelection': ({ dx, dy }) => mountedView.moveSelectionBy(dx, dy),\n 'schematic.rotateSelection': ({ degrees }) => mountedView.rotateSelection(degrees),\n 'schematic.placeDevice': ({ deviceId }) => mountedView.placeDevice(deviceId),\n 'schematic.undo': () => model.undo(),\n 'schematic.redo': () => model.redo(),\n 'schematic.setTool': ({ tool }) => mountedView.setTool(tool),\n 'schematic.zoom': ({ scale }) => mountedView.zoomTo(scale),\n 'schematic.fit': () => mountedView.fitToContent(),\n 'schematic.resetView': () => mountedView.setViewport({ scale: 1, offsetX: 0, offsetY: 0 }),\n };\n const getState = (): IEditorIntegrationState =>\n snapshot({\n readOnly,\n mode: 'edit',\n canUndo: model.getCanUndo(),\n canRedo: model.getCanRedo(),\n tool: mountedView.getTool(),\n });\n let lastState = getState();\n const reportError = (source: IEditorErrorEvent['source'], error: unknown) => {\n let detached: unknown;\n try {\n detached = snapshot(error);\n } catch {\n detached = Object.freeze(new Error(String(error)));\n }\n errors.fire(Object.freeze({ source, error: detached }));\n };\n subscriptions.add(mountedView.onDidChangeContent((value) => content.fire(snapshot(value))));\n subscriptions.add(mountedView.onDidChangeSelection((value) => selection.fire(snapshot(value))));\n subscriptions.add(\n mountedView.onDidChangeState(() => {\n const next = getState();\n if (JSON.stringify(next) !== JSON.stringify(lastState)) {\n lastState = next;\n stateChanged.fire(next);\n }\n }),\n );\n subscriptions.add(\n mountedView.onDidChangeError((error) => {\n if (error !== undefined && !executing) reportError('runtime', error);\n }),\n );\n return {\n uri,\n get state() {\n return state;\n },\n onDidChangeContent: content.event,\n onDidChangeSelection: selection.event,\n onDidClick: click.event,\n onDidDoubleClick: doubleClick.event,\n onDidContextMenu: contextMenu.event,\n onDidChangeState: stateChanged.event,\n onDidError: errors.event,\n getDocument() {\n assertReady();\n return snapshot(model.getValue());\n },\n getSelection() {\n assertReady();\n return snapshot(mountedView.getSelection());\n },\n setSelection(value) {\n assertReady();\n mountedView.setSelection(snapshot(value));\n },\n getProperties(symbolId) {\n assertReady();\n const inspector = buildInspector(model.getValue(), [{ kind: 'symbol', id: symbolId }], {\n devices: model.getDevices(),\n topology: () => model.getTopology(),\n });\n if (inspector?.kind !== 'symbol') return Object.freeze([]);\n return snapshot(\n inspector.properties.map((field) => ({\n ...field,\n label: field.title ?? field.key,\n value: field.value === undefined ? field.defaultValue : field.value,\n defaultValue: field.defaultValue,\n overrideValue: field.value,\n overridden: field.value !== undefined,\n readOnly,\n })),\n );\n },\n getState() {\n assertReady();\n return getState();\n },\n executeCommand<K extends keyof ISchematicCommandMap>(\n id: K,\n ...args: EditorCommandArgs<ISchematicCommandMap[K]>\n ): Promise<ISchematicCommandMap[K]['result']> {\n let params: ISchematicCommandMap[K]['params'];\n try {\n params = snapshot(args[0]) as ISchematicCommandMap[K]['params'];\n } catch (error) {\n reportError('command', error);\n return Promise.reject(error);\n }\n const pending = queue\n .then(async () => {\n assertReady();\n if (!Object.hasOwn(handlers, id)) throw new Error(`Unknown command: ${String(id)}`);\n if (\n readOnly &&\n id !== 'schematic.zoom' &&\n id !== 'schematic.fit' &&\n id !== 'schematic.resetView'\n )\n throw new Error('Schematic editor is read-only.');\n if (\n (id === 'schematic.addDevice' ||\n id === 'schematic.updateDevice' ||\n id === 'schematic.placeDevice') &&\n params !== undefined &&\n 'deviceId' in params &&\n typeof params.deviceId === 'string'\n )\n await prepare(params.deviceId);\n executing = true;\n try {\n return handlers[id](params);\n } finally {\n executing = false;\n }\n })\n .catch((error: unknown) => {\n reportError('command', error);\n throw error;\n });\n queue = pending.catch(() => undefined);\n return pending;\n },\n dispose() {\n if (disposal) return disposal;\n state = 'disposing';\n disposal = Promise.resolve().then(async () => {\n try {\n subscriptions.dispose();\n } finally {\n try {\n mountedView.dispose();\n } finally {\n try {\n await scope.dispose();\n } finally {\n state = 'disposed';\n }\n }\n }\n });\n return disposal;\n },\n };\n } catch (error) {\n const errors: unknown[] = [error];\n try {\n subscriptions.dispose();\n } catch (cleanupError) {\n errors.push(cleanupError);\n }\n try {\n view?.dispose();\n } catch (cleanupError) {\n errors.push(cleanupError);\n }\n try {\n await scope.dispose();\n } catch (cleanupError) {\n errors.push(cleanupError);\n }\n if (errors.length > 1)\n throw new AggregateError(errors, 'Schematic initialization and cleanup failed.', {\n cause: error,\n });\n throw error;\n }\n}\n","import { toDisposable, type Disposable } from '@mica-js/core/lifecycle';\nimport { createDecorator } from './instantiation';\n\nexport interface ICommandContribution {\n readonly id: string;\n readonly execute: (...args: readonly unknown[]) => unknown;\n}\n\nexport interface ICommandService {\n register(command: ICommandContribution): Disposable;\n execute(id: string, ...args: readonly unknown[]): Promise<unknown>;\n}\n\nexport const ICommandService = createDecorator<ICommandService>('editor.commandService');\n\nexport class Commands implements ICommandService {\n readonly #commands = new Map<string, ICommandContribution>();\n #disposed = false;\n\n register(command: ICommandContribution): Disposable {\n this.#assertActive();\n if (!command.id.trim()) throw new Error('Command id must not be empty.');\n if (this.#commands.has(command.id)) throw new Error(`Duplicate command: ${command.id}`);\n const snapshot = { id: command.id, execute: command.execute };\n this.#commands.set(snapshot.id, snapshot);\n return toDisposable(() => {\n if (this.#commands.get(snapshot.id) === snapshot) this.#commands.delete(snapshot.id);\n });\n }\n\n async execute(id: string, ...args: readonly unknown[]): Promise<unknown> {\n this.#assertActive();\n const command = this.#commands.get(id);\n if (!command) throw new Error(`Unknown command: ${id}`);\n return command.execute(...args);\n }\n\n dispose(): void {\n this.#disposed = true;\n this.#commands.clear();\n }\n\n #assertActive(): void {\n if (this.#disposed) throw new Error('Command service is disposed.');\n }\n}\n","import {\n assertCanvasBindings,\n validateCanvasBindings,\n resolveDelivery,\n type CanvasBindingCatalog,\n type CanvasBindingTarget,\n type CanvasDocument,\n type CanvasPortDescriptor,\n} from '@mica-js/document/canvas';\nimport { parseSchematic, type SchematicDocument } from '@mica-js/document/schematic';\nimport type { WidgetModule } from '@mica-js/widget';\nimport type {\n IDeviceDescription,\n IDeviceLibrary,\n IFileSystemProvider,\n IWidgetLibrary,\n} from '../providers';\n\nexport interface ICanvasResources {\n readonly document: CanvasDocument;\n readonly schematic: SchematicDocument;\n readonly devices: readonly (IDeviceDescription & { readonly id: string })[];\n readonly widgets: ReadonlyMap<string, WidgetModule>;\n readonly assets: ReadonlyMap<string, Readonly<Record<string, Uint8Array>>>;\n readonly simulationAssets: Readonly<Record<string, Readonly<Record<string, Uint8Array>>>>;\n}\n\nconst emptySchematic: SchematicDocument = {\n version: 1,\n sheet: { symbols: [], wires: [], junctions: [] },\n};\n\nexport async function prepareCanvasResources(\n document: CanvasDocument,\n uri: string,\n files: IFileSystemProvider,\n deviceLibrary: IDeviceLibrary,\n widgetLibrary: IWidgetLibrary,\n projectRoot?: string,\n): Promise<ICanvasResources> {\n const schematicUri =\n document.schematic === undefined\n ? undefined\n : new URL(document.schematic, projectRoot ?? uri).href;\n const schematic =\n schematicUri === undefined\n ? emptySchematic\n : parseSchematic(\n new TextDecoder('utf-8', { fatal: true }).decode(await files.read(schematicUri)),\n );\n const devices = await Promise.all(\n [...new Set(schematic.sheet.symbols.map((symbol) => symbol.device))]\n .filter((id) => !id.startsWith('builtin:'))\n .map(async (id) => {\n const value = await deviceLibrary.resolve(id);\n if (!value) throw new Error(`Device ${JSON.stringify(id)} was not found.`);\n return { id, ...value };\n }),\n );\n const widgets = new Map(\n await Promise.all(\n [...new Set(document.widgets.map((instance) => instance.widget))].map(async (id) => {\n const value = await widgetLibrary.resolve(id);\n if (!value) throw new Error(`Widget ${JSON.stringify(id)} was not found.`);\n return [id, value] as const;\n }),\n ),\n );\n const deviceMap = new Map(devices.map((device) => [device.id, device.definition]));\n const symbols = new Map(schematic.sheet.symbols.map((symbol) => [symbol.id, symbol]));\n assertCanvasBindings(document, {\n catalog: {\n widgetDefinition(id) {\n const definition = widgets.get(id)?.definition;\n return definition === undefined\n ? undefined\n : { ports: definition.ports, propertyKeys: Object.keys(definition.properties) };\n },\n hasSchematic: (path) => path === document.schematic && schematicUri !== undefined,\n hasSymbol: (id) => symbols.has(id),\n symbolPort(id, port): CanvasPortDescriptor | undefined {\n const symbol = symbols.get(id);\n const definition = symbol === undefined ? undefined : deviceMap.get(symbol.device);\n return definition?.ports?.[port];\n },\n },\n });\n const assets = new Map(\n await Promise.all(\n document.widgets.map(async (instance) => {\n const module = widgets.get(instance.widget)!;\n const props = {\n ...Object.fromEntries(\n Object.entries(module.definition.properties).map(([key, descriptor]) => [\n key,\n descriptor.default,\n ]),\n ),\n ...instance.properties,\n };\n return [instance.id, await prepareAssets(props, projectRoot ?? uri, files)] as const;\n }),\n ),\n );\n const simulationAssets = Object.fromEntries(\n await Promise.all(\n schematic.sheet.symbols.map(async (symbol) => {\n const definition = deviceMap.get(symbol.device);\n const props = {\n ...Object.fromEntries(\n Object.entries(definition?.properties ?? {}).map(([key, descriptor]) => [\n key,\n typeof descriptor === 'object' && descriptor !== null && 'default' in descriptor\n ? descriptor.default\n : undefined,\n ]),\n ),\n ...symbol.properties,\n };\n return [\n symbol.id,\n await prepareAssets(props, projectRoot ?? schematicUri ?? uri, files),\n ] as const;\n }),\n ),\n );\n const resources = { document, schematic, devices, widgets, assets, simulationAssets };\n for (const instance of document.widgets) {\n for (const [port, target] of Object.entries(instance.bindings ?? {})) {\n const reason = canvasBindingReason(resources, instance.id, port, target);\n if (reason !== undefined) throw new Error(reason);\n }\n }\n return resources;\n}\n\nexport function canvasBindingCatalog(resources: ICanvasResources): CanvasBindingCatalog {\n return {\n widgetDefinition(id) {\n const definition = resources.widgets.get(id)?.definition;\n return (\n definition && { ports: definition.ports, propertyKeys: Object.keys(definition.properties) }\n );\n },\n hasSchematic: (path) => path === resources.document.schematic,\n hasSymbol: (id) => resources.schematic.sheet.symbols.some((symbol) => symbol.id === id),\n symbolPort(id, port) {\n const symbol = resources.schematic.sheet.symbols.find((symbol) => symbol.id === id);\n return resources.devices.find((device) => device.id === symbol?.device)?.definition.ports?.[\n port\n ];\n },\n };\n}\n\n/** Use the document validator for queries as well as writes; delivery is an additional host check. */\nexport function canvasBindingReason(\n resources: ICanvasResources,\n instanceId: string,\n port: string,\n target: CanvasBindingTarget,\n): string | undefined {\n const instance = resources.document.widgets.find((item) => item.id === instanceId);\n if (!instance) throw new Error(`Unknown widget instance \"${instanceId}\".`);\n const catalog = canvasBindingCatalog(resources);\n const diagnostics = validateCanvasBindings(\n {\n ...resources.document,\n widgets: [{ ...instance, bindings: { [port]: target } }],\n },\n { catalog },\n );\n if (diagnostics.length) return diagnostics.map((item) => item.message).join(' ');\n const source = resources.widgets.get(instance.widget)?.definition.ports[port];\n const destination = catalog.symbolPort(target.symbol, target.port);\n if (\n source &&\n destination &&\n resolveDelivery(source.delivery, source.type) !==\n resolveDelivery(destination.delivery, destination.type)\n ) {\n return `Widget port \"${port}\" cannot bind to device port \"${target.port}\": delivery must match.`;\n }\n return undefined;\n}\n\nasync function prepareAssets(\n properties: Readonly<Record<string, unknown>>,\n uri: string,\n files: IFileSystemProvider,\n): Promise<Readonly<Record<string, Uint8Array>>> {\n const refs = new Map<string, { src: string; mode: string }>();\n for (const value of Object.values(properties)) {\n if (\n typeof value !== 'object' ||\n value === null ||\n !('src' in value) ||\n typeof value.src !== 'string' ||\n !('mode' in value) ||\n typeof value.mode !== 'string'\n )\n continue;\n refs.set(value.src, { src: value.src, mode: value.mode });\n }\n return Object.fromEntries(\n await Promise.all(\n [...refs.values()].map(async (ref) => {\n if (ref.mode === 'inline')\n return [ref.src, Uint8Array.from(atob(ref.src), (char) => char.charCodeAt(0))] as const;\n const bytes = await files.read(new URL(ref.src, uri).href);\n return [ref.src, bytes.slice()] as const;\n }),\n ),\n );\n}\n","import type { ISimulationRuntime } from '@mica-js/simulator';\nimport type { IWidgetRuntime } from '@mica-js/widget';\nimport { createDecorator } from '../instantiation';\n\nexport interface ICanvasRuntimes {\n readonly simulation: ISimulationRuntime;\n readonly widgets: IWidgetRuntime;\n resumeAudio(): Promise<void>;\n dispose(): Promise<void>;\n}\n\nexport interface ICanvasRuntimeFactory {\n create(container: HTMLElement): Promise<ICanvasRuntimes>;\n}\nexport const ICanvasRuntimeFactory = createDecorator<ICanvasRuntimeFactory>(\n 'editor.canvasRuntimeFactory',\n);\n\nexport class CanvasRuntimeFactory implements ICanvasRuntimeFactory {\n async create(container: HTMLElement): Promise<ICanvasRuntimes> {\n const [\n { createSimulationRuntimeFromWorker, createSimulationRuntimeGuestSandbox },\n { createWidgetHostGuestSandbox, createWidgetSandboxFromWorker, createWidgetRuntime },\n ] = await Promise.all([import('@mica-js/simulator/sandbox'), import('@mica-js/widget')]);\n const channel = new MessageChannel();\n let deviceWorker: ReturnType<typeof createSimulationRuntimeGuestSandbox> | undefined;\n let widgetWorker: ReturnType<typeof createWidgetHostGuestSandbox> | undefined;\n let simulation: ISimulationRuntime | undefined;\n let widgets: IWidgetRuntime | undefined;\n let audioContext: AudioContext | undefined;\n try {\n deviceWorker = createSimulationRuntimeGuestSandbox({ container });\n simulation = await createSimulationRuntimeFromWorker(deviceWorker, {\n topicPort: channel.port1,\n });\n widgetWorker = createWidgetHostGuestSandbox({ container });\n const sandbox = await createWidgetSandboxFromWorker(widgetWorker, {\n container,\n devicePort: channel.port2,\n });\n if (typeof globalThis.AudioContext === 'function') audioContext = new AudioContext();\n widgets = createWidgetRuntime(sandbox, {\n ...(audioContext === undefined ? {} : { audio: { context: audioContext } }),\n });\n widgets.audio.suspend();\n const ownedSimulation = simulation;\n const ownedWidgets = widgets;\n let disposal: Promise<void> | undefined;\n return {\n simulation,\n widgets,\n async resumeAudio() {\n if (!disposal && audioContext?.state === 'suspended') await audioContext.resume();\n },\n dispose() {\n return (disposal ??= Promise.allSettled([\n ownedWidgets.dispose(),\n ownedSimulation.dispose(),\n audioContext?.close(),\n ]).then((results) => {\n const errors = results\n .filter((result): result is PromiseRejectedResult => result.status === 'rejected')\n .map((result) => result.reason as unknown);\n if (errors.length)\n throw new AggregateError(errors, 'Canvas runtimes failed to dispose.');\n }));\n },\n };\n } catch (error) {\n channel.port1.close();\n channel.port2.close();\n await Promise.allSettled([\n widgets?.dispose() ?? widgetWorker?.terminate('Canvas initialization failed'),\n simulation?.dispose() ?? deviceWorker?.terminate('Canvas initialization failed'),\n audioContext?.close(),\n ]);\n throw error;\n }\n }\n}\n","import { timePs, toTimePs, type TimePs } from '@mica-js/core';\nimport { Emitter, type Event, type IDisposable } from '@mica-js/core/lifecycle';\nimport type { CanvasDocument } from '@mica-js/document/canvas';\nimport type { IWidgetFrame, WidgetInputEvent } from '@mica-js/widget';\nimport { createDecorator } from '../instantiation';\nimport { IDeviceLibraryResolver, IWidgetLibraryResolver } from '../libraries';\nimport { IFileSystemProvider } from '../provider-services';\nimport type { IDeviceLibrary, IWidgetLibrary } from '../providers';\nimport { prepareCanvasResources, canvasBindingReason, type ICanvasResources } from './resources';\nimport type { ICanvasBindingInfo } from '../canvas-host';\nimport { canvasSnapshot } from '../canvas-host';\nimport type { IEditorProperty } from '../host';\nimport { ICanvasRuntimeFactory, type ICanvasRuntimes } from './runtime-factory';\n\nexport interface ICanvasConfiguration {\n readonly uri: string;\n readonly projectRoot?: string;\n readonly stepMs?: number;\n readonly voltageReferences?: Readonly<Record<string, number>>;\n readonly container: HTMLElement;\n}\nexport const ICanvasConfiguration = createDecorator<ICanvasConfiguration>(\n 'editor.canvasConfiguration',\n);\n\ninterface IRunningCanvas {\n readonly runtimes: ICanvasRuntimes;\n readonly frames: Map<string, IWidgetFrame>;\n readonly subscriptions: IDisposable[];\n}\n\nexport class CanvasSession {\n readonly #renders = new Emitter<void>();\n readonly onDidRender: Event<void> = this.#renders.event;\n readonly #changes = new Emitter<void>();\n readonly onDidChangeState = this.#changes.event;\n readonly #errors = new Emitter<unknown>();\n readonly onDidError = this.#errors.event;\n\n getProperties(instanceId: string, readOnly: boolean): readonly IEditorProperty[] {\n const resources = this.#resources;\n const instance = resources?.document.widgets.find((item) => item.id === instanceId);\n if (!resources || !instance) throw new Error(`Unknown widget instance \"${instanceId}\".`);\n const definitions = resources.widgets.get(instance.widget)!.definition.properties;\n return canvasSnapshot(\n Object.entries(definitions).map(([key, descriptor]) => ({\n ...descriptor,\n key,\n label: String(descriptor.label ?? descriptor.title ?? key),\n type: descriptor.type,\n defaultValue: descriptor.default,\n overrideValue: instance.properties?.[key],\n overridden: Object.hasOwn(instance.properties ?? {}, key),\n value: Object.hasOwn(instance.properties ?? {}, key)\n ? instance.properties?.[key]\n : descriptor.default,\n readOnly: readOnly || descriptor.readOnly === true,\n })),\n );\n }\n\n getBindings(instanceId: string): readonly ICanvasBindingInfo[] {\n const resources = this.#resources;\n const instance = resources?.document.widgets.find((item) => item.id === instanceId);\n if (!resources || !instance) throw new Error(`Unknown widget instance \"${instanceId}\".`);\n return canvasSnapshot(\n Object.entries(resources.widgets.get(instance.widget)!.definition.ports).map(\n ([port, descriptor]) => ({\n ...descriptor,\n port,\n target: instance.bindings?.[port] ?? null,\n candidates: resources.schematic.sheet.symbols.flatMap((symbol) => {\n const device = resources.devices.find((item) => item.id === symbol.device);\n return Object.keys(device?.definition.ports ?? {}).map((targetPort) => {\n const target = { symbol: symbol.id, port: targetPort };\n const reason = canvasBindingReason(resources, instanceId, port, target);\n return {\n target,\n label: `${symbol.designator ?? symbol.id} / ${device?.definition.displayName ?? symbol.device} / ${targetPort}`,\n compatible: reason === undefined,\n ...(reason === undefined ? {} : { reason }),\n };\n });\n }),\n }),\n ),\n );\n }\n #active: IRunningCanvas | undefined;\n #resources: ICanvasResources | undefined;\n #signature: string | undefined;\n #mode: 'edit' | 'simulation' = 'edit';\n #simTime = timePs(0);\n #running = false;\n #timer: ReturnType<typeof setTimeout> | undefined;\n #nextFrame: number | undefined;\n #disposed = false;\n #queue: Promise<void> = Promise.resolve();\n #disposal: Promise<void> | undefined;\n readonly #frameMs: number;\n readonly #step: TimePs;\n readonly #unlockAudio = (): void => {\n const active = this.#active;\n if (this.#disposed || !this.#running || !active) return;\n void active.runtimes.resumeAudio().catch((error: unknown) => {\n if (!this.#disposed && this.#active === active) this.#errors.fire(error);\n });\n };\n\n constructor(\n @ICanvasConfiguration private readonly configuration: ICanvasConfiguration,\n @IFileSystemProvider private readonly files: IFileSystemProvider,\n @IDeviceLibraryResolver private readonly devices: IDeviceLibrary,\n @IWidgetLibraryResolver private readonly widgets: IWidgetLibrary,\n @ICanvasRuntimeFactory private readonly factory: ICanvasRuntimeFactory,\n ) {\n this.#frameMs = configuration.stepMs ?? 20;\n if (!Number.isFinite(this.#frameMs) || this.#frameMs <= 0)\n throw new Error('stepMs must be a positive finite number.');\n this.#step = toTimePs(this.#frameMs, 'ms');\n if (this.#step <= 0) throw new Error('stepMs must represent at least one picosecond.');\n configuration.container.addEventListener('pointerdown', this.#unlockAudio, true);\n configuration.container.addEventListener('keydown', this.#unlockAudio, true);\n }\n\n get mode() {\n return this.#mode;\n }\n get status() {\n return { mode: this.#mode, running: this.#running, simTime: this.#simTime };\n }\n getFrame(id: string): IWidgetFrame | undefined {\n return this.#active?.frames.get(id);\n }\n\n synchronize(document: CanvasDocument): Promise<void> {\n return this.#enqueue(async () => {\n if (this.#resources && this.#mode !== 'edit')\n throw new Error('Switch to edit mode before changing the canvas.');\n const prepared = await prepareCanvasResources(\n document,\n this.configuration.uri,\n this.files,\n this.devices,\n this.widgets,\n this.configuration.projectRoot,\n );\n this.#assertAlive();\n const signature = JSON.stringify({\n schematic: prepared.schematic,\n voltageReferences: this.configuration.voltageReferences,\n devices: prepared.devices,\n widgets: document.widgets.map((instance) => ({\n id: instance.id,\n widget: instance.widget,\n width: instance.width,\n height: instance.height,\n properties: instance.properties,\n bindings: instance.bindings,\n })),\n modules: [...prepared.widgets],\n assets: [...prepared.assets].map(([id, values]) => [\n id,\n Object.entries(values).map(([key, bytes]) => [key, Array.from(bytes)]),\n ]),\n simulationAssets: Object.entries(prepared.simulationAssets).map(([id, values]) => [\n id,\n Object.entries(values).map(([key, bytes]) => [key, Array.from(bytes)]),\n ]),\n });\n if (signature !== this.#signature) await this.#replace(prepared);\n this.#assertAlive();\n this.#signature = signature;\n this.#resources = prepared;\n });\n }\n\n setMode(mode: 'edit' | 'simulation'): Promise<void> {\n return this.#enqueue(async () => {\n if (mode !== 'edit' && mode !== 'simulation') throw new TypeError('Invalid canvas mode.');\n if (mode === this.#mode) return;\n this.pause();\n const previous = this.#mode;\n this.#mode = mode;\n try {\n if (this.#resources) await this.#replace(this.#resources);\n } catch (error) {\n this.#mode = previous;\n throw error;\n }\n this.#changes.fire();\n });\n }\n\n reset(): Promise<void> {\n return this.#enqueue(async () => {\n this.pause();\n if (this.#resources) await this.#replace(this.#resources);\n });\n }\n\n run(): void {\n this.#assertAlive();\n if (this.#mode !== 'simulation') throw new Error('Switch to simulation mode before running.');\n if (this.#running) return;\n this.#running = true;\n this.#active?.runtimes.widgets.audio.resume();\n this.#unlockAudio();\n this.#changes.fire();\n this.#schedule();\n }\n\n pause(): void {\n if (!this.#running) return;\n this.#running = false;\n this.#active?.runtimes.widgets.audio.suspend();\n this.#changes.fire();\n }\n\n step(): Promise<void> {\n return this.#enqueue(() => this.#advance(this.#step));\n }\n\n dispatch(id: string, event: WidgetInputEvent): Promise<void> {\n return this.#enqueue(async () => {\n if (this.#mode !== 'simulation') return;\n await this.#active?.runtimes.widgets.dispatch(id, event);\n if (!this.#running) await this.#advance(timePs(0));\n });\n }\n\n dispose(): Promise<void> {\n if (this.#disposal) return this.#disposal;\n this.#disposed = true;\n this.configuration.container.removeEventListener('pointerdown', this.#unlockAudio, true);\n this.configuration.container.removeEventListener('keydown', this.#unlockAudio, true);\n this.pause();\n if (this.#timer !== undefined) clearTimeout(this.#timer);\n this.#timer = undefined;\n this.#nextFrame = undefined;\n this.#disposal = this.#queue.then(async () => {\n const active = this.#active;\n this.#active = undefined;\n this.#resources = undefined;\n try {\n if (active) await this.#release(active);\n } finally {\n this.#renders.dispose();\n this.#changes.dispose();\n this.#errors.dispose();\n }\n });\n return this.#disposal;\n }\n\n async #replace(resources: ICanvasResources): Promise<void> {\n const runtimes = await this.factory.create(this.configuration.container);\n const candidate: IRunningCanvas = { runtimes, frames: new Map(), subscriptions: [] };\n candidate.subscriptions.push(\n runtimes.widgets.onDidRender((frame) => {\n candidate.frames.set(frame.instanceId, frame);\n if (this.#active === candidate) this.#renders.fire();\n }),\n );\n const report = (error: unknown) => {\n if (this.#active === candidate && !this.#disposed) this.#errors.fire(error);\n };\n const widgetErrors = runtimes.widgets.onDidDiagnostic?.(report);\n const simulationErrors = runtimes.simulation.onDidDiagnostic?.(report);\n if (widgetErrors) candidate.subscriptions.push(widgetErrors);\n if (simulationErrors) candidate.subscriptions.push(simulationErrors);\n try {\n this.#assertAlive();\n await runtimes.simulation.load({\n schematic: resources.schematic,\n ...(this.configuration.voltageReferences === undefined\n ? {}\n : { voltageReferences: this.configuration.voltageReferences }),\n devices: resources.devices,\n assets: structuredClone(resources.simulationAssets),\n });\n this.#assertAlive();\n for (const instance of resources.document.widgets) {\n await runtimes.widgets.mount({\n instanceId: instance.id,\n widget: instance.widget,\n module: resources.widgets.get(instance.widget)!,\n width: instance.width,\n height: instance.height,\n dpr: globalThis.devicePixelRatio || 1,\n ...(instance.properties === undefined ? {} : { properties: instance.properties }),\n assets: structuredClone(resources.assets.get(instance.id) ?? {}),\n });\n await runtimes.widgets.setBindings(instance.id, instance.bindings ?? {});\n this.#assertAlive();\n }\n await runtimes.widgets.step({ simTime: timePs(0), dt: timePs(0), mode: this.#mode });\n this.#assertAlive();\n } catch (error) {\n await this.#release(candidate).catch(() => undefined);\n throw error;\n }\n const previous = this.#active;\n this.#active = candidate;\n this.#simTime = timePs(0);\n this.#renders.fire();\n if (previous) await this.#release(previous).catch((error) => this.#errors.fire(error));\n this.#schedule();\n }\n\n async #advance(dt: TimePs): Promise<void> {\n const active = this.#active;\n if (!active) return;\n if (this.#mode === 'simulation' && dt > 0) {\n const report = await active.runtimes.simulation.tick(dt);\n this.#assertAlive();\n this.#simTime = report.simTime;\n }\n await active.runtimes.widgets.step({ simTime: this.#simTime, dt, mode: this.#mode });\n this.#assertAlive();\n }\n\n #schedule(): void {\n if (this.#disposed || !this.#active || this.#timer !== undefined) return;\n const now = performance.now();\n this.#nextFrame ??= now + this.#frameMs;\n // Keep the original frame cadence, skipping elapsed slots instead of accumulating work.\n if (this.#nextFrame < now)\n this.#nextFrame += Math.ceil((now - this.#nextFrame) / this.#frameMs) * this.#frameMs;\n this.#timer = setTimeout(() => {\n this.#timer = undefined;\n this.#nextFrame! += this.#frameMs;\n void this.#enqueue(() => this.#advance(this.#running ? this.#step : timePs(0))).then(\n () => this.#schedule(),\n (error) => {\n this.#nextFrame = undefined;\n this.pause();\n if (!this.#disposed) this.#errors.fire(error);\n },\n );\n }, this.#nextFrame - now);\n }\n\n async #release(active: IRunningCanvas): Promise<void> {\n for (const subscription of active.subscriptions) subscription.dispose();\n active.frames.clear();\n await active.runtimes.dispose();\n }\n\n #enqueue(run: () => void | Promise<void>): Promise<void> {\n const result = this.#queue.then(async () => {\n this.#assertAlive();\n await run();\n });\n this.#queue = result.catch(() => undefined);\n return result;\n }\n #assertAlive(): void {\n if (this.#disposed) throw new Error('Canvas session is disposed.');\n }\n}\nexport type ICanvasSession = CanvasSession;\nexport const ICanvasSession = createDecorator<ICanvasSession>('editor.canvasSession');\n","import { Emitter, type Event } from '@mica-js/core/lifecycle';\nimport {\n applyCanvasCommand,\n parseCanvas,\n type CanvasCommand,\n type CanvasDocument,\n} from '@mica-js/document/canvas';\n\n/** Undo steps kept by {@link CanvasModel}; the schematic document editor uses the same limit. */\nconst HISTORY_LIMIT = 200;\n\n/**\n * Owns one `.cnv` document and its undo history, independent of any DOM.\n *\n * The model is the single writer for document content. Construction parses a private copy of the\n * argument, every commit replaces the document with a new immutable snapshot, and each change is\n * delivered through {@link CanvasModel.onDidChangeContent}. Edits run one at a time, and a snapshot\n * becomes visible only after `prepare` resolved, so the host can resolve libraries, validate\n * bindings and synchronize the widget runtime before anyone observes the new content.\n */\nexport class CanvasModel {\n readonly #content = new Emitter<CanvasDocument>();\n #prepare: ((next: CanvasDocument) => Promise<void>) | undefined;\n #document: CanvasDocument;\n #past: CanvasDocument[] = [];\n #future: CanvasDocument[] = [];\n #queue: Promise<void> = Promise.resolve();\n #disposed = false;\n\n /** Fires after every committed change with the new snapshot; rejected edits do not fire it. */\n readonly onDidChangeContent: Event<CanvasDocument> = this.#content.event;\n\n /**\n * @param document Initial content; it is parsed into a private copy, so the caller keeps\n * ownership of its own object and later mutations of it never reach the model.\n * @param prepare Preparation of the next snapshot. It must resolve before the snapshot is\n * committed and may reject to reject the edit, leaving document and history untouched.\n * @throws {SchematicError} when `document` is not a valid `.cnv` document.\n */\n constructor(document: CanvasDocument, prepare?: (next: CanvasDocument) => Promise<void>) {\n this.#document = parseCanvas(document);\n this.#prepare = prepare;\n }\n\n /** Current snapshot; the same reference until the next commit replaces it. */\n get document(): CanvasDocument {\n return this.#document;\n }\n\n get canUndo(): boolean {\n return this.#past.length > 0;\n }\n\n get canRedo(): boolean {\n return this.#future.length > 0;\n }\n\n whenIdle(): Promise<void> {\n return this.#queue;\n }\n\n /**\n * Applies one command as one undoable edit.\n *\n * Commands are derived from the document as it is when they reach the front of the queue, so\n * concurrent calls never interleave and a later command always sees the earlier commit.\n *\n * @throws {SchematicError} when the command is invalid, or when `prepare` rejects; the content\n * stays untouched in either case.\n */\n async apply(command: CanvasCommand): Promise<void> {\n return this.applyMany([command]);\n }\n\n async applyMany(commands: readonly CanvasCommand[]): Promise<void> {\n this.#assertAlive();\n if (commands.length === 0) return this.whenIdle();\n return this.transform((document) =>\n commands.reduce((next, command) => applyCanvasCommand(next, command), document),\n );\n }\n\n /** Prepare one complete transaction before changing content or history. */\n async transform(update: (document: CanvasDocument) => CanvasDocument): Promise<void> {\n this.#assertAlive();\n await this.#enqueue(async () => {\n if (this.#disposed) return;\n const next = parseCanvas(update(this.#document));\n if (!(await this.#prepareSnapshot(next))) return;\n this.#commit(next);\n });\n }\n\n /**\n * Restores the previous snapshot as one change. `prepare` runs for the restored snapshot too,\n * because the widget runtime has to follow the document back to that state.\n */\n async undo(): Promise<void> {\n this.#assertAlive();\n await this.#enqueue(async () => {\n if (this.#disposed) return;\n const previous = this.#past[this.#past.length - 1];\n if (previous === undefined) return;\n if (!(await this.#prepareSnapshot(previous))) return;\n this.#past.pop();\n this.#future.push(this.#document);\n this.#document = previous;\n this.#content.fire(previous);\n });\n }\n\n /** Reapplies the last undone snapshot, through the same preparation as {@link CanvasModel.undo}. */\n async redo(): Promise<void> {\n this.#assertAlive();\n await this.#enqueue(async () => {\n if (this.#disposed) return;\n const next = this.#future[this.#future.length - 1];\n if (next === undefined) return;\n if (!(await this.#prepareSnapshot(next))) return;\n this.#future.pop();\n this.#past.push(this.#document);\n this.#document = next;\n this.#content.fire(next);\n });\n }\n\n /**\n * Releases the change event and drops the history. A preparation still in flight resolves into\n * no commit, so a disposed model never changes its document again; calls made afterwards reject.\n */\n dispose(): void {\n if (this.#disposed) return;\n this.#disposed = true;\n this.#prepare = undefined;\n this.#past = [];\n this.#future = [];\n this.#content.dispose();\n }\n\n #commit(next: CanvasDocument): void {\n this.#past.push(this.#document);\n if (this.#past.length > HISTORY_LIMIT) {\n this.#past.shift();\n }\n this.#future = [];\n this.#document = next;\n this.#content.fire(next);\n }\n\n /** @returns false when the model was disposed while `prepare` was pending. */\n async #prepareSnapshot(next: CanvasDocument): Promise<boolean> {\n const prepare = this.#prepare;\n if (prepare === undefined) {\n return !this.#disposed;\n }\n try {\n await prepare(next);\n } catch (error) {\n // A rejected preparation of a disposed model is teardown noise, not a caller's error.\n if (this.#disposed) return false;\n throw error;\n }\n return !this.#disposed;\n }\n\n #enqueue(run: () => Promise<void>): Promise<void> {\n const pending = this.#queue.then(run);\n // A rejected edit must not poison the queue: the next operation starts from a settled chain.\n this.#queue = pending.then(\n () => undefined,\n () => undefined,\n );\n return pending;\n }\n\n #assertAlive(): void {\n if (this.#disposed) throw new Error('Canvas model is disposed.');\n }\n}\n","import { parseCanvas, type CanvasCommand } from '@mica-js/document/canvas';\nimport { createDecorator } from '../instantiation';\nimport { IFileSystemProvider } from '../provider-services';\nimport { ICanvasConfiguration, ICanvasSession } from './session';\nimport { CanvasModel } from './model';\n\nexport class CanvasDocumentService {\n #model: CanvasModel | undefined;\n #disposed = false;\n\n constructor(\n @ICanvasConfiguration private readonly configuration: ICanvasConfiguration,\n @IFileSystemProvider private readonly files: IFileSystemProvider,\n @ICanvasSession private readonly session: ICanvasSession,\n ) {}\n\n async initialize(): Promise<void> {\n const bytes = await this.files.read(this.configuration.uri);\n this.#assertAlive();\n const document = parseCanvas(new TextDecoder('utf-8', { fatal: true }).decode(bytes));\n await this.session.synchronize(document);\n this.#assertAlive();\n this.#model = new CanvasModel(document, (next) => this.session.synchronize(next));\n }\n\n get model(): CanvasModel {\n this.#assertAlive();\n if (!this.#model) throw new Error('Canvas document is not initialized.');\n return this.#model;\n }\n apply(command: CanvasCommand): Promise<void> {\n return this.model.apply(command);\n }\n undo(): Promise<void> {\n return this.model.undo();\n }\n redo(): Promise<void> {\n return this.model.redo();\n }\n dispose(): void {\n this.#disposed = true;\n this.#model?.dispose();\n this.#model = undefined;\n }\n #assertAlive(): void {\n if (this.#disposed) throw new Error('Canvas document is disposed.');\n }\n}\nexport const ICanvasDocumentService =\n createDecorator<CanvasDocumentService>('editor.canvasDocument');\n","import { DisposableStore } from '@mica-js/core/lifecycle';\nimport type {\n CanvasDocument,\n CanvasWidgetInstance,\n WidgetPlacement,\n} from '@mica-js/document/canvas';\nimport type { WidgetInputEvent } from '@mica-js/widget';\nimport type { CanvasModel } from './model';\nimport type { ICanvasTarget } from '../canvas-host';\nimport { canvasSnapshot } from '../canvas-host';\nimport type { IEditorPointerEvent } from '../host';\n\n/** A point in document units; one unit is one CSS pixel on the unzoomed surface. */\nexport interface ICanvasPoint {\n readonly x: number;\n readonly y: number;\n}\n\n/** Axis-aligned rectangle in document units. */\nexport interface ICanvasRect {\n readonly x: number;\n readonly y: number;\n readonly width: number;\n readonly height: number;\n}\n\n/** Corner handle of the selected widget instance. */\nexport type ICanvasHandle = 'nw' | 'ne' | 'se' | 'sw';\n\n/** Pan and zoom of the surface; `x`/`y` are the screen offset of the document origin. */\nexport interface ICanvasViewport {\n readonly x: number;\n readonly y: number;\n readonly scale: number;\n}\n\n/** Corners in draw order: top-left, top-right, bottom-right, bottom-left. */\nexport const CANVAS_CORNER_HANDLES: readonly ICanvasHandle[] = ['nw', 'ne', 'se', 'sw'];\n/** Smallest width and height a resize produces, in document units. */\nexport const CANVAS_MIN_INSTANCE_SIZE = 1;\n/** Edge length of a square corner handle, in CSS pixels. */\nexport const CANVAS_HANDLE_SIZE = 8;\n/** Radius around a handle that starts a resize or rotation, in CSS pixels. */\nexport const CANVAS_HANDLE_HIT_RADIUS = 8;\n/** Distance from the top edge to the rotation handle center, in CSS pixels. */\nexport const CANVAS_ROTATION_HANDLE_OFFSET = 24;\n/** A press must travel this far before it becomes a drag, so a click never nudges. */\nexport const CANVAS_DRAG_THRESHOLD = 3;\n/** Smallest and largest zoom a wheel, the zoom methods or {@link fitViewport} produce. */\nexport const CANVAS_MIN_ZOOM = 0.1;\nexport const CANVAS_MAX_ZOOM = 8;\n/** Factor of one {@link ICanvasView.zoomIn} / {@link ICanvasView.zoomOut} step. */\nexport const CANVAS_ZOOM_FACTOR = 1.2;\n/** Screen-space margin {@link fitViewport} keeps around the document bounds. */\nexport const CANVAS_FIT_PADDING = 24;\n/** Exponent per wheel pixel: `scale * exp(-deltaY * CANVAS_WHEEL_ZOOM_RATE)`. */\nexport const CANVAS_WHEEL_ZOOM_RATE = 0.0015;\n/** Document units between two grid lines at 100 %; the step adapts to the zoom. */\nexport const CANVAS_GRID_STEP = 10;\n/** Smallest on-screen distance between two grid lines, in CSS pixels. */\nexport const CANVAS_GRID_MIN_SCREEN = 8;\n\n/** Viewport with no pan and no zoom. */\nexport const CANVAS_IDENTITY_VIEWPORT: ICanvasViewport = { x: 0, y: 0, scale: 1 };\n\nconst BACKGROUND = '#f4f4f5';\nconst GRID_STROKE = '#e4e4e7';\nconst PLACEHOLDER_FILL = '#ffffff';\nconst PLACEHOLDER_STROKE = '#a1a1aa';\nconst SELECTION_STROKE = '#2563eb';\nconst HANDLE_FILL = '#ffffff';\nconst HANDLE_STROKE = '#2563eb';\n\nexport function degreesToRadians(degrees: number): number {\n return (degrees * Math.PI) / 180;\n}\n\n/** Clamps a zoom to the supported range; NaN or non-positive values fall back to the minimum. */\nexport function clampCanvasZoom(scale: number): number {\n if (Number.isNaN(scale) || scale <= 0) return CANVAS_MIN_ZOOM;\n return Math.min(CANVAS_MAX_ZOOM, Math.max(CANVAS_MIN_ZOOM, scale));\n}\n\n/** Screen (CSS pixel) point → document units. */\nexport function viewportToDocument(\n viewport: ICanvasViewport,\n screenPoint: ICanvasPoint,\n): ICanvasPoint {\n return {\n x: (screenPoint.x - viewport.x) / viewport.scale,\n y: (screenPoint.y - viewport.y) / viewport.scale,\n };\n}\n\n/** Document units → screen (CSS pixel) point. */\nexport function documentToViewport(viewport: ICanvasViewport, point: ICanvasPoint): ICanvasPoint {\n return {\n x: point.x * viewport.scale + viewport.x,\n y: point.y * viewport.scale + viewport.y,\n };\n}\n\n/**\n * Zooms around a screen point, keeping the document point under it in place.\n * The result is clamped to {@link CANVAS_MIN_ZOOM}..{@link CANVAS_MAX_ZOOM}.\n */\nexport function zoomViewportAt(\n viewport: ICanvasViewport,\n screenPoint: ICanvasPoint,\n scale: number,\n): ICanvasViewport {\n const next = clampCanvasZoom(scale);\n if (next === viewport.scale) {\n return viewport;\n }\n const anchor = viewportToDocument(viewport, screenPoint);\n return {\n scale: next,\n x: screenPoint.x - anchor.x * next,\n y: screenPoint.y - anchor.y * next,\n };\n}\n\n/**\n * Fits document bounds into a `width` × `height` surface with `padding` screen pixels on each\n * side, centering them. Empty bounds reset the viewport.\n */\nexport function fitViewport(\n bounds: ICanvasRect | undefined,\n width: number,\n height: number,\n padding = CANVAS_FIT_PADDING,\n): ICanvasViewport {\n if (bounds === undefined || bounds.width <= 0 || bounds.height <= 0) {\n return CANVAS_IDENTITY_VIEWPORT;\n }\n const availableWidth = Math.max(1, width - padding * 2);\n const availableHeight = Math.max(1, height - padding * 2);\n const scale = clampCanvasZoom(\n Math.min(availableWidth / bounds.width, availableHeight / bounds.height),\n );\n const center = { x: bounds.x + bounds.width / 2, y: bounds.y + bounds.height / 2 };\n return {\n scale,\n x: width / 2 - center.x * scale,\n y: height / 2 - center.y * scale,\n };\n}\n\n/** Document-unit distance between two grid lines at `scale`, never below the screen minimum. */\nexport function canvasGridStep(scale: number): number {\n const zoom = Number.isFinite(scale) && scale > 0 ? scale : 1;\n let step = CANVAS_GRID_STEP;\n while (step * zoom < CANVAS_GRID_MIN_SCREEN) {\n step *= 10;\n }\n while (step * zoom > CANVAS_GRID_MIN_SCREEN * 10) {\n step /= 10;\n }\n return step;\n}\n\n/** Union of the rotation-aware bounds of every instance; `undefined` for an empty canvas. */\nfunction canvasDocumentBounds(widgets: readonly CanvasWidgetInstance[]): ICanvasRect | undefined {\n if (widgets.length === 0) {\n return undefined;\n }\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const widget of widgets) {\n for (const corner of canvasPlacementCorners(widget)) {\n minX = Math.min(minX, corner.x);\n minY = Math.min(minY, corner.y);\n maxX = Math.max(maxX, corner.x);\n maxY = Math.max(maxY, corner.y);\n }\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/** Rotates a vector clockwise, matching `CanvasRenderingContext2D.rotate`. */\nexport function rotateCanvasVector(vector: ICanvasPoint, degrees: number): ICanvasPoint {\n const radians = degreesToRadians(degrees);\n const cos = Math.cos(radians);\n const sin = Math.sin(radians);\n return { x: vector.x * cos - vector.y * sin, y: vector.x * sin + vector.y * cos };\n}\n\nexport function canvasPlacementCenter(placement: WidgetPlacement): ICanvasPoint {\n return { x: placement.x + placement.width / 2, y: placement.y + placement.height / 2 };\n}\n\n/** Document point → offset from the instance center with the instance rotation removed. */\nexport function canvasPointToLocal(placement: WidgetPlacement, point: ICanvasPoint): ICanvasPoint {\n const center = canvasPlacementCenter(placement);\n return rotateCanvasVector({ x: point.x - center.x, y: point.y - center.y }, -placement.rotation);\n}\n\n/** Offset from the instance center in its unrotated frame → document point. */\nexport function canvasLocalToPoint(placement: WidgetPlacement, local: ICanvasPoint): ICanvasPoint {\n const center = canvasPlacementCenter(placement);\n const offset = rotateCanvasVector(local, placement.rotation);\n return { x: center.x + offset.x, y: center.y + offset.y };\n}\n\n/** True when `point` is inside the rotation-aware rectangle of `placement`. */\nexport function containsCanvasPoint(placement: WidgetPlacement, point: ICanvasPoint): boolean {\n const local = canvasPointToLocal(placement, point);\n return Math.abs(local.x) <= placement.width / 2 && Math.abs(local.y) <= placement.height / 2;\n}\n\n/** Topmost instance under `point`; the last entry paints above the earlier ones. */\nexport function hitTestCanvasInstance<T extends WidgetPlacement & { readonly id: string }>(\n instances: readonly T[],\n point: ICanvasPoint,\n): T | undefined {\n for (let index = instances.length - 1; index >= 0; index -= 1) {\n const instance = instances[index];\n if (instance !== undefined && containsCanvasPoint(instance, point)) {\n return instance;\n }\n }\n return undefined;\n}\n\nexport function canvasPlacementCorners(placement: WidgetPlacement): readonly ICanvasPoint[] {\n const halfWidth = placement.width / 2;\n const halfHeight = placement.height / 2;\n return [\n canvasLocalToPoint(placement, { x: -halfWidth, y: -halfHeight }),\n canvasLocalToPoint(placement, { x: halfWidth, y: -halfHeight }),\n canvasLocalToPoint(placement, { x: halfWidth, y: halfHeight }),\n canvasLocalToPoint(placement, { x: -halfWidth, y: halfHeight }),\n ];\n}\n\n/** Axis-aligned bounding box of the rotated instance. */\nexport function canvasPlacementBounds(placement: WidgetPlacement): ICanvasRect {\n let minX = Infinity;\n let minY = Infinity;\n let maxX = -Infinity;\n let maxY = -Infinity;\n for (const corner of canvasPlacementCorners(placement)) {\n minX = Math.min(minX, corner.x);\n minY = Math.min(minY, corner.y);\n maxX = Math.max(maxX, corner.x);\n maxY = Math.max(maxY, corner.y);\n }\n return { x: minX, y: minY, width: maxX - minX, height: maxY - minY };\n}\n\n/** Corner handle positions in document units. */\nexport function canvasHandlePoints(\n placement: WidgetPlacement,\n): Readonly<Record<ICanvasHandle, ICanvasPoint>> {\n const halfWidth = placement.width / 2;\n const halfHeight = placement.height / 2;\n const at = (x: number, y: number): ICanvasPoint => canvasLocalToPoint(placement, { x, y });\n return {\n nw: at(-halfWidth, -halfHeight),\n ne: at(halfWidth, -halfHeight),\n se: at(halfWidth, halfHeight),\n sw: at(-halfWidth, halfHeight),\n };\n}\n\nfunction canvasResizeCursor(handle: ICanvasHandle, rotation: number): string {\n const diagonal = handle === 'nw' || handle === 'se' ? 45 : 135;\n const direction = ((Math.round((rotation + diagonal) / 45) % 4) + 4) % 4;\n return ['ew-resize', 'nwse-resize', 'ns-resize', 'nesw-resize'][direction]!;\n}\n\n/** Rotation handle in document units, a constant screen distance above the rotated top edge. */\nexport function canvasRotationHandlePoint(placement: WidgetPlacement, scale = 1): ICanvasPoint {\n return canvasLocalToPoint(placement, {\n x: 0,\n y: -placement.height / 2 - CANVAS_ROTATION_HANDLE_OFFSET / scale,\n });\n}\n\n/** Rotation handle hit test with a constant CSS-pixel radius at the current zoom. */\nexport function hitTestCanvasRotationHandle(\n placement: WidgetPlacement,\n point: ICanvasPoint,\n scale = 1,\n): boolean {\n const handle = canvasRotationHandlePoint(placement, scale);\n return Math.hypot(handle.x - point.x, handle.y - point.y) <= CANVAS_HANDLE_HIT_RADIUS / scale;\n}\n\n/** Rotates around the fixed center, preserving the pointer-down offset within the handle. */\nexport function rotateCanvasPlacement(\n placement: WidgetPlacement,\n origin: ICanvasPoint,\n pointer: ICanvasPoint,\n): WidgetPlacement {\n const center = canvasPlacementCenter(placement);\n const start = { x: origin.x - center.x, y: origin.y - center.y };\n const end = { x: pointer.x - center.x, y: pointer.y - center.y };\n if (Math.hypot(start.x, start.y) === 0 || Math.hypot(end.x, end.y) === 0) return placement;\n const delta =\n (Math.atan2(start.x * end.y - start.y * end.x, start.x * end.x + start.y * end.y) * 180) /\n Math.PI;\n // Returning to the baseline must not create an edit from floating-point noise.\n if (Math.abs(delta) < 1e-10) return placement;\n return { ...placement, rotation: placement.rotation + delta };\n}\n\n/** Nearest corner handle within `radius`; corners do not overlap, so the first match wins. */\nexport function hitTestCanvasHandle(\n placement: WidgetPlacement,\n point: ICanvasPoint,\n radius = CANVAS_HANDLE_HIT_RADIUS,\n): ICanvasHandle | undefined {\n const points = canvasHandlePoints(placement);\n for (const handle of CANVAS_CORNER_HANDLES) {\n const handlePoint = points[handle];\n if (Math.hypot(handlePoint.x - point.x, handlePoint.y - point.y) <= radius) {\n return handle;\n }\n }\n return undefined;\n}\n\n/**\n * Drags one corner to `pointer` and returns the new placement.\n *\n * The opposite corner stays where it is and the rotation is preserved, so a rotated instance is\n * resized along its own axes. Sizes are clamped to `minSize`.\n */\nexport function resizeCanvasPlacement(\n placement: WidgetPlacement,\n handle: ICanvasHandle,\n pointer: ICanvasPoint,\n minSize = CANVAS_MIN_INSTANCE_SIZE,\n): WidgetPlacement {\n const center = canvasPlacementCenter(placement);\n const local = canvasPointToLocal(placement, pointer);\n const halfWidth = placement.width / 2;\n const halfHeight = placement.height / 2;\n\n let width: number;\n if (handle === 'ne' || handle === 'se') {\n width = Math.max(minSize, local.x + halfWidth);\n } else {\n width = Math.max(minSize, halfWidth - local.x);\n }\n let height: number;\n if (handle === 'se' || handle === 'sw') {\n height = Math.max(minSize, local.y + halfHeight);\n } else {\n height = Math.max(minSize, halfHeight - local.y);\n }\n\n // `left`/`top` place the new top-left corner in the old center's frame: the dragged corner\n // moves, the opposite one stays pinned.\n const left = handle === 'ne' || handle === 'se' ? -halfWidth : halfWidth - width;\n const top = handle === 'se' || handle === 'sw' ? -halfHeight : halfHeight - height;\n const offset = rotateCanvasVector(\n { x: left + width / 2, y: top + height / 2 },\n placement.rotation,\n );\n const centerX = center.x + offset.x;\n const centerY = center.y + offset.y;\n\n return {\n x: centerX - width / 2,\n y: centerY - height / 2,\n width,\n height,\n rotation: placement.rotation,\n };\n}\n\n/**\n * Document point → widget-local logical units, with the origin at the widget's top-left corner.\n * The result matches `WidgetInputEvent.x` / `.y`.\n */\nexport function widgetPointFromCanvas(\n placement: WidgetPlacement,\n point: ICanvasPoint,\n): ICanvasPoint {\n const local = canvasPointToLocal(placement, point);\n return { x: local.x + placement.width / 2, y: local.y + placement.height / 2 };\n}\n\n/** One rendered widget frame, owned by the host that runs the widget runtime. */\nexport interface ICanvasFrame {\n readonly bitmap: ImageBitmap;\n readonly width: number;\n readonly height: number;\n readonly dpr: number;\n}\n\nexport interface ICanvasViewOptions {\n /** Caller-provided container; the view only appends and removes its own canvas. */\n readonly container: HTMLElement;\n readonly model: CanvasModel;\n /** Disables every document edit; selection and simulation input keep working. */\n readonly readOnly?: boolean;\n /** Latest rendered frame of one instance, or `undefined` while the runtime has none. */\n readonly getFrame: (id: string) => ICanvasFrame | undefined;\n /** Forwards one simulation pointer event to a widget instance. */\n readonly onDispatch: (instanceId: string, event: WidgetInputEvent) => Promise<void>;\n /** Whether the widgets are running; only then is pointer input forwarded. */\n readonly isSimulation: () => boolean;\n /** Receives rendering, dispatch and document failures; the view keeps running. */\n readonly onError?: (error: unknown, source?: 'render' | 'runtime' | 'command') => void;\n readonly onSelectionChange?: (selection: readonly ICanvasTarget[]) => void;\n readonly onClick?: (event: IEditorPointerEvent<ICanvasTarget>) => void;\n readonly onDoubleClick?: (event: IEditorPointerEvent<ICanvasTarget>) => void;\n readonly onContextMenu?: (event: IEditorPointerEvent<ICanvasTarget>) => void;\n}\n\nexport interface ICanvasView {\n getSelection(): readonly ICanvasTarget[];\n setSelection(selection: readonly ICanvasTarget[]): void;\n /** Redraws the current document; also runs on model changes and container resizes. */\n render(): void;\n /** Zooms in one step around the surface center. */\n zoomIn(): void;\n /** Zooms out one step around the surface center. */\n zoomOut(): void;\n /** Restores the identity viewport: no pan, 100 % zoom. */\n resetView(): void;\n /** Fits the rotated widget bounds into the surface with padding; an empty canvas resets. */\n fitView(): void;\n dispose(): void;\n}\n\ntype Gesture =\n | { readonly kind: 'pan'; readonly origin: ICanvasPoint; readonly start: ICanvasViewport }\n | { readonly kind: 'forward'; readonly instanceId: string }\n | {\n readonly kind: 'press';\n readonly instanceId: string;\n readonly start: WidgetPlacement;\n readonly origin: ICanvasPoint;\n }\n | {\n readonly kind: 'drag';\n readonly instanceId: string;\n readonly start: WidgetPlacement;\n readonly origin: ICanvasPoint;\n }\n | {\n readonly kind: 'resize';\n readonly instanceId: string;\n readonly start: WidgetPlacement;\n readonly handle: ICanvasHandle;\n }\n | {\n readonly kind: 'rotate';\n readonly instanceId: string;\n readonly start: WidgetPlacement;\n readonly origin: ICanvasPoint;\n };\n\ninterface IPreview {\n readonly instanceId: string;\n readonly placement: WidgetPlacement;\n}\n\n/**\n * Canvas2D surface over one {@link CanvasModel}.\n *\n * The view draws the document in drawing order, applies each instance rotation and draws the\n * selected instance with its resize and rotation handles. It renders on model changes, container resizes and\n * explicit {@link ICanvasView.render} calls; it has no clock of its own, so the host decides when\n * a new widget frame becomes visible.\n */\nclass CanvasView implements ICanvasView {\n readonly #options: ICanvasViewOptions;\n readonly #canvas: HTMLCanvasElement;\n readonly #context: CanvasRenderingContext2D | null;\n readonly #subscriptions = new DisposableStore();\n readonly #cleanups: (() => void)[] = [];\n #observer: ResizeObserver | undefined;\n #width = 1;\n #height = 1;\n #dpr = 1;\n #viewport: ICanvasViewport = CANVAS_IDENTITY_VIEWPORT;\n #spaceHeld = false;\n #selectedId: string | undefined;\n #gesture: Gesture | undefined;\n #preview: IPreview | undefined;\n #pointerId: number | undefined;\n #disposed = false;\n #hostPress:\n | { pointerId: number; origin: ICanvasPoint; target: ICanvasTarget | null; moved: boolean }\n | undefined;\n #suppressDoubleClick = false;\n\n constructor(options: ICanvasViewOptions) {\n this.#options = options;\n const canvas = options.container.ownerDocument.createElement('canvas');\n canvas.className = 'mica-canvas';\n canvas.tabIndex = 0;\n options.container.append(canvas);\n this.#canvas = canvas;\n this.#context = canvas.getContext('2d');\n this.#listen('pointerdown', (event) => {\n this.#handlePointerDown(event);\n this.#observePress(event);\n });\n this.#listen('pointermove', (event) => {\n this.#observeMove(event);\n this.#handlePointerMove(event);\n });\n this.#listen('pointerup', (event) => {\n this.#handlePointerUp(event);\n this.#observeRelease(event);\n });\n this.#listen('pointercancel', (event) => {\n this.#hostPress = undefined;\n this.#handlePointerCancel(event);\n });\n this.#listen('dblclick', (event) => {\n if (!this.#suppressDoubleClick) this.#options.onDoubleClick?.(this.#hostEvent(event));\n });\n this.#listen('contextmenu', (event) => {\n const payload = this.#hostEvent(event);\n this.#setSelection(payload.target?.id);\n this.#options.onContextMenu?.(payload);\n });\n this.#listen('lostpointercapture', () => this.#handleLostPointerCapture());\n this.#listen('keydown', (event) => this.#handleKeyDown(event));\n this.#listen('keyup', (event) => this.#handleKeyUp(event));\n this.#listen('blur', () => this.#handleBlur());\n this.#listen('wheel', (event) => this.#handleWheel(event), { passive: false });\n // Middle-button drag pans; the browser would otherwise start its own autoscroll.\n this.#listen('mousedown', (event) => {\n if (event.button === 1) event.preventDefault();\n });\n this.#listen('auxclick', (event) => {\n if (event.button === 1) event.preventDefault();\n });\n this.#subscriptions.add(options.model.onDidChangeContent(() => this.#handleModelChange()));\n this.#observeSize();\n this.#syncSize();\n this.render();\n }\n\n getSelection(): readonly ICanvasTarget[] {\n return canvasSnapshot(\n this.#selectedId === undefined ? [] : [{ kind: 'widget', id: this.#selectedId }],\n );\n }\n\n setSelection(selection: readonly ICanvasTarget[]): void {\n if (this.#disposed) throw new Error('Canvas view is disposed.');\n if (selection.length > 1) throw new Error('Canvas supports only a single selection.');\n const target = selection[0];\n if (target && (target.kind !== 'widget' || !this.#findInstance(target.id))) {\n throw new Error(`Unknown canvas selection target \"${target.id}\".`);\n }\n this.#setSelection(target?.id);\n }\n\n #hostEvent(event: MouseEvent): IEditorPointerEvent<ICanvasTarget> {\n const position = viewportToDocument(this.#viewport, this.#pointerScreenPoint(event));\n const hit = hitTestCanvasInstance(this.#options.model.document.widgets, position);\n return canvasSnapshot({\n target: hit ? { kind: 'widget' as const, id: hit.id } : null,\n position,\n clientPosition: { x: event.clientX, y: event.clientY },\n button: event.button,\n altKey: event.altKey ?? false,\n ctrlKey: event.ctrlKey ?? false,\n metaKey: event.metaKey ?? false,\n shiftKey: event.shiftKey ?? false,\n mode: this.#isSimulation() ? 'simulation' : 'edit',\n });\n }\n\n #observePress(event: PointerEvent): void {\n if (this.#disposed || this.#hostPress) return;\n const gesture = this.#gesture;\n const suppress =\n event.button !== 0 ||\n this.#isPanPress(event) ||\n gesture?.kind === 'resize' ||\n gesture?.kind === 'rotate';\n this.#suppressDoubleClick = suppress;\n if (suppress) return;\n const payload = this.#hostEvent(event);\n this.#setSelection(payload.target?.id);\n this.#hostPress = {\n pointerId: event.pointerId,\n origin: { x: event.clientX, y: event.clientY },\n target: payload.target,\n moved: false,\n };\n }\n\n #observeMove(event: PointerEvent): void {\n const press = this.#hostPress;\n if (!press || press.pointerId !== event.pointerId) return;\n if (\n Math.hypot(event.clientX - press.origin.x, event.clientY - press.origin.y) >=\n CANVAS_DRAG_THRESHOLD\n ) {\n press.moved = true;\n this.#suppressDoubleClick = true;\n }\n }\n\n #observeRelease(event: PointerEvent): void {\n const press = this.#hostPress;\n if (!press || press.pointerId !== event.pointerId) return;\n this.#observeMove(event);\n this.#hostPress = undefined;\n const payload = this.#hostEvent(event);\n if (!press.moved && press.target?.id === payload.target?.id) this.#options.onClick?.(payload);\n }\n\n render(): void {\n if (this.#disposed) return;\n try {\n this.#render();\n } catch (error) {\n this.#report(error);\n }\n }\n\n #render(): void {\n const simulation = this.#isSimulation();\n const gesture = this.#gesture;\n if (\n (simulation || this.#readOnly) &&\n gesture !== undefined &&\n gesture.kind !== 'forward' &&\n gesture.kind !== 'pan'\n ) {\n this.#endGesture();\n }\n if (this.#observer === undefined) {\n // Without a ResizeObserver the layout is the only source of the surface size.\n this.#syncSize();\n } else if (this.#devicePixelRatio() !== this.#dpr) {\n this.#applySize(this.#width, this.#height);\n }\n const context = this.#context;\n if (context === null) return;\n const document = this.#options.model.document;\n const { scale, x, y } = this.#viewport;\n\n context.setTransform(this.#dpr, 0, 0, this.#dpr, 0, 0);\n context.fillStyle = BACKGROUND;\n context.fillRect(0, 0, this.#width, this.#height);\n context.setTransform(this.#dpr * scale, 0, 0, this.#dpr * scale, this.#dpr * x, this.#dpr * y);\n this.#drawGrid(context, scale);\n for (const instance of document.widgets) {\n this.#drawInstance(context, instance);\n }\n if (!simulation) {\n this.#drawSelection(context, document, scale);\n }\n }\n\n zoomIn(): void {\n this.#zoomBy(CANVAS_ZOOM_FACTOR);\n }\n\n zoomOut(): void {\n this.#zoomBy(1 / CANVAS_ZOOM_FACTOR);\n }\n\n resetView(): void {\n this.#setViewport(CANVAS_IDENTITY_VIEWPORT);\n }\n\n fitView(): void {\n this.#setViewport(\n fitViewport(\n canvasDocumentBounds(this.#options.model.document.widgets),\n this.#width,\n this.#height,\n ),\n );\n }\n\n dispose(): void {\n if (this.#disposed) return;\n this.#disposed = true;\n this.#spaceHeld = false;\n this.#endGesture();\n this.#subscriptions.dispose();\n this.#observer?.disconnect();\n this.#observer = undefined;\n for (const cleanup of this.#cleanups.splice(0)) {\n cleanup();\n }\n this.#canvas.remove();\n }\n\n #setViewport(viewport: ICanvasViewport): void {\n if (\n viewport.x === this.#viewport.x &&\n viewport.y === this.#viewport.y &&\n viewport.scale === this.#viewport.scale\n ) {\n return;\n }\n this.#viewport = viewport;\n this.render();\n }\n\n #zoomBy(factor: number): void {\n this.#setViewport(\n zoomViewportAt(\n this.#viewport,\n { x: this.#width / 2, y: this.#height / 2 },\n this.#viewport.scale * factor,\n ),\n );\n }\n\n #drawGrid(context: CanvasRenderingContext2D, scale: number): void {\n const step = canvasGridStep(scale);\n const topLeft = viewportToDocument(this.#viewport, { x: 0, y: 0 });\n const right = this.#width;\n const bottom = this.#height;\n const bottomRight = viewportToDocument(this.#viewport, { x: right, y: bottom });\n context.strokeStyle = GRID_STROKE;\n context.lineWidth = 1 / scale;\n context.beginPath();\n for (let x = Math.floor(topLeft.x / step) * step; x <= bottomRight.x; x += step) {\n context.moveTo(x, topLeft.y);\n context.lineTo(x, bottomRight.y);\n }\n for (let y = Math.floor(topLeft.y / step) * step; y <= bottomRight.y; y += step) {\n context.moveTo(topLeft.x, y);\n context.lineTo(bottomRight.x, y);\n }\n context.stroke();\n }\n\n #drawInstance(context: CanvasRenderingContext2D, instance: CanvasWidgetInstance): void {\n const preview = this.#preview;\n const placement =\n preview !== undefined && preview.instanceId === instance.id ? preview.placement : instance;\n const center = canvasPlacementCenter(placement);\n\n let frame: ICanvasFrame | undefined;\n try {\n frame = this.#options.getFrame(instance.id);\n } catch (error) {\n this.#report(error);\n }\n\n context.save();\n context.translate(center.x, center.y);\n context.rotate(degreesToRadians(placement.rotation));\n if (frame === undefined) {\n this.#drawPlaceholder(context, placement.width, placement.height);\n } else {\n try {\n context.drawImage(\n frame.bitmap,\n -placement.width / 2,\n -placement.height / 2,\n placement.width,\n placement.height,\n );\n } catch (error) {\n this.#report(error);\n this.#drawPlaceholder(context, placement.width, placement.height);\n }\n }\n context.restore();\n }\n\n #drawPlaceholder(context: CanvasRenderingContext2D, width: number, height: number): void {\n const { scale } = this.#viewport;\n context.fillStyle = PLACEHOLDER_FILL;\n context.fillRect(-width / 2, -height / 2, width, height);\n context.strokeStyle = PLACEHOLDER_STROKE;\n context.lineWidth = 1 / scale;\n context.setLineDash([4 / scale, 3 / scale]);\n context.strokeRect(-width / 2, -height / 2, width, height);\n context.setLineDash([]);\n }\n\n #drawSelection(context: CanvasRenderingContext2D, document: CanvasDocument, scale: number): void {\n const id = this.#selectedId;\n if (id === undefined) return;\n const instance = document.widgets.find((widget) => widget.id === id);\n if (instance === undefined) return;\n const preview = this.#preview;\n const placement =\n preview !== undefined && preview.instanceId === id ? preview.placement : instance;\n const center = canvasPlacementCenter(placement);\n\n context.save();\n context.translate(center.x, center.y);\n context.rotate(degreesToRadians(placement.rotation));\n context.strokeStyle = SELECTION_STROKE;\n context.lineWidth = 1.5 / scale;\n context.setLineDash([4 / scale, 3 / scale]);\n context.strokeRect(\n -placement.width / 2,\n -placement.height / 2,\n placement.width,\n placement.height,\n );\n context.setLineDash([]);\n context.restore();\n\n if (this.#readOnly) return;\n const points = canvasHandlePoints(placement);\n const size = CANVAS_HANDLE_SIZE / scale;\n const half = size / 2;\n context.fillStyle = HANDLE_FILL;\n context.strokeStyle = HANDLE_STROKE;\n context.lineWidth = 1 / scale;\n for (const handle of CANVAS_CORNER_HANDLES) {\n const point = points[handle];\n context.fillRect(point.x - half, point.y - half, size, size);\n context.strokeRect(point.x - half, point.y - half, size, size);\n }\n const top = canvasLocalToPoint(placement, { x: 0, y: -placement.height / 2 });\n const rotation = canvasRotationHandlePoint(placement, scale);\n context.beginPath();\n context.moveTo(top.x, top.y);\n context.lineTo(rotation.x, rotation.y);\n context.stroke();\n context.beginPath();\n context.arc(rotation.x, rotation.y, half, 0, Math.PI * 2);\n context.fill();\n context.stroke();\n }\n\n #handleModelChange(): void {\n if (this.#disposed) return;\n this.#pruneSelection();\n const gesture = this.#gesture;\n if (gesture !== undefined && gesture.kind !== 'forward' && gesture.kind !== 'pan') {\n // A document change during a gesture (undo, host command) invalidates its preview.\n this.#endGesture();\n }\n this.render();\n }\n\n #handlePointerDown(event: PointerEvent): void {\n if (this.#disposed || this.#gesture !== undefined) return;\n const screen = this.#pointerScreenPoint(event);\n this.#focus();\n if (this.#isPanPress(event)) {\n this.#beginGesture(event, { kind: 'pan', origin: screen, start: this.#viewport });\n return;\n }\n const point = viewportToDocument(this.#viewport, screen);\n if (this.#isSimulation()) {\n this.#startForward(event, point);\n return;\n }\n const document = this.#options.model.document;\n const selected = this.#selectedInstance(document);\n const scale = this.#viewport.scale;\n if (!this.#readOnly && selected !== undefined) {\n if (event.button === 0 && hitTestCanvasRotationHandle(selected, point, scale)) {\n this.#beginGesture(event, {\n kind: 'rotate',\n instanceId: selected.id,\n start: selected,\n origin: point,\n });\n return;\n }\n const handle = hitTestCanvasHandle(selected, point, CANVAS_HANDLE_HIT_RADIUS / scale);\n if (handle !== undefined) {\n this.#beginGesture(event, {\n kind: 'resize',\n instanceId: selected.id,\n start: selected,\n handle,\n });\n return;\n }\n }\n const hit = hitTestCanvasInstance(document.widgets, point);\n this.#setSelection(hit?.id);\n if (hit === undefined || this.#readOnly) return;\n this.#beginGesture(event, {\n kind: 'press',\n instanceId: hit.id,\n start: hit,\n origin: point,\n });\n }\n\n /** Middle-button drag and Space + left drag pan; neither ever edits or forwards input. */\n #isPanPress(event: PointerEvent): boolean {\n if (event.button === 1) return true;\n return this.#spaceHeld && event.button === 0;\n }\n\n #handlePointerMove(event: PointerEvent): void {\n const gesture = this.#gesture;\n if (this.#disposed) return;\n const screen = this.#pointerScreenPoint(event);\n if (gesture === undefined) {\n const selected = this.#selectedInstance(this.#options.model.document);\n let cursor = '';\n if (!this.#readOnly && !this.#isSimulation() && selected !== undefined) {\n const point = viewportToDocument(this.#viewport, screen);\n const scale = this.#viewport.scale;\n if (hitTestCanvasRotationHandle(selected, point, scale)) {\n cursor = 'grab';\n } else {\n const handle = hitTestCanvasHandle(selected, point, CANVAS_HANDLE_HIT_RADIUS / scale);\n if (handle !== undefined) cursor = canvasResizeCursor(handle, selected.rotation);\n }\n }\n this.#canvas.style.cursor = cursor;\n return;\n }\n if (!this.#ownsPointer(event)) return;\n\n if (gesture.kind === 'pan') {\n this.#setViewport({\n scale: gesture.start.scale,\n x: gesture.start.x + screen.x - gesture.origin.x,\n y: gesture.start.y + screen.y - gesture.origin.y,\n });\n return;\n }\n\n const point = viewportToDocument(this.#viewport, screen);\n if (gesture.kind === 'forward') {\n const instance = this.#findInstance(gesture.instanceId);\n if (!this.#isSimulation() || instance === undefined) {\n this.#endGesture();\n return;\n }\n this.#dispatch(gesture.instanceId, this.#pointerInput('pointermove', instance, point, event));\n return;\n }\n if (this.#readOnly || this.#isSimulation()) {\n this.#endGesture();\n this.render();\n return;\n }\n\n if (\n gesture.kind === 'rotate' &&\n this.#preview === undefined &&\n !this.#rotationDragMoved(gesture, point)\n ) {\n return;\n }\n let active = gesture;\n if (active.kind === 'press') {\n const distance =\n Math.hypot(point.x - active.origin.x, point.y - active.origin.y) * this.#viewport.scale;\n if (distance < CANVAS_DRAG_THRESHOLD) return;\n active = {\n kind: 'drag',\n instanceId: active.instanceId,\n start: active.start,\n origin: active.origin,\n };\n this.#gesture = active;\n }\n\n const placement =\n active.kind === 'drag'\n ? {\n ...active.start,\n x: active.start.x + point.x - active.origin.x,\n y: active.start.y + point.y - active.origin.y,\n }\n : active.kind === 'rotate'\n ? rotateCanvasPlacement(active.start, active.origin, point)\n : resizeCanvasPlacement(active.start, active.handle, point);\n this.#preview = { instanceId: active.instanceId, placement };\n this.render();\n }\n\n #handlePointerUp(event: PointerEvent): void {\n const gesture = this.#gesture;\n if (this.#disposed || gesture === undefined || !this.#ownsPointer(event)) return;\n const screen = this.#pointerScreenPoint(event);\n\n if (gesture.kind === 'pan') {\n // Panning changed only the local viewport; the document keeps its history.\n this.#setViewport({\n scale: gesture.start.scale,\n x: gesture.start.x + screen.x - gesture.origin.x,\n y: gesture.start.y + screen.y - gesture.origin.y,\n });\n this.#endGesture();\n return;\n }\n\n const point = viewportToDocument(this.#viewport, screen);\n if (gesture.kind === 'forward') {\n const instance = this.#findInstance(gesture.instanceId);\n if (this.#isSimulation() && instance !== undefined) {\n this.#dispatch(gesture.instanceId, this.#pointerInput('pointerup', instance, point, event));\n }\n this.#endGesture();\n return;\n }\n\n if (this.#isSimulation() || this.#readOnly) {\n // A mode switch during a gesture cancels it: simulation never edits the document.\n this.#endGesture();\n this.render();\n return;\n }\n\n const preview =\n gesture.kind === 'rotate' &&\n (this.#preview !== undefined || this.#rotationDragMoved(gesture, point))\n ? {\n instanceId: gesture.instanceId,\n placement: rotateCanvasPlacement(gesture.start, gesture.origin, point),\n }\n : this.#preview;\n const start = gesture.start;\n this.#endGesture();\n if (preview !== undefined && !samePlacement(preview.placement, start)) {\n this.#run(() =>\n this.#options.model.apply({\n type: 'set-placement',\n instanceId: preview.instanceId,\n placement: preview.placement,\n }),\n );\n return;\n }\n this.render();\n }\n\n #rotationDragMoved(gesture: Extract<Gesture, { kind: 'rotate' }>, point: ICanvasPoint): boolean {\n return (\n Math.hypot(point.x - gesture.origin.x, point.y - gesture.origin.y) * this.#viewport.scale >=\n CANVAS_DRAG_THRESHOLD\n );\n }\n\n #handlePointerCancel(event: PointerEvent): void {\n const gesture = this.#gesture;\n if (this.#disposed || gesture === undefined || !this.#ownsPointer(event)) return;\n if (gesture.kind === 'forward' && this.#isSimulation()) {\n const instance = this.#findInstance(gesture.instanceId);\n if (instance !== undefined) {\n const point = viewportToDocument(this.#viewport, this.#pointerScreenPoint(event));\n this.#dispatch(\n gesture.instanceId,\n this.#pointerInput('pointercancel', instance, point, event),\n );\n }\n }\n this.#endGesture();\n this.render();\n }\n\n /** Losing the capture ends a gesture; `pointerup` and `pointercancel` already sent their input. */\n #handleLostPointerCapture(): void {\n if (this.#disposed || this.#gesture === undefined) return;\n this.#endGesture();\n this.render();\n }\n\n #handleWheel(event: WheelEvent): void {\n if (this.#disposed) return;\n // The canvas owns its wheel gesture; the page keeps scrolling everywhere else.\n this.#preventDefault(event);\n const delta = wheelDelta(event, this.#height);\n if (delta === 0) return;\n const screen = this.#pointerScreenPoint(event);\n this.#setViewport(\n zoomViewportAt(\n this.#viewport,\n screen,\n this.#viewport.scale * Math.exp(-delta * CANVAS_WHEEL_ZOOM_RATE),\n ),\n );\n }\n\n #handleKeyDown(event: KeyboardEvent): void {\n if (this.#disposed) return;\n if (event.key === 'Escape' && this.#cancelEditGesture()) {\n this.#preventDefault(event);\n return;\n }\n if (isSpaceKey(event)) {\n // Space arms panning; keeping it from the page only matters while the canvas has focus.\n this.#spaceHeld = true;\n this.#preventDefault(event);\n return;\n }\n if (this.#spaceHeld || this.#readOnly || this.#isSimulation()) return;\n const modifier = event.ctrlKey === true || event.metaKey === true;\n const key = event.key.toLowerCase();\n if (modifier && key === 'z') {\n this.#preventDefault(event);\n this.#run(() =>\n event.shiftKey === true ? this.#options.model.redo() : this.#options.model.undo(),\n );\n return;\n }\n if (modifier && key === 'y') {\n this.#preventDefault(event);\n this.#run(() => this.#options.model.redo());\n return;\n }\n if (key === 'delete' || key === 'backspace') {\n const selected = this.#selectedInstance(this.#options.model.document);\n if (selected === undefined) return;\n this.#preventDefault(event);\n this.#run(() =>\n this.#options.model.apply({ type: 'remove-instance', instanceId: selected.id }),\n );\n }\n }\n\n #handleKeyUp(event: KeyboardEvent): void {\n if (isSpaceKey(event)) {\n this.#spaceHeld = false;\n }\n }\n\n #handleBlur(): void {\n this.#spaceHeld = false;\n this.#cancelEditGesture();\n }\n\n #cancelEditGesture(): boolean {\n const gesture = this.#gesture;\n if (gesture === undefined || gesture.kind === 'pan' || gesture.kind === 'forward') return false;\n this.#endGesture();\n this.render();\n return true;\n }\n\n #startForward(event: PointerEvent, point: ICanvasPoint): void {\n const hit = hitTestCanvasInstance(this.#options.model.document.widgets, point);\n if (hit === undefined) return;\n this.#beginGesture(event, { kind: 'forward', instanceId: hit.id });\n this.#dispatch(hit.id, this.#pointerInput('pointerdown', hit, point, event));\n }\n\n #pointerInput(\n type: string,\n placement: WidgetPlacement,\n point: ICanvasPoint,\n event: PointerEvent,\n ): WidgetInputEvent {\n const local = widgetPointFromCanvas(placement, point);\n return {\n type,\n x: local.x,\n y: local.y,\n button: typeof event.button === 'number' ? event.button : 0,\n buttons: typeof event.buttons === 'number' ? event.buttons : 0,\n altKey: event.altKey === true,\n ctrlKey: event.ctrlKey === true,\n metaKey: event.metaKey === true,\n shiftKey: event.shiftKey === true,\n };\n }\n\n #dispatch(instanceId: string, event: WidgetInputEvent): void {\n try {\n void this.#options\n .onDispatch(instanceId, event)\n .catch((error: unknown) => this.#report(error, 'runtime'));\n } catch (error) {\n this.#report(error, 'runtime');\n }\n }\n\n #run(operation: () => Promise<void>): void {\n const fail = (error: unknown): void => {\n this.#report(error, 'command');\n // A rejected edit or history step leaves the document unchanged; repaint it without the\n // gesture preview so the surface never shows geometry the document does not have.\n this.render();\n };\n try {\n void operation().catch(fail);\n } catch (error) {\n fail(error);\n }\n }\n\n #beginGesture(event: PointerEvent, gesture: Gesture): void {\n this.#gesture = gesture;\n this.#preview = undefined;\n this.#canvas.style.cursor =\n gesture.kind === 'rotate'\n ? 'grabbing'\n : gesture.kind === 'resize'\n ? canvasResizeCursor(gesture.handle, gesture.start.rotation)\n : '';\n const pointerId = event.pointerId;\n if (typeof pointerId === 'number' && Number.isFinite(pointerId)) {\n this.#pointerId = pointerId;\n try {\n this.#canvas.setPointerCapture(pointerId);\n } catch {\n // Capture is an optimization; a pointer that already ended still delivers its events.\n }\n } else {\n this.#pointerId = undefined;\n }\n }\n\n #endGesture(): void {\n const pointerId = this.#pointerId;\n this.#pointerId = undefined;\n this.#gesture = undefined;\n this.#preview = undefined;\n this.#canvas.style.cursor = '';\n if (pointerId === undefined || typeof this.#canvas.releasePointerCapture !== 'function') {\n return;\n }\n try {\n if (this.#canvas.hasPointerCapture?.(pointerId) !== false) {\n this.#canvas.releasePointerCapture(pointerId);\n }\n } catch {\n // The pointer may be gone already; losing the capture is harmless here.\n }\n }\n\n #ownsPointer(event: PointerEvent): boolean {\n const pointerId = this.#pointerId;\n if (pointerId === undefined) return true;\n return typeof event.pointerId !== 'number' || event.pointerId === pointerId;\n }\n\n #selectedInstance(document: CanvasDocument): CanvasWidgetInstance | undefined {\n const id = this.#selectedId;\n return id === undefined ? undefined : document.widgets.find((widget) => widget.id === id);\n }\n\n #findInstance(instanceId: string): CanvasWidgetInstance | undefined {\n return this.#options.model.document.widgets.find((widget) => widget.id === instanceId);\n }\n\n #setSelection(id: string | undefined): void {\n if (this.#selectedId === id) return;\n this.#selectedId = id;\n this.#options.onSelectionChange?.(this.getSelection());\n this.render();\n }\n\n #pruneSelection(): void {\n const id = this.#selectedId;\n if (id === undefined) return;\n if (!this.#options.model.document.widgets.some((widget) => widget.id === id)) {\n this.#setSelection(undefined);\n }\n }\n\n #pointerScreenPoint(event: MouseEvent | WheelEvent): ICanvasPoint {\n const rect =\n typeof this.#canvas.getBoundingClientRect === 'function'\n ? this.#canvas.getBoundingClientRect()\n : { left: 0, top: 0 };\n const clientX = typeof event.clientX === 'number' ? event.clientX : 0;\n const clientY = typeof event.clientY === 'number' ? event.clientY : 0;\n return { x: clientX - rect.left, y: clientY - rect.top };\n }\n\n #focus(): void {\n try {\n this.#canvas.focus({ preventScroll: true });\n } catch {\n // Focus is a convenience; hosts may embed the canvas without keyboard access.\n }\n }\n\n #preventDefault(event: KeyboardEvent | MouseEvent): void {\n if (typeof event.preventDefault === 'function') {\n event.preventDefault();\n }\n }\n\n #isSimulation(): boolean {\n try {\n return this.#options.isSimulation();\n } catch (error) {\n this.#report(error);\n return false;\n }\n }\n\n get #readOnly(): boolean {\n return this.#options.readOnly ?? false;\n }\n\n #report(error: unknown, source: 'render' | 'runtime' | 'command' = 'render'): void {\n const onError = this.#options.onError;\n if (onError === undefined) return;\n try {\n onError(error, source);\n } catch {\n // A broken error handler must not break rendering or input handling.\n }\n }\n\n #listen<T extends keyof HTMLElementEventMap>(\n type: T,\n handler: (event: HTMLElementEventMap[T]) => void,\n options?: AddEventListenerOptions,\n ): void {\n this.#canvas.addEventListener(type, handler, options);\n this.#cleanups.push(() => this.#canvas.removeEventListener(type, handler, options));\n }\n\n #observeSize(): void {\n if (typeof ResizeObserver !== 'function') return;\n const observer = new ResizeObserver((entries) => {\n const entry = entries[entries.length - 1];\n const content = entry?.contentRect;\n const width =\n content !== undefined && content.width > 0\n ? content.width\n : this.#options.container.clientWidth;\n const height =\n content !== undefined && content.height > 0\n ? content.height\n : this.#options.container.clientHeight;\n if (width <= 0 || height <= 0) return;\n this.#applySize(width, height);\n this.render();\n });\n observer.observe(this.#options.container);\n this.#observer = observer;\n }\n\n #syncSize(): void {\n const { clientWidth, clientHeight } = this.#options.container;\n this.#applySize(Math.max(1, clientWidth), Math.max(1, clientHeight));\n }\n\n #applySize(width: number, height: number): void {\n const dpr = this.#devicePixelRatio();\n const nextWidth = Math.max(1, Math.round(width));\n const nextHeight = Math.max(1, Math.round(height));\n const backingWidth = Math.max(1, Math.round(nextWidth * dpr));\n const backingHeight = Math.max(1, Math.round(nextHeight * dpr));\n if (this.#canvas.width !== backingWidth) {\n this.#canvas.width = backingWidth;\n }\n if (this.#canvas.height !== backingHeight) {\n this.#canvas.height = backingHeight;\n }\n this.#width = nextWidth;\n this.#height = nextHeight;\n this.#dpr = dpr;\n }\n\n #devicePixelRatio(): number {\n const view = this.#canvas.ownerDocument.defaultView;\n const ratio =\n view?.devicePixelRatio ??\n (typeof globalThis.devicePixelRatio === 'number' ? globalThis.devicePixelRatio : 1);\n return Number.isFinite(ratio) && ratio > 0 ? ratio : 1;\n }\n}\n\nfunction samePlacement(left: WidgetPlacement, right: WidgetPlacement): boolean {\n return (\n left.x === right.x &&\n left.y === right.y &&\n left.width === right.width &&\n left.height === right.height &&\n left.rotation === right.rotation\n );\n}\n\nfunction isSpaceKey(event: KeyboardEvent): boolean {\n return event.code === 'Space' || event.key === ' ';\n}\n\n/** Wheel delta in CSS pixels; line and page modes are normalized so zoom speed stays even. */\nfunction wheelDelta(event: WheelEvent, pageHeight: number): number {\n if (event.deltaMode === 1) return event.deltaY * 16;\n if (event.deltaMode === 2) return event.deltaY * Math.max(1, pageHeight);\n return event.deltaY;\n}\n\n/** Mounts one Canvas2D view over `options.model` and returns its handle. */\nexport function createCanvasView(options: ICanvasViewOptions): ICanvasView {\n return new CanvasView(options);\n}\n","import { DisposableStore, Emitter, type Event } from '@mica-js/core/lifecycle';\nimport {\n applyCanvasCommand,\n type CanvasCommand,\n type CanvasDocument,\n} from '@mica-js/document/canvas';\nimport type {\n EditorCommandArgs,\n IEditorErrorEvent,\n IEditorIntegrationState,\n IEditorPointerEvent,\n IEditorProperty,\n} from './host';\nimport type { ICanvasCommandMap } from './canvas-commands';\nimport { canvasSnapshot, type ICanvasTarget, type ICanvasBindingInfo } from './canvas-host';\nexport type { ICanvasCommandMap } from './canvas-commands';\nexport type { ICanvasTarget, ICanvasBindingInfo, ICanvasBindingCandidate } from './canvas-host';\nimport { Commands, ICommandService } from './commands';\nimport type { EditorState } from './editor';\nimport { InstantiationService, ServiceCollection, SyncDescriptor } from './instantiation';\nimport { IDeviceLibrary, IFileSystemProvider, IWidgetLibrary } from './provider-services';\nimport {\n DeviceLibraryResolver,\n IDeviceLibraryResolver,\n WidgetLibraryResolver,\n IWidgetLibraryResolver,\n} from './libraries';\nimport { ICanvasConfiguration, CanvasSession, ICanvasSession } from './canvas/session';\nimport { CanvasRuntimeFactory, ICanvasRuntimeFactory } from './canvas/runtime-factory';\nimport { CanvasDocumentService, ICanvasDocumentService } from './canvas/document';\nimport { createCanvasView } from './canvas/view';\nimport './canvas/styles.css';\n\nexport interface ICanvasEditorOptions {\n readonly container: HTMLElement;\n readonly uri: string;\n readonly fileSystem: IFileSystemProvider;\n readonly deviceLibrary: IDeviceLibrary;\n readonly widgetLibrary: IWidgetLibrary;\n /** Simulation step and target frame period in milliseconds; defaults to 20. */\n readonly stepMs?: number;\n readonly readOnly?: boolean;\n /** Fixed board voltages by exact schematic net name; ignored without a schematic. Ground stays zero. */\n readonly voltageReferences?: Readonly<Record<string, number>>;\n readonly projectRoot?: string;\n}\n\nexport interface ICanvasEditor {\n readonly uri: string;\n readonly state: EditorState;\n readonly onDidChangeContent: Event<CanvasDocument>;\n getDocument(): CanvasDocument;\n getSelection(): readonly ICanvasTarget[];\n setSelection(selection: readonly ICanvasTarget[]): void;\n readonly onDidChangeSelection: Event<readonly ICanvasTarget[]>;\n readonly onDidClick: Event<IEditorPointerEvent<ICanvasTarget>>;\n readonly onDidDoubleClick: Event<IEditorPointerEvent<ICanvasTarget>>;\n readonly onDidContextMenu: Event<IEditorPointerEvent<ICanvasTarget>>;\n getProperties(instanceId: string): readonly IEditorProperty[];\n getBindings(instanceId: string): readonly ICanvasBindingInfo[];\n getState(): IEditorIntegrationState;\n readonly onDidChangeState: Event<IEditorIntegrationState>;\n readonly onDidError: Event<IEditorErrorEvent>;\n executeCommand<K extends keyof ICanvasCommandMap>(\n id: K,\n ...args: EditorCommandArgs<ICanvasCommandMap[K]>\n ): Promise<ICanvasCommandMap[K]['result']>;\n dispose(): Promise<void>;\n}\n\nexport async function createCanvasEditor(options: ICanvasEditorOptions): Promise<ICanvasEditor> {\n const references = options.voltageReferences;\n if (\n references !== undefined &&\n (references === null ||\n typeof references !== 'object' ||\n (Object.getPrototypeOf(references) !== Object.prototype &&\n Object.getPrototypeOf(references) !== null) ||\n Reflect.ownKeys(references).some(\n (name) =>\n typeof name !== 'string' ||\n name.trim().length === 0 ||\n typeof references[name] !== 'number' ||\n !Number.isFinite(references[name]),\n ))\n ) {\n throw new Error(\n 'Expected a plain voltageReferences map with nonempty net names and finite numeric voltages',\n );\n }\n const uri = new URL(options.uri).href;\n const projectRoot =\n options.projectRoot === undefined ? new URL('.', uri).href : new URL(options.projectRoot).href;\n const root = projectRoot.endsWith('/') ? projectRoot : `${projectRoot}/`;\n const subscriptions = new DisposableStore();\n const content = new Emitter<CanvasDocument>();\n const selection = new Emitter<readonly ICanvasTarget[]>();\n const clicks = new Emitter<IEditorPointerEvent<ICanvasTarget>>();\n const doubleClicks = new Emitter<IEditorPointerEvent<ICanvasTarget>>();\n const contextMenus = new Emitter<IEditorPointerEvent<ICanvasTarget>>();\n const changes = new Emitter<IEditorIntegrationState>();\n const errors = new Emitter<IEditorErrorEvent>();\n const reportError = (source: IEditorErrorEvent['source'], error: unknown) => {\n let detached: unknown;\n try {\n detached = canvasSnapshot(error);\n } catch {\n detached = new Error('Editor operation failed with an uncloneable error.');\n }\n errors.fire(Object.freeze({ source, error: detached }));\n };\n for (const emitter of [content, selection, clicks, doubleClicks, contextMenus, changes, errors])\n subscriptions.add(emitter);\n const services = new ServiceCollection();\n services.set(IFileSystemProvider, options.fileSystem);\n services.set(IDeviceLibrary, options.deviceLibrary);\n services.set(IWidgetLibrary, options.widgetLibrary);\n services.set(ICanvasConfiguration, {\n uri,\n ...(options.projectRoot === undefined ? {} : { projectRoot: root }),\n container: options.container,\n ...(options.stepMs === undefined ? {} : { stepMs: options.stepMs }),\n ...(options.voltageReferences === undefined\n ? {}\n : { voltageReferences: Object.freeze(structuredClone(options.voltageReferences)) }),\n });\n services.set(ICommandService, new SyncDescriptor(Commands));\n services.set(IDeviceLibraryResolver, new SyncDescriptor(DeviceLibraryResolver));\n services.set(IWidgetLibraryResolver, new SyncDescriptor(WidgetLibraryResolver));\n services.set(ICanvasRuntimeFactory, new SyncDescriptor(CanvasRuntimeFactory));\n services.set(ICanvasSession, new SyncDescriptor(CanvasSession));\n services.set(ICanvasDocumentService, new SyncDescriptor(CanvasDocumentService));\n const scope = new InstantiationService(services);\n let view: ReturnType<typeof createCanvasView> | undefined;\n let repaint: { dispose(): void } | undefined;\n try {\n const document = scope.get(ICanvasDocumentService);\n await document.initialize();\n const session = scope.get(ICanvasSession);\n const readOnly = options.readOnly ?? false;\n view = createCanvasView({\n container: options.container,\n model: document.model,\n readOnly,\n getFrame: (id) => session.getFrame(id),\n isSimulation: () => session.mode === 'simulation',\n onDispatch: (id, event) => session.dispatch(id, event),\n onError: (error, source = 'render') => reportError(source, error),\n onSelectionChange: (value) => selection.fire(canvasSnapshot(value)),\n onClick: (event) => clicks.fire(canvasSnapshot(event)),\n onDoubleClick: (event) => doubleClicks.fire(canvasSnapshot(event)),\n onContextMenu: (event) => contextMenus.fire(canvasSnapshot(event)),\n });\n const mountedView = view;\n repaint = session.onDidRender(() => mountedView.render());\n const commands = scope.get(ICommandService);\n const assertWritable = () => {\n if (readOnly) throw new Error('Canvas editor is read-only.');\n if (session.mode !== 'edit')\n throw new Error('Switch to edit mode before changing the canvas.');\n };\n const register = <K extends keyof ICanvasCommandMap>(\n id: K,\n execute: (params: ICanvasCommandMap[K]['params']) => void | Promise<void>,\n ) => {\n commands.register({\n id,\n execute: (params) => execute(params as ICanvasCommandMap[K]['params']),\n });\n };\n const edit = (command: CanvasCommand) => {\n assertWritable();\n return document.apply(command);\n };\n register('canvas.setProperty', (params) => edit({ type: 'set-property', ...params }));\n register('canvas.removeProperty', (params) => edit({ type: 'unset-property', ...params }));\n register('canvas.setProperties', (params) => {\n assertWritable();\n return document.model.applyMany([\n ...(params.remove ?? []).map((key): CanvasCommand => ({\n type: 'unset-property',\n instanceId: params.instanceId,\n key,\n })),\n ...Object.entries(params.values).map(([key, value]): CanvasCommand => ({\n type: 'set-property',\n instanceId: params.instanceId,\n key,\n value,\n })),\n ]);\n });\n register('canvas.setBinding', (params) => edit({ type: 'set-binding', ...params }));\n register('canvas.setSchematic', ({ path, bindings = 'preserve' }) => {\n assertWritable();\n if (bindings !== 'preserve' && bindings !== 'clear')\n throw new TypeError('Invalid canvas bindings policy.');\n return document.model.transform((current) => {\n const next = applyCanvasCommand(current, { type: 'set-schematic', schematic: path });\n return path === null || bindings === 'clear'\n ? {\n ...next,\n widgets: next.widgets.map((instance) => {\n const copy = { ...instance };\n delete copy.bindings;\n return copy;\n }),\n }\n : next;\n });\n });\n register('canvas.addWidget', ({ instance, z }) =>\n edit({ type: 'add-instance', instance, z: z ?? document.model.document.widgets.length }),\n );\n register('canvas.removeWidget', (params) => edit({ type: 'remove-instance', ...params }));\n register('canvas.setPlacement', (params) => edit({ type: 'set-placement', ...params }));\n register('canvas.setZ', (params) => edit({ type: 'set-z', ...params }));\n commands.register({\n id: 'canvas.undo',\n execute: () => {\n assertWritable();\n return document.undo();\n },\n });\n commands.register({\n id: 'canvas.redo',\n execute: () => {\n assertWritable();\n return document.redo();\n },\n });\n commands.register({\n id: 'canvas.setMode',\n execute: async (params) => {\n await document.model.whenIdle();\n await session.setMode((params as ICanvasCommandMap['canvas.setMode']['params']).mode);\n mountedView.render();\n },\n });\n commands.register({ id: 'canvas.run', execute: () => session.run() });\n commands.register({ id: 'canvas.pause', execute: () => session.pause() });\n commands.register({ id: 'canvas.step', execute: () => session.step() });\n commands.register({ id: 'canvas.reset', execute: () => session.reset() });\n const getState = (): IEditorIntegrationState =>\n canvasSnapshot({\n readOnly,\n mode: session.mode,\n canUndo: !readOnly && session.mode === 'edit' && document.model.canUndo,\n canRedo: !readOnly && session.mode === 'edit' && document.model.canRedo,\n running: session.status.running,\n });\n let previousState = getState();\n const refreshState = () => {\n const next = getState();\n if (JSON.stringify(previousState) === JSON.stringify(next)) return;\n previousState = next;\n changes.fire(next);\n };\n subscriptions.add(\n document.model.onDidChangeContent((value) => {\n content.fire(canvasSnapshot(value));\n refreshState();\n }),\n );\n subscriptions.add(session.onDidChangeState(refreshState));\n subscriptions.add(session.onDidError((error) => reportError('runtime', error)));\n for (const action of ['zoomIn', 'zoomOut', 'resetView', 'fitView'] as const) {\n commands.register({ id: `canvas.${action}`, execute: () => mountedView[action]() });\n }\n let state: EditorState = 'ready';\n let execution: Promise<unknown> = Promise.resolve();\n let disposal: Promise<void> | undefined;\n return {\n uri,\n get state() {\n return state;\n },\n getDocument: () => canvasSnapshot(document.model.document),\n getSelection: () => mountedView.getSelection(),\n setSelection: (value) => mountedView.setSelection(canvasSnapshot(value)),\n getProperties: (instanceId) =>\n session.getProperties(instanceId, readOnly || session.mode !== 'edit'),\n getBindings: (instanceId) => session.getBindings(instanceId),\n getState,\n onDidChangeContent: content.event,\n onDidChangeSelection: selection.event,\n onDidClick: clicks.event,\n onDidDoubleClick: doubleClicks.event,\n onDidContextMenu: contextMenus.event,\n onDidChangeState: changes.event,\n onDidError: errors.event,\n async executeCommand<K extends keyof ICanvasCommandMap>(\n id: K,\n ...args: EditorCommandArgs<ICanvasCommandMap[K]>\n ): Promise<ICanvasCommandMap[K]['result']> {\n if (state !== 'ready') throw new Error('Canvas editor is disposed.');\n const captured = canvasSnapshot(args);\n const pending = execution.then(async () => {\n if (state !== 'ready') throw new Error('Canvas editor is disposed.');\n try {\n return (await commands.execute(id, ...captured)) as ICanvasCommandMap[K]['result'];\n } catch (error) {\n reportError('command', error);\n throw error;\n } finally {\n if (state === 'ready') refreshState();\n }\n });\n execution = pending.catch(() => undefined);\n return pending;\n },\n dispose() {\n if (disposal) return disposal;\n state = 'disposing';\n disposal = Promise.resolve().then(async () => {\n try {\n repaint?.dispose();\n subscriptions.dispose();\n mountedView.dispose();\n } finally {\n try {\n await scope.dispose();\n } finally {\n state = 'disposed';\n }\n }\n });\n return disposal;\n },\n };\n } catch (error) {\n const errors: unknown[] = [error];\n try {\n repaint?.dispose();\n subscriptions.dispose();\n view?.dispose();\n } catch (cleanupError) {\n errors.push(cleanupError);\n }\n try {\n await scope.dispose();\n } catch (cleanupError) {\n errors.push(cleanupError);\n }\n if (errors.length > 1)\n throw new AggregateError(errors, 'Canvas initialization and cleanup failed.', {\n cause: error,\n });\n throw error;\n }\n}\n"],"mappings":"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"}
|