@tscircuit/rectdiff 0.0.28 → 0.0.30

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.
Files changed (68) hide show
  1. package/.github/workflows/bun-pver-release.yml +24 -45
  2. package/lib/RectDiffPipeline.ts +0 -46
  3. package/lib/fixtures/twoNodeExpansionFixture.ts +1 -1
  4. package/lib/solvers/GapFillSolver/ExpandEdgesToEmptySpaceSolver.ts +4 -2
  5. package/lib/solvers/GapFillSolver/FindSegmentsWithAdjacentEmptySpaceSolver.ts +3 -1
  6. package/lib/solvers/GapFillSolver/GapFillSolverPipeline.ts +6 -2
  7. package/lib/solvers/RectDiffExpansionSolver/RectDiffExpansionSolver.ts +5 -2
  8. package/lib/solvers/RectDiffGridSolverPipeline/RectDiffGridSolverPipeline.ts +8 -5
  9. package/lib/solvers/RectDiffGridSolverPipeline/buildObstacleIndexes.ts +6 -6
  10. package/lib/solvers/RectDiffSeedingSolver/RectDiffSeedingSolver.ts +4 -4
  11. package/lib/solvers/RectDiffSeedingSolver/computeCandidates3D.ts +1 -1
  12. package/lib/solvers/RectDiffSeedingSolver/computeEdgeCandidates3D.ts +1 -1
  13. package/lib/solvers/RectDiffSeedingSolver/longestFreeSpanAroundZ.ts +1 -1
  14. package/lib/types/capacity-mesh-types.ts +1 -1
  15. package/lib/types/srj-types.ts +0 -1
  16. package/lib/utils/expandRectFromSeed.ts +1 -1
  17. package/lib/utils/finalizeRects.ts +1 -1
  18. package/lib/utils/isFullyOccupiedAtPoint.ts +1 -1
  19. package/lib/utils/isSelfRect.ts +1 -1
  20. package/lib/utils/rectToTree.ts +2 -2
  21. package/lib/utils/renderObstacleClearance.ts +1 -1
  22. package/lib/utils/resizeSoftOverlaps.ts +1 -1
  23. package/lib/utils/sameTreeRect.ts +1 -1
  24. package/lib/utils/searchStrip.ts +1 -1
  25. package/package.json +12 -8
  26. package/pages/repro/merge-single-layer-node.page.tsx +17 -0
  27. package/tests/__snapshots__/board-outline.snap.svg +2 -2
  28. package/tests/solver/__snapshots__/rectDiffGridSolverPipeline.snap.svg +1 -1
  29. package/tests/solver/both-points-equivalent/__snapshots__/both-points-equivalent.snap.svg +1 -1
  30. package/tests/solver/bugreport01-be84eb/__snapshots__/bugreport01-be84eb.snap.svg +1 -1
  31. package/tests/solver/bugreport02-bc4361/__snapshots__/bugreport02-bc4361.snap.svg +1 -1
  32. package/tests/solver/bugreport03-fe4a17/__snapshots__/bugreport03-fe4a17.snap.svg +1 -1
  33. package/tests/solver/bugreport07-d3f3be/__snapshots__/bugreport07-d3f3be.snap.svg +1 -1
  34. package/tests/solver/bugreport08-e3ec95/__snapshots__/bugreport08-e3ec95.snap.svg +1 -1
  35. package/tests/solver/bugreport09-618e09/__snapshots__/bugreport09-618e09.snap.svg +1 -1
  36. package/tests/solver/bugreport10-71239a/__snapshots__/bugreport10-71239a.snap.svg +1 -1
  37. package/tests/solver/bugreport11-b2de3c/__snapshots__/bugreport11-b2de3c.snap.svg +1 -1
  38. package/tests/solver/bugreport12-35ce1c/__snapshots__/bugreport12-35ce1c.snap.svg +1 -1
  39. package/tests/solver/bugreport13-b9a758/__snapshots__/bugreport13-b9a758.snap.svg +1 -1
  40. package/tests/solver/bugreport16-d95f38/__snapshots__/bugreport16-d95f38.snap.svg +1 -1
  41. package/tests/solver/bugreport19/__snapshots__/bugreport19.snap.svg +1 -1
  42. package/tests/solver/bugreport20-obstacle-clipping/__snapshots__/bugreport20-obstacle-clipping.snap.svg +1 -1
  43. package/tests/solver/bugreport21-board-outline/__snapshots__/bugreport21-board-outline.snap.svg +2 -2
  44. package/tests/solver/bugreport22-2a75ce/__snapshots__/bugreport22-2a75ce.snap.svg +1 -1
  45. package/tests/solver/bugreport23-LGA15x4/__snapshots__/bugreport23-LGA15x4.snap.svg +1 -1
  46. package/tests/solver/bugreport24-05597c/__snapshots__/bugreport24-05597c.snap.svg +1 -1
  47. package/tests/solver/bugreport25-4b1d55/__snapshots__/bugreport25-4b1d55.snap.svg +1 -1
  48. package/tests/solver/bugreport36-bf8303/__snapshots__/bugreport36-bf8303.snap.svg +1 -1
  49. package/tests/solver/interaction/__snapshots__/interaction.snap.svg +1 -1
  50. package/tests/solver/multi-point/__snapshots__/multi-point.snap.svg +1 -1
  51. package/tests/solver/no-better-path/__snapshots__/no-better-path.snap.svg +1 -1
  52. package/tests/solver/repros/merge-single-layer-node/merge-single-layer-node.json +861 -0
  53. package/tests/solver/{bugreport50-multi-support-layer-merge/bugreport50-multi-support-layer-merge.test.ts → repros/merge-single-layer-node/merge-single-layer-node.test.ts} +7 -42
  54. package/tests/solver/transitivity/__snapshots__/transitivity.snap.svg +2 -2
  55. package/tsconfig.json +5 -1
  56. package/vite.config.ts +4 -0
  57. package/dist/index.d.ts +0 -427
  58. package/dist/index.js +0 -3319
  59. package/lib/solvers/AdjacentLayerContainmentMergeSolver/AdjacentLayerContainmentMergeSolver.ts +0 -456
  60. package/lib/solvers/OuterLayerContainmentMergeSolver/OuterLayerContainmentMergeSolver.ts +0 -314
  61. package/pages/bugreports/bugreport50-multi-support-layer-merge.page.tsx +0 -19
  62. package/pages/pour.page.tsx +0 -18
  63. package/test-assets/bugreport49-634662.json +0 -412
  64. package/tests/outer-layer-containment-merge-solver.test.ts +0 -73
  65. package/tests/solver/bugreport49-634662/__snapshots__/bugreport49-634662.snap.svg +0 -44
  66. package/tests/solver/bugreport49-634662/bugreport49-634662.test.ts +0 -130
  67. package/tests/solver/bugreport50-multi-support-layer-merge/__snapshots__/bugreport50-multi-support-layer-merge.snap.svg +0 -44
  68. package/tests/solver/bugreport50-multi-support-layer-merge/bugreport50-multi-support-layer-merge.json +0 -972
@@ -1,412 +0,0 @@
1
- {
2
- "autorouting_bug_report_id": "6346629c-bb27-4d63-a798-78e850e8572d",
3
- "reporter_account_id": "9f398687-69d0-4ef4-a48c-bb6dc990e7df",
4
- "package_id": null,
5
- "title": "<board#1853 />",
6
- "simple_route_json": {
7
- "bounds": {
8
- "maxX": 5,
9
- "maxY": 5,
10
- "minX": -5,
11
- "minY": -5
12
- },
13
- "obstacles": [
14
- {
15
- "type": "rect",
16
- "width": 1,
17
- "center": {
18
- "x": -2.15,
19
- "y": 1.905
20
- },
21
- "height": 0.6,
22
- "layers": ["top"],
23
- "connectedTo": [
24
- "pcb_smtpad_0",
25
- "connectivity_net8",
26
- "source_trace_3",
27
- "source_port_8",
28
- "source_port_0",
29
- "pcb_smtpad_0",
30
- "pcb_port_0",
31
- "pcb_smtpad_8",
32
- "pcb_port_8"
33
- ]
34
- },
35
- {
36
- "type": "rect",
37
- "width": 1,
38
- "center": {
39
- "x": -2.15,
40
- "y": 0.635
41
- },
42
- "height": 0.6,
43
- "layers": ["top"],
44
- "connectedTo": [
45
- "pcb_smtpad_1",
46
- "connectivity_net16",
47
- "source_trace_6",
48
- "source_port_11",
49
- "source_trace_4",
50
- "source_port_9",
51
- "source_trace_2",
52
- "source_port_3",
53
- "source_trace_0",
54
- "source_port_1",
55
- "source_net_0",
56
- "pcb_smtpad_1",
57
- "pcb_port_1",
58
- "pcb_smtpad_3",
59
- "pcb_port_3",
60
- "pcb_smtpad_9",
61
- "pcb_port_9",
62
- "pcb_smtpad_11",
63
- "pcb_port_11"
64
- ]
65
- },
66
- {
67
- "type": "rect",
68
- "width": 1,
69
- "center": {
70
- "x": -2.15,
71
- "y": -0.635
72
- },
73
- "height": 0.6,
74
- "layers": ["top"],
75
- "connectedTo": [
76
- "pcb_smtpad_2",
77
- "connectivity_net3",
78
- "source_trace_1",
79
- "source_port_2",
80
- "source_net_1",
81
- "pcb_smtpad_2",
82
- "pcb_port_2"
83
- ]
84
- },
85
- {
86
- "type": "rect",
87
- "width": 1,
88
- "center": {
89
- "x": -2.15,
90
- "y": -1.905
91
- },
92
- "height": 0.6,
93
- "layers": ["top"],
94
- "connectedTo": [
95
- "pcb_smtpad_3",
96
- "connectivity_net16",
97
- "source_trace_6",
98
- "source_port_11",
99
- "source_trace_4",
100
- "source_port_9",
101
- "source_trace_2",
102
- "source_port_3",
103
- "source_trace_0",
104
- "source_port_1",
105
- "source_net_0",
106
- "pcb_smtpad_1",
107
- "pcb_port_1",
108
- "pcb_smtpad_3",
109
- "pcb_port_3",
110
- "pcb_smtpad_9",
111
- "pcb_port_9",
112
- "pcb_smtpad_11",
113
- "pcb_port_11"
114
- ]
115
- },
116
- {
117
- "type": "rect",
118
- "width": 1,
119
- "center": {
120
- "x": 2.15,
121
- "y": -1.905
122
- },
123
- "height": 0.6,
124
- "layers": ["top"],
125
- "connectedTo": [
126
- "pcb_smtpad_4",
127
- "connectivity_net42",
128
- "source_port_4",
129
- "pcb_smtpad_4",
130
- "pcb_port_4"
131
- ]
132
- },
133
- {
134
- "type": "rect",
135
- "width": 1,
136
- "center": {
137
- "x": 2.15,
138
- "y": -0.635
139
- },
140
- "height": 0.6,
141
- "layers": ["top"],
142
- "connectedTo": [
143
- "pcb_smtpad_5",
144
- "connectivity_net13",
145
- "source_trace_5",
146
- "source_port_10",
147
- "source_port_5",
148
- "pcb_smtpad_5",
149
- "pcb_port_5",
150
- "pcb_smtpad_10",
151
- "pcb_port_10"
152
- ]
153
- },
154
- {
155
- "type": "rect",
156
- "width": 1,
157
- "center": {
158
- "x": 2.15,
159
- "y": 0.635
160
- },
161
- "height": 0.6,
162
- "layers": ["top"],
163
- "connectedTo": [
164
- "pcb_smtpad_6",
165
- "connectivity_net43",
166
- "source_port_6",
167
- "pcb_smtpad_6",
168
- "pcb_port_6"
169
- ]
170
- },
171
- {
172
- "type": "rect",
173
- "width": 1,
174
- "center": {
175
- "x": 2.15,
176
- "y": 1.905
177
- },
178
- "height": 0.6,
179
- "layers": ["top"],
180
- "connectedTo": [
181
- "pcb_smtpad_7",
182
- "connectivity_net44",
183
- "source_port_7",
184
- "pcb_smtpad_7",
185
- "pcb_port_7"
186
- ]
187
- },
188
- {
189
- "type": "rect",
190
- "width": 0.54,
191
- "center": {
192
- "x": -2.1499999999999995,
193
- "y": 3.525
194
- },
195
- "height": 0.64,
196
- "layers": ["top"],
197
- "connectedTo": [
198
- "pcb_smtpad_8",
199
- "connectivity_net8",
200
- "source_trace_3",
201
- "source_port_8",
202
- "source_port_0",
203
- "pcb_smtpad_0",
204
- "pcb_port_0",
205
- "pcb_smtpad_8",
206
- "pcb_port_8"
207
- ]
208
- },
209
- {
210
- "type": "rect",
211
- "width": 0.54,
212
- "center": {
213
- "x": -1.1299999999999997,
214
- "y": 3.525
215
- },
216
- "height": 0.64,
217
- "layers": ["top"],
218
- "connectedTo": [
219
- "pcb_smtpad_9",
220
- "connectivity_net16",
221
- "source_trace_6",
222
- "source_port_11",
223
- "source_trace_4",
224
- "source_port_9",
225
- "source_trace_2",
226
- "source_port_3",
227
- "source_trace_0",
228
- "source_port_1",
229
- "source_net_0",
230
- "pcb_smtpad_1",
231
- "pcb_port_1",
232
- "pcb_smtpad_3",
233
- "pcb_port_3",
234
- "pcb_smtpad_9",
235
- "pcb_port_9",
236
- "pcb_smtpad_11",
237
- "pcb_port_11"
238
- ]
239
- },
240
- {
241
- "type": "rect",
242
- "width": 0.64,
243
- "center": {
244
- "x": 3.9699999999999998,
245
- "y": -0.635
246
- },
247
- "height": 0.54,
248
- "layers": ["top"],
249
- "connectedTo": [
250
- "pcb_smtpad_10",
251
- "connectivity_net13",
252
- "source_trace_5",
253
- "source_port_10",
254
- "source_port_5",
255
- "pcb_smtpad_5",
256
- "pcb_port_5",
257
- "pcb_smtpad_10",
258
- "pcb_port_10"
259
- ]
260
- },
261
- {
262
- "type": "rect",
263
- "width": 0.64,
264
- "center": {
265
- "x": 3.9699999999999998,
266
- "y": 0.385
267
- },
268
- "height": 0.54,
269
- "layers": ["top"],
270
- "connectedTo": [
271
- "pcb_smtpad_11",
272
- "connectivity_net16",
273
- "source_trace_6",
274
- "source_port_11",
275
- "source_trace_4",
276
- "source_port_9",
277
- "source_trace_2",
278
- "source_port_3",
279
- "source_trace_0",
280
- "source_port_1",
281
- "source_net_0",
282
- "pcb_smtpad_1",
283
- "pcb_port_1",
284
- "pcb_smtpad_3",
285
- "pcb_port_3",
286
- "pcb_smtpad_9",
287
- "pcb_port_9",
288
- "pcb_smtpad_11",
289
- "pcb_port_11"
290
- ]
291
- },
292
- {
293
- "type": "rect",
294
- "width": 10,
295
- "center": {
296
- "x": 0,
297
- "y": 0
298
- },
299
- "height": 10,
300
- "layers": ["inner1"],
301
- "connectedTo": ["net.VCC"],
302
- "isCopperPour": true
303
- },
304
- {
305
- "type": "rect",
306
- "width": 10,
307
- "center": {
308
- "x": 0,
309
- "y": 0
310
- },
311
- "height": 10,
312
- "layers": ["inner2"],
313
- "connectedTo": ["net.GND"],
314
- "isCopperPour": true
315
- }
316
- ],
317
- "layerCount": 4,
318
- "connections": [
319
- {
320
- "name": "source_trace_3",
321
- "pointsToConnect": [
322
- {
323
- "x": -2.1499999999999995,
324
- "y": 3.525,
325
- "layer": "top",
326
- "pointId": "pcb_port_8",
327
- "pcb_port_id": "pcb_port_8"
328
- },
329
- {
330
- "x": -2.15,
331
- "y": 1.905,
332
- "layer": "top",
333
- "pointId": "pcb_port_0",
334
- "pcb_port_id": "pcb_port_0"
335
- }
336
- ],
337
- "source_trace_id": "source_trace_3"
338
- },
339
- {
340
- "name": "source_trace_5",
341
- "pointsToConnect": [
342
- {
343
- "x": 3.9699999999999998,
344
- "y": -0.635,
345
- "layer": "top",
346
- "pointId": "pcb_port_10",
347
- "pcb_port_id": "pcb_port_10"
348
- },
349
- {
350
- "x": 2.15,
351
- "y": -0.635,
352
- "layer": "top",
353
- "pointId": "pcb_port_5",
354
- "pcb_port_id": "pcb_port_5"
355
- }
356
- ],
357
- "source_trace_id": "source_trace_5"
358
- },
359
- {
360
- "name": "source_net_0",
361
- "netConnectionName": "net.VCC",
362
- "pointsToConnect": [
363
- {
364
- "x": -2.15,
365
- "y": 0.635,
366
- "layer": "top",
367
- "pointId": "pcb_port_1",
368
- "pcb_port_id": "pcb_port_1"
369
- },
370
- {
371
- "x": -2.15,
372
- "y": -1.905,
373
- "layer": "top",
374
- "pointId": "pcb_port_3",
375
- "pcb_port_id": "pcb_port_3"
376
- },
377
- {
378
- "x": -1.1299999999999997,
379
- "y": 3.525,
380
- "layer": "top",
381
- "pointId": "pcb_port_9",
382
- "pcb_port_id": "pcb_port_9"
383
- },
384
- {
385
- "x": 3.9699999999999998,
386
- "y": 0.385,
387
- "layer": "top",
388
- "pointId": "pcb_port_11",
389
- "pcb_port_id": "pcb_port_11"
390
- }
391
- ]
392
- },
393
- {
394
- "name": "source_net_1",
395
- "netConnectionName": "net.GND",
396
- "pointsToConnect": [
397
- {
398
- "x": -2.15,
399
- "y": -0.635,
400
- "layer": "top",
401
- "pointId": "pcb_port_2",
402
- "pcb_port_id": "pcb_port_2"
403
- }
404
- ]
405
- }
406
- ],
407
- "minTraceWidth": 0.15
408
- },
409
- "circuit_json": null,
410
- "subcircuit_id": null,
411
- "created_at": "2026-04-11T17:08:22.076Z"
412
- }
@@ -1,73 +0,0 @@
1
- import { expect, test } from "bun:test"
2
- import { OuterLayerContainmentMergeSolver } from "lib/solvers/OuterLayerContainmentMergeSolver/OuterLayerContainmentMergeSolver"
3
- import type { CapacityMeshNode } from "lib/types/capacity-mesh-types"
4
- import type { SimpleRouteJson } from "lib/types/srj-types"
5
-
6
- const makeNode = (
7
- capacityMeshNodeId: string,
8
- centerX: number,
9
- width: number,
10
- height: number,
11
- availableZ: number[],
12
- ): CapacityMeshNode => ({
13
- capacityMeshNodeId,
14
- center: { x: centerX, y: 0 },
15
- width,
16
- height,
17
- layer: `z${availableZ.join(",")}`,
18
- availableZ,
19
- })
20
-
21
- test("OuterLayerContainmentMergeSolver only promotes nodes larger than 1 mm^2", () => {
22
- const simpleRouteJson: SimpleRouteJson = {
23
- bounds: {
24
- minX: -1,
25
- maxX: 6,
26
- minY: -1,
27
- maxY: 1,
28
- },
29
- obstacles: [
30
- {
31
- type: "rect",
32
- layers: ["inner1"],
33
- zLayers: [1],
34
- center: { x: 2.5, y: 0 },
35
- width: 7,
36
- height: 2,
37
- connectedTo: [],
38
- isCopperPour: true,
39
- },
40
- ],
41
- connections: [],
42
- layerCount: 3,
43
- minTraceWidth: 0.1,
44
- }
45
-
46
- const solver = new OuterLayerContainmentMergeSolver({
47
- meshNodes: [
48
- makeNode("below-threshold", 0.4, 0.8, 1, [0]),
49
- makeNode("at-threshold", 2, 1, 1, [0]),
50
- makeNode("above-threshold", 4.6, 1.2, 1, [0]),
51
- makeNode("below-support", 0.4, 0.8, 1, [1, 2]),
52
- makeNode("at-support", 2, 1, 1, [1, 2]),
53
- makeNode("above-support", 4.6, 1.2, 1, [1, 2]),
54
- ],
55
- simpleRouteJson,
56
- zIndexByName: new Map([
57
- ["top", 0],
58
- ["inner1", 1],
59
- ["bottom", 2],
60
- ]),
61
- })
62
-
63
- solver.solve()
64
-
65
- const outputNodes = solver.getOutput().outputNodes
66
- const nodeById = new Map(
67
- outputNodes.map((node) => [node.capacityMeshNodeId, node] as const),
68
- )
69
-
70
- expect(nodeById.get("below-threshold")?.availableZ).toEqual([0])
71
- expect(nodeById.get("at-threshold")?.availableZ).toEqual([0])
72
- expect(nodeById.get("above-threshold")?.availableZ).toEqual([0, 2])
73
- })
@@ -1,44 +0,0 @@
1
- <svg width="640" height="3699" viewBox="0 0 640 3699" xmlns="http://www.w3.org/2000/svg"><rect width="100%" height="100%" fill="white"/><g><polyline data-points="-5,-5 5,-5 5,5 -5,5 -5,-5" data-type="line" data-label="bounds" points="40,912.6666666666667 600,912.6666666666667 600,352.66666666666674 40,352.66666666666674 40,912.6666666666667" fill="none" stroke="#111827" stroke-width="5.6000000000000005"/></g><g><polyline data-points="-5,-20.208333333333332 5,-20.208333333333332 5,-10.208333333333332 -5,-10.208333333333332 -5,-20.208333333333332" data-type="line" data-label="bounds" points="40,1764.3333333333333 600,1764.3333333333333 600,1204.3333333333335 40,1204.3333333333335 40,1764.3333333333333" fill="none" stroke="#111827" stroke-width="5.6000000000000005"/></g><g><polyline data-points="-5,-35.416666666666664 5,-35.416666666666664 5,-25.416666666666664 -5,-25.416666666666664 -5,-35.416666666666664" data-type="line" data-label="bounds" points="40,2616 600,2616 600,2056 40,2056 40,2616" fill="none" stroke="#111827" stroke-width="5.6000000000000005"/></g><g><polyline data-points="-5,-50.62499999999999 5,-50.62499999999999 5,-40.62499999999999 -5,-40.62499999999999 -5,-50.62499999999999" data-type="line" data-label="bounds" points="40,3467.666666666666 600,3467.666666666666 600,2907.666666666666 40,2907.666666666666 40,3467.666666666666" fill="none" stroke="#111827" stroke-width="5.6000000000000005"/></g><g><rect data-type="rect" data-label="node" data-x="-2.15" data-y="1.905" x="171.6" y="509.1866666666667" width="56.00000000000003" height="33.60000000000002" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-2.15" data-y="0.635" x="171.6" y="580.3066666666667" width="56.00000000000003" height="33.60000000000002" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-2.15" data-y="-0.635" x="171.6" y="651.4266666666667" width="56.00000000000003" height="33.60000000000002" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-2.15" data-y="-1.905" x="171.6" y="722.5466666666667" width="56.00000000000003" height="33.60000000000002" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="2.15" data-y="-1.905" x="412.4" y="722.5466666666667" width="56" height="33.60000000000002" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="2.15" data-y="-0.635" x="412.4" y="651.4266666666667" width="56" height="33.60000000000002" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="2.15" data-y="0.635" x="412.4" y="580.3066666666667" width="56" height="33.60000000000002" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="2.15" data-y="1.905" x="412.4" y="509.1866666666667" width="56" height="33.60000000000002" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-2.1499999999999995" data-y="3.5250000000000004" x="184.48000000000002" y="417.3466666666667" width="30.24000000000001" height="35.84000000000003" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-1.1299999999999997" data-y="3.5250000000000004" x="241.60000000000002" y="417.3466666666667" width="30.24000000000001" height="35.84000000000003" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="3.9699999999999998" data-y="-0.635" x="524.4" y="653.1066666666668" width="35.84000000000003" height="30.239999999999895" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="3.9699999999999998" data-y="0.385" x="524.4" y="595.9866666666668" width="35.84000000000003" height="30.239999999999895" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-2.15" data-y="1.27" x="171.6" y="542.7866666666667" width="56.00000000000003" height="37.51999999999998" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-2.2649999999999997" data-y="2.705" x="171.60000000000002" y="453.1866666666667" width="43.120000000000005" height="56" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="2.15" data-y="1.27" x="412.4" y="542.7866666666667" width="56" height="37.51999999999998" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="2.1500000000000004" data-y="-1.27" x="412.4" y="685.0266666666668" width="56.00000000000006" height="37.51999999999998" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="3.15" data-y="0.4949999999999999" x="468.4" y="595.9866666666668" width="56" height="17.91999999999996" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="3.15" data-y="-0.6350000000000001" x="468.4" y="653.1066666666668" width="56" height="30.24000000000001" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="3.4699999999999998" data-y="-0.125" x="468.4" y="626.2266666666667" width="91.84000000000003" height="26.88000000000011" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-1.7649999999999997" data-y="2.705" x="214.72000000000003" y="453.1866666666667" width="12.879999999999995" height="56" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-2.5349999999999993" data-y="3.5249999999999995" x="171.60000000000002" y="417.3466666666668" width="12.880000000000024" height="35.83999999999992" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-1.6399999999999997" data-y="3.5249999999999995" x="214.72000000000003" y="417.3466666666668" width="26.879999999999995" height="35.83999999999992" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="3.15" data-y="0.22499999999999998" x="468.4" y="613.9066666666668" width="56" height="12.319999999999936" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-0.3550000000000004" data-y="-3.6025" x="40" y="756.1466666666668" width="520.24" height="156.51999999999998" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="0" data-y="1.77" x="227.60000000000002" y="453.1866666666667" width="184.79999999999995" height="160.72000000000003" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-1.1749999999999998" data-y="4.422499999999999" x="40" y="352.66666666666674" width="428.40000000000003" height="64.68000000000006" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-3.825" data-y="2.09" x="40" y="417.34666666666675" width="131.59999999999997" height="196.56" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="3.4699999999999998" data-y="2.8275" x="468.4" y="352.66666666666674" width="91.84000000000003" height="243.31999999999994" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="4.645" data-y="0" x="560.24" y="352.66666666666674" width="39.75999999999999" height="560" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="0" data-y="-1.27" x="227.60000000000002" y="651.4266666666667" width="184.79999999999995" height="104.72000000000003" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-1.1749999999999998" data-y="0" x="40" y="613.9066666666668" width="428.40000000000003" height="37.51999999999998" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-3.325" data-y="-1.27" x="40" y="685.0266666666668" width="187.6" height="37.51999999999998" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="3.4699999999999998" data-y="-1.5550000000000002" x="468.4" y="683.3466666666668" width="91.84000000000003" height="72.79999999999995" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="2.15" data-y="3.025" x="412.4" y="417.34666666666675" width="56" height="91.83999999999997" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="0.39499999999999996" data-y="3.525" x="271.84000000000003" y="417.34666666666675" width="140.55999999999995" height="35.839999999999975" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-3.825" data-y="-1.905" x="40" y="722.5466666666667" width="131.59999999999997" height="33.60000000000002" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-3.825" data-y="-0.635" x="40" y="651.4266666666667" width="131.59999999999997" height="33.60000000000002" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="0" data-y="-15.208333333333332" x="40" y="1204.3333333333335" width="560" height="559.9999999999998" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="0" data-y="-30.416666666666664" x="40" y="2056" width="560" height="560" fill="red" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-0.3550000000000004" data-y="-49.22749999999999" x="40" y="3311.1466666666665" width="520.24" height="156.51999999999953" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="0" data-y="-43.85499999999999" x="227.60000000000002" y="3008.1866666666665" width="184.79999999999995" height="160.72000000000025" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-1.1749999999999998" data-y="-41.20249999999999" x="40" y="2907.666666666666" width="428.40000000000003" height="64.68000000000029" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-3.825" data-y="-43.535" x="40" y="2972.3466666666664" width="131.59999999999997" height="196.5600000000004" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="3.4699999999999998" data-y="-42.79749999999999" x="468.4" y="2907.666666666666" width="91.84000000000003" height="243.32000000000062" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="4.645" data-y="-45.62499999999999" x="560.24" y="2907.666666666666" width="39.75999999999999" height="560" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="0" data-y="-46.894999999999996" x="227.60000000000002" y="3206.4266666666663" width="184.79999999999995" height="104.72000000000025" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-1.1749999999999998" data-y="-45.62499999999999" x="40" y="3168.9066666666668" width="428.40000000000003" height="37.51999999999953" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-3.325" data-y="-46.894999999999996" x="40" y="3240.0266666666666" width="187.6" height="37.51999999999953" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="3.4699999999999998" data-y="-47.17999999999999" x="468.4" y="3238.3466666666664" width="91.84000000000003" height="72.80000000000018" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="2.15" data-y="-42.599999999999994" x="412.4" y="2972.3466666666664" width="56" height="91.84000000000015" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="0.39499999999999996" data-y="-42.099999999999994" x="271.84000000000003" y="2972.3466666666664" width="140.55999999999995" height="35.840000000000146" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-3.825" data-y="-47.529999999999994" x="40" y="3277.546666666666" width="131.59999999999997" height="33.600000000000364" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-3.825" data-y="-46.25999999999999" x="40" y="3206.4266666666663" width="131.59999999999997" height="33.599999999999454" fill="#dbeafe" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-2.15" data-y="-47.529999999999994" x="171.6" y="3277.546666666666" width="56.00000000000003" height="33.600000000000364" fill="#e9d5ff" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-2.15" data-y="-46.25999999999999" x="171.6" y="3206.4266666666663" width="56.00000000000003" height="33.599999999999454" fill="#e9d5ff" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-2.15" data-y="-43.535" x="171.6" y="2972.3466666666664" width="56.00000000000003" height="196.5600000000004" fill="#e9d5ff" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="3.4699999999999998" data-y="-45.74999999999999" x="468.40000000000003" y="3150.9866666666667" width="91.83999999999997" height="87.35999999999967" fill="#e9d5ff" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="2.1500000000000004" data-y="-46.894999999999996" x="412.4" y="3206.4266666666663" width="56.00000000000006" height="104.72000000000025" fill="#e9d5ff" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="2.15" data-y="-44.35499999999999" x="412.4" y="3064.1866666666665" width="56" height="104.72000000000025" fill="#e9d5ff" stroke="black" stroke-width="0.017857142857142856"/></g><g><rect data-type="rect" data-label="node" data-x="-1.255" data-y="-42.099999999999994" x="227.60000000000002" y="2972.3466666666664" width="44.24000000000001" height="35.840000000000146" fill="#e9d5ff" stroke="black" stroke-width="0.017857142857142856"/></g><text data-type="text" data-label="Layer z=0" data-x="0" data-y="6.666666666666666" x="320" y="259.3333333333334" fill="black" font-size="28" font-family="sans-serif" text-anchor="end" dominant-baseline="text-before-edge">Layer z=0</text><text data-type="text" data-label="Layer z=1" data-x="0" data-y="-8.541666666666666" x="320" y="1111" fill="black" font-size="28" font-family="sans-serif" text-anchor="end" dominant-baseline="text-before-edge">Layer z=1</text><text data-type="text" data-label="Layer z=2" data-x="0" data-y="-23.75" x="320" y="1962.6666666666667" fill="black" font-size="28" font-family="sans-serif" text-anchor="end" dominant-baseline="text-before-edge">Layer z=2</text><text data-type="text" data-label="Layer z=3" data-x="0" data-y="-38.95833333333333" x="320" y="2814.333333333333" fill="black" font-size="28" font-family="sans-serif" text-anchor="end" dominant-baseline="text-before-edge">Layer z=3</text><g id="crosshair" style="display: none"><line id="crosshair-h" y1="0" y2="3699" stroke="#666" stroke-width="0.5"/><line id="crosshair-v" x1="0" x2="640" stroke="#666" stroke-width="0.5"/><text id="coordinates" font-family="monospace" font-size="12" fill="#666"></text></g><script><![CDATA[
2
- document.currentScript.parentElement.addEventListener('mousemove', (e) => {
3
- const svg = e.currentTarget;
4
- const rect = svg.getBoundingClientRect();
5
- const x = e.clientX - rect.left;
6
- const y = e.clientY - rect.top;
7
- const crosshair = svg.getElementById('crosshair');
8
- const h = svg.getElementById('crosshair-h');
9
- const v = svg.getElementById('crosshair-v');
10
- const coords = svg.getElementById('coordinates');
11
-
12
- crosshair.style.display = 'block';
13
- h.setAttribute('x1', '0');
14
- h.setAttribute('x2', '640');
15
- h.setAttribute('y1', y);
16
- h.setAttribute('y2', y);
17
- v.setAttribute('x1', x);
18
- v.setAttribute('x2', x);
19
- v.setAttribute('y1', '0');
20
- v.setAttribute('y2', '3699');
21
-
22
- // Calculate real coordinates using inverse transformation
23
- const matrix = {"a":56,"c":0,"e":320,"b":0,"d":-56,"f":632.6666666666667};
24
- // Manually invert and apply the affine transform
25
- // Since we only use translate and scale, we can directly compute:
26
- // x' = (x - tx) / sx
27
- // y' = (y - ty) / sy
28
- const sx = matrix.a;
29
- const sy = matrix.d;
30
- const tx = matrix.e;
31
- const ty = matrix.f;
32
- const realPoint = {
33
- x: (x - tx) / sx,
34
- y: (y - ty) / sy // Flip y back since we used negative scale
35
- }
36
-
37
- coords.textContent = `(${realPoint.x.toFixed(2)}, ${realPoint.y.toFixed(2)})`;
38
- coords.setAttribute('x', (x + 5).toString());
39
- coords.setAttribute('y', (y - 5).toString());
40
- });
41
- document.currentScript.parentElement.addEventListener('mouseleave', () => {
42
- document.currentScript.parentElement.getElementById('crosshair').style.display = 'none';
43
- });
44
- ]]></script></svg>