graphics-debug 0.0.32 → 0.0.34

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.
@@ -143,7 +143,7 @@ function drawGraphicsToCanvas(graphics, target, options = {}) {
143
143
  ctx.fill();
144
144
  }
145
145
  if (circle.stroke) {
146
- ctx.strokeStyle = circle.stroke;
146
+ ctx.strokeStyle = circle.stroke ?? "transparent";
147
147
  ctx.stroke();
148
148
  }
149
149
  });
@@ -201,4 +201,4 @@ export {
201
201
  getBounds,
202
202
  drawGraphicsToCanvas
203
203
  };
204
- //# sourceMappingURL=chunk-CZLSXU7Y.js.map
204
+ //# sourceMappingURL=chunk-NJDYOUJ2.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../lib/drawGraphicsToCanvas.ts"],"sourcesContent":["import {\n compose,\n scale,\n translate,\n applyToPoint,\n type Matrix,\n} from \"transformation-matrix\"\nimport type {\n GraphicsObject,\n Viewbox,\n CenterViewbox,\n TransformOptions,\n} from \"./types\"\n\n/**\n * Computes a transformation matrix based on a provided viewbox\n * Handles both min/max style viewboxes and center/width/height style viewboxes\n */\nexport function computeTransformFromViewbox(\n viewbox: Viewbox | CenterViewbox,\n canvasWidth: number,\n canvasHeight: number,\n options: { padding?: number; yFlip?: boolean } = {},\n): Matrix {\n const padding = options.padding ?? 40\n const yFlip = options.yFlip ?? false\n\n // Convert CenterViewbox to Viewbox if needed\n let bounds: Viewbox\n if (\"center\" in viewbox) {\n const halfWidth = viewbox.width / 2\n const halfHeight = viewbox.height / 2\n bounds = {\n minX: viewbox.center.x - halfWidth,\n maxX: viewbox.center.x + halfWidth,\n minY: viewbox.center.y - halfHeight,\n maxY: viewbox.center.y + halfHeight,\n }\n } else {\n bounds = viewbox\n }\n\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n\n const scale_factor = Math.min(\n (canvasWidth - 2 * padding) / width,\n (canvasHeight - 2 * padding) / height,\n )\n\n return compose(\n translate(canvasWidth / 2, canvasHeight / 2),\n scale(scale_factor, yFlip ? -scale_factor : scale_factor),\n translate(-(bounds.minX + width / 2), -(bounds.minY + height / 2)),\n )\n}\n\n/**\n * Computes bounds for a graphics object\n */\nexport function getBounds(graphics: GraphicsObject): Viewbox {\n const points = [\n ...(graphics.points || []),\n ...(graphics.lines || []).flatMap((line) => line.points),\n ...(graphics.rects || []).flatMap((rect) => {\n const halfWidth = rect.width / 2\n const halfHeight = rect.height / 2\n return [\n { x: rect.center.x - halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x - halfWidth, y: rect.center.y + halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y + halfHeight },\n ]\n }),\n ...(graphics.circles || []).flatMap((circle) => [\n { x: circle.center.x - circle.radius, y: circle.center.y }, // left\n { x: circle.center.x + circle.radius, y: circle.center.y }, // right\n { x: circle.center.x, y: circle.center.y - circle.radius }, // top\n { x: circle.center.x, y: circle.center.y + circle.radius }, // bottom\n ]),\n ]\n\n if (points.length === 0) {\n return { minX: -1, maxX: 1, minY: -1, maxY: 1 }\n }\n\n return points.reduce(\n (bounds, point) => ({\n minX: Math.min(bounds.minX, point.x),\n maxX: Math.max(bounds.maxX, point.x),\n minY: Math.min(bounds.minY, point.y),\n maxY: Math.max(bounds.maxY, point.y),\n }),\n { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity },\n )\n}\n\n/**\n * Draws a graphics object onto a canvas or context\n * @param graphics - The graphics object to draw\n * @param target - The canvas element or 2D context to draw on\n * @param options - Options for controlling the transform and rendering\n */\nexport function drawGraphicsToCanvas(\n graphics: GraphicsObject,\n target: HTMLCanvasElement | CanvasRenderingContext2D,\n options: TransformOptions = {},\n): void {\n // Get the context\n const ctx =\n target instanceof HTMLCanvasElement ? target.getContext(\"2d\") : target\n\n if (!ctx) {\n throw new Error(\"Could not get 2D context from canvas\")\n }\n\n // Get canvas dimensions\n const canvasWidth =\n target instanceof HTMLCanvasElement ? target.width : target.canvas.width\n\n const canvasHeight =\n target instanceof HTMLCanvasElement ? target.height : target.canvas.height\n\n // Get or compute the transform matrix\n let matrix: Matrix\n\n if (options.transform) {\n matrix = options.transform\n } else if (options.viewbox) {\n matrix = computeTransformFromViewbox(\n options.viewbox,\n canvasWidth,\n canvasHeight,\n {\n padding: options.padding,\n yFlip: options.yFlip,\n },\n )\n } else {\n // Auto-compute bounds and transform if not provided\n const bounds = getBounds(graphics)\n const yFlip = graphics.coordinateSystem === \"cartesian\"\n matrix = computeTransformFromViewbox(bounds, canvasWidth, canvasHeight, {\n padding: options.padding ?? 40,\n yFlip,\n })\n }\n\n // Clear the canvas\n ctx.clearRect(0, 0, canvasWidth, canvasHeight)\n\n // Save the current transform state\n ctx.save()\n\n // Draw the graphics elements\n // Draw rectangles\n if (graphics.rects && graphics.rects.length > 0) {\n graphics.rects.forEach((rect) => {\n const halfWidth = rect.width / 2\n const halfHeight = rect.height / 2\n\n const topLeft = applyToPoint(matrix, {\n x: rect.center.x - halfWidth,\n y: rect.center.y - halfHeight,\n })\n\n const bottomRight = applyToPoint(matrix, {\n x: rect.center.x + halfWidth,\n y: rect.center.y + halfHeight,\n })\n\n const width = Math.abs(bottomRight.x - topLeft.x)\n const height = Math.abs(bottomRight.y - topLeft.y)\n\n ctx.beginPath()\n ctx.rect(\n Math.min(topLeft.x, bottomRight.x),\n Math.min(topLeft.y, bottomRight.y),\n width,\n height,\n )\n\n if (rect.fill) {\n ctx.fillStyle = rect.fill\n ctx.fill()\n }\n\n if (rect.stroke) {\n ctx.strokeStyle = rect.stroke\n ctx.stroke()\n }\n })\n }\n\n // Draw circles\n if (graphics.circles && graphics.circles.length > 0) {\n graphics.circles.forEach((circle) => {\n const projected = applyToPoint(matrix, circle.center)\n const scaledRadius = circle.radius * Math.abs(matrix.a) // Use matrix scale factor\n\n ctx.beginPath()\n ctx.arc(projected.x, projected.y, scaledRadius, 0, 2 * Math.PI)\n\n if (circle.fill) {\n ctx.fillStyle = circle.fill\n ctx.fill()\n }\n\n if (circle.stroke) {\n ctx.strokeStyle = circle.stroke ?? \"transparent\"\n ctx.stroke()\n }\n })\n }\n\n // Draw lines\n if (graphics.lines && graphics.lines.length > 0) {\n graphics.lines.forEach((line) => {\n if (line.points.length === 0) return\n\n ctx.beginPath()\n\n const firstPoint = applyToPoint(matrix, line.points[0])\n ctx.moveTo(firstPoint.x, firstPoint.y)\n\n for (let i = 1; i < line.points.length; i++) {\n const projected = applyToPoint(matrix, line.points[i])\n ctx.lineTo(projected.x, projected.y)\n }\n\n ctx.strokeStyle = line.strokeColor || \"black\"\n if (line.strokeWidth) {\n ctx.lineWidth = line.strokeWidth * matrix.a\n } else {\n ctx.lineWidth = 2\n }\n ctx.lineCap = \"round\"\n\n if (line.strokeDash) {\n if (typeof line.strokeDash === \"string\") {\n ctx.setLineDash(\n line.strokeDash\n .split(\",\")\n .map(Number)\n .map((n) => n * Math.abs(matrix.a)),\n )\n } else {\n ctx.setLineDash(line.strokeDash.map((n) => n * Math.abs(matrix.a)))\n }\n } else {\n ctx.setLineDash([])\n }\n\n ctx.stroke()\n })\n }\n\n // Draw points\n if (graphics.points && graphics.points.length > 0) {\n graphics.points.forEach((point) => {\n const projected = applyToPoint(matrix, point)\n\n // Draw point as a small circle\n ctx.beginPath()\n ctx.arc(projected.x, projected.y, 3, 0, 2 * Math.PI)\n ctx.fillStyle = point.color || \"black\"\n ctx.fill()\n\n // Draw label if present and labels aren't disabled\n if (point.label && !options.disableLabels) {\n ctx.fillStyle = point.color || \"black\"\n ctx.font = \"12px sans-serif\"\n ctx.fillText(point.label, projected.x + 5, projected.y - 5)\n }\n })\n }\n\n // Restore the original transform\n ctx.restore()\n}\n"],"mappings":"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","names":[]}
package/dist/cli/cli.js CHANGED
@@ -3,7 +3,7 @@ import {
3
3
  getHtmlFromLogString,
4
4
  getSvgsFromLogString
5
5
  } from "../chunk-KXJRUEMA.js";
6
- import "../chunk-CZLSXU7Y.js";
6
+ import "../chunk-NJDYOUJ2.js";
7
7
  import {
8
8
  getGraphicsObjectsFromLogString
9
9
  } from "../chunk-NG6H63SM.js";
@@ -2,7 +2,7 @@ import {
2
2
  computeTransformFromViewbox,
3
3
  drawGraphicsToCanvas,
4
4
  getBounds
5
- } from "../chunk-CZLSXU7Y.js";
5
+ } from "../chunk-NJDYOUJ2.js";
6
6
  export {
7
7
  computeTransformFromViewbox,
8
8
  drawGraphicsToCanvas,
package/dist/lib/index.js CHANGED
@@ -7,7 +7,7 @@ import {
7
7
  computeTransformFromViewbox,
8
8
  drawGraphicsToCanvas,
9
9
  getBounds
10
- } from "../chunk-CZLSXU7Y.js";
10
+ } from "../chunk-NJDYOUJ2.js";
11
11
  import {
12
12
  getGraphicsObjectsFromLogString
13
13
  } from "../chunk-NG6H63SM.js";
package/dist/lib/react.js CHANGED
@@ -2,7 +2,7 @@ import "../chunk-KXJRUEMA.js";
2
2
  import {
3
3
  drawGraphicsToCanvas,
4
4
  getBounds
5
- } from "../chunk-CZLSXU7Y.js";
5
+ } from "../chunk-NJDYOUJ2.js";
6
6
  import "../chunk-NG6H63SM.js";
7
7
  import "../chunk-A4VFIZRQ.js";
8
8
 
@@ -1085,25 +1085,38 @@ function InteractiveGraphicsCanvas({
1085
1085
  const [showLabels, setShowLabels] = useState7(showLabelsByDefault);
1086
1086
  const [showLastStep, setShowLastStep] = useState7(true);
1087
1087
  const maxStep = useMemo8(() => {
1088
- return Math.max(
1088
+ const maxPointStep = Math.max(
1089
1089
  0,
1090
- ...graphics.points?.map((p) => p.step ?? 0) ?? [],
1091
- ...graphics.lines?.map((l) => l.step ?? 0) ?? [],
1092
- ...graphics.rects?.map((r) => r.step ?? 0) ?? [],
1093
- ...graphics.circles?.map((c) => c.step ?? 0) ?? []
1090
+ ...graphics.points?.map(
1091
+ (p) => Number.isNaN(p.step) ? 0 : p.step || 0
1092
+ ) ?? []
1094
1093
  );
1094
+ const maxLineStep = Math.max(
1095
+ 0,
1096
+ ...graphics.lines?.map(
1097
+ (l) => Number.isNaN(l.step) ? 0 : l.step || 0
1098
+ ) ?? []
1099
+ );
1100
+ const maxRectStep = Math.max(
1101
+ 0,
1102
+ ...graphics.rects?.map(
1103
+ (r) => Number.isNaN(r.step) ? 0 : r.step || 0
1104
+ ) ?? []
1105
+ );
1106
+ const maxCircleStep = Math.max(
1107
+ 0,
1108
+ ...graphics.circles?.map(
1109
+ (c) => Number.isNaN(c.step) ? 0 : c.step || 0
1110
+ ) ?? []
1111
+ );
1112
+ return Math.max(maxPointStep, maxLineStep, maxRectStep, maxCircleStep);
1095
1113
  }, [graphics]);
1096
1114
  const filteredGraphics = useMemo8(() => {
1097
- if (activeStep === null) {
1115
+ const selectedStep = showLastStep ? maxStep : activeStep;
1116
+ if (selectedStep === null) {
1098
1117
  return graphics;
1099
1118
  }
1100
- const maxStep2 = Math.max(
1101
- ...graphics.points?.map((p) => p.step ?? 0) ?? [],
1102
- ...graphics.lines?.map((l) => l.step ?? 0) ?? [],
1103
- ...graphics.rects?.map((r) => r.step ?? 0) ?? [],
1104
- ...graphics.circles?.map((c) => c.step ?? 0) ?? []
1105
- );
1106
- const filterByStep = showLastStep ? (objStep) => objStep === void 0 || objStep === maxStep2 : activeStep ? (objStep) => objStep === void 0 || objStep === activeStep : () => true;
1119
+ const filterByStep = (objStep) => objStep === void 0 || objStep === selectedStep;
1107
1120
  return {
1108
1121
  ...graphics,
1109
1122
  points: graphics.points?.filter((p) => filterByStep(p.step)),
@@ -1111,7 +1124,7 @@ function InteractiveGraphicsCanvas({
1111
1124
  rects: graphics.rects?.filter((r) => filterByStep(r.step)),
1112
1125
  circles: graphics.circles?.filter((c) => filterByStep(c.step))
1113
1126
  };
1114
- }, [graphics, activeStep, showLastStep]);
1127
+ }, [graphics, activeStep, showLastStep, maxStep]);
1115
1128
  const graphicsBoundsWithPadding = useMemo8(() => {
1116
1129
  const bounds = getBounds(graphics);
1117
1130
  const width2 = bounds.maxX - bounds.minX;
@@ -1 +1 @@
1
- {"version":3,"sources":["../../site/components/InteractiveGraphics/InteractiveGraphics.tsx","../../site/components/InteractiveGraphics/Line.tsx","../../site/components/InteractiveGraphics/Tooltip.tsx","../../site/utils/distToLineSegment.ts","../../site/components/InteractiveGraphics/defaultColors.ts","../../site/utils/safeLighten.ts","../../site/components/InteractiveGraphics/Point.tsx","../../site/components/InteractiveGraphics/Rect.tsx","../../site/components/InteractiveGraphics/Circle.tsx","../../site/utils/getGraphicsBounds.ts","../../site/components/InteractiveGraphics/hooks/useIsPointOnScreen.ts","../../site/components/InteractiveGraphics/hooks/useDoesLineIntersectViewport.ts","../../site/components/InteractiveGraphics/hooks/useFilterLines.ts","../../site/components/InteractiveGraphics/hooks/useFilterPoints.ts","../../site/components/InteractiveGraphics/hooks/useFilterRects.ts","../../site/components/InteractiveGraphics/hooks/useFilterCircles.ts","../../site/components/DimensionOverlay.tsx","../../site/components/InteractiveGraphicsCanvas.tsx","../../site/components/CanvasGraphics/CanvasGraphics.tsx"],"sourcesContent":["import { compose, scale, translate } from \"transformation-matrix\"\nimport { GraphicsObject } from \"../../../lib\"\nimport { useMemo, useState } from \"react\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { InteractiveState } from \"./InteractiveState\"\nimport { SuperGrid } from \"react-supergrid\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { Line } from \"./Line\"\nimport { Point } from \"./Point\"\nimport { Rect } from \"./Rect\"\nimport { Circle } from \"./Circle\"\nimport { getGraphicsBounds } from \"site/utils/getGraphicsBounds\"\nimport {\n useIsPointOnScreen,\n useDoesLineIntersectViewport,\n useFilterLines,\n useFilterPoints,\n useFilterRects,\n useFilterCircles,\n} from \"./hooks\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\n\nexport type GraphicsObjectClickEvent = {\n type: \"point\" | \"line\" | \"rect\" | \"circle\"\n index: number\n object: any\n}\n\nexport const InteractiveGraphics = ({\n graphics,\n onObjectClicked,\n objectLimit,\n}: {\n graphics: GraphicsObject\n onObjectClicked?: (event: GraphicsObjectClickEvent) => void\n objectLimit?: number\n}) => {\n const [activeLayers, setActiveLayers] = useState<string[] | null>(null)\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const availableLayers: string[] = Array.from(\n new Set([\n ...(graphics.lines?.map((l) => l.layer!).filter(Boolean) ?? []),\n ...(graphics.rects?.map((r) => r.layer!).filter(Boolean) ?? []),\n ...(graphics.points?.map((p) => p.layer!).filter(Boolean) ?? []),\n ]),\n )\n const maxStep = Math.max(\n 0,\n ...(graphics.lines?.map((l) => l.step!).filter(Boolean) ?? []),\n ...(graphics.rects?.map((r) => r.step!).filter(Boolean) ?? []),\n ...(graphics.points?.map((p) => p.step!).filter(Boolean) ?? []),\n )\n\n const graphicsBoundsWithPadding = useMemo(() => {\n const actualBounds = getGraphicsBounds(graphics)\n const width = actualBounds.maxX - actualBounds.minX\n const height = actualBounds.maxY - actualBounds.minY\n return {\n minX: actualBounds.minX - width / 10,\n minY: actualBounds.minY - height / 10,\n maxX: actualBounds.maxX + width / 10,\n maxY: actualBounds.maxY + height / 10,\n }\n }, [graphics])\n\n const { transform: realToScreen, ref } = useMouseMatrixTransform({\n initialTransform: compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n ),\n })\n\n useResizeObserver(ref, (entry: ResizeObserverEntry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n const interactiveState: InteractiveState = {\n activeLayers: activeLayers,\n activeStep: activeStep,\n realToScreen: realToScreen,\n onObjectClicked: onObjectClicked,\n }\n\n const showToolbar = availableLayers.length > 1 || maxStep > 0\n\n // Use custom hooks for visibility checks and filtering\n const isPointOnScreen = useIsPointOnScreen(realToScreen, size)\n\n const doesLineIntersectViewport = useDoesLineIntersectViewport(\n realToScreen,\n size,\n )\n\n // Filter by layer and step\n const filterLayerAndStep = (obj: { layer?: string; step?: number }) => {\n if (activeLayers && obj.layer && !activeLayers.includes(obj.layer))\n return false\n if (\n activeStep !== null &&\n obj.step !== undefined &&\n obj.step !== activeStep\n )\n return false\n return true\n }\n\n const filterLines = useFilterLines(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterPoints = useFilterPoints(isPointOnScreen, filterLayerAndStep)\n\n const filterRects = useFilterRects(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterCircles = useFilterCircles(\n isPointOnScreen,\n filterLayerAndStep,\n realToScreen,\n size,\n )\n\n const filterAndLimit = <T,>(\n objects: T[] | undefined,\n filterFn: (obj: T) => boolean,\n ): (T & { originalIndex: number })[] => {\n if (!objects) return []\n const filtered = objects\n .map((obj, index) => ({ ...obj, originalIndex: index }))\n .filter(filterFn)\n return objectLimit ? filtered.slice(-objectLimit) : filtered\n }\n\n const filteredLines = useMemo(\n () => filterAndLimit(graphics.lines, filterLines),\n [graphics.lines, filterLines, objectLimit],\n )\n const filteredRects = useMemo(\n () => filterAndLimit(graphics.rects, filterRects),\n [graphics.rects, filterRects, objectLimit],\n )\n const filteredPoints = useMemo(\n () => filterAndLimit(graphics.points, filterPoints),\n [graphics.points, filterPoints, objectLimit],\n )\n const filteredCircles = useMemo(\n () => filterAndLimit(graphics.circles, filterCircles),\n [graphics.circles, filterCircles, objectLimit],\n )\n\n const totalFilteredObjects =\n filteredLines.length +\n filteredRects.length +\n filteredPoints.length +\n filteredCircles.length\n const isLimitReached = objectLimit && totalFilteredObjects > objectLimit\n\n return (\n <div>\n {showToolbar && (\n <div style={{ margin: 8 }}>\n {availableLayers.length > 1 && (\n <select\n value={activeLayers ? activeLayers[0] : \"\"}\n onChange={(e) => {\n const value = e.target.value\n setActiveLayers(value === \"\" ? null : [value])\n }}\n style={{ marginRight: 8 }}\n >\n <option value=\"\">All Layers</option>\n {availableLayers.map((layer) => (\n <option key={layer} value={layer}>\n {layer}\n </option>\n ))}\n </select>\n )}\n\n {maxStep > 0 && (\n <div\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 8 }}\n >\n Step:\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setActiveStep(Number.isNaN(value) ? null : value)\n }}\n disabled={activeStep === null}\n />\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n {isLimitReached && (\n <span style={{ color: \"red\", fontSize: \"12px\" }}>\n Display limited to {objectLimit} objects. Received:{\" \"}\n {totalFilteredObjects}.\n </span>\n )}\n </div>\n )}\n </div>\n )}\n\n <div\n ref={ref}\n style={{\n position: \"relative\",\n height: 600,\n overflow: \"hidden\",\n }}\n >\n <DimensionOverlay transform={realToScreen}>\n {filteredLines.map((line) => (\n <Line\n key={line.originalIndex}\n line={line}\n index={line.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredRects.map((rect) => (\n <Rect\n key={rect.originalIndex}\n rect={rect}\n index={rect.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredPoints.map((point) => (\n <Point\n key={point.originalIndex}\n point={point}\n index={point.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredCircles.map((circle) => (\n <Circle\n key={circle.originalIndex}\n circle={circle}\n index={circle.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n <SuperGrid\n stringifyCoord={(x, y) => `${x.toFixed(2)}, ${y.toFixed(2)}`}\n width={size.width}\n height={size.height}\n transform={realToScreen}\n />\n </DimensionOverlay>\n </div>\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { distToLineSegment } from \"site/utils/distToLineSegment\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Line = ({\n line,\n index,\n interactiveState,\n}: { line: Types.Line; index: number; interactiveState: InteractiveState }) => {\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const {\n points,\n layer,\n step,\n strokeColor,\n strokeWidth = 1 / realToScreen.a,\n strokeDash,\n } = line\n const [isHovered, setIsHovered] = useState(false)\n const [mousePos, setMousePos] = useState({ x: 0, y: 0 })\n\n const screenPoints = points.map((p) => applyToPoint(realToScreen, p))\n\n const handleMouseMove = (e: React.MouseEvent) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const mouseX = e.clientX - rect.left\n const mouseY = e.clientY - rect.top\n const hoverThreshold = 10 // pixels\n\n setMousePos({ x: mouseX, y: mouseY })\n\n // Check distance to each line segment\n let isNearLine = false\n for (let i = 0; i < screenPoints.length - 1; i++) {\n const dist = distToLineSegment(\n mouseX,\n mouseY,\n screenPoints[i].x,\n screenPoints[i].y,\n screenPoints[i + 1].x,\n screenPoints[i + 1].y,\n )\n if (dist < hoverThreshold) {\n isNearLine = true\n break\n }\n }\n\n setIsHovered(isNearLine)\n }\n\n const baseColor = strokeColor ?? defaultColors[index % defaultColors.length]\n\n return (\n <svg\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n onMouseMove={handleMouseMove}\n onMouseLeave={() => setIsHovered(false)}\n onClick={\n isHovered\n ? () =>\n onObjectClicked?.({\n type: \"line\",\n index,\n object: line,\n })\n : undefined\n }\n >\n <polyline\n points={screenPoints.map((p) => `${p.x},${p.y}`).join(\" \")}\n stroke={isHovered ? safeLighten(0.2, baseColor) : baseColor}\n fill=\"none\"\n strokeWidth={strokeWidth * realToScreen.a}\n strokeDasharray={\n !strokeDash\n ? undefined\n : typeof strokeDash === \"string\"\n ? strokeDash\n : `${strokeDash[0] * realToScreen.a}, ${strokeDash[1] * realToScreen.a}`\n }\n strokeLinecap=\"round\"\n />\n {isHovered && line.label && (\n <foreignObject\n x={mousePos.x}\n y={mousePos.y - 40}\n width={300}\n height={40}\n >\n <Tooltip text={line.label} />\n </foreignObject>\n )}\n </svg>\n )\n}\n","export const Tooltip = ({ text }: { text: string }) => {\n return (\n <div\n style={{\n background: \"white\",\n border: \"1px solid #ccc\",\n boxShadow: \"0 0 10px 0 rgba(0, 0, 0, 0.1)\",\n borderRadius: \"4px\",\n padding: \"4px 8px\",\n fontSize: \"12px\",\n minWidth: \"150px\",\n maxWidth: \"300px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"pre-wrap\",\n zIndex: 100,\n }}\n >\n {text}\n </div>\n )\n}\n","// Calculate distance from point to line segment\nexport const distToLineSegment = (\n px: number,\n py: number,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n) => {\n const A = px - x1\n const B = py - y1\n const C = x2 - x1\n const D = y2 - y1\n\n const dot = A * C + B * D\n const lenSq = C * C + D * D\n let param = -1\n\n if (lenSq !== 0) param = dot / lenSq\n\n let xx = 0\n let yy = 0\n\n if (param < 0) {\n xx = x1\n yy = y1\n } else if (param > 1) {\n xx = x2\n yy = y2\n } else {\n xx = x1 + param * C\n yy = y1 + param * D\n }\n\n const dx = px - xx\n const dy = py - yy\n return Math.sqrt(dx * dx + dy * dy)\n}\n","// These are default colors if no color is provided\n// colors are made based on the index of the item in the array\n\nexport const defaultColors = [\n \"rgba(239, 68, 68, 0.8)\", // red-300\n \"rgba(249, 115, 22, 0.8)\", // orange-300\n \"rgba(245, 158, 11, 0.8)\", // amber-300\n \"rgba(234, 179, 8, 0.8)\", // yellow-300\n \"rgba(132, 204, 22, 0.8)\", // lime-300\n \"rgba(34, 197, 94, 0.8)\", // green-300\n \"rgba(16, 185, 129, 0.8)\", // emerald-300\n \"rgba(20, 184, 166, 0.8)\", // teal-300\n \"rgba(6, 182, 212, 0.8)\", // cyan-300\n \"rgba(14, 165, 233, 0.8)\", // sky-300\n \"rgba(59, 130, 246, 0.8)\", // blue-300\n \"rgba(99, 102, 241, 0.8)\", // indigo-300\n \"rgba(139, 92, 246, 0.8)\", // violet-300\n \"rgba(168, 85, 247, 0.8)\", // purple-300\n \"rgba(217, 70, 239, 0.8)\", // fuchsia-300\n \"rgba(236, 72, 153, 0.8)\", // pink-300\n \"rgba(249, 168, 212, 0.8)\", // rose-300\n \"rgba(161, 161, 170, 0.8)\", // zinc-300\n]\n","import { lighten } from \"polished\"\n\nexport const safeLighten = (amount: number, color: string) => {\n try {\n return lighten(amount, color)\n } catch (e) {\n return color\n }\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Point = ({\n point,\n interactiveState,\n index,\n}: {\n point: Types.Point\n interactiveState: InteractiveState\n index: number\n}) => {\n const { color, label, layer, step } = point\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenPoint = applyToPoint(realToScreen, point)\n const size = 10\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenPoint.x - size / 2,\n top: screenPoint.y - size / 2,\n width: size,\n height: size,\n borderRadius: \"50%\",\n border: `2px solid ${\n isHovered\n ? safeLighten(\n 0.2,\n color ?? defaultColors[index % defaultColors.length],\n )\n : (color ?? defaultColors[index % defaultColors.length])\n }`,\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"point\",\n index,\n object: point,\n })\n }\n >\n {isHovered && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip\n text={`${label ? `${label}\\n` : \"\"}x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`}\n />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Rect = ({\n rect,\n interactiveState,\n index,\n}: {\n rect: Types.Rect\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, width, height, fill, stroke, layer, step } = rect\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenCenter = applyToPoint(realToScreen, center)\n const screenWidth = width * realToScreen.a\n const screenHeight = height * Math.abs(realToScreen.d)\n\n // Default style when neither fill nor stroke is specified\n const hasStrokeOrFill = fill !== undefined || stroke !== undefined\n\n let backgroundColor = hasStrokeOrFill ? fill || \"transparent\" : defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = safeLighten(0.2, stroke!)\n }\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenWidth / 2,\n top: screenCenter.y - screenHeight / 2,\n width: screenWidth,\n height: screenHeight,\n backgroundColor,\n border: stroke\n ? `2px solid ${isHovered ? safeLighten(0.2, stroke) : stroke}`\n : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"rect\",\n index,\n object: rect,\n })\n }\n >\n {isHovered && rect.label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={rect.label} />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Circle = ({\n circle,\n interactiveState,\n index,\n}: {\n circle: Types.Circle\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, radius, fill, stroke, layer, step, label } = circle\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n const screenCenter = applyToPoint(realToScreen, center)\n const screenRadius = radius * realToScreen.a\n let backgroundColor = fill || defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = stroke ? safeLighten(0.2, stroke) : stroke\n }\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenRadius,\n top: screenCenter.y - screenRadius,\n width: screenRadius * 2,\n height: screenRadius * 2,\n borderRadius: \"50%\",\n backgroundColor,\n border: stroke ? `2px solid ${stroke}` : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"circle\",\n index,\n object: circle,\n })\n }\n >\n {isHovered && label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={label} />\n </div>\n )}\n </div>\n )\n}\n","import { GraphicsObject } from \"lib/types\"\n\nexport const getGraphicsBounds = (graphics: GraphicsObject) => {\n const bounds = {\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n }\n for (const line of graphics.lines ?? []) {\n for (const point of line.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n }\n for (const rect of graphics.rects ?? []) {\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n bounds.minX = Math.min(bounds.minX, center.x - halfWidth)\n bounds.minY = Math.min(bounds.minY, center.y - halfHeight)\n bounds.maxX = Math.max(bounds.maxX, center.x + halfWidth)\n bounds.maxY = Math.max(bounds.maxY, center.y + halfHeight)\n }\n for (const point of graphics.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n return bounds\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\nexport const useIsPointOnScreen = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (point: { x: number; y: number }) => {\n const screenPoint = applyToPoint(realToScreen, point)\n return (\n screenPoint.x >= -OFFSCREEN_MARGIN &&\n screenPoint.x <= size.width + OFFSCREEN_MARGIN &&\n screenPoint.y >= -OFFSCREEN_MARGIN &&\n screenPoint.y <= size.height + OFFSCREEN_MARGIN\n )\n }\n }, [realToScreen, size])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\n\n// Margin in pixels for determining if elements are off-screen\nexport const OFFSCREEN_MARGIN = 5\n\nexport const useDoesLineIntersectViewport = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (p1: { x: number; y: number }, p2: { x: number; y: number }) => {\n // Convert real-world points to screen coordinates\n const sp1 = applyToPoint(realToScreen, p1)\n const sp2 = applyToPoint(realToScreen, p2)\n\n // Viewport boundaries with margin\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // If either point is inside the viewport, the line intersects\n if (\n (sp1.x >= left && sp1.x <= right && sp1.y >= top && sp1.y <= bottom) ||\n (sp2.x >= left && sp2.x <= right && sp2.y >= top && sp2.y <= bottom)\n ) {\n return true\n }\n\n // Helper function to check if a line intersects with a line segment\n const intersects = (\n a1: { x: number; y: number },\n a2: { x: number; y: number },\n b1: { x: number; y: number },\n b2: { x: number; y: number },\n ) => {\n // Line segment A is (a1, a2), line segment B is (b1, b2)\n const det =\n (a2.x - a1.x) * (b2.y - b1.y) - (a2.y - a1.y) * (b2.x - b1.x)\n\n // If lines are parallel or coincident, they don't intersect in a unique point\n if (det === 0) return false\n\n const lambda =\n ((b2.y - b1.y) * (b2.x - a1.x) + (b1.x - b2.x) * (b2.y - a1.y)) / det\n const gamma =\n ((a1.y - a2.y) * (b2.x - a1.x) + (a2.x - a1.x) * (b2.y - a1.y)) / det\n\n // Check if the intersection point is within both line segments\n return lambda >= 0 && lambda <= 1 && gamma >= 0 && gamma <= 1\n }\n\n // Check intersection with each edge of the viewport\n return (\n // Top edge\n intersects(sp1, sp2, { x: left, y: top }, { x: right, y: top }) ||\n // Right edge\n intersects(sp1, sp2, { x: right, y: top }, { x: right, y: bottom }) ||\n // Bottom edge\n intersects(sp1, sp2, { x: left, y: bottom }, { x: right, y: bottom }) ||\n // Left edge\n intersects(sp1, sp2, { x: left, y: top }, { x: left, y: bottom })\n )\n }\n }, [realToScreen, size])\n}\n","import { useMemo } from \"react\"\n\ntype Line = {\n points: Array<{ x: number; y: number }>\n layer?: string\n step?: number\n closed?: boolean\n}\n\nexport const useFilterLines = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (line: Line) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(line)) return false\n\n // Then check if any point of the line is visible\n if (line.points.some((p) => isPointOnScreen(p))) {\n return true\n }\n\n // If no points are visible, check if any line segment intersects the viewport\n for (let i = 0; i < line.points.length - 1; i++) {\n if (doesLineIntersectViewport(line.points[i], line.points[i + 1])) {\n return true\n }\n }\n\n // If it's a closed shape (polyline), check the last segment too\n if (line.points.length > 2 && line.closed) {\n if (\n doesLineIntersectViewport(\n line.points[line.points.length - 1],\n line.points[0],\n )\n ) {\n return true\n }\n }\n\n return false\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Point = {\n x: number\n y: number\n layer?: string\n step?: number\n}\n\nexport const useFilterPoints = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (point: Point) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(point)) return false\n\n // Then check if the point is visible\n return isPointOnScreen(point)\n }\n }, [isPointOnScreen, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Rect = {\n center: { x: number; y: number }\n width: number\n height: number\n layer?: string\n step?: number\n}\n\nexport const useFilterRects = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (rect: Rect) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(rect)) return false\n\n // For rectangles, check if any corner or the center is visible\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n\n const topLeft = { x: center.x - halfWidth, y: center.y - halfHeight }\n const topRight = { x: center.x + halfWidth, y: center.y - halfHeight }\n const bottomLeft = { x: center.x - halfWidth, y: center.y + halfHeight }\n const bottomRight = { x: center.x + halfWidth, y: center.y + halfHeight }\n\n // Check if any corner or center is visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen(topLeft) ||\n isPointOnScreen(topRight) ||\n isPointOnScreen(bottomLeft) ||\n isPointOnScreen(bottomRight)\n ) {\n return true\n }\n\n // Check if any edge of the rectangle intersects the viewport\n return (\n doesLineIntersectViewport(topLeft, topRight) ||\n doesLineIntersectViewport(topRight, bottomRight) ||\n doesLineIntersectViewport(bottomRight, bottomLeft) ||\n doesLineIntersectViewport(bottomLeft, topLeft)\n )\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\ntype Circle = {\n center: { x: number; y: number }\n radius: number\n layer?: string\n step?: number\n}\n\nexport const useFilterCircles = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (circle: Circle) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(circle)) return false\n\n // For circles, check if center is visible or if any cardinal point is visible\n const { center, radius } = circle\n\n // Check if center or cardinal points on the circle are visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen({ x: center.x + radius, y: center.y }) ||\n isPointOnScreen({ x: center.x - radius, y: center.y }) ||\n isPointOnScreen({ x: center.x, y: center.y + radius }) ||\n isPointOnScreen({ x: center.x, y: center.y - radius })\n ) {\n return true\n }\n\n // Check if the circle intersects the viewport\n // Convert to screen coordinates for viewport intersection test\n const screenCenter = applyToPoint(realToScreen, center)\n const scale = Math.abs(realToScreen.a) // Get the scale factor\n const screenRadius = radius * scale\n\n // Viewport boundaries\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // Check if the circle intersects with the viewport\n // Case 1: Circle center is inside the viewport horizontally but outside vertically\n if (screenCenter.x >= left && screenCenter.x <= right) {\n if (\n Math.abs(screenCenter.y - top) <= screenRadius ||\n Math.abs(screenCenter.y - bottom) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 2: Circle center is inside the viewport vertically but outside horizontally\n if (screenCenter.y >= top && screenCenter.y <= bottom) {\n if (\n Math.abs(screenCenter.x - left) <= screenRadius ||\n Math.abs(screenCenter.x - right) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 3: Circle center is outside the viewport, check corners\n const cornerDistanceSquared = (cornerX: number, cornerY: number) => {\n const dx = screenCenter.x - cornerX\n const dy = screenCenter.y - cornerY\n return dx * dx + dy * dy\n }\n\n const radiusSquared = screenRadius * screenRadius\n\n return (\n cornerDistanceSquared(left, top) <= radiusSquared ||\n cornerDistanceSquared(right, top) <= radiusSquared ||\n cornerDistanceSquared(left, bottom) <= radiusSquared ||\n cornerDistanceSquared(right, bottom) <= radiusSquared\n )\n }\n }, [isPointOnScreen, filterLayerAndStep, realToScreen, size])\n}\n","import React, { useEffect, useRef, useState } from \"react\"\nimport { applyToPoint, identity, inverse } from \"transformation-matrix\"\nimport type { Matrix } from \"transformation-matrix\"\n\ninterface Props {\n transform?: Matrix\n children: React.ReactNode\n}\n\nexport const DimensionOverlay: React.FC<Props> = ({ children, transform }) => {\n if (!transform) transform = identity()\n const [dimensionToolVisible, setDimensionToolVisible] = useState(false)\n const [dimensionToolStretching, setDimensionToolStretching] = useState(false)\n // Start of dimension tool line in real-world coordinates (not screen)\n const [dStart, setDStart] = useState({ x: 0, y: 0 })\n // End of dimension tool line in real-world coordinates (not screen)\n const [dEnd, setDEnd] = useState({ x: 0, y: 0 })\n const mousePosRef = useRef({ x: 0, y: 0 })\n const containerRef = useRef<HTMLDivElement | null>(null)\n const container = containerRef.current!\n const containerBounds = container?.getBoundingClientRect()\n\n const bindKeys = () => {\n const container = containerRef.current\n\n const down = (e: KeyboardEvent) => {\n if (e.key === \"d\") {\n setDStart({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDEnd({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDimensionToolVisible((visible: boolean) => !visible)\n setDimensionToolStretching(true)\n }\n if (e.key === \"Escape\") {\n setDimensionToolVisible(false)\n setDimensionToolStretching(false)\n }\n }\n\n const addKeyListener = () => {\n if (container) {\n window.addEventListener(\"keydown\", down)\n }\n }\n\n const removeKeyListener = () => {\n if (container) {\n window.removeEventListener(\"keydown\", down)\n }\n }\n\n if (container) {\n container.addEventListener(\"focus\", addKeyListener)\n container.addEventListener(\"blur\", removeKeyListener)\n container.addEventListener(\"mouseenter\", addKeyListener)\n container.addEventListener(\"mouseleave\", removeKeyListener)\n }\n return () => {\n if (container) {\n container.removeEventListener(\"focus\", addKeyListener)\n container.removeEventListener(\"blur\", removeKeyListener)\n container.removeEventListener(\"mouseenter\", addKeyListener)\n container.removeEventListener(\"mouseleave\", removeKeyListener)\n }\n }\n }\n\n useEffect(bindKeys, [containerBounds?.width, containerBounds?.height])\n\n const screenDStart = applyToPoint(transform, dStart)\n const screenDEnd = applyToPoint(transform, dEnd)\n\n const arrowScreenBounds = {\n left: Math.min(screenDStart.x, screenDEnd.x),\n right: Math.max(screenDStart.x, screenDEnd.x),\n top: Math.min(screenDStart.y, screenDEnd.y),\n bottom: Math.max(screenDStart.y, screenDEnd.y),\n flipX: screenDStart.x > screenDEnd.x,\n flipY: screenDStart.y > screenDEnd.y,\n width: 0,\n height: 0,\n }\n arrowScreenBounds.width = arrowScreenBounds.right - arrowScreenBounds.left\n arrowScreenBounds.height = arrowScreenBounds.bottom - arrowScreenBounds.top\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n style={{ position: \"relative\" }}\n onMouseMove={(e: React.MouseEvent<HTMLDivElement>) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const rwPoint = applyToPoint(inverse(transform!), { x, y })\n mousePosRef.current.x = rwPoint.x\n mousePosRef.current.y = rwPoint.y\n\n if (dimensionToolStretching) {\n setDEnd({ x: rwPoint.x, y: rwPoint.y })\n }\n }}\n onMouseDown={() => {\n if (dimensionToolStretching) {\n setDimensionToolStretching(false)\n } else if (dimensionToolVisible) {\n setDimensionToolVisible(false)\n }\n }}\n onMouseEnter={() => {\n if (containerRef.current) {\n bindKeys()\n }\n }}\n >\n {children}\n {dimensionToolVisible && (\n <>\n <div\n style={{\n position: \"absolute\",\n left: arrowScreenBounds.left,\n width: arrowScreenBounds.width,\n textAlign: \"center\",\n top: screenDStart.y + 2,\n color: \"red\",\n mixBlendMode: \"difference\",\n pointerEvents: \"none\",\n marginTop: arrowScreenBounds.flipY ? 0 : -20,\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n {Math.abs(dStart.x - dEnd.x).toFixed(2)}\n </div>\n <div\n style={{\n position: \"absolute\",\n left: screenDEnd.x,\n height: arrowScreenBounds.height,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n top: arrowScreenBounds.top,\n color: \"red\",\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n <div\n style={{\n marginLeft: arrowScreenBounds.flipX ? \"-100%\" : 4,\n paddingRight: 4,\n }}\n >\n {Math.abs(dStart.y - dEnd.y).toFixed(2)}\n </div>\n </div>\n <svg\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n zIndex: 30,\n }}\n width={containerBounds?.width || \"100%\"}\n height={containerBounds?.height || \"100%\"}\n >\n <defs>\n <marker\n id=\"head\"\n orient=\"auto\"\n markerWidth=\"3\"\n markerHeight=\"4\"\n refX=\"2\"\n refY=\"2\"\n >\n <path d=\"M0,0 V4 L2,2 Z\" fill=\"red\" />\n </marker>\n </defs>\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n markerEnd=\"url(#head)\"\n strokeWidth={1.5}\n fill=\"none\"\n stroke=\"red\"\n />\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDStart.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n <line\n x1={screenDEnd.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n </svg>\n <div\n style={{\n right: 0,\n bottom: 0,\n position: \"absolute\",\n color: \"red\",\n fontFamily: \"sans-serif\",\n fontSize: 12,\n margin: 4,\n }}\n >\n ({dStart.x.toFixed(2)},{dStart.y.toFixed(2)})<br />(\n {dEnd.x.toFixed(2)},{dEnd.y.toFixed(2)})<br />\n dist:{\" \"}\n {Math.sqrt(\n (dEnd.x - dStart.x) ** 2 + (dEnd.y - dStart.y) ** 2,\n ).toFixed(2)}\n </div>\n </>\n )}\n </div>\n )\n}\n","import React, { useRef, useEffect, useState, useMemo } from \"react\"\nimport { drawGraphicsToCanvas, getBounds, type GraphicsObject } from \"../../lib\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"./DimensionOverlay\"\n\ninterface InteractiveGraphicsCanvasProps {\n graphics: GraphicsObject\n showLabelsByDefault?: boolean\n showGrid?: boolean\n height?: number | string\n width?: number | string\n}\n\nexport function InteractiveGraphicsCanvas({\n graphics,\n showLabelsByDefault = true,\n showGrid = true,\n height = 500,\n width = \"100%\",\n}: InteractiveGraphicsCanvasProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [showLabels, setShowLabels] = useState(showLabelsByDefault)\n const [showLastStep, setShowLastStep] = useState(true)\n\n // Calculate the maximum step value from all graphics objects\n const maxStep = useMemo(() => {\n return Math.max(\n 0,\n ...(graphics.points?.map((p) => p.step ?? 0) ?? []),\n ...(graphics.lines?.map((l) => l.step ?? 0) ?? []),\n ...(graphics.rects?.map((r) => r.step ?? 0) ?? []),\n ...(graphics.circles?.map((c) => c.step ?? 0) ?? []),\n )\n }, [graphics])\n\n // Filter graphics objects based on step\n const filteredGraphics = useMemo(() => {\n if (activeStep === null) {\n return graphics\n }\n\n // If showLastStep is enabled and we're filtering by step, show everything up to and including the current step\n const maxStep = Math.max(\n ...(graphics.points?.map((p) => p.step ?? 0) ?? []),\n ...(graphics.lines?.map((l) => l.step ?? 0) ?? []),\n ...(graphics.rects?.map((r) => r.step ?? 0) ?? []),\n ...(graphics.circles?.map((c) => c.step ?? 0) ?? []),\n )\n const filterByStep = showLastStep\n ? (objStep?: number) => objStep === undefined || objStep === maxStep\n : activeStep\n ? (objStep?: number) => objStep === undefined || objStep === activeStep\n : () => true\n\n return {\n ...graphics,\n points: graphics.points?.filter((p) => filterByStep(p.step)),\n lines: graphics.lines?.filter((l) => filterByStep(l.step)),\n rects: graphics.rects?.filter((r) => filterByStep(r.step)),\n circles: graphics.circles?.filter((c) => filterByStep(c.step)),\n }\n }, [graphics, activeStep, showLastStep])\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = useMemo(() => {\n const bounds = getBounds(graphics)\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - width / 10,\n minY: bounds.minY - height / 10,\n maxX: bounds.maxX + width / 10,\n maxY: bounds.maxY + height / 10,\n }\n }, [graphics])\n\n // Use mouse transform hook for panning/zooming\n const { transform, ref: mouseTransformRef } = useMouseMatrixTransform({\n initialTransform: compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n ),\n })\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = () => {\n if (!canvasRef.current) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(filteredGraphics, canvasRef.current, {\n transform: transform,\n disableLabels: !showLabels,\n })\n\n // Draw a grid for reference if requested\n if (showGrid) {\n drawGrid(canvasRef.current, transform)\n }\n }\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: any) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Determine grid spacing based on zoom level\n const gridSize = 10\n\n // Draw vertical grid lines\n for (let x = -100; x <= 100; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -100 }, transform)\n const end = transformPoint({ x, y: 100 }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -100; y <= 100; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -100, y }, transform)\n const end = transformPoint({ x: 100, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: any) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [transform, size, filteredGraphics, showGrid, showLabels])\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: \"10px\" }}>\n {maxStep > 0 && (\n <div style={{ display: \"flex\", gap: \"12px\", alignItems: \"center\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setShowLastStep(false)\n setActiveStep(\n Number.isNaN(value) ? 0 : Math.min(value, maxStep),\n )\n }}\n disabled={activeStep === null}\n style={{ width: \"60px\" }}\n />\n\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLastStep}\n onChange={(e) => {\n setShowLastStep(e.target.checked)\n setActiveStep(null)\n }}\n />\n Show last step\n </label>\n </div>\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLabels}\n onChange={(e) => {\n setShowLabels(e.target.checked)\n }}\n />\n Show labels\n </label>\n </div>\n </div>\n )}\n\n <div\n ref={(node) => {\n // Using a callback ref approach\n containerRef.current = node\n // Apply the mouse transform ref if available\n if (mouseTransformRef && node) {\n mouseTransformRef.current = node\n }\n }}\n style={{\n position: \"relative\",\n width: width,\n height: height,\n border: \"1px solid #ccc\",\n overflow: \"hidden\",\n }}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width,\n height,\n }}\n />\n </div>\n </div>\n )\n}\n\nexport default InteractiveGraphicsCanvas\n","import React, { useRef, useEffect, useState } from \"react\"\nimport { GraphicsObject } from \"../../../lib/types\"\nimport {\n drawGraphicsToCanvas,\n getBounds,\n} from \"../../../lib/drawGraphicsToCanvas\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate, type Matrix } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\n\ninterface CanvasGraphicsProps {\n graphics: GraphicsObject\n width?: number\n height?: number\n withGrid?: boolean\n initialTransform?: Matrix\n disableLabels?: boolean\n}\n\n// Create a container component that handles the mouse matrix transform\nfunction TransformContainer({\n initialTransform,\n children,\n onTransformChange,\n}: {\n initialTransform: Matrix\n children: React.ReactNode\n onTransformChange: (transform: Matrix) => void\n}) {\n const { transform, ref } = useMouseMatrixTransform({\n initialTransform,\n })\n\n // Update parent with transform changes\n useEffect(() => {\n onTransformChange(transform)\n }, [transform, onTransformChange])\n\n return (\n <div\n ref={ref}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {children}\n </div>\n )\n}\n\nexport const CanvasGraphics = ({\n graphics,\n width = 600,\n height = 600,\n withGrid = true,\n disableLabels = false,\n initialTransform,\n}: CanvasGraphicsProps) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [size, setSize] = useState({ width, height })\n const [currentTransform, setCurrentTransform] = useState<Matrix | null>(null)\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = React.useMemo(() => {\n const bounds = getBounds(graphics)\n const bWidth = bounds.maxX - bounds.minX\n const bHeight = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - bWidth / 10,\n minY: bounds.minY - bHeight / 10,\n maxX: bounds.maxX + bWidth / 10,\n maxY: bounds.maxY + bHeight / 10,\n }\n }, [graphics])\n\n // Compute initial transform if not provided\n const computedInitialTransform = React.useMemo(() => {\n if (initialTransform) return initialTransform\n\n const yFlip = graphics.coordinateSystem === \"cartesian\"\n return compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n yFlip\n ? -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n )\n : Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n )\n }, [graphics, graphicsBoundsWithPadding, initialTransform, size])\n\n // Track transform changes from the mouse transform hook\n const handleTransformChange = React.useCallback((transform: Matrix) => {\n setCurrentTransform(transform)\n }, [])\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = React.useCallback(() => {\n if (!canvasRef.current || !currentTransform) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(graphics, canvasRef.current, {\n transform: currentTransform,\n disableLabels,\n })\n\n // Draw a grid for reference if enabled\n if (withGrid) {\n drawGrid(canvasRef.current, currentTransform)\n }\n }, [canvasRef, currentTransform, graphics, size, withGrid])\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: Matrix) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Calculate a good grid size based on zoom level\n // This is an approximate calculation\n const zoomLevel = Math.abs(transform.a) // Scale factor\n const gridSize = Math.pow(10, Math.floor(Math.log10(100 / zoomLevel)))\n\n const gridRange = Math.ceil(1000 / gridSize) * gridSize\n\n // Draw vertical grid lines\n for (let x = -gridRange; x <= gridRange; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -gridRange }, transform)\n const end = transformPoint({ x, y: gridRange }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -gridRange; y <= gridRange; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -gridRange, y }, transform)\n const end = transformPoint({ x: gridRange, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: Matrix) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [drawCanvas])\n\n // Initialize transform\n useEffect(() => {\n setCurrentTransform(computedInitialTransform)\n }, [computedInitialTransform])\n\n return (\n <div\n ref={containerRef}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: `${height}px`,\n border: \"1px solid #eee\",\n overflow: \"hidden\",\n }}\n >\n <TransformContainer\n initialTransform={computedInitialTransform}\n onTransformChange={handleTransformChange}\n >\n <DimensionOverlay\n transform={currentTransform || computedInitialTransform}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n />\n </DimensionOverlay>\n </TransformContainer>\n </div>\n )\n}\n"],"mappings":"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","names":["useMemo","useState","jsx","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useMemo","applyToPoint","useMemo","applyToPoint","useMemo","useMemo","useMemo","applyToPoint","useMemo","useMemo","applyToPoint","scale","useState","applyToPoint","jsx","jsxs","container","jsx","jsxs","useState","useMemo","useRef","useEffect","useState","useMemo","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","jsxs","useRef","useState","useMemo","maxStep","width","height","transform","useEffect","React","useRef","useEffect","useState","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","useMouseMatrixTransform","useEffect","useRef","useState","React","compose","translate","scale","useResizeObserver"]}
1
+ {"version":3,"sources":["../../site/components/InteractiveGraphics/InteractiveGraphics.tsx","../../site/components/InteractiveGraphics/Line.tsx","../../site/components/InteractiveGraphics/Tooltip.tsx","../../site/utils/distToLineSegment.ts","../../site/components/InteractiveGraphics/defaultColors.ts","../../site/utils/safeLighten.ts","../../site/components/InteractiveGraphics/Point.tsx","../../site/components/InteractiveGraphics/Rect.tsx","../../site/components/InteractiveGraphics/Circle.tsx","../../site/utils/getGraphicsBounds.ts","../../site/components/InteractiveGraphics/hooks/useIsPointOnScreen.ts","../../site/components/InteractiveGraphics/hooks/useDoesLineIntersectViewport.ts","../../site/components/InteractiveGraphics/hooks/useFilterLines.ts","../../site/components/InteractiveGraphics/hooks/useFilterPoints.ts","../../site/components/InteractiveGraphics/hooks/useFilterRects.ts","../../site/components/InteractiveGraphics/hooks/useFilterCircles.ts","../../site/components/DimensionOverlay.tsx","../../site/components/InteractiveGraphicsCanvas.tsx","../../site/components/CanvasGraphics/CanvasGraphics.tsx"],"sourcesContent":["import { compose, scale, translate } from \"transformation-matrix\"\nimport { GraphicsObject } from \"../../../lib\"\nimport { useMemo, useState } from \"react\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { InteractiveState } from \"./InteractiveState\"\nimport { SuperGrid } from \"react-supergrid\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { Line } from \"./Line\"\nimport { Point } from \"./Point\"\nimport { Rect } from \"./Rect\"\nimport { Circle } from \"./Circle\"\nimport { getGraphicsBounds } from \"site/utils/getGraphicsBounds\"\nimport {\n useIsPointOnScreen,\n useDoesLineIntersectViewport,\n useFilterLines,\n useFilterPoints,\n useFilterRects,\n useFilterCircles,\n} from \"./hooks\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\n\nexport type GraphicsObjectClickEvent = {\n type: \"point\" | \"line\" | \"rect\" | \"circle\"\n index: number\n object: any\n}\n\nexport const InteractiveGraphics = ({\n graphics,\n onObjectClicked,\n objectLimit,\n}: {\n graphics: GraphicsObject\n onObjectClicked?: (event: GraphicsObjectClickEvent) => void\n objectLimit?: number\n}) => {\n const [activeLayers, setActiveLayers] = useState<string[] | null>(null)\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const availableLayers: string[] = Array.from(\n new Set([\n ...(graphics.lines?.map((l) => l.layer!).filter(Boolean) ?? []),\n ...(graphics.rects?.map((r) => r.layer!).filter(Boolean) ?? []),\n ...(graphics.points?.map((p) => p.layer!).filter(Boolean) ?? []),\n ]),\n )\n const maxStep = Math.max(\n 0,\n ...(graphics.lines?.map((l) => l.step!).filter(Boolean) ?? []),\n ...(graphics.rects?.map((r) => r.step!).filter(Boolean) ?? []),\n ...(graphics.points?.map((p) => p.step!).filter(Boolean) ?? []),\n )\n\n const graphicsBoundsWithPadding = useMemo(() => {\n const actualBounds = getGraphicsBounds(graphics)\n const width = actualBounds.maxX - actualBounds.minX\n const height = actualBounds.maxY - actualBounds.minY\n return {\n minX: actualBounds.minX - width / 10,\n minY: actualBounds.minY - height / 10,\n maxX: actualBounds.maxX + width / 10,\n maxY: actualBounds.maxY + height / 10,\n }\n }, [graphics])\n\n const { transform: realToScreen, ref } = useMouseMatrixTransform({\n initialTransform: compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n ),\n })\n\n useResizeObserver(ref, (entry: ResizeObserverEntry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n const interactiveState: InteractiveState = {\n activeLayers: activeLayers,\n activeStep: activeStep,\n realToScreen: realToScreen,\n onObjectClicked: onObjectClicked,\n }\n\n const showToolbar = availableLayers.length > 1 || maxStep > 0\n\n // Use custom hooks for visibility checks and filtering\n const isPointOnScreen = useIsPointOnScreen(realToScreen, size)\n\n const doesLineIntersectViewport = useDoesLineIntersectViewport(\n realToScreen,\n size,\n )\n\n // Filter by layer and step\n const filterLayerAndStep = (obj: { layer?: string; step?: number }) => {\n if (activeLayers && obj.layer && !activeLayers.includes(obj.layer))\n return false\n if (\n activeStep !== null &&\n obj.step !== undefined &&\n obj.step !== activeStep\n )\n return false\n return true\n }\n\n const filterLines = useFilterLines(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterPoints = useFilterPoints(isPointOnScreen, filterLayerAndStep)\n\n const filterRects = useFilterRects(\n isPointOnScreen,\n doesLineIntersectViewport,\n filterLayerAndStep,\n )\n\n const filterCircles = useFilterCircles(\n isPointOnScreen,\n filterLayerAndStep,\n realToScreen,\n size,\n )\n\n const filterAndLimit = <T,>(\n objects: T[] | undefined,\n filterFn: (obj: T) => boolean,\n ): (T & { originalIndex: number })[] => {\n if (!objects) return []\n const filtered = objects\n .map((obj, index) => ({ ...obj, originalIndex: index }))\n .filter(filterFn)\n return objectLimit ? filtered.slice(-objectLimit) : filtered\n }\n\n const filteredLines = useMemo(\n () => filterAndLimit(graphics.lines, filterLines),\n [graphics.lines, filterLines, objectLimit],\n )\n const filteredRects = useMemo(\n () => filterAndLimit(graphics.rects, filterRects),\n [graphics.rects, filterRects, objectLimit],\n )\n const filteredPoints = useMemo(\n () => filterAndLimit(graphics.points, filterPoints),\n [graphics.points, filterPoints, objectLimit],\n )\n const filteredCircles = useMemo(\n () => filterAndLimit(graphics.circles, filterCircles),\n [graphics.circles, filterCircles, objectLimit],\n )\n\n const totalFilteredObjects =\n filteredLines.length +\n filteredRects.length +\n filteredPoints.length +\n filteredCircles.length\n const isLimitReached = objectLimit && totalFilteredObjects > objectLimit\n\n return (\n <div>\n {showToolbar && (\n <div style={{ margin: 8 }}>\n {availableLayers.length > 1 && (\n <select\n value={activeLayers ? activeLayers[0] : \"\"}\n onChange={(e) => {\n const value = e.target.value\n setActiveLayers(value === \"\" ? null : [value])\n }}\n style={{ marginRight: 8 }}\n >\n <option value=\"\">All Layers</option>\n {availableLayers.map((layer) => (\n <option key={layer} value={layer}>\n {layer}\n </option>\n ))}\n </select>\n )}\n\n {maxStep > 0 && (\n <div\n style={{ display: \"inline-flex\", alignItems: \"center\", gap: 8 }}\n >\n Step:\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setActiveStep(Number.isNaN(value) ? null : value)\n }}\n disabled={activeStep === null}\n />\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n {isLimitReached && (\n <span style={{ color: \"red\", fontSize: \"12px\" }}>\n Display limited to {objectLimit} objects. Received:{\" \"}\n {totalFilteredObjects}.\n </span>\n )}\n </div>\n )}\n </div>\n )}\n\n <div\n ref={ref}\n style={{\n position: \"relative\",\n height: 600,\n overflow: \"hidden\",\n }}\n >\n <DimensionOverlay transform={realToScreen}>\n {filteredLines.map((line) => (\n <Line\n key={line.originalIndex}\n line={line}\n index={line.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredRects.map((rect) => (\n <Rect\n key={rect.originalIndex}\n rect={rect}\n index={rect.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredPoints.map((point) => (\n <Point\n key={point.originalIndex}\n point={point}\n index={point.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n {filteredCircles.map((circle) => (\n <Circle\n key={circle.originalIndex}\n circle={circle}\n index={circle.originalIndex}\n interactiveState={interactiveState}\n />\n ))}\n <SuperGrid\n stringifyCoord={(x, y) => `${x.toFixed(2)}, ${y.toFixed(2)}`}\n width={size.width}\n height={size.height}\n transform={realToScreen}\n />\n </DimensionOverlay>\n </div>\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { distToLineSegment } from \"site/utils/distToLineSegment\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Line = ({\n line,\n index,\n interactiveState,\n}: { line: Types.Line; index: number; interactiveState: InteractiveState }) => {\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const {\n points,\n layer,\n step,\n strokeColor,\n strokeWidth = 1 / realToScreen.a,\n strokeDash,\n } = line\n const [isHovered, setIsHovered] = useState(false)\n const [mousePos, setMousePos] = useState({ x: 0, y: 0 })\n\n const screenPoints = points.map((p) => applyToPoint(realToScreen, p))\n\n const handleMouseMove = (e: React.MouseEvent) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const mouseX = e.clientX - rect.left\n const mouseY = e.clientY - rect.top\n const hoverThreshold = 10 // pixels\n\n setMousePos({ x: mouseX, y: mouseY })\n\n // Check distance to each line segment\n let isNearLine = false\n for (let i = 0; i < screenPoints.length - 1; i++) {\n const dist = distToLineSegment(\n mouseX,\n mouseY,\n screenPoints[i].x,\n screenPoints[i].y,\n screenPoints[i + 1].x,\n screenPoints[i + 1].y,\n )\n if (dist < hoverThreshold) {\n isNearLine = true\n break\n }\n }\n\n setIsHovered(isNearLine)\n }\n\n const baseColor = strokeColor ?? defaultColors[index % defaultColors.length]\n\n return (\n <svg\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n onMouseMove={handleMouseMove}\n onMouseLeave={() => setIsHovered(false)}\n onClick={\n isHovered\n ? () =>\n onObjectClicked?.({\n type: \"line\",\n index,\n object: line,\n })\n : undefined\n }\n >\n <polyline\n points={screenPoints.map((p) => `${p.x},${p.y}`).join(\" \")}\n stroke={isHovered ? safeLighten(0.2, baseColor) : baseColor}\n fill=\"none\"\n strokeWidth={strokeWidth * realToScreen.a}\n strokeDasharray={\n !strokeDash\n ? undefined\n : typeof strokeDash === \"string\"\n ? strokeDash\n : `${strokeDash[0] * realToScreen.a}, ${strokeDash[1] * realToScreen.a}`\n }\n strokeLinecap=\"round\"\n />\n {isHovered && line.label && (\n <foreignObject\n x={mousePos.x}\n y={mousePos.y - 40}\n width={300}\n height={40}\n >\n <Tooltip text={line.label} />\n </foreignObject>\n )}\n </svg>\n )\n}\n","export const Tooltip = ({ text }: { text: string }) => {\n return (\n <div\n style={{\n background: \"white\",\n border: \"1px solid #ccc\",\n boxShadow: \"0 0 10px 0 rgba(0, 0, 0, 0.1)\",\n borderRadius: \"4px\",\n padding: \"4px 8px\",\n fontSize: \"12px\",\n minWidth: \"150px\",\n maxWidth: \"300px\",\n overflow: \"hidden\",\n textOverflow: \"ellipsis\",\n whiteSpace: \"pre-wrap\",\n zIndex: 100,\n }}\n >\n {text}\n </div>\n )\n}\n","// Calculate distance from point to line segment\nexport const distToLineSegment = (\n px: number,\n py: number,\n x1: number,\n y1: number,\n x2: number,\n y2: number,\n) => {\n const A = px - x1\n const B = py - y1\n const C = x2 - x1\n const D = y2 - y1\n\n const dot = A * C + B * D\n const lenSq = C * C + D * D\n let param = -1\n\n if (lenSq !== 0) param = dot / lenSq\n\n let xx = 0\n let yy = 0\n\n if (param < 0) {\n xx = x1\n yy = y1\n } else if (param > 1) {\n xx = x2\n yy = y2\n } else {\n xx = x1 + param * C\n yy = y1 + param * D\n }\n\n const dx = px - xx\n const dy = py - yy\n return Math.sqrt(dx * dx + dy * dy)\n}\n","// These are default colors if no color is provided\n// colors are made based on the index of the item in the array\n\nexport const defaultColors = [\n \"rgba(239, 68, 68, 0.8)\", // red-300\n \"rgba(249, 115, 22, 0.8)\", // orange-300\n \"rgba(245, 158, 11, 0.8)\", // amber-300\n \"rgba(234, 179, 8, 0.8)\", // yellow-300\n \"rgba(132, 204, 22, 0.8)\", // lime-300\n \"rgba(34, 197, 94, 0.8)\", // green-300\n \"rgba(16, 185, 129, 0.8)\", // emerald-300\n \"rgba(20, 184, 166, 0.8)\", // teal-300\n \"rgba(6, 182, 212, 0.8)\", // cyan-300\n \"rgba(14, 165, 233, 0.8)\", // sky-300\n \"rgba(59, 130, 246, 0.8)\", // blue-300\n \"rgba(99, 102, 241, 0.8)\", // indigo-300\n \"rgba(139, 92, 246, 0.8)\", // violet-300\n \"rgba(168, 85, 247, 0.8)\", // purple-300\n \"rgba(217, 70, 239, 0.8)\", // fuchsia-300\n \"rgba(236, 72, 153, 0.8)\", // pink-300\n \"rgba(249, 168, 212, 0.8)\", // rose-300\n \"rgba(161, 161, 170, 0.8)\", // zinc-300\n]\n","import { lighten } from \"polished\"\n\nexport const safeLighten = (amount: number, color: string) => {\n try {\n return lighten(amount, color)\n } catch (e) {\n return color\n }\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Point = ({\n point,\n interactiveState,\n index,\n}: {\n point: Types.Point\n interactiveState: InteractiveState\n index: number\n}) => {\n const { color, label, layer, step } = point\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenPoint = applyToPoint(realToScreen, point)\n const size = 10\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenPoint.x - size / 2,\n top: screenPoint.y - size / 2,\n width: size,\n height: size,\n borderRadius: \"50%\",\n border: `2px solid ${\n isHovered\n ? safeLighten(\n 0.2,\n color ?? defaultColors[index % defaultColors.length],\n )\n : (color ?? defaultColors[index % defaultColors.length])\n }`,\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"point\",\n index,\n object: point,\n })\n }\n >\n {isHovered && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip\n text={`${label ? `${label}\\n` : \"\"}x: ${point.x.toFixed(2)}, y: ${point.y.toFixed(2)}`}\n />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { lighten } from \"polished\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Rect = ({\n rect,\n interactiveState,\n index,\n}: {\n rect: Types.Rect\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, width, height, fill, stroke, layer, step } = rect\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n\n const screenCenter = applyToPoint(realToScreen, center)\n const screenWidth = width * realToScreen.a\n const screenHeight = height * Math.abs(realToScreen.d)\n\n // Default style when neither fill nor stroke is specified\n const hasStrokeOrFill = fill !== undefined || stroke !== undefined\n\n let backgroundColor = hasStrokeOrFill ? fill || \"transparent\" : defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = safeLighten(0.2, stroke!)\n }\n\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenWidth / 2,\n top: screenCenter.y - screenHeight / 2,\n width: screenWidth,\n height: screenHeight,\n backgroundColor,\n border: stroke\n ? `2px solid ${isHovered ? safeLighten(0.2, stroke) : stroke}`\n : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"rect\",\n index,\n object: rect,\n })\n }\n >\n {isHovered && rect.label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={rect.label} />\n </div>\n )}\n </div>\n )\n}\n","import type * as Types from \"lib/types\"\nimport { applyToPoint } from \"transformation-matrix\"\nimport type { InteractiveState } from \"./InteractiveState\"\nimport { useState } from \"react\"\nimport { Tooltip } from \"./Tooltip\"\nimport { defaultColors } from \"./defaultColors\"\nimport { safeLighten } from \"site/utils/safeLighten\"\n\nexport const Circle = ({\n circle,\n interactiveState,\n index,\n}: {\n circle: Types.Circle\n interactiveState: InteractiveState\n index: number\n}) => {\n const defaultColor = defaultColors[index % defaultColors.length]\n let { center, radius, fill, stroke, layer, step, label } = circle\n const { activeLayers, activeStep, realToScreen, onObjectClicked } =\n interactiveState\n const [isHovered, setIsHovered] = useState(false)\n const screenCenter = applyToPoint(realToScreen, center)\n const screenRadius = radius * realToScreen.a\n let backgroundColor = fill || defaultColor\n if (isHovered) {\n backgroundColor = safeLighten(0.2, backgroundColor)\n stroke = stroke ? safeLighten(0.2, stroke) : stroke\n }\n return (\n <div\n style={{\n position: \"absolute\",\n left: screenCenter.x - screenRadius,\n top: screenCenter.y - screenRadius,\n width: screenRadius * 2,\n height: screenRadius * 2,\n borderRadius: \"50%\",\n backgroundColor,\n border: stroke ? `2px solid ${stroke}` : \"none\",\n cursor: \"pointer\",\n transition: \"border-color 0.2s\",\n }}\n onMouseEnter={() => setIsHovered(true)}\n onMouseLeave={() => setIsHovered(false)}\n onClick={() =>\n onObjectClicked?.({\n type: \"circle\",\n index,\n object: circle,\n })\n }\n >\n {isHovered && label && (\n <div\n style={{\n position: \"absolute\",\n bottom: \"100%\",\n left: \"50%\",\n transform: \"translateX(-50%)\",\n marginBottom: 8,\n }}\n >\n <Tooltip text={label} />\n </div>\n )}\n </div>\n )\n}\n","import { GraphicsObject } from \"lib/types\"\n\nexport const getGraphicsBounds = (graphics: GraphicsObject) => {\n const bounds = {\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity,\n }\n for (const line of graphics.lines ?? []) {\n for (const point of line.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n }\n for (const rect of graphics.rects ?? []) {\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n bounds.minX = Math.min(bounds.minX, center.x - halfWidth)\n bounds.minY = Math.min(bounds.minY, center.y - halfHeight)\n bounds.maxX = Math.max(bounds.maxX, center.x + halfWidth)\n bounds.maxY = Math.max(bounds.maxY, center.y + halfHeight)\n }\n for (const point of graphics.points ?? []) {\n bounds.minX = Math.min(bounds.minX, point.x)\n bounds.minY = Math.min(bounds.minY, point.y)\n bounds.maxX = Math.max(bounds.maxX, point.x)\n bounds.maxY = Math.max(bounds.maxY, point.y)\n }\n return bounds\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\nexport const useIsPointOnScreen = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (point: { x: number; y: number }) => {\n const screenPoint = applyToPoint(realToScreen, point)\n return (\n screenPoint.x >= -OFFSCREEN_MARGIN &&\n screenPoint.x <= size.width + OFFSCREEN_MARGIN &&\n screenPoint.y >= -OFFSCREEN_MARGIN &&\n screenPoint.y <= size.height + OFFSCREEN_MARGIN\n )\n }\n }, [realToScreen, size])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\n\n// Margin in pixels for determining if elements are off-screen\nexport const OFFSCREEN_MARGIN = 5\n\nexport const useDoesLineIntersectViewport = (\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (p1: { x: number; y: number }, p2: { x: number; y: number }) => {\n // Convert real-world points to screen coordinates\n const sp1 = applyToPoint(realToScreen, p1)\n const sp2 = applyToPoint(realToScreen, p2)\n\n // Viewport boundaries with margin\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // If either point is inside the viewport, the line intersects\n if (\n (sp1.x >= left && sp1.x <= right && sp1.y >= top && sp1.y <= bottom) ||\n (sp2.x >= left && sp2.x <= right && sp2.y >= top && sp2.y <= bottom)\n ) {\n return true\n }\n\n // Helper function to check if a line intersects with a line segment\n const intersects = (\n a1: { x: number; y: number },\n a2: { x: number; y: number },\n b1: { x: number; y: number },\n b2: { x: number; y: number },\n ) => {\n // Line segment A is (a1, a2), line segment B is (b1, b2)\n const det =\n (a2.x - a1.x) * (b2.y - b1.y) - (a2.y - a1.y) * (b2.x - b1.x)\n\n // If lines are parallel or coincident, they don't intersect in a unique point\n if (det === 0) return false\n\n const lambda =\n ((b2.y - b1.y) * (b2.x - a1.x) + (b1.x - b2.x) * (b2.y - a1.y)) / det\n const gamma =\n ((a1.y - a2.y) * (b2.x - a1.x) + (a2.x - a1.x) * (b2.y - a1.y)) / det\n\n // Check if the intersection point is within both line segments\n return lambda >= 0 && lambda <= 1 && gamma >= 0 && gamma <= 1\n }\n\n // Check intersection with each edge of the viewport\n return (\n // Top edge\n intersects(sp1, sp2, { x: left, y: top }, { x: right, y: top }) ||\n // Right edge\n intersects(sp1, sp2, { x: right, y: top }, { x: right, y: bottom }) ||\n // Bottom edge\n intersects(sp1, sp2, { x: left, y: bottom }, { x: right, y: bottom }) ||\n // Left edge\n intersects(sp1, sp2, { x: left, y: top }, { x: left, y: bottom })\n )\n }\n }, [realToScreen, size])\n}\n","import { useMemo } from \"react\"\n\ntype Line = {\n points: Array<{ x: number; y: number }>\n layer?: string\n step?: number\n closed?: boolean\n}\n\nexport const useFilterLines = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (line: Line) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(line)) return false\n\n // Then check if any point of the line is visible\n if (line.points.some((p) => isPointOnScreen(p))) {\n return true\n }\n\n // If no points are visible, check if any line segment intersects the viewport\n for (let i = 0; i < line.points.length - 1; i++) {\n if (doesLineIntersectViewport(line.points[i], line.points[i + 1])) {\n return true\n }\n }\n\n // If it's a closed shape (polyline), check the last segment too\n if (line.points.length > 2 && line.closed) {\n if (\n doesLineIntersectViewport(\n line.points[line.points.length - 1],\n line.points[0],\n )\n ) {\n return true\n }\n }\n\n return false\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Point = {\n x: number\n y: number\n layer?: string\n step?: number\n}\n\nexport const useFilterPoints = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (point: Point) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(point)) return false\n\n // Then check if the point is visible\n return isPointOnScreen(point)\n }\n }, [isPointOnScreen, filterLayerAndStep])\n}\n","import { useMemo } from \"react\"\n\ntype Rect = {\n center: { x: number; y: number }\n width: number\n height: number\n layer?: string\n step?: number\n}\n\nexport const useFilterRects = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n doesLineIntersectViewport: (\n p1: { x: number; y: number },\n p2: { x: number; y: number },\n ) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n) => {\n return useMemo(() => {\n return (rect: Rect) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(rect)) return false\n\n // For rectangles, check if any corner or the center is visible\n const { center, width, height } = rect\n const halfWidth = width / 2\n const halfHeight = height / 2\n\n const topLeft = { x: center.x - halfWidth, y: center.y - halfHeight }\n const topRight = { x: center.x + halfWidth, y: center.y - halfHeight }\n const bottomLeft = { x: center.x - halfWidth, y: center.y + halfHeight }\n const bottomRight = { x: center.x + halfWidth, y: center.y + halfHeight }\n\n // Check if any corner or center is visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen(topLeft) ||\n isPointOnScreen(topRight) ||\n isPointOnScreen(bottomLeft) ||\n isPointOnScreen(bottomRight)\n ) {\n return true\n }\n\n // Check if any edge of the rectangle intersects the viewport\n return (\n doesLineIntersectViewport(topLeft, topRight) ||\n doesLineIntersectViewport(topRight, bottomRight) ||\n doesLineIntersectViewport(bottomRight, bottomLeft) ||\n doesLineIntersectViewport(bottomLeft, topLeft)\n )\n }\n }, [isPointOnScreen, doesLineIntersectViewport, filterLayerAndStep])\n}\n","import { applyToPoint, type Matrix } from \"transformation-matrix\"\nimport { useMemo } from \"react\"\nimport { OFFSCREEN_MARGIN } from \"./useDoesLineIntersectViewport\"\n\ntype Circle = {\n center: { x: number; y: number }\n radius: number\n layer?: string\n step?: number\n}\n\nexport const useFilterCircles = (\n isPointOnScreen: (point: { x: number; y: number }) => boolean,\n filterLayerAndStep: (obj: { layer?: string; step?: number }) => boolean,\n realToScreen: Matrix,\n size: { width: number; height: number },\n) => {\n return useMemo(() => {\n return (circle: Circle) => {\n // First apply layer and step filters\n if (!filterLayerAndStep(circle)) return false\n\n // For circles, check if center is visible or if any cardinal point is visible\n const { center, radius } = circle\n\n // Check if center or cardinal points on the circle are visible\n if (\n isPointOnScreen(center) ||\n isPointOnScreen({ x: center.x + radius, y: center.y }) ||\n isPointOnScreen({ x: center.x - radius, y: center.y }) ||\n isPointOnScreen({ x: center.x, y: center.y + radius }) ||\n isPointOnScreen({ x: center.x, y: center.y - radius })\n ) {\n return true\n }\n\n // Check if the circle intersects the viewport\n // Convert to screen coordinates for viewport intersection test\n const screenCenter = applyToPoint(realToScreen, center)\n const scale = Math.abs(realToScreen.a) // Get the scale factor\n const screenRadius = radius * scale\n\n // Viewport boundaries\n const left = -OFFSCREEN_MARGIN\n const right = size.width + OFFSCREEN_MARGIN\n const top = -OFFSCREEN_MARGIN\n const bottom = size.height + OFFSCREEN_MARGIN\n\n // Check if the circle intersects with the viewport\n // Case 1: Circle center is inside the viewport horizontally but outside vertically\n if (screenCenter.x >= left && screenCenter.x <= right) {\n if (\n Math.abs(screenCenter.y - top) <= screenRadius ||\n Math.abs(screenCenter.y - bottom) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 2: Circle center is inside the viewport vertically but outside horizontally\n if (screenCenter.y >= top && screenCenter.y <= bottom) {\n if (\n Math.abs(screenCenter.x - left) <= screenRadius ||\n Math.abs(screenCenter.x - right) <= screenRadius\n ) {\n return true\n }\n }\n\n // Case 3: Circle center is outside the viewport, check corners\n const cornerDistanceSquared = (cornerX: number, cornerY: number) => {\n const dx = screenCenter.x - cornerX\n const dy = screenCenter.y - cornerY\n return dx * dx + dy * dy\n }\n\n const radiusSquared = screenRadius * screenRadius\n\n return (\n cornerDistanceSquared(left, top) <= radiusSquared ||\n cornerDistanceSquared(right, top) <= radiusSquared ||\n cornerDistanceSquared(left, bottom) <= radiusSquared ||\n cornerDistanceSquared(right, bottom) <= radiusSquared\n )\n }\n }, [isPointOnScreen, filterLayerAndStep, realToScreen, size])\n}\n","import React, { useEffect, useRef, useState } from \"react\"\nimport { applyToPoint, identity, inverse } from \"transformation-matrix\"\nimport type { Matrix } from \"transformation-matrix\"\n\ninterface Props {\n transform?: Matrix\n children: React.ReactNode\n}\n\nexport const DimensionOverlay: React.FC<Props> = ({ children, transform }) => {\n if (!transform) transform = identity()\n const [dimensionToolVisible, setDimensionToolVisible] = useState(false)\n const [dimensionToolStretching, setDimensionToolStretching] = useState(false)\n // Start of dimension tool line in real-world coordinates (not screen)\n const [dStart, setDStart] = useState({ x: 0, y: 0 })\n // End of dimension tool line in real-world coordinates (not screen)\n const [dEnd, setDEnd] = useState({ x: 0, y: 0 })\n const mousePosRef = useRef({ x: 0, y: 0 })\n const containerRef = useRef<HTMLDivElement | null>(null)\n const container = containerRef.current!\n const containerBounds = container?.getBoundingClientRect()\n\n const bindKeys = () => {\n const container = containerRef.current\n\n const down = (e: KeyboardEvent) => {\n if (e.key === \"d\") {\n setDStart({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDEnd({ x: mousePosRef.current.x, y: mousePosRef.current.y })\n setDimensionToolVisible((visible: boolean) => !visible)\n setDimensionToolStretching(true)\n }\n if (e.key === \"Escape\") {\n setDimensionToolVisible(false)\n setDimensionToolStretching(false)\n }\n }\n\n const addKeyListener = () => {\n if (container) {\n window.addEventListener(\"keydown\", down)\n }\n }\n\n const removeKeyListener = () => {\n if (container) {\n window.removeEventListener(\"keydown\", down)\n }\n }\n\n if (container) {\n container.addEventListener(\"focus\", addKeyListener)\n container.addEventListener(\"blur\", removeKeyListener)\n container.addEventListener(\"mouseenter\", addKeyListener)\n container.addEventListener(\"mouseleave\", removeKeyListener)\n }\n return () => {\n if (container) {\n container.removeEventListener(\"focus\", addKeyListener)\n container.removeEventListener(\"blur\", removeKeyListener)\n container.removeEventListener(\"mouseenter\", addKeyListener)\n container.removeEventListener(\"mouseleave\", removeKeyListener)\n }\n }\n }\n\n useEffect(bindKeys, [containerBounds?.width, containerBounds?.height])\n\n const screenDStart = applyToPoint(transform, dStart)\n const screenDEnd = applyToPoint(transform, dEnd)\n\n const arrowScreenBounds = {\n left: Math.min(screenDStart.x, screenDEnd.x),\n right: Math.max(screenDStart.x, screenDEnd.x),\n top: Math.min(screenDStart.y, screenDEnd.y),\n bottom: Math.max(screenDStart.y, screenDEnd.y),\n flipX: screenDStart.x > screenDEnd.x,\n flipY: screenDStart.y > screenDEnd.y,\n width: 0,\n height: 0,\n }\n arrowScreenBounds.width = arrowScreenBounds.right - arrowScreenBounds.left\n arrowScreenBounds.height = arrowScreenBounds.bottom - arrowScreenBounds.top\n\n return (\n <div\n ref={containerRef}\n tabIndex={0}\n style={{ position: \"relative\" }}\n onMouseMove={(e: React.MouseEvent<HTMLDivElement>) => {\n const rect = e.currentTarget.getBoundingClientRect()\n const x = e.clientX - rect.left\n const y = e.clientY - rect.top\n const rwPoint = applyToPoint(inverse(transform!), { x, y })\n mousePosRef.current.x = rwPoint.x\n mousePosRef.current.y = rwPoint.y\n\n if (dimensionToolStretching) {\n setDEnd({ x: rwPoint.x, y: rwPoint.y })\n }\n }}\n onMouseDown={() => {\n if (dimensionToolStretching) {\n setDimensionToolStretching(false)\n } else if (dimensionToolVisible) {\n setDimensionToolVisible(false)\n }\n }}\n onMouseEnter={() => {\n if (containerRef.current) {\n bindKeys()\n }\n }}\n >\n {children}\n {dimensionToolVisible && (\n <>\n <div\n style={{\n position: \"absolute\",\n left: arrowScreenBounds.left,\n width: arrowScreenBounds.width,\n textAlign: \"center\",\n top: screenDStart.y + 2,\n color: \"red\",\n mixBlendMode: \"difference\",\n pointerEvents: \"none\",\n marginTop: arrowScreenBounds.flipY ? 0 : -20,\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n {Math.abs(dStart.x - dEnd.x).toFixed(2)}\n </div>\n <div\n style={{\n position: \"absolute\",\n left: screenDEnd.x,\n height: arrowScreenBounds.height,\n display: \"flex\",\n flexDirection: \"column\",\n justifyContent: \"center\",\n top: arrowScreenBounds.top,\n color: \"red\",\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n fontSize: 12,\n fontFamily: \"sans-serif\",\n zIndex: 30,\n }}\n >\n <div\n style={{\n marginLeft: arrowScreenBounds.flipX ? \"-100%\" : 4,\n paddingRight: 4,\n }}\n >\n {Math.abs(dStart.y - dEnd.y).toFixed(2)}\n </div>\n </div>\n <svg\n style={{\n position: \"absolute\",\n left: 0,\n top: 0,\n pointerEvents: \"none\",\n mixBlendMode: \"difference\",\n zIndex: 30,\n }}\n width={containerBounds?.width || \"100%\"}\n height={containerBounds?.height || \"100%\"}\n >\n <defs>\n <marker\n id=\"head\"\n orient=\"auto\"\n markerWidth=\"3\"\n markerHeight=\"4\"\n refX=\"2\"\n refY=\"2\"\n >\n <path d=\"M0,0 V4 L2,2 Z\" fill=\"red\" />\n </marker>\n </defs>\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n markerEnd=\"url(#head)\"\n strokeWidth={1.5}\n fill=\"none\"\n stroke=\"red\"\n />\n <line\n x1={screenDStart.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDStart.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n <line\n x1={screenDEnd.x}\n y1={screenDStart.y}\n x2={screenDEnd.x}\n y2={screenDEnd.y}\n strokeWidth={1.5}\n fill=\"none\"\n strokeDasharray={\"2,2\"}\n stroke=\"red\"\n />\n </svg>\n <div\n style={{\n right: 0,\n bottom: 0,\n position: \"absolute\",\n color: \"red\",\n fontFamily: \"sans-serif\",\n fontSize: 12,\n margin: 4,\n }}\n >\n ({dStart.x.toFixed(2)},{dStart.y.toFixed(2)})<br />(\n {dEnd.x.toFixed(2)},{dEnd.y.toFixed(2)})<br />\n dist:{\" \"}\n {Math.sqrt(\n (dEnd.x - dStart.x) ** 2 + (dEnd.y - dStart.y) ** 2,\n ).toFixed(2)}\n </div>\n </>\n )}\n </div>\n )\n}\n","import React, { useRef, useEffect, useState, useMemo } from \"react\"\nimport { drawGraphicsToCanvas, getBounds, type GraphicsObject } from \"../../lib\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"./DimensionOverlay\"\n\ninterface InteractiveGraphicsCanvasProps {\n graphics: GraphicsObject\n showLabelsByDefault?: boolean\n showGrid?: boolean\n height?: number | string\n width?: number | string\n}\n\nexport function InteractiveGraphicsCanvas({\n graphics,\n showLabelsByDefault = true,\n showGrid = true,\n height = 500,\n width = \"100%\",\n}: InteractiveGraphicsCanvasProps) {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement | null>(null)\n const [size, setSize] = useState({ width: 600, height: 600 })\n const [activeStep, setActiveStep] = useState<number | null>(null)\n const [showLabels, setShowLabels] = useState(showLabelsByDefault)\n const [showLastStep, setShowLastStep] = useState(true)\n\n // Calculate the maximum step value from all graphics objects\n const maxStep = useMemo(() => {\n const maxPointStep = Math.max(\n 0,\n ...(graphics.points?.map((p) =>\n Number.isNaN(p.step) ? 0 : p.step || 0,\n ) ?? []),\n )\n const maxLineStep = Math.max(\n 0,\n ...(graphics.lines?.map((l) =>\n Number.isNaN(l.step) ? 0 : l.step || 0,\n ) ?? []),\n )\n const maxRectStep = Math.max(\n 0,\n ...(graphics.rects?.map((r) =>\n Number.isNaN(r.step) ? 0 : r.step || 0,\n ) ?? []),\n )\n const maxCircleStep = Math.max(\n 0,\n ...(graphics.circles?.map((c) =>\n Number.isNaN(c.step) ? 0 : c.step || 0,\n ) ?? []),\n )\n return Math.max(maxPointStep, maxLineStep, maxRectStep, maxCircleStep)\n }, [graphics])\n\n // Filter graphics objects based on step\n const filteredGraphics = useMemo(() => {\n const selectedStep = showLastStep ? maxStep : activeStep\n\n if (selectedStep === null) {\n return graphics\n }\n\n const filterByStep = (objStep?: number) =>\n objStep === undefined || objStep === selectedStep\n\n return {\n ...graphics,\n points: graphics.points?.filter((p) => filterByStep(p.step)),\n lines: graphics.lines?.filter((l) => filterByStep(l.step)),\n rects: graphics.rects?.filter((r) => filterByStep(r.step)),\n circles: graphics.circles?.filter((c) => filterByStep(c.step)),\n }\n }, [graphics, activeStep, showLastStep, maxStep])\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = useMemo(() => {\n const bounds = getBounds(graphics)\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - width / 10,\n minY: bounds.minY - height / 10,\n maxX: bounds.maxX + width / 10,\n maxY: bounds.maxY + height / 10,\n }\n }, [graphics])\n\n // Use mouse transform hook for panning/zooming\n const { transform, ref: mouseTransformRef } = useMouseMatrixTransform({\n initialTransform: compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n ),\n })\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = () => {\n if (!canvasRef.current) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(filteredGraphics, canvasRef.current, {\n transform: transform,\n disableLabels: !showLabels,\n })\n\n // Draw a grid for reference if requested\n if (showGrid) {\n drawGrid(canvasRef.current, transform)\n }\n }\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: any) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Determine grid spacing based on zoom level\n const gridSize = 10\n\n // Draw vertical grid lines\n for (let x = -100; x <= 100; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -100 }, transform)\n const end = transformPoint({ x, y: 100 }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -100; y <= 100; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -100, y }, transform)\n const end = transformPoint({ x: 100, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: any) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [transform, size, filteredGraphics, showGrid, showLabels])\n\n return (\n <div style={{ display: \"flex\", flexDirection: \"column\", gap: \"10px\" }}>\n {maxStep > 0 && (\n <div style={{ display: \"flex\", gap: \"12px\", alignItems: \"center\" }}>\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={activeStep !== null}\n onChange={(e) => {\n setActiveStep(e.target.checked ? 0 : null)\n }}\n />\n Filter by step\n </label>\n\n <input\n type=\"number\"\n min={0}\n max={maxStep}\n value={activeStep ?? 0}\n onChange={(e) => {\n const value = parseInt(e.target.value)\n setShowLastStep(false)\n setActiveStep(\n Number.isNaN(value) ? 0 : Math.min(value, maxStep),\n )\n }}\n disabled={activeStep === null}\n style={{ width: \"60px\" }}\n />\n\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLastStep}\n onChange={(e) => {\n setShowLastStep(e.target.checked)\n setActiveStep(null)\n }}\n />\n Show last step\n </label>\n </div>\n\n <div style={{ display: \"flex\", alignItems: \"center\", gap: \"8px\" }}>\n <label>\n <input\n type=\"checkbox\"\n style={{ marginRight: 4 }}\n checked={showLabels}\n onChange={(e) => {\n setShowLabels(e.target.checked)\n }}\n />\n Show labels\n </label>\n </div>\n </div>\n )}\n\n <div\n ref={(node) => {\n // Using a callback ref approach\n containerRef.current = node\n // Apply the mouse transform ref if available\n if (mouseTransformRef && node) {\n mouseTransformRef.current = node\n }\n }}\n style={{\n position: \"relative\",\n width: width,\n height: height,\n border: \"1px solid #ccc\",\n overflow: \"hidden\",\n }}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width,\n height,\n }}\n />\n </div>\n </div>\n )\n}\n\nexport default InteractiveGraphicsCanvas\n","import React, { useRef, useEffect, useState } from \"react\"\nimport { GraphicsObject } from \"../../../lib/types\"\nimport {\n drawGraphicsToCanvas,\n getBounds,\n} from \"../../../lib/drawGraphicsToCanvas\"\nimport useMouseMatrixTransform from \"use-mouse-matrix-transform\"\nimport { compose, scale, translate, type Matrix } from \"transformation-matrix\"\nimport useResizeObserver from \"@react-hook/resize-observer\"\nimport { DimensionOverlay } from \"../DimensionOverlay\"\n\ninterface CanvasGraphicsProps {\n graphics: GraphicsObject\n width?: number\n height?: number\n withGrid?: boolean\n initialTransform?: Matrix\n disableLabels?: boolean\n}\n\n// Create a container component that handles the mouse matrix transform\nfunction TransformContainer({\n initialTransform,\n children,\n onTransformChange,\n}: {\n initialTransform: Matrix\n children: React.ReactNode\n onTransformChange: (transform: Matrix) => void\n}) {\n const { transform, ref } = useMouseMatrixTransform({\n initialTransform,\n })\n\n // Update parent with transform changes\n useEffect(() => {\n onTransformChange(transform)\n }, [transform, onTransformChange])\n\n return (\n <div\n ref={ref}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: \"100%\",\n }}\n >\n {children}\n </div>\n )\n}\n\nexport const CanvasGraphics = ({\n graphics,\n width = 600,\n height = 600,\n withGrid = true,\n disableLabels = false,\n initialTransform,\n}: CanvasGraphicsProps) => {\n const canvasRef = useRef<HTMLCanvasElement>(null)\n const containerRef = useRef<HTMLDivElement>(null)\n const [size, setSize] = useState({ width, height })\n const [currentTransform, setCurrentTransform] = useState<Matrix | null>(null)\n\n // Get bounds of the graphics with padding\n const graphicsBoundsWithPadding = React.useMemo(() => {\n const bounds = getBounds(graphics)\n const bWidth = bounds.maxX - bounds.minX\n const bHeight = bounds.maxY - bounds.minY\n return {\n minX: bounds.minX - bWidth / 10,\n minY: bounds.minY - bHeight / 10,\n maxX: bounds.maxX + bWidth / 10,\n maxY: bounds.maxY + bHeight / 10,\n }\n }, [graphics])\n\n // Compute initial transform if not provided\n const computedInitialTransform = React.useMemo(() => {\n if (initialTransform) return initialTransform\n\n const yFlip = graphics.coordinateSystem === \"cartesian\"\n return compose(\n translate(size.width / 2, size.height / 2),\n scale(\n Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX - graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY - graphicsBoundsWithPadding.minY),\n ),\n yFlip\n ? -Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n )\n : Math.min(\n size.width /\n (graphicsBoundsWithPadding.maxX -\n graphicsBoundsWithPadding.minX),\n size.height /\n (graphicsBoundsWithPadding.maxY -\n graphicsBoundsWithPadding.minY),\n ),\n ),\n translate(\n -(graphicsBoundsWithPadding.maxX + graphicsBoundsWithPadding.minX) / 2,\n -(graphicsBoundsWithPadding.maxY + graphicsBoundsWithPadding.minY) / 2,\n ),\n )\n }, [graphics, graphicsBoundsWithPadding, initialTransform, size])\n\n // Track transform changes from the mouse transform hook\n const handleTransformChange = React.useCallback((transform: Matrix) => {\n setCurrentTransform(transform)\n }, [])\n\n // Monitor container size\n useResizeObserver(containerRef, (entry) => {\n setSize({\n width: entry.contentRect.width,\n height: entry.contentRect.height,\n })\n })\n\n // Draw function that uses our canvas renderer\n const drawCanvas = React.useCallback(() => {\n if (!canvasRef.current || !currentTransform) return\n\n // Make sure canvas dimensions match container\n canvasRef.current.width = size.width\n canvasRef.current.height = size.height\n\n // Draw the graphics with the current transform\n drawGraphicsToCanvas(graphics, canvasRef.current, {\n transform: currentTransform,\n disableLabels,\n })\n\n // Draw a grid for reference if enabled\n if (withGrid) {\n drawGrid(canvasRef.current, currentTransform)\n }\n }, [canvasRef, currentTransform, graphics, size, withGrid])\n\n // Draw a grid to help with visualization\n const drawGrid = (canvas: HTMLCanvasElement, transform: Matrix) => {\n const ctx = canvas.getContext(\"2d\")\n if (!ctx) return\n\n ctx.save()\n\n // Draw coordinate axes\n ctx.beginPath()\n\n // X-axis\n const xAxisStart = { x: -1000, y: 0 }\n const xAxisEnd = { x: 1000, y: 0 }\n const xAxisStartTransformed = transformPoint(xAxisStart, transform)\n const xAxisEndTransformed = transformPoint(xAxisEnd, transform)\n\n ctx.moveTo(xAxisStartTransformed.x, xAxisStartTransformed.y)\n ctx.lineTo(xAxisEndTransformed.x, xAxisEndTransformed.y)\n\n // Y-axis\n const yAxisStart = { x: 0, y: -1000 }\n const yAxisEnd = { x: 0, y: 1000 }\n const yAxisStartTransformed = transformPoint(yAxisStart, transform)\n const yAxisEndTransformed = transformPoint(yAxisEnd, transform)\n\n ctx.moveTo(yAxisStartTransformed.x, yAxisStartTransformed.y)\n ctx.lineTo(yAxisEndTransformed.x, yAxisEndTransformed.y)\n\n ctx.strokeStyle = \"#aaa\"\n ctx.lineWidth = 1\n ctx.stroke()\n\n // Draw grid lines\n ctx.beginPath()\n ctx.setLineDash([2, 2])\n\n // Calculate a good grid size based on zoom level\n // This is an approximate calculation\n const zoomLevel = Math.abs(transform.a) // Scale factor\n const gridSize = Math.pow(10, Math.floor(Math.log10(100 / zoomLevel)))\n\n const gridRange = Math.ceil(1000 / gridSize) * gridSize\n\n // Draw vertical grid lines\n for (let x = -gridRange; x <= gridRange; x += gridSize) {\n if (x === 0) continue // Skip the axis\n\n const start = transformPoint({ x, y: -gridRange }, transform)\n const end = transformPoint({ x, y: gridRange }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n // Draw horizontal grid lines\n for (let y = -gridRange; y <= gridRange; y += gridSize) {\n if (y === 0) continue // Skip the axis\n\n const start = transformPoint({ x: -gridRange, y }, transform)\n const end = transformPoint({ x: gridRange, y }, transform)\n\n ctx.moveTo(start.x, start.y)\n ctx.lineTo(end.x, end.y)\n }\n\n ctx.strokeStyle = \"#ddd\"\n ctx.stroke()\n ctx.restore()\n }\n\n // Helper to transform a point through the matrix\n const transformPoint = (point: { x: number; y: number }, matrix: Matrix) => {\n return {\n x: matrix.a * point.x + matrix.c * point.y + matrix.e,\n y: matrix.b * point.x + matrix.d * point.y + matrix.f,\n }\n }\n\n // Apply the drawing when transform changes\n useEffect(() => {\n drawCanvas()\n }, [drawCanvas])\n\n // Initialize transform\n useEffect(() => {\n setCurrentTransform(computedInitialTransform)\n }, [computedInitialTransform])\n\n return (\n <div\n ref={containerRef}\n style={{\n position: \"relative\",\n width: \"100%\",\n height: `${height}px`,\n border: \"1px solid #eee\",\n overflow: \"hidden\",\n }}\n >\n <TransformContainer\n initialTransform={computedInitialTransform}\n onTransformChange={handleTransformChange}\n >\n <DimensionOverlay\n transform={currentTransform || computedInitialTransform}\n >\n <canvas\n ref={canvasRef}\n style={{\n position: \"absolute\",\n top: 0,\n left: 0,\n width: \"100%\",\n height: \"100%\",\n }}\n />\n </DimensionOverlay>\n </TransformContainer>\n </div>\n )\n}\n"],"mappings":"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","names":["useMemo","useState","jsx","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useState","jsx","useState","applyToPoint","applyToPoint","useMemo","applyToPoint","useMemo","applyToPoint","useMemo","useMemo","useMemo","applyToPoint","useMemo","useMemo","applyToPoint","scale","useState","applyToPoint","jsx","jsxs","container","jsx","jsxs","useState","useMemo","useRef","useEffect","useState","useMemo","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","jsxs","useRef","useState","useMemo","width","height","transform","useEffect","React","useRef","useEffect","useState","useMouseMatrixTransform","compose","scale","translate","useResizeObserver","jsx","useMouseMatrixTransform","useEffect","useRef","useState","React","compose","translate","scale","useResizeObserver"]}
package/package.json CHANGED
@@ -2,7 +2,7 @@
2
2
  "name": "graphics-debug",
3
3
  "main": "dist/lib/index.js",
4
4
  "type": "module",
5
- "version": "0.0.32",
5
+ "version": "0.0.34",
6
6
  "files": [
7
7
  "dist"
8
8
  ],
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../lib/drawGraphicsToCanvas.ts"],"sourcesContent":["import {\n compose,\n scale,\n translate,\n applyToPoint,\n type Matrix,\n} from \"transformation-matrix\"\nimport type {\n GraphicsObject,\n Viewbox,\n CenterViewbox,\n TransformOptions,\n} from \"./types\"\n\n/**\n * Computes a transformation matrix based on a provided viewbox\n * Handles both min/max style viewboxes and center/width/height style viewboxes\n */\nexport function computeTransformFromViewbox(\n viewbox: Viewbox | CenterViewbox,\n canvasWidth: number,\n canvasHeight: number,\n options: { padding?: number; yFlip?: boolean } = {},\n): Matrix {\n const padding = options.padding ?? 40\n const yFlip = options.yFlip ?? false\n\n // Convert CenterViewbox to Viewbox if needed\n let bounds: Viewbox\n if (\"center\" in viewbox) {\n const halfWidth = viewbox.width / 2\n const halfHeight = viewbox.height / 2\n bounds = {\n minX: viewbox.center.x - halfWidth,\n maxX: viewbox.center.x + halfWidth,\n minY: viewbox.center.y - halfHeight,\n maxY: viewbox.center.y + halfHeight,\n }\n } else {\n bounds = viewbox\n }\n\n const width = bounds.maxX - bounds.minX\n const height = bounds.maxY - bounds.minY\n\n const scale_factor = Math.min(\n (canvasWidth - 2 * padding) / width,\n (canvasHeight - 2 * padding) / height,\n )\n\n return compose(\n translate(canvasWidth / 2, canvasHeight / 2),\n scale(scale_factor, yFlip ? -scale_factor : scale_factor),\n translate(-(bounds.minX + width / 2), -(bounds.minY + height / 2)),\n )\n}\n\n/**\n * Computes bounds for a graphics object\n */\nexport function getBounds(graphics: GraphicsObject): Viewbox {\n const points = [\n ...(graphics.points || []),\n ...(graphics.lines || []).flatMap((line) => line.points),\n ...(graphics.rects || []).flatMap((rect) => {\n const halfWidth = rect.width / 2\n const halfHeight = rect.height / 2\n return [\n { x: rect.center.x - halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y - halfHeight },\n { x: rect.center.x - halfWidth, y: rect.center.y + halfHeight },\n { x: rect.center.x + halfWidth, y: rect.center.y + halfHeight },\n ]\n }),\n ...(graphics.circles || []).flatMap((circle) => [\n { x: circle.center.x - circle.radius, y: circle.center.y }, // left\n { x: circle.center.x + circle.radius, y: circle.center.y }, // right\n { x: circle.center.x, y: circle.center.y - circle.radius }, // top\n { x: circle.center.x, y: circle.center.y + circle.radius }, // bottom\n ]),\n ]\n\n if (points.length === 0) {\n return { minX: -1, maxX: 1, minY: -1, maxY: 1 }\n }\n\n return points.reduce(\n (bounds, point) => ({\n minX: Math.min(bounds.minX, point.x),\n maxX: Math.max(bounds.maxX, point.x),\n minY: Math.min(bounds.minY, point.y),\n maxY: Math.max(bounds.maxY, point.y),\n }),\n { minX: Infinity, maxX: -Infinity, minY: Infinity, maxY: -Infinity },\n )\n}\n\n/**\n * Draws a graphics object onto a canvas or context\n * @param graphics - The graphics object to draw\n * @param target - The canvas element or 2D context to draw on\n * @param options - Options for controlling the transform and rendering\n */\nexport function drawGraphicsToCanvas(\n graphics: GraphicsObject,\n target: HTMLCanvasElement | CanvasRenderingContext2D,\n options: TransformOptions = {},\n): void {\n // Get the context\n const ctx =\n target instanceof HTMLCanvasElement ? target.getContext(\"2d\") : target\n\n if (!ctx) {\n throw new Error(\"Could not get 2D context from canvas\")\n }\n\n // Get canvas dimensions\n const canvasWidth =\n target instanceof HTMLCanvasElement ? target.width : target.canvas.width\n\n const canvasHeight =\n target instanceof HTMLCanvasElement ? target.height : target.canvas.height\n\n // Get or compute the transform matrix\n let matrix: Matrix\n\n if (options.transform) {\n matrix = options.transform\n } else if (options.viewbox) {\n matrix = computeTransformFromViewbox(\n options.viewbox,\n canvasWidth,\n canvasHeight,\n {\n padding: options.padding,\n yFlip: options.yFlip,\n },\n )\n } else {\n // Auto-compute bounds and transform if not provided\n const bounds = getBounds(graphics)\n const yFlip = graphics.coordinateSystem === \"cartesian\"\n matrix = computeTransformFromViewbox(bounds, canvasWidth, canvasHeight, {\n padding: options.padding ?? 40,\n yFlip,\n })\n }\n\n // Clear the canvas\n ctx.clearRect(0, 0, canvasWidth, canvasHeight)\n\n // Save the current transform state\n ctx.save()\n\n // Draw the graphics elements\n // Draw rectangles\n if (graphics.rects && graphics.rects.length > 0) {\n graphics.rects.forEach((rect) => {\n const halfWidth = rect.width / 2\n const halfHeight = rect.height / 2\n\n const topLeft = applyToPoint(matrix, {\n x: rect.center.x - halfWidth,\n y: rect.center.y - halfHeight,\n })\n\n const bottomRight = applyToPoint(matrix, {\n x: rect.center.x + halfWidth,\n y: rect.center.y + halfHeight,\n })\n\n const width = Math.abs(bottomRight.x - topLeft.x)\n const height = Math.abs(bottomRight.y - topLeft.y)\n\n ctx.beginPath()\n ctx.rect(\n Math.min(topLeft.x, bottomRight.x),\n Math.min(topLeft.y, bottomRight.y),\n width,\n height,\n )\n\n if (rect.fill) {\n ctx.fillStyle = rect.fill\n ctx.fill()\n }\n\n if (rect.stroke) {\n ctx.strokeStyle = rect.stroke\n ctx.stroke()\n }\n })\n }\n\n // Draw circles\n if (graphics.circles && graphics.circles.length > 0) {\n graphics.circles.forEach((circle) => {\n const projected = applyToPoint(matrix, circle.center)\n const scaledRadius = circle.radius * Math.abs(matrix.a) // Use matrix scale factor\n\n ctx.beginPath()\n ctx.arc(projected.x, projected.y, scaledRadius, 0, 2 * Math.PI)\n\n if (circle.fill) {\n ctx.fillStyle = circle.fill\n ctx.fill()\n }\n\n if (circle.stroke) {\n ctx.strokeStyle = circle.stroke\n ctx.stroke()\n }\n })\n }\n\n // Draw lines\n if (graphics.lines && graphics.lines.length > 0) {\n graphics.lines.forEach((line) => {\n if (line.points.length === 0) return\n\n ctx.beginPath()\n\n const firstPoint = applyToPoint(matrix, line.points[0])\n ctx.moveTo(firstPoint.x, firstPoint.y)\n\n for (let i = 1; i < line.points.length; i++) {\n const projected = applyToPoint(matrix, line.points[i])\n ctx.lineTo(projected.x, projected.y)\n }\n\n ctx.strokeStyle = line.strokeColor || \"black\"\n if (line.strokeWidth) {\n ctx.lineWidth = line.strokeWidth * matrix.a\n } else {\n ctx.lineWidth = 2\n }\n ctx.lineCap = \"round\"\n\n if (line.strokeDash) {\n if (typeof line.strokeDash === \"string\") {\n ctx.setLineDash(\n line.strokeDash\n .split(\",\")\n .map(Number)\n .map((n) => n * Math.abs(matrix.a)),\n )\n } else {\n ctx.setLineDash(line.strokeDash.map((n) => n * Math.abs(matrix.a)))\n }\n } else {\n ctx.setLineDash([])\n }\n\n ctx.stroke()\n })\n }\n\n // Draw points\n if (graphics.points && graphics.points.length > 0) {\n graphics.points.forEach((point) => {\n const projected = applyToPoint(matrix, point)\n\n // Draw point as a small circle\n ctx.beginPath()\n ctx.arc(projected.x, projected.y, 3, 0, 2 * Math.PI)\n ctx.fillStyle = point.color || \"black\"\n ctx.fill()\n\n // Draw label if present and labels aren't disabled\n if (point.label && !options.disableLabels) {\n ctx.fillStyle = point.color || \"black\"\n ctx.font = \"12px sans-serif\"\n ctx.fillText(point.label, projected.x + 5, projected.y - 5)\n }\n })\n }\n\n // Restore the original transform\n ctx.restore()\n}\n"],"mappings":";AAAA;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAYA,SAAS,4BACd,SACA,aACA,cACA,UAAiD,CAAC,GAC1C;AACR,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,QAAQ,QAAQ,SAAS;AAG/B,MAAI;AACJ,MAAI,YAAY,SAAS;AACvB,UAAM,YAAY,QAAQ,QAAQ;AAClC,UAAM,aAAa,QAAQ,SAAS;AACpC,aAAS;AAAA,MACP,MAAM,QAAQ,OAAO,IAAI;AAAA,MACzB,MAAM,QAAQ,OAAO,IAAI;AAAA,MACzB,MAAM,QAAQ,OAAO,IAAI;AAAA,MACzB,MAAM,QAAQ,OAAO,IAAI;AAAA,IAC3B;AAAA,EACF,OAAO;AACL,aAAS;AAAA,EACX;AAEA,QAAM,QAAQ,OAAO,OAAO,OAAO;AACnC,QAAM,SAAS,OAAO,OAAO,OAAO;AAEpC,QAAM,eAAe,KAAK;AAAA,KACvB,cAAc,IAAI,WAAW;AAAA,KAC7B,eAAe,IAAI,WAAW;AAAA,EACjC;AAEA,SAAO;AAAA,IACL,UAAU,cAAc,GAAG,eAAe,CAAC;AAAA,IAC3C,MAAM,cAAc,QAAQ,CAAC,eAAe,YAAY;AAAA,IACxD,UAAU,EAAE,OAAO,OAAO,QAAQ,IAAI,EAAE,OAAO,OAAO,SAAS,EAAE;AAAA,EACnE;AACF;AAKO,SAAS,UAAU,UAAmC;AAC3D,QAAM,SAAS;AAAA,IACb,GAAI,SAAS,UAAU,CAAC;AAAA,IACxB,IAAI,SAAS,SAAS,CAAC,GAAG,QAAQ,CAAC,SAAS,KAAK,MAAM;AAAA,IACvD,IAAI,SAAS,SAAS,CAAC,GAAG,QAAQ,CAAC,SAAS;AAC1C,YAAM,YAAY,KAAK,QAAQ;AAC/B,YAAM,aAAa,KAAK,SAAS;AACjC,aAAO;AAAA,QACL,EAAE,GAAG,KAAK,OAAO,IAAI,WAAW,GAAG,KAAK,OAAO,IAAI,WAAW;AAAA,QAC9D,EAAE,GAAG,KAAK,OAAO,IAAI,WAAW,GAAG,KAAK,OAAO,IAAI,WAAW;AAAA,QAC9D,EAAE,GAAG,KAAK,OAAO,IAAI,WAAW,GAAG,KAAK,OAAO,IAAI,WAAW;AAAA,QAC9D,EAAE,GAAG,KAAK,OAAO,IAAI,WAAW,GAAG,KAAK,OAAO,IAAI,WAAW;AAAA,MAChE;AAAA,IACF,CAAC;AAAA,IACD,IAAI,SAAS,WAAW,CAAC,GAAG,QAAQ,CAAC,WAAW;AAAA,MAC9C,EAAE,GAAG,OAAO,OAAO,IAAI,OAAO,QAAQ,GAAG,OAAO,OAAO,EAAE;AAAA;AAAA,MACzD,EAAE,GAAG,OAAO,OAAO,IAAI,OAAO,QAAQ,GAAG,OAAO,OAAO,EAAE;AAAA;AAAA,MACzD,EAAE,GAAG,OAAO,OAAO,GAAG,GAAG,OAAO,OAAO,IAAI,OAAO,OAAO;AAAA;AAAA,MACzD,EAAE,GAAG,OAAO,OAAO,GAAG,GAAG,OAAO,OAAO,IAAI,OAAO,OAAO;AAAA;AAAA,IAC3D,CAAC;AAAA,EACH;AAEA,MAAI,OAAO,WAAW,GAAG;AACvB,WAAO,EAAE,MAAM,IAAI,MAAM,GAAG,MAAM,IAAI,MAAM,EAAE;AAAA,EAChD;AAEA,SAAO,OAAO;AAAA,IACZ,CAAC,QAAQ,WAAW;AAAA,MAClB,MAAM,KAAK,IAAI,OAAO,MAAM,MAAM,CAAC;AAAA,MACnC,MAAM,KAAK,IAAI,OAAO,MAAM,MAAM,CAAC;AAAA,MACnC,MAAM,KAAK,IAAI,OAAO,MAAM,MAAM,CAAC;AAAA,MACnC,MAAM,KAAK,IAAI,OAAO,MAAM,MAAM,CAAC;AAAA,IACrC;AAAA,IACA,EAAE,MAAM,UAAU,MAAM,WAAW,MAAM,UAAU,MAAM,UAAU;AAAA,EACrE;AACF;AAQO,SAAS,qBACd,UACA,QACA,UAA4B,CAAC,GACvB;AAEN,QAAM,MACJ,kBAAkB,oBAAoB,OAAO,WAAW,IAAI,IAAI;AAElE,MAAI,CAAC,KAAK;AACR,UAAM,IAAI,MAAM,sCAAsC;AAAA,EACxD;AAGA,QAAM,cACJ,kBAAkB,oBAAoB,OAAO,QAAQ,OAAO,OAAO;AAErE,QAAM,eACJ,kBAAkB,oBAAoB,OAAO,SAAS,OAAO,OAAO;AAGtE,MAAI;AAEJ,MAAI,QAAQ,WAAW;AACrB,aAAS,QAAQ;AAAA,EACnB,WAAW,QAAQ,SAAS;AAC1B,aAAS;AAAA,MACP,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA;AAAA,QACE,SAAS,QAAQ;AAAA,QACjB,OAAO,QAAQ;AAAA,MACjB;AAAA,IACF;AAAA,EACF,OAAO;AAEL,UAAM,SAAS,UAAU,QAAQ;AACjC,UAAM,QAAQ,SAAS,qBAAqB;AAC5C,aAAS,4BAA4B,QAAQ,aAAa,cAAc;AAAA,MACtE,SAAS,QAAQ,WAAW;AAAA,MAC5B;AAAA,IACF,CAAC;AAAA,EACH;AAGA,MAAI,UAAU,GAAG,GAAG,aAAa,YAAY;AAG7C,MAAI,KAAK;AAIT,MAAI,SAAS,SAAS,SAAS,MAAM,SAAS,GAAG;AAC/C,aAAS,MAAM,QAAQ,CAAC,SAAS;AAC/B,YAAM,YAAY,KAAK,QAAQ;AAC/B,YAAM,aAAa,KAAK,SAAS;AAEjC,YAAM,UAAU,aAAa,QAAQ;AAAA,QACnC,GAAG,KAAK,OAAO,IAAI;AAAA,QACnB,GAAG,KAAK,OAAO,IAAI;AAAA,MACrB,CAAC;AAED,YAAM,cAAc,aAAa,QAAQ;AAAA,QACvC,GAAG,KAAK,OAAO,IAAI;AAAA,QACnB,GAAG,KAAK,OAAO,IAAI;AAAA,MACrB,CAAC;AAED,YAAM,QAAQ,KAAK,IAAI,YAAY,IAAI,QAAQ,CAAC;AAChD,YAAM,SAAS,KAAK,IAAI,YAAY,IAAI,QAAQ,CAAC;AAEjD,UAAI,UAAU;AACd,UAAI;AAAA,QACF,KAAK,IAAI,QAAQ,GAAG,YAAY,CAAC;AAAA,QACjC,KAAK,IAAI,QAAQ,GAAG,YAAY,CAAC;AAAA,QACjC;AAAA,QACA;AAAA,MACF;AAEA,UAAI,KAAK,MAAM;AACb,YAAI,YAAY,KAAK;AACrB,YAAI,KAAK;AAAA,MACX;AAEA,UAAI,KAAK,QAAQ;AACf,YAAI,cAAc,KAAK;AACvB,YAAI,OAAO;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH;AAGA,MAAI,SAAS,WAAW,SAAS,QAAQ,SAAS,GAAG;AACnD,aAAS,QAAQ,QAAQ,CAAC,WAAW;AACnC,YAAM,YAAY,aAAa,QAAQ,OAAO,MAAM;AACpD,YAAM,eAAe,OAAO,SAAS,KAAK,IAAI,OAAO,CAAC;AAEtD,UAAI,UAAU;AACd,UAAI,IAAI,UAAU,GAAG,UAAU,GAAG,cAAc,GAAG,IAAI,KAAK,EAAE;AAE9D,UAAI,OAAO,MAAM;AACf,YAAI,YAAY,OAAO;AACvB,YAAI,KAAK;AAAA,MACX;AAEA,UAAI,OAAO,QAAQ;AACjB,YAAI,cAAc,OAAO;AACzB,YAAI,OAAO;AAAA,MACb;AAAA,IACF,CAAC;AAAA,EACH;AAGA,MAAI,SAAS,SAAS,SAAS,MAAM,SAAS,GAAG;AAC/C,aAAS,MAAM,QAAQ,CAAC,SAAS;AAC/B,UAAI,KAAK,OAAO,WAAW,EAAG;AAE9B,UAAI,UAAU;AAEd,YAAM,aAAa,aAAa,QAAQ,KAAK,OAAO,CAAC,CAAC;AACtD,UAAI,OAAO,WAAW,GAAG,WAAW,CAAC;AAErC,eAAS,IAAI,GAAG,IAAI,KAAK,OAAO,QAAQ,KAAK;AAC3C,cAAM,YAAY,aAAa,QAAQ,KAAK,OAAO,CAAC,CAAC;AACrD,YAAI,OAAO,UAAU,GAAG,UAAU,CAAC;AAAA,MACrC;AAEA,UAAI,cAAc,KAAK,eAAe;AACtC,UAAI,KAAK,aAAa;AACpB,YAAI,YAAY,KAAK,cAAc,OAAO;AAAA,MAC5C,OAAO;AACL,YAAI,YAAY;AAAA,MAClB;AACA,UAAI,UAAU;AAEd,UAAI,KAAK,YAAY;AACnB,YAAI,OAAO,KAAK,eAAe,UAAU;AACvC,cAAI;AAAA,YACF,KAAK,WACF,MAAM,GAAG,EACT,IAAI,MAAM,EACV,IAAI,CAAC,MAAM,IAAI,KAAK,IAAI,OAAO,CAAC,CAAC;AAAA,UACtC;AAAA,QACF,OAAO;AACL,cAAI,YAAY,KAAK,WAAW,IAAI,CAAC,MAAM,IAAI,KAAK,IAAI,OAAO,CAAC,CAAC,CAAC;AAAA,QACpE;AAAA,MACF,OAAO;AACL,YAAI,YAAY,CAAC,CAAC;AAAA,MACpB;AAEA,UAAI,OAAO;AAAA,IACb,CAAC;AAAA,EACH;AAGA,MAAI,SAAS,UAAU,SAAS,OAAO,SAAS,GAAG;AACjD,aAAS,OAAO,QAAQ,CAAC,UAAU;AACjC,YAAM,YAAY,aAAa,QAAQ,KAAK;AAG5C,UAAI,UAAU;AACd,UAAI,IAAI,UAAU,GAAG,UAAU,GAAG,GAAG,GAAG,IAAI,KAAK,EAAE;AACnD,UAAI,YAAY,MAAM,SAAS;AAC/B,UAAI,KAAK;AAGT,UAAI,MAAM,SAAS,CAAC,QAAQ,eAAe;AACzC,YAAI,YAAY,MAAM,SAAS;AAC/B,YAAI,OAAO;AACX,YAAI,SAAS,MAAM,OAAO,UAAU,IAAI,GAAG,UAAU,IAAI,CAAC;AAAA,MAC5D;AAAA,IACF,CAAC;AAAA,EACH;AAGA,MAAI,QAAQ;AACd;","names":[]}