@tscircuit/schematic-trace-solver 0.0.44 → 0.0.45
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/index.d.ts +14 -3
- package/dist/index.js +754 -95
- package/lib/solvers/SchematicTracePipelineSolver/SchematicTracePipelineSolver.ts +0 -1
- package/lib/solvers/TraceCleanupSolver/TraceCleanupSolver.ts +83 -36
- package/lib/solvers/TraceCleanupSolver/hasCollisions.ts +16 -4
- package/lib/solvers/TraceCleanupSolver/is4PointRectangle.ts +17 -0
- package/lib/solvers/TraceCleanupSolver/isSegmentAnEndpointSegment.ts +36 -0
- package/lib/solvers/TraceCleanupSolver/mergeGraphicsObjects.ts +28 -0
- package/lib/solvers/TraceCleanupSolver/minimizeTurnsWithFilteredLabels.ts +18 -1
- package/lib/solvers/TraceCleanupSolver/recognizeStairStepPattern.ts +56 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/UntangleTraceSubsolver.ts +370 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/findAllLShapedTurns.ts +48 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/findIntersectionsWithObstacles.ts +36 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/generateLShapeRerouteCandidates.ts +107 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/generateRectangleCandidates.ts +55 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/getTraceObstacles.ts +25 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/isPathColliding.ts +58 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/visualizeCandidates.ts +33 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/visualizeCollision.ts +20 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/visualizeIntersectionPoints.ts +26 -0
- package/lib/solvers/TraceCleanupSolver/sub-solver/visualizeLSapes.ts +33 -0
- package/lib/solvers/TraceCleanupSolver/turnMinimization.ts +50 -56
- package/lib/solvers/TraceCleanupSolver/visualizeTightRectangle.ts +24 -0
- package/package.json +1 -1
- package/tests/examples/__snapshots__/example29.snap.svg +6 -6
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { GraphicsObject } from "graphics-debug"
|
|
2
|
+
import type { Point } from "@tscircuit/math-utils"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Visualizes a set of candidate paths and optional intersection points.
|
|
6
|
+
* It draws each candidate path as a line with a specified color and marks intersection points with green circles.
|
|
7
|
+
* This function is useful for debugging and understanding the rerouting process.
|
|
8
|
+
*/
|
|
9
|
+
export const visualizeCandidates = (
|
|
10
|
+
candidates: Point[][],
|
|
11
|
+
color = "gray",
|
|
12
|
+
intersectionPoints: Point[] = [],
|
|
13
|
+
): GraphicsObject => {
|
|
14
|
+
const graphics: GraphicsObject = { lines: [], circles: [] }
|
|
15
|
+
|
|
16
|
+
for (const candidate of candidates) {
|
|
17
|
+
graphics.lines!.push({
|
|
18
|
+
points: candidate,
|
|
19
|
+
strokeColor: color,
|
|
20
|
+
})
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
// Draw intersection points
|
|
24
|
+
for (const point of intersectionPoints) {
|
|
25
|
+
graphics.circles!.push({
|
|
26
|
+
center: point,
|
|
27
|
+
radius: 0.01, // Larger radius for intersection points
|
|
28
|
+
fill: "green",
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return graphics
|
|
33
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import type { GraphicsObject } from "graphics-debug"
|
|
2
|
+
import type { CollisionInfo } from "./isPathColliding"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Visualizes a collision point if collision information is provided and a collision occurred.
|
|
6
|
+
* It draws a red circle at the collision point to highlight the location of the collision.
|
|
7
|
+
*/
|
|
8
|
+
export const visualizeCollision = (
|
|
9
|
+
collisionInfo: CollisionInfo | null,
|
|
10
|
+
): GraphicsObject => {
|
|
11
|
+
const collisionGraphics: GraphicsObject = { circles: [] }
|
|
12
|
+
if (collisionInfo?.isColliding && collisionInfo.collisionPoint) {
|
|
13
|
+
collisionGraphics.circles!.push({
|
|
14
|
+
center: collisionInfo.collisionPoint,
|
|
15
|
+
radius: 0.01,
|
|
16
|
+
fill: "red",
|
|
17
|
+
})
|
|
18
|
+
}
|
|
19
|
+
return collisionGraphics
|
|
20
|
+
}
|
|
@@ -0,0 +1,26 @@
|
|
|
1
|
+
import type { Point } from "@tscircuit/math-utils"
|
|
2
|
+
import type { GraphicsObject } from "graphics-debug"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Visualizes a set of intersection points by drawing circles at their locations.
|
|
6
|
+
* This function is used to highlight where different trace segments or obstacles intersect.
|
|
7
|
+
*/
|
|
8
|
+
export const visualizeIntersectionPoints = (
|
|
9
|
+
points: Point[],
|
|
10
|
+
color = "red",
|
|
11
|
+
): GraphicsObject => {
|
|
12
|
+
const graphics: GraphicsObject = { circles: [] }
|
|
13
|
+
|
|
14
|
+
for (const point of points) {
|
|
15
|
+
graphics.circles!.push({
|
|
16
|
+
center: {
|
|
17
|
+
x: point.x,
|
|
18
|
+
y: point.y,
|
|
19
|
+
},
|
|
20
|
+
radius: 0.01,
|
|
21
|
+
fill: color,
|
|
22
|
+
})
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
return graphics
|
|
26
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { LShape } from "./findAllLShapedTurns"
|
|
2
|
+
import type { GraphicsObject } from "graphics-debug"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Visualizes L-shaped turns by drawing a blue circle at the corner point (p2)
|
|
6
|
+
* and light blue lines connecting p1, p2, and p3.
|
|
7
|
+
* This function can visualize a single L-shape or an array of L-shapes.
|
|
8
|
+
*/
|
|
9
|
+
export const visualizeLSapes = (lShapes: LShape[] | LShape): GraphicsObject => {
|
|
10
|
+
const graphics: GraphicsObject = { circles: [], lines: [] }
|
|
11
|
+
|
|
12
|
+
const lShapesArray = Array.isArray(lShapes) ? lShapes : [lShapes]
|
|
13
|
+
|
|
14
|
+
for (const lShape of lShapesArray) {
|
|
15
|
+
// Draw the center point as a blue ball
|
|
16
|
+
graphics.circles!.push({
|
|
17
|
+
center: {
|
|
18
|
+
x: lShape.p2.x,
|
|
19
|
+
y: lShape.p2.y,
|
|
20
|
+
},
|
|
21
|
+
radius: 0.01,
|
|
22
|
+
fill: "blue",
|
|
23
|
+
})
|
|
24
|
+
|
|
25
|
+
// Draw the two lines in a light blue color
|
|
26
|
+
graphics.lines!.push({
|
|
27
|
+
points: [lShape.p1, lShape.p2, lShape.p3],
|
|
28
|
+
strokeColor: "lightblue",
|
|
29
|
+
})
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
return graphics
|
|
33
|
+
}
|
|
@@ -4,75 +4,32 @@ import { countTurns } from "./countTurns"
|
|
|
4
4
|
import { simplifyPath } from "./simplifyPath"
|
|
5
5
|
import { tryConnectPoints } from "./tryConnectPoints"
|
|
6
6
|
import { hasCollisionsWithLabels } from "./hasCollisionsWithLabels"
|
|
7
|
-
|
|
7
|
+
import { recognizeStairStepPattern } from "./recognizeStairStepPattern"
|
|
8
|
+
import { isSegmentAnEndpointSegment } from "./isSegmentAnEndpointSegment"
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Minimizes the number of turns in a given path while avoiding collisions with obstacles and labels.
|
|
12
|
+
* This function employs an iterative approach, attempting to simplify the path in several ways:
|
|
13
|
+
* 1. **Stair-step pattern recognition**: It first looks for and attempts to simplify stair-step patterns by connecting the start and end points of the pattern with a simpler path, if no collisions are introduced.
|
|
14
|
+
* 2. **Point removal and reconnection**: If no stair-step optimization is possible, it tries to remove intermediate points and reconnect the remaining segments with a simpler path, prioritizing solutions that reduce turns or path length.
|
|
15
|
+
* 3. **Collinear segment merging**: Finally, it attempts to merge collinear segments to further simplify the path.
|
|
16
|
+
* The process continues until no further improvements can be made without introducing collisions.
|
|
17
|
+
*/
|
|
8
18
|
export const minimizeTurns = ({
|
|
9
19
|
path,
|
|
10
20
|
obstacles,
|
|
11
21
|
labelBounds,
|
|
22
|
+
originalPath,
|
|
12
23
|
}: {
|
|
13
24
|
path: Point[]
|
|
14
25
|
obstacles: any[]
|
|
15
26
|
labelBounds: any[]
|
|
27
|
+
originalPath: Point[]
|
|
16
28
|
}): Point[] => {
|
|
17
29
|
if (path.length <= 2) {
|
|
18
30
|
return path
|
|
19
31
|
}
|
|
20
32
|
|
|
21
|
-
const recognizeStairStepPattern = (
|
|
22
|
-
pathToCheck: Point[],
|
|
23
|
-
startIdx: number,
|
|
24
|
-
): number => {
|
|
25
|
-
if (startIdx >= pathToCheck.length - 3) return -1
|
|
26
|
-
|
|
27
|
-
let endIdx = startIdx
|
|
28
|
-
let isStairStep = true
|
|
29
|
-
|
|
30
|
-
for (
|
|
31
|
-
let i = startIdx;
|
|
32
|
-
i < pathToCheck.length - 2 && i < startIdx + 10;
|
|
33
|
-
i++
|
|
34
|
-
) {
|
|
35
|
-
if (i + 2 >= pathToCheck.length) break
|
|
36
|
-
|
|
37
|
-
const p1 = pathToCheck[i]
|
|
38
|
-
const p2 = pathToCheck[i + 1]
|
|
39
|
-
const p3 = pathToCheck[i + 2]
|
|
40
|
-
|
|
41
|
-
const seg1Vertical = p1.x === p2.x
|
|
42
|
-
const seg2Vertical = p2.x === p3.x
|
|
43
|
-
|
|
44
|
-
if (seg1Vertical === seg2Vertical) {
|
|
45
|
-
break
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
const seg1Direction = seg1Vertical
|
|
49
|
-
? Math.sign(p2.y - p1.y)
|
|
50
|
-
: Math.sign(p2.x - p1.x)
|
|
51
|
-
|
|
52
|
-
if (i > startIdx) {
|
|
53
|
-
const prevP = pathToCheck[i - 1]
|
|
54
|
-
const prevSegVertical = prevP.x === p1.x
|
|
55
|
-
const prevDirection = prevSegVertical
|
|
56
|
-
? Math.sign(p1.y - prevP.y)
|
|
57
|
-
: Math.sign(p1.x - prevP.x)
|
|
58
|
-
|
|
59
|
-
if (
|
|
60
|
-
(seg1Vertical &&
|
|
61
|
-
prevSegVertical &&
|
|
62
|
-
seg1Direction !== prevDirection) ||
|
|
63
|
-
(!seg1Vertical && !prevSegVertical && seg1Direction !== prevDirection)
|
|
64
|
-
) {
|
|
65
|
-
isStairStep = false
|
|
66
|
-
break
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
|
|
70
|
-
endIdx = i + 2
|
|
71
|
-
}
|
|
72
|
-
|
|
73
|
-
return isStairStep && endIdx - startIdx >= 3 ? endIdx : -1
|
|
74
|
-
}
|
|
75
|
-
|
|
76
33
|
let optimizedPath = [...path]
|
|
77
34
|
let currentTurns = countTurns(optimizedPath)
|
|
78
35
|
let improved = true
|
|
@@ -85,6 +42,21 @@ export const minimizeTurns = ({
|
|
|
85
42
|
const stairEndIdx = recognizeStairStepPattern(optimizedPath, startIdx)
|
|
86
43
|
|
|
87
44
|
if (stairEndIdx > 0) {
|
|
45
|
+
if (
|
|
46
|
+
isSegmentAnEndpointSegment(
|
|
47
|
+
optimizedPath[startIdx],
|
|
48
|
+
optimizedPath[startIdx + 1],
|
|
49
|
+
originalPath,
|
|
50
|
+
) ||
|
|
51
|
+
isSegmentAnEndpointSegment(
|
|
52
|
+
optimizedPath[stairEndIdx - 1],
|
|
53
|
+
optimizedPath[stairEndIdx],
|
|
54
|
+
originalPath,
|
|
55
|
+
)
|
|
56
|
+
) {
|
|
57
|
+
continue
|
|
58
|
+
}
|
|
59
|
+
|
|
88
60
|
const startPoint = optimizedPath[startIdx]
|
|
89
61
|
const endPoint = optimizedPath[stairEndIdx]
|
|
90
62
|
|
|
@@ -129,6 +101,21 @@ export const minimizeTurns = ({
|
|
|
129
101
|
|
|
130
102
|
if (endIdx >= optimizedPath.length) continue
|
|
131
103
|
|
|
104
|
+
if (
|
|
105
|
+
isSegmentAnEndpointSegment(
|
|
106
|
+
optimizedPath[startIdx],
|
|
107
|
+
optimizedPath[startIdx + 1],
|
|
108
|
+
originalPath,
|
|
109
|
+
) ||
|
|
110
|
+
isSegmentAnEndpointSegment(
|
|
111
|
+
optimizedPath[endIdx - 1],
|
|
112
|
+
optimizedPath[endIdx],
|
|
113
|
+
originalPath,
|
|
114
|
+
)
|
|
115
|
+
) {
|
|
116
|
+
continue
|
|
117
|
+
}
|
|
118
|
+
|
|
132
119
|
const startPoint = optimizedPath[startIdx]
|
|
133
120
|
const endPoint = optimizedPath[endIdx]
|
|
134
121
|
|
|
@@ -179,6 +166,13 @@ export const minimizeTurns = ({
|
|
|
179
166
|
const p2 = optimizedPath[i + 1]
|
|
180
167
|
const p3 = optimizedPath[i + 2]
|
|
181
168
|
|
|
169
|
+
if (
|
|
170
|
+
isSegmentAnEndpointSegment(p1, p2, originalPath) ||
|
|
171
|
+
isSegmentAnEndpointSegment(p2, p3, originalPath)
|
|
172
|
+
) {
|
|
173
|
+
continue
|
|
174
|
+
}
|
|
175
|
+
|
|
182
176
|
const allVertical = p1.x === p2.x && p2.x === p3.x
|
|
183
177
|
const allHorizontal = p1.y === p2.y && p2.y === p3.y
|
|
184
178
|
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
import type { GraphicsObject } from "graphics-debug"
|
|
2
|
+
import type { Rectangle } from "./sub-solver/generateRectangleCandidates"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Visualizes a given rectangle by drawing it as a green-stroked rectangle.
|
|
6
|
+
* This function is useful for highlighting specific rectangular areas in a graphical representation.
|
|
7
|
+
*/
|
|
8
|
+
export const visualizeTightRectangle = (
|
|
9
|
+
rectangle: Rectangle,
|
|
10
|
+
): GraphicsObject => {
|
|
11
|
+
const graphics: GraphicsObject = { rects: [] }
|
|
12
|
+
|
|
13
|
+
graphics.rects!.push({
|
|
14
|
+
center: {
|
|
15
|
+
x: rectangle.x + rectangle.width / 2,
|
|
16
|
+
y: rectangle.y + rectangle.height / 2,
|
|
17
|
+
},
|
|
18
|
+
width: rectangle.width,
|
|
19
|
+
height: rectangle.height,
|
|
20
|
+
stroke: "green",
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
return graphics
|
|
24
|
+
}
|
package/package.json
CHANGED
|
@@ -543,7 +543,7 @@ x+" data-x="-8.4" data-y="-17" cx="198.31710258539454" cy="399.68032912258366" r
|
|
|
543
543
|
<circle data-type="point" data-label="" data-x="3.5999999999999996" data-y="0.5000000000000013" cx="413.0516274346982" cy="86.52581371734914" r="3" fill="hsl(80, 100%, 50%, 0.9)" />
|
|
544
544
|
</g>
|
|
545
545
|
<g>
|
|
546
|
-
<circle data-type="point" data-label="" data-x="-6.
|
|
546
|
+
<circle data-type="point" data-label="" data-x="-6.112500000000001" data-y="-12" cx="239.25087138479304" cy="310.2076104353738" r="3" fill="hsl(80, 100%, 50%, 0.9)" />
|
|
547
547
|
</g>
|
|
548
548
|
<g>
|
|
549
549
|
<circle data-type="point" data-label="" data-x="-4" data-y="-14.225" cx="277.0530950301392" cy="350.0229702511822" r="3" fill="hsl(80, 100%, 50%, 0.9)" />
|
|
@@ -849,7 +849,7 @@ x+" data-x="-8.4" data-y="-17" cx="198.31710258539454" cy="399.68032912258366" r
|
|
|
849
849
|
<polyline data-points="-4.449999999999999,-10 -4,-10 -4,-10.45" data-type="line" data-label="" points="269.00055034829035,274.4185229604899 277.0530950301392,274.4185229604899 277.0530950301392,282.47106764233877" fill="none" stroke="purple" stroke-width="1" />
|
|
850
850
|
</g>
|
|
851
851
|
<g>
|
|
852
|
-
<polyline data-points="-5.550000000000001,-10 -5.750000000000001,-10 -5.750000000000001,-
|
|
852
|
+
<polyline data-points="-5.550000000000001,-10 -5.750000000000001,-10 -5.750000000000001,-9 -8.200000000000001,-9 -8.200000000000001,-5 -8.4,-5" data-type="line" data-label="" points="249.31655223710416,274.4185229604899 245.73764348961578,274.4185229604899 245.73764348961578,256.52397922304795 201.89601133288292,256.52397922304795 201.89601133288292,184.94580427328003 198.31710258539454,184.94580427328003" fill="none" stroke="purple" stroke-width="1" />
|
|
853
853
|
</g>
|
|
854
854
|
<g>
|
|
855
855
|
<polyline data-points="-4,-11.55 -4,-12 -3,-12 -3,-12.45" data-type="line" data-label="" points="277.0530950301392,302.1550657535249 277.0530950301392,310.2076104353738 294.9476387675812,310.2076104353738 294.9476387675812,318.2601551172227" fill="none" stroke="purple" stroke-width="1" />
|
|
@@ -858,7 +858,7 @@ x+" data-x="-8.4" data-y="-17" cx="198.31710258539454" cy="399.68032912258366" r
|
|
|
858
858
|
<polyline data-points="-4.449999999999999,-12 -4,-12 -4,-11.55" data-type="line" data-label="" points="269.00055034829035,310.2076104353738 277.0530950301392,310.2076104353738 277.0530950301392,302.1550657535249" fill="none" stroke="purple" stroke-width="1" />
|
|
859
859
|
</g>
|
|
860
860
|
<g>
|
|
861
|
-
<polyline data-points="-5.550000000000001,-12 -6.
|
|
861
|
+
<polyline data-points="-5.550000000000001,-12 -6.675000000000001,-12 -6.675000000000001,-9.2 -8.4,-9.2" data-type="line" data-label="" points="249.31655223710416,310.2076104353738 229.18519053248195,310.2076104353738 229.18519053248195,260.1028879705363 198.31710258539454,260.1028879705363" fill="none" stroke="purple" stroke-width="1" />
|
|
862
862
|
</g>
|
|
863
863
|
<g>
|
|
864
864
|
<polyline data-points="-4,-14.45 -4,-14 -3,-14 -3,-13.55" data-type="line" data-label="" points="277.0530950301392,354.0492425921067 277.0530950301392,345.9966979102578 294.9476387675812,345.9966979102578 294.9476387675812,337.94415322840894" fill="none" stroke="purple" stroke-width="1" />
|
|
@@ -876,7 +876,7 @@ x+" data-x="-8.4" data-y="-17" cx="198.31710258539454" cy="399.68032912258366" r
|
|
|
876
876
|
<polyline data-points="-3,-16.45 -3,-16 -4,-16 -4,-15.55" data-type="line" data-label="" points="294.9476387675812,389.8383300669906 294.9476387675812,381.7857853851417 277.0530950301392,381.7857853851417 277.0530950301392,373.73324070329284" fill="none" stroke="purple" stroke-width="1" />
|
|
877
877
|
</g>
|
|
878
878
|
<g>
|
|
879
|
-
<polyline data-points="-5.550000000000001,-16 -6.875000000000001,-16 -6.875000000000001,-
|
|
879
|
+
<polyline data-points="-5.550000000000001,-16 -6.875000000000001,-16 -6.875000000000001,-10 -8.4,-10" data-type="line" data-label="" points="249.31655223710416,381.7857853851417 225.60628178499354,381.7857853851417 225.60628178499354,274.4185229604899 198.31710258539454,274.4185229604899" fill="none" stroke="purple" stroke-width="1" />
|
|
880
880
|
</g>
|
|
881
881
|
<g>
|
|
882
882
|
<polyline data-points="-4,-18.45 -4,-18 -3,-18 -3,-17.55" data-type="line" data-label="" points="277.0530950301392,425.6274175418746 277.0530950301392,417.5748728600257 294.9476387675812,417.5748728600257 294.9476387675812,409.52232817817685" fill="none" stroke="purple" stroke-width="1" />
|
|
@@ -1056,7 +1056,7 @@ x+" data-x="-8.4" data-y="-17" cx="198.31710258539454" cy="399.68032912258366" r
|
|
|
1056
1056
|
<rect data-type="rect" data-label="" data-x="3.3739999999999997" data-y="0.7000000000000015" x="404.9811882091119" y="81.15745059611653" width="8.052544681848872" height="3.5789087474883985" fill="hsl(80, 100%, 50%, 0.35)" stroke="black" stroke-width="0.05588295598214286" />
|
|
1057
1057
|
</g>
|
|
1058
1058
|
<g>
|
|
1059
|
-
<rect data-type="rect" data-label="" data-x="-5.750000000000001" data-y="-
|
|
1059
|
+
<rect data-type="rect" data-label="" data-x="-5.750000000000001" data-y="-10.225" x="243.94818911587157" y="274.4185229604899" width="3.5789087474883843" height="8.052544681848872" fill="hsl(80, 100%, 50%, 0.35)" stroke="black" stroke-width="0.05588295598214286" />
|
|
1060
1060
|
</g>
|
|
1061
1061
|
<g>
|
|
1062
1062
|
<rect data-type="rect" data-label="" data-x="-3.775" data-y="-11.775" x="277.0530950301392" y="304.3918837207052" width="8.052544681848929" height="3.5789087474884127" fill="hsl(80, 100%, 50%, 0.35)" stroke="black" stroke-width="0.05588295598214286" />
|
|
@@ -1065,7 +1065,7 @@ x+" data-x="-8.4" data-y="-17" cx="198.31710258539454" cy="399.68032912258366" r
|
|
|
1065
1065
|
<rect data-type="rect" data-label="" data-x="3.3739999999999997" data-y="0.5000000000000013" x="404.9811882091119" y="84.73635934360493" width="8.052544681848872" height="3.5789087474883985" fill="hsl(80, 100%, 50%, 0.35)" stroke="black" stroke-width="0.05588295598214286" />
|
|
1066
1066
|
</g>
|
|
1067
1067
|
<g>
|
|
1068
|
-
<rect data-type="rect" data-label="" data-x="-6.
|
|
1068
|
+
<rect data-type="rect" data-label="" data-x="-6.112500000000001" data-y="-11.775" x="237.46141701104887" y="302.1550657535249" width="3.578908747488356" height="8.052544681848872" fill="hsl(80, 100%, 50%, 0.35)" stroke="black" stroke-width="0.05588295598214286" />
|
|
1069
1069
|
</g>
|
|
1070
1070
|
<g>
|
|
1071
1071
|
<rect data-type="rect" data-label="" data-x="-3.775" data-y="-14.225" x="277.0530950301392" y="348.23351587743804" width="8.052544681848929" height="3.578908747488356" fill="hsl(80, 100%, 50%, 0.35)" stroke="black" stroke-width="0.05588295598214286" />
|