graphics-debug 0.0.47 → 0.0.49
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/{chunk-G3XJ25G4.js → chunk-ARYXS3GC.js} +66 -4
- package/dist/chunk-ARYXS3GC.js.map +1 -0
- package/dist/{chunk-Y2SLD6OY.js → chunk-JFOAYFXQ.js} +2 -2
- package/dist/chunk-JFOAYFXQ.js.map +1 -0
- package/dist/{chunk-ISJTINOL.js → chunk-K2IJQPPY.js} +6 -1
- package/dist/chunk-K2IJQPPY.js.map +1 -0
- package/dist/{chunk-O3RDZ6NK.js → chunk-NSJFCQQH.js} +80 -6
- package/dist/chunk-NSJFCQQH.js.map +1 -0
- package/dist/{chunk-NQULJFUY.js → chunk-TJJMMKHI.js} +3 -2
- package/dist/chunk-TJJMMKHI.js.map +1 -0
- package/dist/chunk-ZGI74PYD.js +9 -0
- package/dist/chunk-ZGI74PYD.js.map +1 -0
- package/dist/cli/cli.js +6 -5
- package/dist/cli/cli.js.map +1 -1
- package/dist/lib/constants.d.ts +4 -0
- package/dist/lib/constants.js +9 -0
- package/dist/lib/constants.js.map +1 -0
- package/dist/lib/drawGraphicsToCanvas.js +2 -1
- package/dist/lib/getSvgFromGraphicsObject.js +2 -1
- package/dist/lib/index.d.ts +2 -1
- package/dist/lib/index.js +11 -5
- package/dist/lib/matcher.js +2 -1
- package/dist/lib/matcher.js.map +1 -1
- package/dist/lib/mergeGraphics.js +1 -1
- package/dist/lib/react.d.ts +1 -1
- package/dist/lib/react.js +167 -76
- package/dist/lib/react.js.map +1 -1
- package/dist/lib/translateGraphics.js +1 -1
- package/dist/lib/types.d.ts +13 -1
- package/package.json +1 -1
- package/dist/chunk-G3XJ25G4.js.map +0 -1
- package/dist/chunk-ISJTINOL.js.map +0 -1
- package/dist/chunk-NQULJFUY.js.map +0 -1
- package/dist/chunk-O3RDZ6NK.js.map +0 -1
- package/dist/chunk-Y2SLD6OY.js.map +0 -1
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FONT_SIZE_HEIGHT_RATIO,
|
|
3
|
+
FONT_SIZE_WIDTH_RATIO
|
|
4
|
+
} from "./chunk-ZGI74PYD.js";
|
|
5
|
+
|
|
1
6
|
// lib/drawGraphicsToCanvas.ts
|
|
2
7
|
import {
|
|
3
8
|
compose,
|
|
@@ -63,8 +68,8 @@ function computeTransformFromViewbox(viewbox, canvasWidth, canvasHeight, options
|
|
|
63
68
|
} else {
|
|
64
69
|
bounds = viewbox;
|
|
65
70
|
}
|
|
66
|
-
const width = bounds.maxX - bounds.minX;
|
|
67
|
-
const height = bounds.maxY - bounds.minY;
|
|
71
|
+
const width = bounds.maxX - bounds.minX || 1;
|
|
72
|
+
const height = bounds.maxY - bounds.minY || 1;
|
|
68
73
|
const scale_factor = Math.min(
|
|
69
74
|
(canvasWidth - 2 * padding) / width,
|
|
70
75
|
(canvasHeight - 2 * padding) / height
|
|
@@ -98,7 +103,31 @@ function getBounds(graphics) {
|
|
|
98
103
|
// top
|
|
99
104
|
{ x: circle.center.x, y: circle.center.y + circle.radius }
|
|
100
105
|
// bottom
|
|
101
|
-
])
|
|
106
|
+
]),
|
|
107
|
+
...(graphics.texts || []).flatMap((text) => {
|
|
108
|
+
const fontSize = text.fontSize ?? 12;
|
|
109
|
+
const width = text.text.length * fontSize * FONT_SIZE_WIDTH_RATIO;
|
|
110
|
+
const height = fontSize * FONT_SIZE_HEIGHT_RATIO;
|
|
111
|
+
const anchor = text.anchorSide ?? "center";
|
|
112
|
+
const offsetMap = {
|
|
113
|
+
top_left: { dx: 0, dy: 0 },
|
|
114
|
+
top_center: { dx: -width / 2, dy: 0 },
|
|
115
|
+
top_right: { dx: -width, dy: 0 },
|
|
116
|
+
center_left: { dx: 0, dy: -height / 2 },
|
|
117
|
+
center: { dx: -width / 2, dy: -height / 2 },
|
|
118
|
+
center_right: { dx: -width, dy: -height / 2 },
|
|
119
|
+
bottom_left: { dx: 0, dy: -height },
|
|
120
|
+
bottom_center: { dx: -width / 2, dy: -height },
|
|
121
|
+
bottom_right: { dx: -width, dy: -height }
|
|
122
|
+
};
|
|
123
|
+
const { dx, dy } = offsetMap[anchor];
|
|
124
|
+
const x0 = text.x + dx;
|
|
125
|
+
const y0 = text.y + dy;
|
|
126
|
+
return [
|
|
127
|
+
{ x: x0, y: y0 },
|
|
128
|
+
{ x: x0 + width, y: y0 + height }
|
|
129
|
+
];
|
|
130
|
+
})
|
|
102
131
|
];
|
|
103
132
|
if (points.length === 0) {
|
|
104
133
|
return { minX: -1, maxX: 1, minY: -1, maxY: 1 };
|
|
@@ -240,6 +269,39 @@ function drawGraphicsToCanvas(graphics, target, options = {}) {
|
|
|
240
269
|
}
|
|
241
270
|
});
|
|
242
271
|
}
|
|
272
|
+
if (graphics.texts && graphics.texts.length > 0) {
|
|
273
|
+
graphics.texts.forEach((text) => {
|
|
274
|
+
const projected = applyToPoint(matrix, { x: text.x, y: text.y });
|
|
275
|
+
ctx.fillStyle = text.color || "black";
|
|
276
|
+
ctx.font = `${(text.fontSize ?? 12) * Math.abs(matrix.a)}px sans-serif`;
|
|
277
|
+
const anchor = text.anchorSide ?? "center";
|
|
278
|
+
const alignMap = {
|
|
279
|
+
top_left: "left",
|
|
280
|
+
center_left: "left",
|
|
281
|
+
bottom_left: "left",
|
|
282
|
+
top_center: "center",
|
|
283
|
+
center: "center",
|
|
284
|
+
bottom_center: "center",
|
|
285
|
+
top_right: "right",
|
|
286
|
+
center_right: "right",
|
|
287
|
+
bottom_right: "right"
|
|
288
|
+
};
|
|
289
|
+
const baselineMap = {
|
|
290
|
+
top_left: "top",
|
|
291
|
+
top_center: "top",
|
|
292
|
+
top_right: "top",
|
|
293
|
+
center_left: "middle",
|
|
294
|
+
center: "middle",
|
|
295
|
+
center_right: "middle",
|
|
296
|
+
bottom_left: "bottom",
|
|
297
|
+
bottom_center: "bottom",
|
|
298
|
+
bottom_right: "bottom"
|
|
299
|
+
};
|
|
300
|
+
ctx.textAlign = alignMap[anchor];
|
|
301
|
+
ctx.textBaseline = baselineMap[anchor];
|
|
302
|
+
ctx.fillText(text.text, projected.x, projected.y);
|
|
303
|
+
});
|
|
304
|
+
}
|
|
243
305
|
ctx.restore();
|
|
244
306
|
}
|
|
245
307
|
|
|
@@ -249,4 +311,4 @@ export {
|
|
|
249
311
|
getBounds,
|
|
250
312
|
drawGraphicsToCanvas
|
|
251
313
|
};
|
|
252
|
-
//# sourceMappingURL=chunk-
|
|
314
|
+
//# sourceMappingURL=chunk-ARYXS3GC.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/drawGraphicsToCanvas.ts","../site/components/InteractiveGraphics/defaultColors.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\"\nimport { defaultColors } from \"site/components/InteractiveGraphics/defaultColors\"\nimport { FONT_SIZE_WIDTH_RATIO, FONT_SIZE_HEIGHT_RATIO } from \"./constants\"\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 || 1\n const height = bounds.maxY - bounds.minY || 1\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 ...(graphics.texts || []).flatMap((text) => {\n const fontSize = text.fontSize ?? 12\n const width = text.text.length * fontSize * FONT_SIZE_WIDTH_RATIO\n const height = fontSize * FONT_SIZE_HEIGHT_RATIO\n const anchor = text.anchorSide ?? \"center\"\n const offsetMap: Record<string, { dx: number; dy: number }> = {\n top_left: { dx: 0, dy: 0 },\n top_center: { dx: -width / 2, dy: 0 },\n top_right: { dx: -width, dy: 0 },\n center_left: { dx: 0, dy: -height / 2 },\n center: { dx: -width / 2, dy: -height / 2 },\n center_right: { dx: -width, dy: -height / 2 },\n bottom_left: { dx: 0, dy: -height },\n bottom_center: { dx: -width / 2, dy: -height },\n bottom_right: { dx: -width, dy: -height },\n }\n const { dx, dy } = offsetMap[anchor]\n const x0 = text.x + dx\n const y0 = text.y + dy\n return [\n { x: x0, y: y0 },\n { x: x0 + width, y: y0 + height },\n ]\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, lineIndex) => {\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 =\n line.strokeColor || defaultColors[lineIndex % defaultColors.length]\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 // Convert string to array of numbers, handling single values properly\n let dashArray: number[]\n\n // If the string contains commas, split and convert to numbers\n if (line.strokeDash.includes(\",\")) {\n dashArray = line.strokeDash\n .split(\",\")\n .map((s) => parseFloat(s.trim()))\n .filter((n) => !Number.isNaN(n))\n } else {\n // Handle single value case\n const value = parseFloat(line.strokeDash.trim())\n dashArray = !Number.isNaN(value) ? [value] : []\n }\n\n // Scale dash values based on transform matrix\n ctx.setLineDash(dashArray)\n } else {\n // Handle array format\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, pointIndex) => {\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 =\n point.color || defaultColors[pointIndex % defaultColors.length]\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 // Draw texts\n if (graphics.texts && graphics.texts.length > 0) {\n graphics.texts.forEach((text) => {\n const projected = applyToPoint(matrix, { x: text.x, y: text.y })\n ctx.fillStyle = text.color || \"black\"\n ctx.font = `${(text.fontSize ?? 12) * Math.abs(matrix.a)}px sans-serif`\n\n const anchor = text.anchorSide ?? \"center\"\n const alignMap: Record<string, CanvasTextAlign> = {\n top_left: \"left\",\n center_left: \"left\",\n bottom_left: \"left\",\n top_center: \"center\",\n center: \"center\",\n bottom_center: \"center\",\n top_right: \"right\",\n center_right: \"right\",\n bottom_right: \"right\",\n }\n const baselineMap: Record<string, CanvasTextBaseline> = {\n top_left: \"top\",\n top_center: \"top\",\n top_right: \"top\",\n center_left: \"middle\",\n center: \"middle\",\n center_right: \"middle\",\n bottom_left: \"bottom\",\n bottom_center: \"bottom\",\n bottom_right: \"bottom\",\n }\n ctx.textAlign = alignMap[anchor]\n ctx.textBaseline = baselineMap[anchor]\n\n ctx.fillText(text.text, projected.x, projected.y)\n })\n }\n\n // Restore the original transform\n ctx.restore()\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"],"mappings":"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","names":[]}
|
|
@@ -3,7 +3,7 @@ import {
|
|
|
3
3
|
} from "./chunk-NG6H63SM.js";
|
|
4
4
|
import {
|
|
5
5
|
getSvgFromGraphicsObject
|
|
6
|
-
} from "./chunk-
|
|
6
|
+
} from "./chunk-NSJFCQQH.js";
|
|
7
7
|
|
|
8
8
|
// lib/index.ts
|
|
9
9
|
function getSvgFromLogString(logString) {
|
|
@@ -53,4 +53,4 @@ export {
|
|
|
53
53
|
getHtmlFromLogString,
|
|
54
54
|
getSvgsFromLogString
|
|
55
55
|
};
|
|
56
|
-
//# sourceMappingURL=chunk-
|
|
56
|
+
//# sourceMappingURL=chunk-JFOAYFXQ.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/index.ts"],"sourcesContent":["import { getGraphicsObjectsFromLogString } from \"./getGraphicsObjectsFromLogString\"\nimport { getSvgFromGraphicsObject } from \"./getSvgFromGraphicsObject\"\nimport {\n drawGraphicsToCanvas,\n computeTransformFromViewbox,\n getBounds,\n} from \"./drawGraphicsToCanvas\"\nimport { translateGraphics } from \"./translateGraphics\"\nimport { mergeGraphics } from \"./mergeGraphics\"\n\nexport type {\n Point,\n Line,\n Rect,\n Circle,\n Text,\n NinePointAnchor,\n GraphicsObject,\n Viewbox,\n CenterViewbox,\n TransformOptions,\n} from \"./types\"\nexport { getGraphicsObjectsFromLogString } from \"./getGraphicsObjectsFromLogString\"\nexport { getSvgFromGraphicsObject } from \"./getSvgFromGraphicsObject\"\nexport {\n drawGraphicsToCanvas,\n computeTransformFromViewbox,\n getBounds,\n} from \"./drawGraphicsToCanvas\"\nexport { translateGraphics } from \"./translateGraphics\"\nexport { mergeGraphics } from \"./mergeGraphics\"\nexport { FONT_SIZE_WIDTH_RATIO, FONT_SIZE_HEIGHT_RATIO } from \"./constants\"\n\nexport function getSvgFromLogString(logString: string): string {\n const objects = getGraphicsObjectsFromLogString(logString)\n if (objects.length === 0) return \"\"\n return getSvgFromGraphicsObject(objects[0])\n}\n\nexport function getHtmlFromLogString(logString: string): string {\n const svgs = getSvgsFromLogString(logString)\n if (svgs.length === 0) return \"\"\n\n const sections = svgs\n .map(\n ({ title, svg }) => `\n <section>\n <h2>${title}</h2>\n ${svg}\n </section>\n `,\n )\n .join(\"\\n\")\n\n return `\n<!DOCTYPE html>\n<html>\n<head>\n <title>Graphics Debug Output</title>\n <style>\n body { font-family: system-ui; max-width: 1200px; margin: 0 auto; padding: 20px; }\n h1 { color: #333; }\n section { margin: 40px 0; }\n svg { max-width: 100%; height: auto; border: 1px solid #eee; }\n </style>\n</head>\n<body>\n <h1>Graphics Debug Output</h1>\n ${sections}\n</body>\n</html>`\n}\n\nexport function getSvgsFromLogString(\n logString: string,\n): Array<{ title: string; svg: string }> {\n const objects = getGraphicsObjectsFromLogString(logString)\n return objects.map((obj) => ({\n title: obj.title || \"Untitled Graphic\",\n svg: getSvgFromGraphicsObject(obj),\n }))\n}\n"],"mappings":";;;;;;;;AAiCO,SAAS,oBAAoB,WAA2B;AAC7D,QAAM,UAAU,gCAAgC,SAAS;AACzD,MAAI,QAAQ,WAAW,EAAG,QAAO;AACjC,SAAO,yBAAyB,QAAQ,CAAC,CAAC;AAC5C;AAEO,SAAS,qBAAqB,WAA2B;AAC9D,QAAM,OAAO,qBAAqB,SAAS;AAC3C,MAAI,KAAK,WAAW,EAAG,QAAO;AAE9B,QAAM,WAAW,KACd;AAAA,IACC,CAAC,EAAE,OAAO,IAAI,MAAM;AAAA;AAAA,YAEd,KAAK;AAAA,QACT,GAAG;AAAA;AAAA;AAAA,EAGP,EACC,KAAK,IAAI;AAEZ,SAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,IAcL,QAAQ;AAAA;AAAA;AAGZ;AAEO,SAAS,qBACd,WACuC;AACvC,QAAM,UAAU,gCAAgC,SAAS;AACzD,SAAO,QAAQ,IAAI,CAAC,SAAS;AAAA,IAC3B,OAAO,IAAI,SAAS;AAAA,IACpB,KAAK,yBAAyB,GAAG;AAAA,EACnC,EAAE;AACJ;","names":[]}
|
|
@@ -18,6 +18,11 @@ function translateGraphics(graphics, dx, dy) {
|
|
|
18
18
|
circles: graphics.circles?.map((circle) => ({
|
|
19
19
|
...circle,
|
|
20
20
|
center: { x: circle.center.x + dx, y: circle.center.y + dy }
|
|
21
|
+
})),
|
|
22
|
+
texts: graphics.texts?.map((text) => ({
|
|
23
|
+
...text,
|
|
24
|
+
x: text.x + dx,
|
|
25
|
+
y: text.y + dy
|
|
21
26
|
}))
|
|
22
27
|
};
|
|
23
28
|
}
|
|
@@ -25,4 +30,4 @@ function translateGraphics(graphics, dx, dy) {
|
|
|
25
30
|
export {
|
|
26
31
|
translateGraphics
|
|
27
32
|
};
|
|
28
|
-
//# sourceMappingURL=chunk-
|
|
33
|
+
//# sourceMappingURL=chunk-K2IJQPPY.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/translateGraphics.ts"],"sourcesContent":["import type { GraphicsObject } from \"./types\"\n\nexport function translateGraphics(\n graphics: GraphicsObject,\n dx: number,\n dy: number,\n): GraphicsObject {\n return {\n ...graphics,\n points: graphics.points?.map((p) => ({\n ...p,\n x: p.x + dx,\n y: p.y + dy,\n })),\n lines: graphics.lines?.map((line) => ({\n ...line,\n points: line.points.map((pt) => ({ x: pt.x + dx, y: pt.y + dy })),\n })),\n rects: graphics.rects?.map((rect) => ({\n ...rect,\n center: { x: rect.center.x + dx, y: rect.center.y + dy },\n })),\n circles: graphics.circles?.map((circle) => ({\n ...circle,\n center: { x: circle.center.x + dx, y: circle.center.y + dy },\n })),\n texts: graphics.texts?.map((text) => ({\n ...text,\n x: text.x + dx,\n y: text.y + dy,\n })),\n }\n}\n"],"mappings":";AAEO,SAAS,kBACd,UACA,IACA,IACgB;AAChB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,QAAQ,SAAS,QAAQ,IAAI,CAAC,OAAO;AAAA,MACnC,GAAG;AAAA,MACH,GAAG,EAAE,IAAI;AAAA,MACT,GAAG,EAAE,IAAI;AAAA,IACX,EAAE;AAAA,IACF,OAAO,SAAS,OAAO,IAAI,CAAC,UAAU;AAAA,MACpC,GAAG;AAAA,MACH,QAAQ,KAAK,OAAO,IAAI,CAAC,QAAQ,EAAE,GAAG,GAAG,IAAI,IAAI,GAAG,GAAG,IAAI,GAAG,EAAE;AAAA,IAClE,EAAE;AAAA,IACF,OAAO,SAAS,OAAO,IAAI,CAAC,UAAU;AAAA,MACpC,GAAG;AAAA,MACH,QAAQ,EAAE,GAAG,KAAK,OAAO,IAAI,IAAI,GAAG,KAAK,OAAO,IAAI,GAAG;AAAA,IACzD,EAAE;AAAA,IACF,SAAS,SAAS,SAAS,IAAI,CAAC,YAAY;AAAA,MAC1C,GAAG;AAAA,MACH,QAAQ,EAAE,GAAG,OAAO,OAAO,IAAI,IAAI,GAAG,OAAO,OAAO,IAAI,GAAG;AAAA,IAC7D,EAAE;AAAA,IACF,OAAO,SAAS,OAAO,IAAI,CAAC,UAAU;AAAA,MACpC,GAAG;AAAA,MACH,GAAG,KAAK,IAAI;AAAA,MACZ,GAAG,KAAK,IAAI;AAAA,IACd,EAAE;AAAA,EACJ;AACF;","names":[]}
|
|
@@ -1,3 +1,8 @@
|
|
|
1
|
+
import {
|
|
2
|
+
FONT_SIZE_HEIGHT_RATIO,
|
|
3
|
+
FONT_SIZE_WIDTH_RATIO
|
|
4
|
+
} from "./chunk-ZGI74PYD.js";
|
|
5
|
+
|
|
1
6
|
// lib/getSvgFromGraphicsObject.ts
|
|
2
7
|
import {
|
|
3
8
|
compose,
|
|
@@ -32,7 +37,31 @@ function getBounds(graphics) {
|
|
|
32
37
|
// top
|
|
33
38
|
{ x: circle.center.x, y: circle.center.y + circle.radius }
|
|
34
39
|
// bottom
|
|
35
|
-
])
|
|
40
|
+
]),
|
|
41
|
+
...(graphics.texts || []).flatMap((t) => {
|
|
42
|
+
const fontSize = t.fontSize ?? 12;
|
|
43
|
+
const width = t.text.length * fontSize * FONT_SIZE_WIDTH_RATIO;
|
|
44
|
+
const height = fontSize * FONT_SIZE_HEIGHT_RATIO;
|
|
45
|
+
const anchor = t.anchorSide ?? "center";
|
|
46
|
+
const offsetMap = {
|
|
47
|
+
top_left: { dx: 0, dy: 0 },
|
|
48
|
+
top_center: { dx: -width / 2, dy: 0 },
|
|
49
|
+
top_right: { dx: -width, dy: 0 },
|
|
50
|
+
center_left: { dx: 0, dy: -height / 2 },
|
|
51
|
+
center: { dx: -width / 2, dy: -height / 2 },
|
|
52
|
+
center_right: { dx: -width, dy: -height / 2 },
|
|
53
|
+
bottom_left: { dx: 0, dy: -height },
|
|
54
|
+
bottom_center: { dx: -width / 2, dy: -height },
|
|
55
|
+
bottom_right: { dx: -width, dy: -height }
|
|
56
|
+
};
|
|
57
|
+
const { dx, dy } = offsetMap[anchor];
|
|
58
|
+
const x0 = t.x + dx;
|
|
59
|
+
const y0 = t.y + dy;
|
|
60
|
+
return [
|
|
61
|
+
{ x: x0, y: y0 },
|
|
62
|
+
{ x: x0 + width, y: y0 + height }
|
|
63
|
+
];
|
|
64
|
+
})
|
|
36
65
|
];
|
|
37
66
|
if (points.length === 0) {
|
|
38
67
|
return { minX: -1, maxX: 1, minY: -1, maxY: 1 };
|
|
@@ -48,8 +77,8 @@ function getBounds(graphics) {
|
|
|
48
77
|
);
|
|
49
78
|
}
|
|
50
79
|
function getProjectionMatrix(bounds, coordinateSystem) {
|
|
51
|
-
const width = bounds.maxX - bounds.minX;
|
|
52
|
-
const height = bounds.maxY - bounds.minY;
|
|
80
|
+
const width = bounds.maxX - bounds.minX || 1;
|
|
81
|
+
const height = bounds.maxY - bounds.minY || 1;
|
|
53
82
|
const scale_factor = Math.min(
|
|
54
83
|
(DEFAULT_SVG_SIZE - 2 * PADDING) / width,
|
|
55
84
|
(DEFAULT_SVG_SIZE - 2 * PADDING) / height
|
|
@@ -66,7 +95,7 @@ function projectPoint(point, matrix) {
|
|
|
66
95
|
return { ...point, ...projected };
|
|
67
96
|
}
|
|
68
97
|
function getSvgFromGraphicsObject(graphics, {
|
|
69
|
-
includeTextLabels =
|
|
98
|
+
includeTextLabels = true,
|
|
70
99
|
backgroundColor
|
|
71
100
|
} = {}) {
|
|
72
101
|
const bounds = getBounds(graphics);
|
|
@@ -158,7 +187,7 @@ function getSvgFromGraphicsObject(graphics, {
|
|
|
158
187
|
points: projectedPoints.map((p) => `${p.x},${p.y}`).join(" "),
|
|
159
188
|
fill: "none",
|
|
160
189
|
stroke: line.strokeColor || "black",
|
|
161
|
-
"stroke-width": (line.strokeWidth
|
|
190
|
+
"stroke-width": (line.strokeWidth ?? 1).toString(),
|
|
162
191
|
...line.strokeDash && {
|
|
163
192
|
"stroke-dasharray": Array.isArray(line.strokeDash) ? line.strokeDash.join(" ") : line.strokeDash
|
|
164
193
|
}
|
|
@@ -260,6 +289,51 @@ function getSvgFromGraphicsObject(graphics, {
|
|
|
260
289
|
}
|
|
261
290
|
};
|
|
262
291
|
}),
|
|
292
|
+
// Texts
|
|
293
|
+
...(graphics.texts || []).map((txt) => {
|
|
294
|
+
const projected = projectPoint({ x: txt.x, y: txt.y }, matrix);
|
|
295
|
+
const anchor = txt.anchorSide ?? "center";
|
|
296
|
+
const alignMap = {
|
|
297
|
+
top_left: "start",
|
|
298
|
+
center_left: "start",
|
|
299
|
+
bottom_left: "start",
|
|
300
|
+
top_center: "middle",
|
|
301
|
+
center: "middle",
|
|
302
|
+
bottom_center: "middle",
|
|
303
|
+
top_right: "end",
|
|
304
|
+
center_right: "end",
|
|
305
|
+
bottom_right: "end"
|
|
306
|
+
};
|
|
307
|
+
const baselineMap = {
|
|
308
|
+
top_left: "text-before-edge",
|
|
309
|
+
top_center: "text-before-edge",
|
|
310
|
+
top_right: "text-before-edge",
|
|
311
|
+
center_left: "central",
|
|
312
|
+
center: "central",
|
|
313
|
+
center_right: "central",
|
|
314
|
+
bottom_left: "text-after-edge",
|
|
315
|
+
bottom_center: "text-after-edge",
|
|
316
|
+
bottom_right: "text-after-edge"
|
|
317
|
+
};
|
|
318
|
+
return {
|
|
319
|
+
name: "text",
|
|
320
|
+
type: "element",
|
|
321
|
+
attributes: {
|
|
322
|
+
"data-type": "text",
|
|
323
|
+
"data-label": txt.text,
|
|
324
|
+
"data-x": txt.x.toString(),
|
|
325
|
+
"data-y": txt.y.toString(),
|
|
326
|
+
x: projected.x.toString(),
|
|
327
|
+
y: projected.y.toString(),
|
|
328
|
+
fill: txt.color || "black",
|
|
329
|
+
"font-size": ((txt.fontSize ?? 12) * Math.abs(matrix.a)).toString(),
|
|
330
|
+
"font-family": "sans-serif",
|
|
331
|
+
"text-anchor": alignMap[anchor],
|
|
332
|
+
"dominant-baseline": baselineMap[anchor]
|
|
333
|
+
},
|
|
334
|
+
children: [{ type: "text", value: txt.text }]
|
|
335
|
+
};
|
|
336
|
+
}),
|
|
263
337
|
// Crosshair lines and coordinates (initially hidden)
|
|
264
338
|
{
|
|
265
339
|
name: "g",
|
|
@@ -366,4 +440,4 @@ function getSvgFromGraphicsObject(graphics, {
|
|
|
366
440
|
export {
|
|
367
441
|
getSvgFromGraphicsObject
|
|
368
442
|
};
|
|
369
|
-
//# sourceMappingURL=chunk-
|
|
443
|
+
//# sourceMappingURL=chunk-NSJFCQQH.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/getSvgFromGraphicsObject.ts"],"sourcesContent":["import {\n transform,\n compose,\n translate,\n scale,\n applyToPoint,\n identity,\n type Matrix,\n} from \"transformation-matrix\"\nimport type { GraphicsObject, Point } from \"./types\"\nimport { stringify } from \"svgson\"\nimport pretty from \"pretty\"\nimport { FONT_SIZE_WIDTH_RATIO, FONT_SIZE_HEIGHT_RATIO } from \"./constants\"\n\nconst DEFAULT_SVG_SIZE = 640\nconst PADDING = 40\n\ninterface Bounds {\n minX: number\n maxX: number\n minY: number\n maxY: number\n}\n\nfunction getBounds(graphics: GraphicsObject): Bounds {\n const points: Point[] = [\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 ...(graphics.texts || []).flatMap((t) => {\n const fontSize = t.fontSize ?? 12\n const width = t.text.length * fontSize * FONT_SIZE_WIDTH_RATIO\n const height = fontSize * FONT_SIZE_HEIGHT_RATIO\n const anchor = t.anchorSide ?? \"center\"\n const offsetMap: Record<string, { dx: number; dy: number }> = {\n top_left: { dx: 0, dy: 0 },\n top_center: { dx: -width / 2, dy: 0 },\n top_right: { dx: -width, dy: 0 },\n center_left: { dx: 0, dy: -height / 2 },\n center: { dx: -width / 2, dy: -height / 2 },\n center_right: { dx: -width, dy: -height / 2 },\n bottom_left: { dx: 0, dy: -height },\n bottom_center: { dx: -width / 2, dy: -height },\n bottom_right: { dx: -width, dy: -height },\n }\n const { dx, dy } = offsetMap[anchor]\n const x0 = t.x + dx\n const y0 = t.y + dy\n return [\n { x: x0, y: y0 },\n { x: x0 + width, y: y0 + height },\n ]\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\nfunction getProjectionMatrix(\n bounds: Bounds,\n coordinateSystem: GraphicsObject[\"coordinateSystem\"],\n) {\n const width = bounds.maxX - bounds.minX || 1\n const height = bounds.maxY - bounds.minY || 1\n\n const scale_factor = Math.min(\n (DEFAULT_SVG_SIZE - 2 * PADDING) / width,\n (DEFAULT_SVG_SIZE - 2 * PADDING) / height,\n )\n\n const yFlip = coordinateSystem === \"screen\" ? 1 : -1\n\n return compose(\n translate(DEFAULT_SVG_SIZE / 2, DEFAULT_SVG_SIZE / 2),\n scale(scale_factor, yFlip * scale_factor),\n translate(-(bounds.minX + width / 2), -(bounds.minY + height / 2)),\n )\n}\n\nfunction projectPoint(point: Point, matrix: Matrix) {\n const projected = applyToPoint(matrix, { x: point.x, y: point.y })\n return { ...point, ...projected }\n}\n\nexport function getSvgFromGraphicsObject(\n graphics: GraphicsObject,\n {\n includeTextLabels = true,\n backgroundColor,\n }: {\n includeTextLabels?: boolean | Array<\"points\" | \"lines\" | \"rects\">\n backgroundColor?: string\n } = {},\n): string {\n const bounds = getBounds(graphics)\n const matrix = getProjectionMatrix(bounds, graphics.coordinateSystem)\n\n const shouldRenderLabel = (type: \"points\" | \"lines\" | \"rects\"): boolean => {\n if (typeof includeTextLabels === \"boolean\") {\n return includeTextLabels\n }\n if (Array.isArray(includeTextLabels)) {\n return includeTextLabels.includes(type)\n }\n return false\n }\n\n const svgObject = {\n name: \"svg\",\n type: \"element\",\n attributes: {\n width: DEFAULT_SVG_SIZE.toString(),\n height: DEFAULT_SVG_SIZE.toString(),\n viewBox: `0 0 ${DEFAULT_SVG_SIZE} ${DEFAULT_SVG_SIZE}`,\n xmlns: \"http://www.w3.org/2000/svg\",\n },\n children: [\n // Background rectangle (optional)\n ...(backgroundColor\n ? [\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n width: \"100%\",\n height: \"100%\",\n fill: backgroundColor,\n },\n },\n ]\n : []),\n // Points\n ...(graphics.points || []).map((point) => {\n const projected = projectPoint(point, matrix)\n return {\n name: \"g\",\n type: \"element\",\n attributes: {},\n children: [\n {\n name: \"circle\",\n type: \"element\",\n attributes: {\n \"data-type\": \"point\",\n \"data-label\": point.label || \"\",\n \"data-x\": point.x.toString(),\n \"data-y\": point.y.toString(),\n cx: projected.x.toString(),\n cy: projected.y.toString(),\n r: \"3\",\n fill: point.color || \"black\",\n },\n },\n ...(shouldRenderLabel(\"points\") && point.label\n ? [\n {\n name: \"text\",\n type: \"element\",\n attributes: {\n x: (projected.x + 5).toString(),\n y: (projected.y - 5).toString(),\n \"font-family\": \"sans-serif\",\n \"font-size\": \"12\",\n },\n children: [{ type: \"text\", value: point.label }],\n },\n ]\n : []),\n ],\n }\n }),\n // Lines\n ...(graphics.lines || []).map((line) => {\n const projectedPoints = line.points.map((p) => projectPoint(p, matrix))\n return {\n name: \"g\",\n type: \"element\",\n attributes: {},\n children: [\n {\n name: \"polyline\",\n type: \"element\",\n attributes: {\n \"data-points\": line.points\n .map((p) => `${p.x},${p.y}`)\n .join(\" \"),\n \"data-type\": \"line\",\n \"data-label\": line.label || \"\",\n points: projectedPoints.map((p) => `${p.x},${p.y}`).join(\" \"),\n fill: \"none\",\n stroke: line.strokeColor || \"black\",\n \"stroke-width\": (line.strokeWidth ?? 1).toString(),\n ...(line.strokeDash && {\n \"stroke-dasharray\": Array.isArray(line.strokeDash)\n ? line.strokeDash.join(\" \")\n : line.strokeDash,\n }),\n },\n },\n ...(shouldRenderLabel(\"lines\") &&\n line.label &&\n projectedPoints.length > 0\n ? [\n {\n name: \"text\",\n type: \"element\",\n attributes: {\n x: (projectedPoints[0].x + 5).toString(),\n y: (projectedPoints[0].y - 5).toString(),\n \"font-family\": \"sans-serif\",\n \"font-size\": \"12\",\n fill: line.strokeColor || \"black\",\n },\n children: [{ type: \"text\", value: line.label }],\n },\n ]\n : []),\n ],\n }\n }),\n // Rectangles\n ...(graphics.rects || []).map((rect) => {\n const corner1 = {\n x: rect.center.x - rect.width / 2,\n y: rect.center.y - rect.height / 2,\n }\n const projectedCorner1 = projectPoint(corner1, matrix)\n const corner2 = {\n x: rect.center.x + rect.width / 2,\n y: rect.center.y + rect.height / 2,\n }\n const projectedCorner2 = projectPoint(corner2, matrix)\n const scaledWidth = Math.abs(projectedCorner2.x - projectedCorner1.x)\n const scaledHeight = Math.abs(projectedCorner2.y - projectedCorner1.y)\n const rectX = Math.min(projectedCorner1.x, projectedCorner2.x)\n const rectY = Math.min(projectedCorner1.y, projectedCorner2.y)\n\n return {\n name: \"g\",\n type: \"element\",\n attributes: {},\n children: [\n {\n name: \"rect\",\n type: \"element\",\n attributes: {\n \"data-type\": \"rect\",\n \"data-label\": rect.label || \"\",\n \"data-x\": rect.center.x.toString(),\n \"data-y\": rect.center.y.toString(),\n x: rectX.toString(),\n y: rectY.toString(),\n width: scaledWidth.toString(),\n height: scaledHeight.toString(),\n fill: rect.fill || \"none\",\n stroke: rect.stroke || \"black\",\n \"stroke-width\": Math.abs(1 / matrix.a).toString(), // Consider scaling stroke width like lines if needed\n },\n },\n ...(shouldRenderLabel(\"rects\") && rect.label\n ? [\n {\n name: \"text\",\n type: \"element\",\n attributes: {\n x: (rectX + 5).toString(),\n y: (rectY - 5).toString(), // Position above the top-left corner\n \"font-family\": \"sans-serif\",\n \"font-size\": \"12\",\n fill: rect.stroke || \"black\", // Default to stroke color for label\n },\n children: [{ type: \"text\", value: rect.label }],\n },\n ]\n : []),\n ],\n }\n }),\n // Circles\n ...(graphics.circles || []).map((circle) => {\n const projected = projectPoint(circle.center, matrix)\n const scaledRadius = circle.radius * Math.abs(matrix.a)\n return {\n name: \"circle\",\n type: \"element\",\n attributes: {\n \"data-type\": \"circle\",\n \"data-label\": \"\",\n \"data-x\": circle.center.x.toString(),\n \"data-y\": circle.center.y.toString(),\n cx: projected.x.toString(),\n cy: projected.y.toString(),\n r: scaledRadius.toString(),\n fill: circle.fill || \"none\",\n stroke: circle.stroke || \"black\",\n \"stroke-width\": Math.abs(1 / matrix.a).toString(),\n },\n }\n }),\n // Texts\n ...(graphics.texts || []).map((txt) => {\n const projected = projectPoint({ x: txt.x, y: txt.y }, matrix)\n const anchor = txt.anchorSide ?? \"center\"\n const alignMap: Record<string, string> = {\n top_left: \"start\",\n center_left: \"start\",\n bottom_left: \"start\",\n top_center: \"middle\",\n center: \"middle\",\n bottom_center: \"middle\",\n top_right: \"end\",\n center_right: \"end\",\n bottom_right: \"end\",\n }\n const baselineMap: Record<string, string> = {\n top_left: \"text-before-edge\",\n top_center: \"text-before-edge\",\n top_right: \"text-before-edge\",\n center_left: \"central\",\n center: \"central\",\n center_right: \"central\",\n bottom_left: \"text-after-edge\",\n bottom_center: \"text-after-edge\",\n bottom_right: \"text-after-edge\",\n }\n return {\n name: \"text\",\n type: \"element\",\n attributes: {\n \"data-type\": \"text\",\n \"data-label\": txt.text,\n \"data-x\": txt.x.toString(),\n \"data-y\": txt.y.toString(),\n x: projected.x.toString(),\n y: projected.y.toString(),\n fill: txt.color || \"black\",\n \"font-size\": ((txt.fontSize ?? 12) * Math.abs(matrix.a)).toString(),\n \"font-family\": \"sans-serif\",\n \"text-anchor\": alignMap[anchor],\n \"dominant-baseline\": baselineMap[anchor],\n },\n children: [{ type: \"text\", value: txt.text }],\n }\n }),\n // Crosshair lines and coordinates (initially hidden)\n {\n name: \"g\",\n type: \"element\",\n attributes: {\n id: \"crosshair\",\n style: \"display: none\",\n },\n children: [\n {\n name: \"line\",\n type: \"element\",\n attributes: {\n id: \"crosshair-h\",\n y1: \"0\",\n y2: DEFAULT_SVG_SIZE.toString(),\n stroke: \"#666\",\n \"stroke-width\": \"0.5\",\n },\n },\n {\n name: \"line\",\n type: \"element\",\n attributes: {\n id: \"crosshair-v\",\n x1: \"0\",\n x2: DEFAULT_SVG_SIZE.toString(),\n stroke: \"#666\",\n \"stroke-width\": \"0.5\",\n },\n },\n {\n name: \"text\",\n type: \"element\",\n attributes: {\n id: \"coordinates\",\n \"font-family\": \"monospace\",\n \"font-size\": \"12\",\n fill: \"#666\",\n },\n children: [{ type: \"text\", value: \"\" }],\n },\n ],\n },\n // Mouse tracking script\n {\n name: \"script\",\n type: \"element\",\n children: [\n {\n type: \"text\",\n value: `\n document.currentScript.parentElement.addEventListener('mousemove', (e) => {\n const svg = e.currentTarget;\n const rect = svg.getBoundingClientRect();\n const x = e.clientX - rect.left;\n const y = e.clientY - rect.top;\n const crosshair = svg.getElementById('crosshair');\n const h = svg.getElementById('crosshair-h');\n const v = svg.getElementById('crosshair-v');\n const coords = svg.getElementById('coordinates');\n \n crosshair.style.display = 'block';\n h.setAttribute('x1', '0');\n h.setAttribute('x2', '${DEFAULT_SVG_SIZE}');\n h.setAttribute('y1', y);\n h.setAttribute('y2', y);\n v.setAttribute('x1', x);\n v.setAttribute('x2', x);\n v.setAttribute('y1', '0');\n v.setAttribute('y2', '${DEFAULT_SVG_SIZE}');\n\n // Calculate real coordinates using inverse transformation\n const matrix = ${JSON.stringify(matrix)};\n // Manually invert and apply the affine transform\n // Since we only use translate and scale, we can directly compute:\n // x' = (x - tx) / sx\n // y' = (y - ty) / sy\n const sx = matrix.a;\n const sy = matrix.d;\n const tx = matrix.e; \n const ty = matrix.f;\n const realPoint = {\n x: (x - tx) / sx,\n y: (y - ty) / sy // Flip y back since we used negative scale\n }\n \n coords.textContent = \\`(\\${realPoint.x.toFixed(2)}, \\${realPoint.y.toFixed(2)})\\`;\n coords.setAttribute('x', (x + 5).toString());\n coords.setAttribute('y', (y - 5).toString());\n });\n document.currentScript.parentElement.addEventListener('mouseleave', () => {\n document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';\n });\n `,\n },\n ],\n },\n ],\n }\n\n // biome-ignore lint/suspicious/noExplicitAny: TODO\n return pretty(stringify(svgObject as any))\n}\n"],"mappings":";;;;;;AAAA;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AAEP,SAAS,iBAAiB;AAC1B,OAAO,YAAY;AAGnB,IAAM,mBAAmB;AACzB,IAAM,UAAU;AAShB,SAAS,UAAU,UAAkC;AACnD,QAAM,SAAkB;AAAA,IACtB,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,IACD,IAAI,SAAS,SAAS,CAAC,GAAG,QAAQ,CAAC,MAAM;AACvC,YAAM,WAAW,EAAE,YAAY;AAC/B,YAAM,QAAQ,EAAE,KAAK,SAAS,WAAW;AACzC,YAAM,SAAS,WAAW;AAC1B,YAAM,SAAS,EAAE,cAAc;AAC/B,YAAM,YAAwD;AAAA,QAC5D,UAAU,EAAE,IAAI,GAAG,IAAI,EAAE;AAAA,QACzB,YAAY,EAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,EAAE;AAAA,QACpC,WAAW,EAAE,IAAI,CAAC,OAAO,IAAI,EAAE;AAAA,QAC/B,aAAa,EAAE,IAAI,GAAG,IAAI,CAAC,SAAS,EAAE;AAAA,QACtC,QAAQ,EAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,SAAS,EAAE;AAAA,QAC1C,cAAc,EAAE,IAAI,CAAC,OAAO,IAAI,CAAC,SAAS,EAAE;AAAA,QAC5C,aAAa,EAAE,IAAI,GAAG,IAAI,CAAC,OAAO;AAAA,QAClC,eAAe,EAAE,IAAI,CAAC,QAAQ,GAAG,IAAI,CAAC,OAAO;AAAA,QAC7C,cAAc,EAAE,IAAI,CAAC,OAAO,IAAI,CAAC,OAAO;AAAA,MAC1C;AACA,YAAM,EAAE,IAAI,GAAG,IAAI,UAAU,MAAM;AACnC,YAAM,KAAK,EAAE,IAAI;AACjB,YAAM,KAAK,EAAE,IAAI;AACjB,aAAO;AAAA,QACL,EAAE,GAAG,IAAI,GAAG,GAAG;AAAA,QACf,EAAE,GAAG,KAAK,OAAO,GAAG,KAAK,OAAO;AAAA,MAClC;AAAA,IACF,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;AAEA,SAAS,oBACP,QACA,kBACA;AACA,QAAM,QAAQ,OAAO,OAAO,OAAO,QAAQ;AAC3C,QAAM,SAAS,OAAO,OAAO,OAAO,QAAQ;AAE5C,QAAM,eAAe,KAAK;AAAA,KACvB,mBAAmB,IAAI,WAAW;AAAA,KAClC,mBAAmB,IAAI,WAAW;AAAA,EACrC;AAEA,QAAM,QAAQ,qBAAqB,WAAW,IAAI;AAElD,SAAO;AAAA,IACL,UAAU,mBAAmB,GAAG,mBAAmB,CAAC;AAAA,IACpD,MAAM,cAAc,QAAQ,YAAY;AAAA,IACxC,UAAU,EAAE,OAAO,OAAO,QAAQ,IAAI,EAAE,OAAO,OAAO,SAAS,EAAE;AAAA,EACnE;AACF;AAEA,SAAS,aAAa,OAAc,QAAgB;AAClD,QAAM,YAAY,aAAa,QAAQ,EAAE,GAAG,MAAM,GAAG,GAAG,MAAM,EAAE,CAAC;AACjE,SAAO,EAAE,GAAG,OAAO,GAAG,UAAU;AAClC;AAEO,SAAS,yBACd,UACA;AAAA,EACE,oBAAoB;AAAA,EACpB;AACF,IAGI,CAAC,GACG;AACR,QAAM,SAAS,UAAU,QAAQ;AACjC,QAAM,SAAS,oBAAoB,QAAQ,SAAS,gBAAgB;AAEpE,QAAM,oBAAoB,CAAC,SAAgD;AACzE,QAAI,OAAO,sBAAsB,WAAW;AAC1C,aAAO;AAAA,IACT;AACA,QAAI,MAAM,QAAQ,iBAAiB,GAAG;AACpC,aAAO,kBAAkB,SAAS,IAAI;AAAA,IACxC;AACA,WAAO;AAAA,EACT;AAEA,QAAM,YAAY;AAAA,IAChB,MAAM;AAAA,IACN,MAAM;AAAA,IACN,YAAY;AAAA,MACV,OAAO,iBAAiB,SAAS;AAAA,MACjC,QAAQ,iBAAiB,SAAS;AAAA,MAClC,SAAS,OAAO,gBAAgB,IAAI,gBAAgB;AAAA,MACpD,OAAO;AAAA,IACT;AAAA,IACA,UAAU;AAAA;AAAA,MAER,GAAI,kBACA;AAAA,QACE;AAAA,UACE,MAAM;AAAA,UACN,MAAM;AAAA,UACN,YAAY;AAAA,YACV,OAAO;AAAA,YACP,QAAQ;AAAA,YACR,MAAM;AAAA,UACR;AAAA,QACF;AAAA,MACF,IACA,CAAC;AAAA;AAAA,MAEL,IAAI,SAAS,UAAU,CAAC,GAAG,IAAI,CAAC,UAAU;AACxC,cAAM,YAAY,aAAa,OAAO,MAAM;AAC5C,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,YAAY,CAAC;AAAA,UACb,UAAU;AAAA,YACR;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,YAAY;AAAA,gBACV,aAAa;AAAA,gBACb,cAAc,MAAM,SAAS;AAAA,gBAC7B,UAAU,MAAM,EAAE,SAAS;AAAA,gBAC3B,UAAU,MAAM,EAAE,SAAS;AAAA,gBAC3B,IAAI,UAAU,EAAE,SAAS;AAAA,gBACzB,IAAI,UAAU,EAAE,SAAS;AAAA,gBACzB,GAAG;AAAA,gBACH,MAAM,MAAM,SAAS;AAAA,cACvB;AAAA,YACF;AAAA,YACA,GAAI,kBAAkB,QAAQ,KAAK,MAAM,QACrC;AAAA,cACE;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,YAAY;AAAA,kBACV,IAAI,UAAU,IAAI,GAAG,SAAS;AAAA,kBAC9B,IAAI,UAAU,IAAI,GAAG,SAAS;AAAA,kBAC9B,eAAe;AAAA,kBACf,aAAa;AAAA,gBACf;AAAA,gBACA,UAAU,CAAC,EAAE,MAAM,QAAQ,OAAO,MAAM,MAAM,CAAC;AAAA,cACjD;AAAA,YACF,IACA,CAAC;AAAA,UACP;AAAA,QACF;AAAA,MACF,CAAC;AAAA;AAAA,MAED,IAAI,SAAS,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS;AACtC,cAAM,kBAAkB,KAAK,OAAO,IAAI,CAAC,MAAM,aAAa,GAAG,MAAM,CAAC;AACtE,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,YAAY,CAAC;AAAA,UACb,UAAU;AAAA,YACR;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,YAAY;AAAA,gBACV,eAAe,KAAK,OACjB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAC1B,KAAK,GAAG;AAAA,gBACX,aAAa;AAAA,gBACb,cAAc,KAAK,SAAS;AAAA,gBAC5B,QAAQ,gBAAgB,IAAI,CAAC,MAAM,GAAG,EAAE,CAAC,IAAI,EAAE,CAAC,EAAE,EAAE,KAAK,GAAG;AAAA,gBAC5D,MAAM;AAAA,gBACN,QAAQ,KAAK,eAAe;AAAA,gBAC5B,iBAAiB,KAAK,eAAe,GAAG,SAAS;AAAA,gBACjD,GAAI,KAAK,cAAc;AAAA,kBACrB,oBAAoB,MAAM,QAAQ,KAAK,UAAU,IAC7C,KAAK,WAAW,KAAK,GAAG,IACxB,KAAK;AAAA,gBACX;AAAA,cACF;AAAA,YACF;AAAA,YACA,GAAI,kBAAkB,OAAO,KAC7B,KAAK,SACL,gBAAgB,SAAS,IACrB;AAAA,cACE;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,YAAY;AAAA,kBACV,IAAI,gBAAgB,CAAC,EAAE,IAAI,GAAG,SAAS;AAAA,kBACvC,IAAI,gBAAgB,CAAC,EAAE,IAAI,GAAG,SAAS;AAAA,kBACvC,eAAe;AAAA,kBACf,aAAa;AAAA,kBACb,MAAM,KAAK,eAAe;AAAA,gBAC5B;AAAA,gBACA,UAAU,CAAC,EAAE,MAAM,QAAQ,OAAO,KAAK,MAAM,CAAC;AAAA,cAChD;AAAA,YACF,IACA,CAAC;AAAA,UACP;AAAA,QACF;AAAA,MACF,CAAC;AAAA;AAAA,MAED,IAAI,SAAS,SAAS,CAAC,GAAG,IAAI,CAAC,SAAS;AACtC,cAAM,UAAU;AAAA,UACd,GAAG,KAAK,OAAO,IAAI,KAAK,QAAQ;AAAA,UAChC,GAAG,KAAK,OAAO,IAAI,KAAK,SAAS;AAAA,QACnC;AACA,cAAM,mBAAmB,aAAa,SAAS,MAAM;AACrD,cAAM,UAAU;AAAA,UACd,GAAG,KAAK,OAAO,IAAI,KAAK,QAAQ;AAAA,UAChC,GAAG,KAAK,OAAO,IAAI,KAAK,SAAS;AAAA,QACnC;AACA,cAAM,mBAAmB,aAAa,SAAS,MAAM;AACrD,cAAM,cAAc,KAAK,IAAI,iBAAiB,IAAI,iBAAiB,CAAC;AACpE,cAAM,eAAe,KAAK,IAAI,iBAAiB,IAAI,iBAAiB,CAAC;AACrE,cAAM,QAAQ,KAAK,IAAI,iBAAiB,GAAG,iBAAiB,CAAC;AAC7D,cAAM,QAAQ,KAAK,IAAI,iBAAiB,GAAG,iBAAiB,CAAC;AAE7D,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,YAAY,CAAC;AAAA,UACb,UAAU;AAAA,YACR;AAAA,cACE,MAAM;AAAA,cACN,MAAM;AAAA,cACN,YAAY;AAAA,gBACV,aAAa;AAAA,gBACb,cAAc,KAAK,SAAS;AAAA,gBAC5B,UAAU,KAAK,OAAO,EAAE,SAAS;AAAA,gBACjC,UAAU,KAAK,OAAO,EAAE,SAAS;AAAA,gBACjC,GAAG,MAAM,SAAS;AAAA,gBAClB,GAAG,MAAM,SAAS;AAAA,gBAClB,OAAO,YAAY,SAAS;AAAA,gBAC5B,QAAQ,aAAa,SAAS;AAAA,gBAC9B,MAAM,KAAK,QAAQ;AAAA,gBACnB,QAAQ,KAAK,UAAU;AAAA,gBACvB,gBAAgB,KAAK,IAAI,IAAI,OAAO,CAAC,EAAE,SAAS;AAAA;AAAA,cAClD;AAAA,YACF;AAAA,YACA,GAAI,kBAAkB,OAAO,KAAK,KAAK,QACnC;AAAA,cACE;AAAA,gBACE,MAAM;AAAA,gBACN,MAAM;AAAA,gBACN,YAAY;AAAA,kBACV,IAAI,QAAQ,GAAG,SAAS;AAAA,kBACxB,IAAI,QAAQ,GAAG,SAAS;AAAA;AAAA,kBACxB,eAAe;AAAA,kBACf,aAAa;AAAA,kBACb,MAAM,KAAK,UAAU;AAAA;AAAA,gBACvB;AAAA,gBACA,UAAU,CAAC,EAAE,MAAM,QAAQ,OAAO,KAAK,MAAM,CAAC;AAAA,cAChD;AAAA,YACF,IACA,CAAC;AAAA,UACP;AAAA,QACF;AAAA,MACF,CAAC;AAAA;AAAA,MAED,IAAI,SAAS,WAAW,CAAC,GAAG,IAAI,CAAC,WAAW;AAC1C,cAAM,YAAY,aAAa,OAAO,QAAQ,MAAM;AACpD,cAAM,eAAe,OAAO,SAAS,KAAK,IAAI,OAAO,CAAC;AACtD,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,YAAY;AAAA,YACV,aAAa;AAAA,YACb,cAAc;AAAA,YACd,UAAU,OAAO,OAAO,EAAE,SAAS;AAAA,YACnC,UAAU,OAAO,OAAO,EAAE,SAAS;AAAA,YACnC,IAAI,UAAU,EAAE,SAAS;AAAA,YACzB,IAAI,UAAU,EAAE,SAAS;AAAA,YACzB,GAAG,aAAa,SAAS;AAAA,YACzB,MAAM,OAAO,QAAQ;AAAA,YACrB,QAAQ,OAAO,UAAU;AAAA,YACzB,gBAAgB,KAAK,IAAI,IAAI,OAAO,CAAC,EAAE,SAAS;AAAA,UAClD;AAAA,QACF;AAAA,MACF,CAAC;AAAA;AAAA,MAED,IAAI,SAAS,SAAS,CAAC,GAAG,IAAI,CAAC,QAAQ;AACrC,cAAM,YAAY,aAAa,EAAE,GAAG,IAAI,GAAG,GAAG,IAAI,EAAE,GAAG,MAAM;AAC7D,cAAM,SAAS,IAAI,cAAc;AACjC,cAAM,WAAmC;AAAA,UACvC,UAAU;AAAA,UACV,aAAa;AAAA,UACb,aAAa;AAAA,UACb,YAAY;AAAA,UACZ,QAAQ;AAAA,UACR,eAAe;AAAA,UACf,WAAW;AAAA,UACX,cAAc;AAAA,UACd,cAAc;AAAA,QAChB;AACA,cAAM,cAAsC;AAAA,UAC1C,UAAU;AAAA,UACV,YAAY;AAAA,UACZ,WAAW;AAAA,UACX,aAAa;AAAA,UACb,QAAQ;AAAA,UACR,cAAc;AAAA,UACd,aAAa;AAAA,UACb,eAAe;AAAA,UACf,cAAc;AAAA,QAChB;AACA,eAAO;AAAA,UACL,MAAM;AAAA,UACN,MAAM;AAAA,UACN,YAAY;AAAA,YACV,aAAa;AAAA,YACb,cAAc,IAAI;AAAA,YAClB,UAAU,IAAI,EAAE,SAAS;AAAA,YACzB,UAAU,IAAI,EAAE,SAAS;AAAA,YACzB,GAAG,UAAU,EAAE,SAAS;AAAA,YACxB,GAAG,UAAU,EAAE,SAAS;AAAA,YACxB,MAAM,IAAI,SAAS;AAAA,YACnB,eAAe,IAAI,YAAY,MAAM,KAAK,IAAI,OAAO,CAAC,GAAG,SAAS;AAAA,YAClE,eAAe;AAAA,YACf,eAAe,SAAS,MAAM;AAAA,YAC9B,qBAAqB,YAAY,MAAM;AAAA,UACzC;AAAA,UACA,UAAU,CAAC,EAAE,MAAM,QAAQ,OAAO,IAAI,KAAK,CAAC;AAAA,QAC9C;AAAA,MACF,CAAC;AAAA;AAAA,MAED;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,YAAY;AAAA,UACV,IAAI;AAAA,UACJ,OAAO;AAAA,QACT;AAAA,QACA,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,YAAY;AAAA,cACV,IAAI;AAAA,cACJ,IAAI;AAAA,cACJ,IAAI,iBAAiB,SAAS;AAAA,cAC9B,QAAQ;AAAA,cACR,gBAAgB;AAAA,YAClB;AAAA,UACF;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,YAAY;AAAA,cACV,IAAI;AAAA,cACJ,IAAI;AAAA,cACJ,IAAI,iBAAiB,SAAS;AAAA,cAC9B,QAAQ;AAAA,cACR,gBAAgB;AAAA,YAClB;AAAA,UACF;AAAA,UACA;AAAA,YACE,MAAM;AAAA,YACN,MAAM;AAAA,YACN,YAAY;AAAA,cACV,IAAI;AAAA,cACJ,eAAe;AAAA,cACf,aAAa;AAAA,cACb,MAAM;AAAA,YACR;AAAA,YACA,UAAU,CAAC,EAAE,MAAM,QAAQ,OAAO,GAAG,CAAC;AAAA,UACxC;AAAA,QACF;AAAA,MACF;AAAA;AAAA,MAEA;AAAA,QACE,MAAM;AAAA,QACN,MAAM;AAAA,QACN,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wCAaqB,gBAAgB;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,wCAMhB,gBAAgB;AAAA;AAAA;AAAA,iCAGvB,KAAK,UAAU,MAAM,CAAC;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,UAsB7C;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAGA,SAAO,OAAO,UAAU,SAAgB,CAAC;AAC3C;","names":[]}
|
|
@@ -5,11 +5,12 @@ var mergeGraphics = (graphics1, graphics2) => {
|
|
|
5
5
|
rects: [...graphics1.rects ?? [], ...graphics2.rects ?? []],
|
|
6
6
|
points: [...graphics1.points ?? [], ...graphics2.points ?? []],
|
|
7
7
|
lines: [...graphics1.lines ?? [], ...graphics2.lines ?? []],
|
|
8
|
-
circles: [...graphics1.circles ?? [], ...graphics2.circles ?? []]
|
|
8
|
+
circles: [...graphics1.circles ?? [], ...graphics2.circles ?? []],
|
|
9
|
+
texts: [...graphics1.texts ?? [], ...graphics2.texts ?? []]
|
|
9
10
|
};
|
|
10
11
|
};
|
|
11
12
|
|
|
12
13
|
export {
|
|
13
14
|
mergeGraphics
|
|
14
15
|
};
|
|
15
|
-
//# sourceMappingURL=chunk-
|
|
16
|
+
//# sourceMappingURL=chunk-TJJMMKHI.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/mergeGraphics.ts"],"sourcesContent":["import type { GraphicsObject } from \"./types\"\n\nexport const mergeGraphics = (\n graphics1: GraphicsObject,\n graphics2: GraphicsObject,\n): GraphicsObject => {\n return {\n ...graphics1,\n rects: [...(graphics1.rects ?? []), ...(graphics2.rects ?? [])],\n points: [...(graphics1.points ?? []), ...(graphics2.points ?? [])],\n lines: [...(graphics1.lines ?? []), ...(graphics2.lines ?? [])],\n circles: [...(graphics1.circles ?? []), ...(graphics2.circles ?? [])],\n texts: [...(graphics1.texts ?? []), ...(graphics2.texts ?? [])],\n }\n}\n"],"mappings":";AAEO,IAAM,gBAAgB,CAC3B,WACA,cACmB;AACnB,SAAO;AAAA,IACL,GAAG;AAAA,IACH,OAAO,CAAC,GAAI,UAAU,SAAS,CAAC,GAAI,GAAI,UAAU,SAAS,CAAC,CAAE;AAAA,IAC9D,QAAQ,CAAC,GAAI,UAAU,UAAU,CAAC,GAAI,GAAI,UAAU,UAAU,CAAC,CAAE;AAAA,IACjE,OAAO,CAAC,GAAI,UAAU,SAAS,CAAC,GAAI,GAAI,UAAU,SAAS,CAAC,CAAE;AAAA,IAC9D,SAAS,CAAC,GAAI,UAAU,WAAW,CAAC,GAAI,GAAI,UAAU,WAAW,CAAC,CAAE;AAAA,IACpE,OAAO,CAAC,GAAI,UAAU,SAAS,CAAC,GAAI,GAAI,UAAU,SAAS,CAAC,CAAE;AAAA,EAChE;AACF;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../lib/constants.ts"],"sourcesContent":["export const FONT_SIZE_WIDTH_RATIO = 0.6\nexport const FONT_SIZE_HEIGHT_RATIO = 1\n"],"mappings":";AAAO,IAAM,wBAAwB;AAC9B,IAAM,yBAAyB;","names":[]}
|
package/dist/cli/cli.js
CHANGED
|
@@ -2,14 +2,15 @@
|
|
|
2
2
|
import {
|
|
3
3
|
getHtmlFromLogString,
|
|
4
4
|
getSvgsFromLogString
|
|
5
|
-
} from "../chunk-
|
|
6
|
-
import "../chunk-
|
|
7
|
-
import "../chunk-
|
|
5
|
+
} from "../chunk-JFOAYFXQ.js";
|
|
6
|
+
import "../chunk-K2IJQPPY.js";
|
|
7
|
+
import "../chunk-ARYXS3GC.js";
|
|
8
8
|
import {
|
|
9
9
|
getGraphicsObjectsFromLogString
|
|
10
10
|
} from "../chunk-NG6H63SM.js";
|
|
11
|
-
import "../chunk-
|
|
12
|
-
import "../chunk-
|
|
11
|
+
import "../chunk-NSJFCQQH.js";
|
|
12
|
+
import "../chunk-ZGI74PYD.js";
|
|
13
|
+
import "../chunk-TJJMMKHI.js";
|
|
13
14
|
|
|
14
15
|
// cli/cli.ts
|
|
15
16
|
import { parseArgs } from "node:util";
|
package/dist/cli/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../cli/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\"\nimport { readFileSync } from \"node:fs\"\nimport { writeFileSync } from \"node:fs\"\nimport {\n getSvgsFromLogString,\n getHtmlFromLogString,\n getGraphicsObjectsFromLogString,\n} from \"../lib\"\n\nasync function getInput(): Promise<string> {\n // Check if there's data being piped in\n if (process.stdin.isTTY && process.stderr.isTTY) {\n console.error(\n \"Error: No input provided. Pipe in content with graphics objects.\",\n )\n process.exit(1)\n }\n\n const chunks = []\n\n // Read from stdin if available\n if (!process.stdin.isTTY) {\n for await (const chunk of process.stdin) {\n chunks.push(chunk)\n }\n }\n\n return chunks.join(\"\")\n}\n\nasync function main() {\n const { values } = parseArgs({\n options: {\n html: { type: \"boolean\" },\n url: { type: \"boolean\" },\n help: { type: \"boolean\" },\n },\n })\n\n if (values.help) {\n console.log(`\nUsage: graphics-debug [options]\n\nOptions:\n --html Output a single HTML file with all graphics\n --url Print a url to view the graphics in a browser\n --help Show this help message\n\nExamples:\n cat debug.log | graphics-debug\n echo '{ graphics: { points: [{x: 0, y: 0}] } }' | graphics-debug --html\n `)\n process.exit(0)\n }\n\n const input = await getInput()\n\n if (values.html) {\n const html = getHtmlFromLogString(input)\n writeFileSync(\"graphicsdebug.debug.html\", html)\n console.log('Wrote to \"graphicsdebug.debug.html\"')\n } else if (values.url) {\n const graphicsObjects = getGraphicsObjectsFromLogString(input)\n if (graphicsObjects.length === 0) {\n console.error(\"No graphics objects found in input\")\n process.exit(0)\n }\n\n const { url } = await fetch(\"https://gdstore.seve.workers.dev/store\", {\n method: \"POST\",\n body: JSON.stringify({\n graphicsObjects: getGraphicsObjectsFromLogString(input),\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }).then((res) => res.json())\n\n const token = url.split(\"/get/\").pop()\n\n console.log(`https://graphicsdebug.com/t/${token}`)\n } else {\n const svgs = getSvgsFromLogString(input)\n svgs.forEach((svg, i) => {\n const filename = `${svg.title.toLowerCase().replace(/\\s+/g, \"-\")}-${i + 1}.debug.svg`\n writeFileSync(filename, svg.svg)\n console.log(`Wrote to \"${filename}\"`)\n })\n }\n}\n\nmain().catch((err) => {\n console.error(\"Error:\", err)\n process.exit(1)\n})\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../cli/cli.ts"],"sourcesContent":["#!/usr/bin/env node\nimport { parseArgs } from \"node:util\"\nimport { readFileSync } from \"node:fs\"\nimport { writeFileSync } from \"node:fs\"\nimport {\n getSvgsFromLogString,\n getHtmlFromLogString,\n getGraphicsObjectsFromLogString,\n} from \"../lib\"\n\nasync function getInput(): Promise<string> {\n // Check if there's data being piped in\n if (process.stdin.isTTY && process.stderr.isTTY) {\n console.error(\n \"Error: No input provided. Pipe in content with graphics objects.\",\n )\n process.exit(1)\n }\n\n const chunks = []\n\n // Read from stdin if available\n if (!process.stdin.isTTY) {\n for await (const chunk of process.stdin) {\n chunks.push(chunk)\n }\n }\n\n return chunks.join(\"\")\n}\n\nasync function main() {\n const { values } = parseArgs({\n options: {\n html: { type: \"boolean\" },\n url: { type: \"boolean\" },\n help: { type: \"boolean\" },\n },\n })\n\n if (values.help) {\n console.log(`\nUsage: graphics-debug [options]\n\nOptions:\n --html Output a single HTML file with all graphics\n --url Print a url to view the graphics in a browser\n --help Show this help message\n\nExamples:\n cat debug.log | graphics-debug\n echo '{ graphics: { points: [{x: 0, y: 0}] } }' | graphics-debug --html\n `)\n process.exit(0)\n }\n\n const input = await getInput()\n\n if (values.html) {\n const html = getHtmlFromLogString(input)\n writeFileSync(\"graphicsdebug.debug.html\", html)\n console.log('Wrote to \"graphicsdebug.debug.html\"')\n } else if (values.url) {\n const graphicsObjects = getGraphicsObjectsFromLogString(input)\n if (graphicsObjects.length === 0) {\n console.error(\"No graphics objects found in input\")\n process.exit(0)\n }\n\n const { url } = await fetch(\"https://gdstore.seve.workers.dev/store\", {\n method: \"POST\",\n body: JSON.stringify({\n graphicsObjects: getGraphicsObjectsFromLogString(input),\n }),\n headers: {\n \"Content-Type\": \"application/json\",\n },\n }).then((res) => res.json())\n\n const token = url.split(\"/get/\").pop()\n\n console.log(`https://graphicsdebug.com/t/${token}`)\n } else {\n const svgs = getSvgsFromLogString(input)\n svgs.forEach((svg, i) => {\n const filename = `${svg.title.toLowerCase().replace(/\\s+/g, \"-\")}-${i + 1}.debug.svg`\n writeFileSync(filename, svg.svg)\n console.log(`Wrote to \"${filename}\"`)\n })\n }\n}\n\nmain().catch((err) => {\n console.error(\"Error:\", err)\n process.exit(1)\n})\n"],"mappings":";;;;;;;;;;;;;;;AACA,SAAS,iBAAiB;AAE1B,SAAS,qBAAqB;AAO9B,eAAe,WAA4B;AAEzC,MAAI,QAAQ,MAAM,SAAS,QAAQ,OAAO,OAAO;AAC/C,YAAQ;AAAA,MACN;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,SAAS,CAAC;AAGhB,MAAI,CAAC,QAAQ,MAAM,OAAO;AACxB,qBAAiB,SAAS,QAAQ,OAAO;AACvC,aAAO,KAAK,KAAK;AAAA,IACnB;AAAA,EACF;AAEA,SAAO,OAAO,KAAK,EAAE;AACvB;AAEA,eAAe,OAAO;AACpB,QAAM,EAAE,OAAO,IAAI,UAAU;AAAA,IAC3B,SAAS;AAAA,MACP,MAAM,EAAE,MAAM,UAAU;AAAA,MACxB,KAAK,EAAE,MAAM,UAAU;AAAA,MACvB,MAAM,EAAE,MAAM,UAAU;AAAA,IAC1B;AAAA,EACF,CAAC;AAED,MAAI,OAAO,MAAM;AACf,YAAQ,IAAI;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,KAWX;AACD,YAAQ,KAAK,CAAC;AAAA,EAChB;AAEA,QAAM,QAAQ,MAAM,SAAS;AAE7B,MAAI,OAAO,MAAM;AACf,UAAM,OAAO,qBAAqB,KAAK;AACvC,kBAAc,4BAA4B,IAAI;AAC9C,YAAQ,IAAI,qCAAqC;AAAA,EACnD,WAAW,OAAO,KAAK;AACrB,UAAM,kBAAkB,gCAAgC,KAAK;AAC7D,QAAI,gBAAgB,WAAW,GAAG;AAChC,cAAQ,MAAM,oCAAoC;AAClD,cAAQ,KAAK,CAAC;AAAA,IAChB;AAEA,UAAM,EAAE,IAAI,IAAI,MAAM,MAAM,0CAA0C;AAAA,MACpE,QAAQ;AAAA,MACR,MAAM,KAAK,UAAU;AAAA,QACnB,iBAAiB,gCAAgC,KAAK;AAAA,MACxD,CAAC;AAAA,MACD,SAAS;AAAA,QACP,gBAAgB;AAAA,MAClB;AAAA,IACF,CAAC,EAAE,KAAK,CAAC,QAAQ,IAAI,KAAK,CAAC;AAE3B,UAAM,QAAQ,IAAI,MAAM,OAAO,EAAE,IAAI;AAErC,YAAQ,IAAI,+BAA+B,KAAK,EAAE;AAAA,EACpD,OAAO;AACL,UAAM,OAAO,qBAAqB,KAAK;AACvC,SAAK,QAAQ,CAAC,KAAK,MAAM;AACvB,YAAM,WAAW,GAAG,IAAI,MAAM,YAAY,EAAE,QAAQ,QAAQ,GAAG,CAAC,IAAI,IAAI,CAAC;AACzE,oBAAc,UAAU,IAAI,GAAG;AAC/B,cAAQ,IAAI,aAAa,QAAQ,GAAG;AAAA,IACtC,CAAC;AAAA,EACH;AACF;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,MAAM,UAAU,GAAG;AAC3B,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":[]}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
|
package/dist/lib/index.d.ts
CHANGED
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
export { CenterViewbox, Circle, GraphicsObject, Line, Point, Rect, TransformOptions, Viewbox } from './types.js';
|
|
1
|
+
export { CenterViewbox, Circle, GraphicsObject, Line, NinePointAnchor, Point, Rect, Text, TransformOptions, Viewbox } from './types.js';
|
|
2
2
|
export { getGraphicsObjectsFromLogString } from './getGraphicsObjectsFromLogString.js';
|
|
3
3
|
export { getSvgFromGraphicsObject } from './getSvgFromGraphicsObject.js';
|
|
4
4
|
export { computeTransformFromViewbox, drawGraphicsToCanvas, getBounds } from './drawGraphicsToCanvas.js';
|
|
5
5
|
export { translateGraphics } from './translateGraphics.js';
|
|
6
6
|
export { mergeGraphics } from './mergeGraphics.js';
|
|
7
|
+
export { FONT_SIZE_HEIGHT_RATIO, FONT_SIZE_WIDTH_RATIO } from './constants.js';
|
|
7
8
|
import 'transformation-matrix';
|
|
8
9
|
|
|
9
10
|
declare function getSvgFromLogString(logString: string): string;
|
package/dist/lib/index.js
CHANGED
|
@@ -2,25 +2,31 @@ import {
|
|
|
2
2
|
getHtmlFromLogString,
|
|
3
3
|
getSvgFromLogString,
|
|
4
4
|
getSvgsFromLogString
|
|
5
|
-
} from "../chunk-
|
|
5
|
+
} from "../chunk-JFOAYFXQ.js";
|
|
6
6
|
import {
|
|
7
7
|
translateGraphics
|
|
8
|
-
} from "../chunk-
|
|
8
|
+
} from "../chunk-K2IJQPPY.js";
|
|
9
9
|
import {
|
|
10
10
|
computeTransformFromViewbox,
|
|
11
11
|
drawGraphicsToCanvas,
|
|
12
12
|
getBounds
|
|
13
|
-
} from "../chunk-
|
|
13
|
+
} from "../chunk-ARYXS3GC.js";
|
|
14
14
|
import {
|
|
15
15
|
getGraphicsObjectsFromLogString
|
|
16
16
|
} from "../chunk-NG6H63SM.js";
|
|
17
17
|
import {
|
|
18
18
|
getSvgFromGraphicsObject
|
|
19
|
-
} from "../chunk-
|
|
19
|
+
} from "../chunk-NSJFCQQH.js";
|
|
20
|
+
import {
|
|
21
|
+
FONT_SIZE_HEIGHT_RATIO,
|
|
22
|
+
FONT_SIZE_WIDTH_RATIO
|
|
23
|
+
} from "../chunk-ZGI74PYD.js";
|
|
20
24
|
import {
|
|
21
25
|
mergeGraphics
|
|
22
|
-
} from "../chunk-
|
|
26
|
+
} from "../chunk-TJJMMKHI.js";
|
|
23
27
|
export {
|
|
28
|
+
FONT_SIZE_HEIGHT_RATIO,
|
|
29
|
+
FONT_SIZE_WIDTH_RATIO,
|
|
24
30
|
computeTransformFromViewbox,
|
|
25
31
|
drawGraphicsToCanvas,
|
|
26
32
|
getBounds,
|
package/dist/lib/matcher.js
CHANGED
package/dist/lib/matcher.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../lib/matcher.ts"],"sourcesContent":["import { expect, type MatcherResult } from \"bun:test\"\nimport * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport looksSame from \"looks-same\"\nimport { GraphicsObject } from \"./types\"\nimport { getSvgFromGraphicsObject } from \"./getSvgFromGraphicsObject\"\n\n/**\n * Custom matcher for Bun tests to compare GraphicsObjects as SVGs\n *\n * @param this Matcher context\n * @param receivedMaybePromise GraphicsObject or Promise<GraphicsObject> to test\n * @param testPathOriginal Path to the test file\n * @param svgName Optional name for the snapshot\n * @returns Matcher result\n */\nasync function toMatchGraphicsSvg(\n // biome-ignore lint/suspicious/noExplicitAny: bun doesn't expose matcher type\n this: any,\n receivedMaybePromise: GraphicsObject | Promise<GraphicsObject>,\n testPathOriginal: string,\n opts: { backgroundColor?: string; svgName?: string } = {},\n): Promise<MatcherResult> {\n const received = await receivedMaybePromise\n const testPath = testPathOriginal.replace(/\\.test\\.tsx?$/, \"\")\n const snapshotDir = path.join(path.dirname(testPath), \"__snapshots__\")\n const snapshotName = opts.svgName\n ? `${opts.svgName}.snap.svg`\n : `${path.basename(testPath)}.snap.svg`\n const filePath = path.join(snapshotDir, snapshotName)\n\n if (!fs.existsSync(snapshotDir)) {\n fs.mkdirSync(snapshotDir, { recursive: true })\n }\n\n // Convert GraphicsObject to SVG\n const receivedSvg = getSvgFromGraphicsObject(received, {\n backgroundColor: opts.backgroundColor,\n })\n\n const updateSnapshot =\n process.argv.includes(\"--update-snapshots\") ||\n process.argv.includes(\"-u\") ||\n Boolean(process.env[\"BUN_UPDATE_SNAPSHOTS\"])\n\n if (!fs.existsSync(filePath) || updateSnapshot) {\n console.log(\"Writing snapshot to\", filePath)\n fs.writeFileSync(filePath, receivedSvg)\n return {\n message: () => `Snapshot created at ${filePath}`,\n pass: true,\n }\n }\n\n const existingSnapshot = fs.readFileSync(filePath, \"utf-8\")\n\n const result: any = await looksSame(\n Buffer.from(receivedSvg),\n Buffer.from(existingSnapshot),\n {\n strict: false,\n tolerance: 2,\n },\n )\n\n if (result.equal) {\n return {\n message: () => \"Snapshot matches\",\n pass: true,\n }\n }\n\n const diffPath = filePath.replace(\".snap.svg\", \".diff.png\")\n await looksSame.createDiff({\n reference: Buffer.from(existingSnapshot),\n current: Buffer.from(receivedSvg),\n diff: diffPath,\n highlightColor: \"#ff00ff\",\n })\n\n return {\n message: () => `Snapshot does not match. Diff saved at ${diffPath}`,\n pass: false,\n }\n}\n\n// Add the custom matcher to the expect object\nexpect.extend({\n // biome-ignore lint/suspicious/noExplicitAny: bun's types don't expose matcher type\n toMatchGraphicsSvg: toMatchGraphicsSvg as any,\n})\n\n// Extend the TypeScript interface for the matcher\ndeclare module \"bun:test\" {\n interface Matchers<T = unknown> {\n toMatchGraphicsSvg(\n testPath: string,\n opts?: { backgroundColor?: string; svgName?: string },\n ): Promise<MatcherResult>\n }\n}\n"],"mappings":"
|
|
1
|
+
{"version":3,"sources":["../../lib/matcher.ts"],"sourcesContent":["import { expect, type MatcherResult } from \"bun:test\"\nimport * as fs from \"node:fs\"\nimport * as path from \"node:path\"\nimport looksSame from \"looks-same\"\nimport { GraphicsObject } from \"./types\"\nimport { getSvgFromGraphicsObject } from \"./getSvgFromGraphicsObject\"\n\n/**\n * Custom matcher for Bun tests to compare GraphicsObjects as SVGs\n *\n * @param this Matcher context\n * @param receivedMaybePromise GraphicsObject or Promise<GraphicsObject> to test\n * @param testPathOriginal Path to the test file\n * @param svgName Optional name for the snapshot\n * @returns Matcher result\n */\nasync function toMatchGraphicsSvg(\n // biome-ignore lint/suspicious/noExplicitAny: bun doesn't expose matcher type\n this: any,\n receivedMaybePromise: GraphicsObject | Promise<GraphicsObject>,\n testPathOriginal: string,\n opts: { backgroundColor?: string; svgName?: string } = {},\n): Promise<MatcherResult> {\n const received = await receivedMaybePromise\n const testPath = testPathOriginal.replace(/\\.test\\.tsx?$/, \"\")\n const snapshotDir = path.join(path.dirname(testPath), \"__snapshots__\")\n const snapshotName = opts.svgName\n ? `${opts.svgName}.snap.svg`\n : `${path.basename(testPath)}.snap.svg`\n const filePath = path.join(snapshotDir, snapshotName)\n\n if (!fs.existsSync(snapshotDir)) {\n fs.mkdirSync(snapshotDir, { recursive: true })\n }\n\n // Convert GraphicsObject to SVG\n const receivedSvg = getSvgFromGraphicsObject(received, {\n backgroundColor: opts.backgroundColor,\n })\n\n const updateSnapshot =\n process.argv.includes(\"--update-snapshots\") ||\n process.argv.includes(\"-u\") ||\n Boolean(process.env[\"BUN_UPDATE_SNAPSHOTS\"])\n\n if (!fs.existsSync(filePath) || updateSnapshot) {\n console.log(\"Writing snapshot to\", filePath)\n fs.writeFileSync(filePath, receivedSvg)\n return {\n message: () => `Snapshot created at ${filePath}`,\n pass: true,\n }\n }\n\n const existingSnapshot = fs.readFileSync(filePath, \"utf-8\")\n\n const result: any = await looksSame(\n Buffer.from(receivedSvg),\n Buffer.from(existingSnapshot),\n {\n strict: false,\n tolerance: 2,\n },\n )\n\n if (result.equal) {\n return {\n message: () => \"Snapshot matches\",\n pass: true,\n }\n }\n\n const diffPath = filePath.replace(\".snap.svg\", \".diff.png\")\n await looksSame.createDiff({\n reference: Buffer.from(existingSnapshot),\n current: Buffer.from(receivedSvg),\n diff: diffPath,\n highlightColor: \"#ff00ff\",\n })\n\n return {\n message: () => `Snapshot does not match. Diff saved at ${diffPath}`,\n pass: false,\n }\n}\n\n// Add the custom matcher to the expect object\nexpect.extend({\n // biome-ignore lint/suspicious/noExplicitAny: bun's types don't expose matcher type\n toMatchGraphicsSvg: toMatchGraphicsSvg as any,\n})\n\n// Extend the TypeScript interface for the matcher\ndeclare module \"bun:test\" {\n interface Matchers<T = unknown> {\n toMatchGraphicsSvg(\n testPath: string,\n opts?: { backgroundColor?: string; svgName?: string },\n ): Promise<MatcherResult>\n }\n}\n"],"mappings":";;;;;;AAAA,SAAS,cAAkC;AAC3C,YAAY,QAAQ;AACpB,YAAY,UAAU;AACtB,OAAO,eAAe;AAatB,eAAe,mBAGb,sBACA,kBACA,OAAuD,CAAC,GAChC;AACxB,QAAM,WAAW,MAAM;AACvB,QAAM,WAAW,iBAAiB,QAAQ,iBAAiB,EAAE;AAC7D,QAAM,cAAmB,UAAU,aAAQ,QAAQ,GAAG,eAAe;AACrE,QAAM,eAAe,KAAK,UACtB,GAAG,KAAK,OAAO,cACf,GAAQ,cAAS,QAAQ,CAAC;AAC9B,QAAM,WAAgB,UAAK,aAAa,YAAY;AAEpD,MAAI,CAAI,cAAW,WAAW,GAAG;AAC/B,IAAG,aAAU,aAAa,EAAE,WAAW,KAAK,CAAC;AAAA,EAC/C;AAGA,QAAM,cAAc,yBAAyB,UAAU;AAAA,IACrD,iBAAiB,KAAK;AAAA,EACxB,CAAC;AAED,QAAM,iBACJ,QAAQ,KAAK,SAAS,oBAAoB,KAC1C,QAAQ,KAAK,SAAS,IAAI,KAC1B,QAAQ,QAAQ,IAAI,sBAAsB,CAAC;AAE7C,MAAI,CAAI,cAAW,QAAQ,KAAK,gBAAgB;AAC9C,YAAQ,IAAI,uBAAuB,QAAQ;AAC3C,IAAG,iBAAc,UAAU,WAAW;AACtC,WAAO;AAAA,MACL,SAAS,MAAM,uBAAuB,QAAQ;AAAA,MAC9C,MAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,mBAAsB,gBAAa,UAAU,OAAO;AAE1D,QAAM,SAAc,MAAM;AAAA,IACxB,OAAO,KAAK,WAAW;AAAA,IACvB,OAAO,KAAK,gBAAgB;AAAA,IAC5B;AAAA,MACE,QAAQ;AAAA,MACR,WAAW;AAAA,IACb;AAAA,EACF;AAEA,MAAI,OAAO,OAAO;AAChB,WAAO;AAAA,MACL,SAAS,MAAM;AAAA,MACf,MAAM;AAAA,IACR;AAAA,EACF;AAEA,QAAM,WAAW,SAAS,QAAQ,aAAa,WAAW;AAC1D,QAAM,UAAU,WAAW;AAAA,IACzB,WAAW,OAAO,KAAK,gBAAgB;AAAA,IACvC,SAAS,OAAO,KAAK,WAAW;AAAA,IAChC,MAAM;AAAA,IACN,gBAAgB;AAAA,EAClB,CAAC;AAED,SAAO;AAAA,IACL,SAAS,MAAM,0CAA0C,QAAQ;AAAA,IACjE,MAAM;AAAA,EACR;AACF;AAGA,OAAO,OAAO;AAAA;AAAA,EAEZ;AACF,CAAC;","names":[]}
|
package/dist/lib/react.d.ts
CHANGED
|
@@ -3,7 +3,7 @@ import { GraphicsObject } from './types.js';
|
|
|
3
3
|
import { Matrix } from 'transformation-matrix';
|
|
4
4
|
|
|
5
5
|
type GraphicsObjectClickEvent = {
|
|
6
|
-
type: "point" | "line" | "rect" | "circle";
|
|
6
|
+
type: "point" | "line" | "rect" | "circle" | "text";
|
|
7
7
|
index: number;
|
|
8
8
|
object: any;
|
|
9
9
|
};
|