pantograph2d 0.6.0 → 0.8.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (132) hide show
  1. package/dist/Diagram-2450b2e6.js +1750 -0
  2. package/dist/Diagram-2450b2e6.js.map +1 -0
  3. package/dist/Diagram-57e17509.cjs +4 -0
  4. package/dist/Diagram-57e17509.cjs.map +1 -0
  5. package/dist/QuadraticBezier-e116a2d6.js +3647 -0
  6. package/dist/QuadraticBezier-e116a2d6.js.map +1 -0
  7. package/dist/QuadraticBezier-e3d7218b.cjs +9 -0
  8. package/dist/QuadraticBezier-e3d7218b.cjs.map +1 -0
  9. package/dist/algorithms/intersections/arcsCubicBezierIntersection.d.ts +5 -0
  10. package/dist/algorithms/intersections/arcsQuadraticBezierIntersection.d.ts +5 -0
  11. package/dist/algorithms/intersections/bezierClip.d.ts +28 -0
  12. package/dist/algorithms/intersections/cubicBezierCubicBezierIntersection.d.ts +4 -0
  13. package/dist/algorithms/intersections/lineBezierIntersection.d.ts +5 -0
  14. package/dist/algorithms/intersections/quadraticBezierQuadraticBezierIntersection.d.ts +4 -0
  15. package/dist/algorithms/optimisation/Brent.d.ts +6 -0
  16. package/dist/api/svg.d.ts +1 -0
  17. package/dist/draw-27ac6dae.cjs +2 -0
  18. package/dist/draw-27ac6dae.cjs.map +1 -0
  19. package/dist/draw-c7b2705c.js +344 -0
  20. package/dist/draw-c7b2705c.js.map +1 -0
  21. package/dist/{types/draw.d.ts → draw.d.ts} +15 -0
  22. package/dist/export/json/exportJSON.d.ts +393 -0
  23. package/dist/export/json/jsonDiagram.d.ts +135 -0
  24. package/dist/export/json/jsonFigure.d.ts +132 -0
  25. package/dist/export/json/jsonLoop.d.ts +65 -0
  26. package/dist/export/json/jsonSegment.d.ts +62 -0
  27. package/dist/export/svg/api.d.ts +6 -0
  28. package/dist/{types/export → export}/svg/exportSVG.d.ts +5 -5
  29. package/dist/{types/export → export}/svg/wrapSVG.d.ts +1 -1
  30. package/dist/{types/import → import}/json/importJSON.d.ts +3 -1
  31. package/dist/{types/main.d.ts → main.d.ts} +1 -1
  32. package/dist/{types/models → models}/BoundingBox.d.ts +3 -0
  33. package/dist/{types/models → models}/exports.d.ts +4 -0
  34. package/dist/models/segments/CubicBezier.d.ts +31 -0
  35. package/dist/models/segments/QuadraticBezier.d.ts +30 -0
  36. package/dist/models/segments/utils/deCasteljau.d.ts +3 -0
  37. package/dist/models/segments/utils/isSegment.d.ts +8 -0
  38. package/dist/pantograph/drawShape.cjs +1 -1
  39. package/dist/pantograph/drawShape.cjs.map +1 -1
  40. package/dist/pantograph/drawShape.js +12 -11
  41. package/dist/pantograph/drawShape.js.map +1 -1
  42. package/dist/pantograph/models.cjs +1 -1
  43. package/dist/pantograph/models.js +15 -10
  44. package/dist/pantograph/models.js.map +1 -1
  45. package/dist/pantograph/svg.cjs +2 -0
  46. package/dist/pantograph/svg.cjs.map +1 -0
  47. package/dist/pantograph/svg.js +11 -0
  48. package/dist/pantograph/svg.js.map +1 -0
  49. package/dist/pantograph.cjs +2 -8
  50. package/dist/pantograph.cjs.map +1 -1
  51. package/dist/pantograph.js +368 -375
  52. package/dist/pantograph.js.map +1 -1
  53. package/dist/utils/removeDuplicateValues.d.ts +1 -0
  54. package/dist/wrapSVG-02b823ac.cjs +8 -0
  55. package/dist/wrapSVG-02b823ac.cjs.map +1 -0
  56. package/dist/wrapSVG-0ec8a111.js +62 -0
  57. package/dist/wrapSVG-0ec8a111.js.map +1 -0
  58. package/package.json +33 -22
  59. package/dist/Diagram-ab93c8b7.cjs +0 -11
  60. package/dist/Diagram-ab93c8b7.cjs.map +0 -1
  61. package/dist/Diagram-d848c815.js +0 -4252
  62. package/dist/Diagram-d848c815.js.map +0 -1
  63. package/dist/draw-0f591ea4.cjs +0 -2
  64. package/dist/draw-0f591ea4.cjs.map +0 -1
  65. package/dist/draw-a830827a.js +0 -288
  66. package/dist/draw-a830827a.js.map +0 -1
  67. package/dist/types/export/json/exportJSON.d.ts +0 -196
  68. package/dist/types/export/json/jsonDiagram.d.ts +0 -69
  69. package/dist/types/export/json/jsonFigure.d.ts +0 -66
  70. package/dist/types/export/json/jsonLoop.d.ts +0 -32
  71. package/dist/types/export/json/jsonSegment.d.ts +0 -29
  72. /package/dist/{types/algorithms → algorithms}/boolean/figureBooleans.d.ts +0 -0
  73. /package/dist/{types/algorithms → algorithms}/boolean/loopBooleans.d.ts +0 -0
  74. /package/dist/{types/algorithms → algorithms}/boolean/strandBoolean.d.ts +0 -0
  75. /package/dist/{types/algorithms → algorithms}/boolean/strandsBetweenIntersections.d.ts +0 -0
  76. /package/dist/{types/algorithms → algorithms}/distances/arcArcDistance.d.ts +0 -0
  77. /package/dist/{types/algorithms → algorithms}/distances/genericDistance.d.ts +0 -0
  78. /package/dist/{types/algorithms → algorithms}/distances/index.d.ts +0 -0
  79. /package/dist/{types/algorithms → algorithms}/distances/lineArcDistance.d.ts +0 -0
  80. /package/dist/{types/algorithms → algorithms}/distances/lineLineDistance.d.ts +0 -0
  81. /package/dist/{types/algorithms → algorithms}/filletSegments.d.ts +0 -0
  82. /package/dist/{types/algorithms → algorithms}/intersections/arcArcIntersection.d.ts +0 -0
  83. /package/dist/{types/algorithms → algorithms}/intersections/arcEllipseArcIntersection.d.ts +0 -0
  84. /package/dist/{types/algorithms → algorithms}/intersections/ellipseArcEllipseArcIntersection.d.ts +0 -0
  85. /package/dist/{types/algorithms → algorithms}/intersections/ellipseEllipseIntersection.d.ts +0 -0
  86. /package/dist/{types/algorithms → algorithms}/intersections/index.d.ts +0 -0
  87. /package/dist/{types/algorithms → algorithms}/intersections/lineArcIntersection.d.ts +0 -0
  88. /package/dist/{types/algorithms → algorithms}/intersections/lineEllipseArcIntersection.d.ts +0 -0
  89. /package/dist/{types/algorithms → algorithms}/intersections/lineLineIntersection.d.ts +0 -0
  90. /package/dist/{types/algorithms → algorithms}/intersections/rayIntersections.d.ts +0 -0
  91. /package/dist/{types/algorithms → algorithms}/offsets/offsetFigure.d.ts +0 -0
  92. /package/dist/{types/algorithms → algorithms}/offsets/offsetSegment.d.ts +0 -0
  93. /package/dist/{types/algorithms → algorithms}/offsets/offsetStroke.d.ts +0 -0
  94. /package/dist/{types/algorithms → algorithms}/optimisation/DiRect.d.ts +0 -0
  95. /package/dist/{types/algorithms → algorithms}/organiseLoops.d.ts +0 -0
  96. /package/dist/{types/algorithms → algorithms}/simplify.d.ts +0 -0
  97. /package/dist/{types/algorithms → algorithms}/solvers/solvePolynomials.d.ts +0 -0
  98. /package/dist/{types/algorithms → algorithms}/stitchSegments.d.ts +0 -0
  99. /package/dist/{types/api → api}/drawShape.d.ts +0 -0
  100. /package/dist/{types/api → api}/models.d.ts +0 -0
  101. /package/dist/{types/booleanOperations.d.ts → booleanOperations.d.ts} +0 -0
  102. /package/dist/{types/definitions.d.ts → definitions.d.ts} +0 -0
  103. /package/dist/{types/drawShape → drawShape}/drawCircle.d.ts +0 -0
  104. /package/dist/{types/drawShape → drawShape}/drawRect.d.ts +0 -0
  105. /package/dist/{types/export → export}/svg/svgDiagram.d.ts +0 -0
  106. /package/dist/{types/export → export}/svg/svgFigure.d.ts +0 -0
  107. /package/dist/{types/export → export}/svg/svgLoop.d.ts +0 -0
  108. /package/dist/{types/export → export}/svg/svgSegment.d.ts +0 -0
  109. /package/dist/{types/export → export}/svg/svgStrand.d.ts +0 -0
  110. /package/dist/{types/models → models}/Diagram.d.ts +0 -0
  111. /package/dist/{types/models → models}/Figure.d.ts +0 -0
  112. /package/dist/{types/models → models}/Loop.d.ts +0 -0
  113. /package/dist/{types/models → models}/Strand.d.ts +0 -0
  114. /package/dist/{types/models → models}/Stroke.d.ts +0 -0
  115. /package/dist/{types/models → models}/TransformationMatrix.d.ts +0 -0
  116. /package/dist/{types/models → models}/segments/Arc.d.ts +0 -0
  117. /package/dist/{types/models → models}/segments/EllipseArc.d.ts +0 -0
  118. /package/dist/{types/models → models}/segments/Line.d.ts +0 -0
  119. /package/dist/{types/models → models}/segments/Segment.d.ts +0 -0
  120. /package/dist/{types/models → models}/utils/Transformable.d.ts +0 -0
  121. /package/dist/{types/offsetOperations.d.ts → offsetOperations.d.ts} +0 -0
  122. /package/dist/{types/operations.d.ts → operations.d.ts} +0 -0
  123. /package/dist/{types/utils → utils}/allCombinations.d.ts +0 -0
  124. /package/dist/{types/utils → utils}/allPairs.d.ts +0 -0
  125. /package/dist/{types/utils → utils}/angularDistance.d.ts +0 -0
  126. /package/dist/{types/utils → utils}/listOfFigures.d.ts +0 -0
  127. /package/dist/{types/utils → utils}/projectPointOnLine.d.ts +0 -0
  128. /package/dist/{types/utils → utils}/range.d.ts +0 -0
  129. /package/dist/{types/utils → utils}/removeDuplicatePoints.d.ts +0 -0
  130. /package/dist/{types/utils → utils}/unitAngle.d.ts +0 -0
  131. /package/dist/{types/utils → utils}/zip.d.ts +0 -0
  132. /package/dist/{types/vectorOperations.d.ts → vectorOperations.d.ts} +0 -0
@@ -0,0 +1 @@
1
+ {"version":3,"file":"Diagram-2450b2e6.js","sources":["../src/utils/projectPointOnLine.ts","../src/algorithms/intersections/lineArcIntersection.ts","../src/algorithms/intersections/arcArcIntersection.ts","../src/algorithms/intersections/lineEllipseArcIntersection.ts","../src/algorithms/intersections/ellipseEllipseIntersection.ts","../src/algorithms/intersections/arcEllipseArcIntersection.ts","../src/algorithms/intersections/ellipseArcEllipseArcIntersection.ts","../src/algorithms/intersections/lineBezierIntersection.ts","../src/utils/removeDuplicateValues.ts","../src/algorithms/intersections/arcsCubicBezierIntersection.ts","../src/algorithms/intersections/arcsQuadraticBezierIntersection.ts","../src/algorithms/intersections/bezierClip.ts","../src/algorithms/intersections/cubicBezierCubicBezierIntersection.ts","../src/algorithms/intersections/quadraticBezierQuadraticBezierIntersection.ts","../src/algorithms/intersections/index.ts","../src/utils/allCombinations.ts","../src/models/Stroke.ts","../src/algorithms/simplify.ts","../src/models/Strand.ts","../src/algorithms/intersections/rayIntersections.ts","../src/models/Loop.ts","../src/models/segments/utils/isSegment.ts","../src/export/json/jsonSegment.ts","../src/export/json/jsonLoop.ts","../src/export/json/jsonFigure.ts","../src/export/json/jsonDiagram.ts","../src/export/json/exportJSON.ts","../../../node_modules/flatqueue/index.js","../../../node_modules/flatbush/index.js","../src/algorithms/stitchSegments.ts","../src/models/Figure.ts","../src/algorithms/organiseLoops.ts","../src/utils/allPairs.ts","../src/algorithms/boolean/strandsBetweenIntersections.ts","../src/algorithms/boolean/loopBooleans.ts","../src/algorithms/boolean/figureBooleans.ts","../src/models/Diagram.ts"],"sourcesContent":["import type { Vector } from \"../definitions.js\";\nimport type { Line } from \"../models/segments/Line.js\";\n\nimport { dotProduct, subtract } from \"../vectorOperations.js\";\n\nexport function projectPointOnLine(line: Line, point: Vector): Vector {\n const delta = subtract(point, line.firstPoint);\n const u = dotProduct(delta, line.V) / line.squareLength;\n return line.paramPoint(u);\n}\n","import { add, scalarMultiply, distance } from \"../../vectorOperations.js\";\nimport { Line } from \"../../models/segments/Line.js\";\nimport { Vector } from \"../../definitions.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { projectPointOnLine } from \"../../utils/projectPointOnLine.js\";\n\nexport function lineArcIntersection(\n line: Line,\n arc: Arc,\n precision?: number,\n): Vector[] {\n const epsilon = precision ? precision : line.precision;\n\n const centerOnLine = projectPointOnLine(line, arc.center);\n const centerDistance = distance(centerOnLine, arc.center);\n\n // the line does not touch the circle\n if (centerDistance > arc.radius + epsilon) return [];\n\n // The line is tangent to the arc\n if (Math.abs(centerDistance - arc.radius) < epsilon) {\n const intersectionPoint = centerOnLine;\n if (\n line.isOnSegment(intersectionPoint) &&\n arc.isOnSegment(intersectionPoint)\n ) {\n return [intersectionPoint];\n }\n return [];\n }\n\n // The line crosses the arc\n const intersections = [];\n\n // delta corresponds to the length between the project center on the line and\n // the crossing points\n const delta = Math.sqrt(\n arc.radius * arc.radius - centerDistance * centerDistance,\n );\n\n // We might be able to optimise the check on segment, but it is not clear\n // that it is worth it\n const lineDir = line.tangentAtFirstPoint;\n const p1 = add(centerOnLine, scalarMultiply(lineDir, delta));\n if (line.isOnSegment(p1) && arc.isOnSegment(p1)) {\n intersections.push(p1);\n }\n\n const p2 = add(centerOnLine, scalarMultiply(lineDir, -delta));\n if (line.isOnSegment(p2) && arc.isOnSegment(p2)) {\n intersections.push(p2);\n }\n\n return intersections;\n}\n","import { Vector } from \"../../definitions.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport removeDuplicatePoints from \"../../utils/removeDuplicatePoints.js\";\nimport {\n add,\n distance,\n normalize,\n perpendicular,\n sameVector,\n scalarMultiply,\n subtract,\n} from \"../../vectorOperations\";\n\nconst complementArc = (arc: Arc): Arc => {\n const { firstPoint, lastPoint, center, clockwise } = arc;\n return new Arc(lastPoint, firstPoint, center, clockwise, {\n ignoreChecks: true,\n });\n};\n\nconst handleOverlaps = (arc1: Arc, arc2: Arc): Arc[] => {\n // handle the case with common points at start or end first\n if (arc1.isSame(arc2)) {\n return [arc1];\n }\n // two arcs with common points at start and end (but not the same arc)\n\n const points = removeDuplicatePoints(\n [\n arc2.isOnSegment(arc1.firstPoint) ? arc1.firstPoint : null,\n arc2.isOnSegment(arc1.lastPoint) ? arc1.lastPoint : null,\n arc1.isOnSegment(arc2.firstPoint) ? arc2.firstPoint : null,\n arc1.isOnSegment(arc2.lastPoint) ? arc2.lastPoint : null,\n ].filter((p) => p !== null) as Vector[],\n // We sort by the param value of the first arc. This means that the points\n // will be sorted with the same orientation than arc1\n ).sort((a, b) => arc1.pointToParam(a) - arc1.pointToParam(b));\n\n if (points.length === 0) return [];\n // We consider the case when the arcs touch only on\n // the last point. We consider that they do not overlap there\n //\n // We might want to revisit this choice\n else if (points.length === 1) return [];\n else if (points.length === 2) {\n // Similar to the case with length 1, we ignore the double overlapping point\n if (arc1.isSame(complementArc(arc2))) return [];\n return [new Arc(points[0], points[1], arc1.center, arc1.clockwise)];\n } else if (points.length === 3) {\n // Similar to the case with length 1, we ignore the single overlapping point\n const startIndex =\n sameVector(points[0], arc2.lastPoint) ||\n sameVector(points[0], arc2.firstPoint)\n ? 1\n : 0;\n return [\n new Arc(\n points[0 + startIndex],\n points[1 + startIndex],\n arc1.center,\n arc1.clockwise,\n ),\n ];\n } else if (points.length === 4) {\n return [\n new Arc(points[0], points[1], arc1.center, arc1.clockwise),\n new Arc(points[2], points[3], arc1.center, arc1.clockwise),\n ];\n }\n throw new Error(\"Bug in the arc arc overlap algorithm\");\n};\n\nexport function arcArcIntersection(\n arc1: Arc,\n arc2: Arc,\n includeOverlaps = false,\n precision?: number,\n): Vector[] | Arc[] {\n const epsilon = precision ? precision : arc1.precision;\n const centersDistance = distance(arc1.center, arc2.center);\n\n const radiusSum = arc1.radius + arc2.radius;\n\n // The circles do not touch\n if (centersDistance > radiusSum + epsilon) {\n return [];\n }\n\n const radiusDifference = Math.abs(arc1.radius - arc2.radius);\n\n // The arcs are concentric\n if (centersDistance < radiusDifference - epsilon) {\n return [];\n }\n\n // With a common center we can have overlaps\n if (centersDistance < epsilon) {\n if (radiusDifference > epsilon) {\n return [];\n } else {\n if (!includeOverlaps) {\n return [];\n }\n return handleOverlaps(arc1, arc2);\n }\n }\n\n const centersVector = normalize(subtract(arc2.center, arc1.center));\n // The circles are tangent to each other\n const isOutsideTangent = centersDistance > radiusSum - epsilon;\n if (\n // circles are outside each other\n isOutsideTangent ||\n // circles are inside each other\n Math.abs(centersDistance - radiusDifference) < epsilon\n ) {\n const orientation = isOutsideTangent || arc1.radius > arc2.radius ? 1 : -1;\n const intersectionPoint = add(\n arc1.center,\n scalarMultiply(centersVector, orientation * arc1.radius),\n );\n\n if (\n arc1.isOnSegment(intersectionPoint) &&\n arc2.isOnSegment(intersectionPoint)\n ) {\n return [intersectionPoint];\n } else {\n return [];\n }\n }\n\n // The circles cross each other\n const radiusToChord =\n (arc1.radius * arc1.radius) / (2 * centersDistance) -\n (arc2.radius * arc2.radius) / (2 * centersDistance) +\n centersDistance / 2;\n\n const midPoint = add(\n arc1.center,\n scalarMultiply(centersVector, radiusToChord),\n );\n\n const halfChord = Math.sqrt(\n arc1.radius * arc1.radius - radiusToChord * radiusToChord,\n );\n\n const chordVector = perpendicular(centersVector);\n\n const p1 = add(midPoint, scalarMultiply(chordVector, halfChord));\n const p2 = add(midPoint, scalarMultiply(chordVector, -halfChord));\n\n const intersections = [];\n if (arc1.isOnSegment(p1) && arc2.isOnSegment(p1)) {\n intersections.push(p1);\n }\n if (arc1.isOnSegment(p2) && arc2.isOnSegment(p2)) {\n intersections.push(p2);\n }\n\n return intersections;\n}\n","import { Line } from \"../../models/segments/Line.js\";\nimport { EllipseArc } from \"../../models/segments/EllipseArc.js\";\nimport { Vector } from \"../../definitions.js\";\n\n// Using the derivation from http://www.nabla.hr/CS-EllipseAndLine1.htm\nexport function lineEllipseArcIntersection(\n line: Line,\n arc: EllipseArc,\n precision = 1e-9,\n) {\n const lineP = line.transform(arc.ellipseReferenceFrameTransform);\n\n const m = lineP.slope;\n const c = lineP.yIntercept;\n\n const a2 = arc.majorRadius * arc.majorRadius;\n const b2 = arc.minorRadius * arc.minorRadius;\n const ab = arc.majorRadius * arc.minorRadius;\n\n const m2 = lineP.slope * lineP.slope;\n const c2 = lineP.yIntercept * lineP.yIntercept;\n\n // Helper function to convert back the intersection from the ellipse\n // reference frame to the original frame\n // It also checks that the intersection is within the bounds of the segments\n const filterIntersectionInRef = (intersections: Vector[]) =>\n intersections\n .map((point) =>\n arc.reverseEllipseReferenceFrameTransform.transform(point),\n )\n .filter((point) => line.isOnSegment(point) && arc.isOnSegment(point));\n\n // We handle the case of the line being vertical\n if (!Number.isFinite(m)) {\n // Vertical line\n const x = lineP.firstPoint[0];\n\n // Outside\n if (Math.abs(x) - arc.majorRadius > precision) return [];\n\n // Tangent\n if (Math.abs(Math.abs(x) - arc.majorRadius) < precision) {\n return filterIntersectionInRef([[x, 0]]);\n }\n\n const y = arc.minorRadius * Math.sqrt(1 - (x * x) / a2);\n\n const p1: Vector = [x, y];\n const p2: Vector = [x, -y];\n\n return filterIntersectionInRef([p1, p2]);\n }\n\n const discriminant = a2 * m2 + b2 - c2;\n\n if (discriminant < -precision) {\n return [];\n }\n\n const denominator = a2 * m2 + b2;\n\n // We have a tangent line\n if (Math.abs(discriminant) < precision) {\n const x = -(a2 * m * c) / denominator;\n const y = (b2 * c) / denominator;\n return filterIntersectionInRef([[x, y]]);\n }\n\n const sqrtDiscriminant = Math.sqrt(discriminant);\n\n const p1: Vector = [\n -(a2 * m * c + ab * sqrtDiscriminant) / denominator,\n (b2 * c - ab * m * sqrtDiscriminant) / denominator,\n ];\n const p2: Vector = [\n -(a2 * m * c - ab * sqrtDiscriminant) / denominator,\n (b2 * c + ab * m * sqrtDiscriminant) / denominator,\n ];\n\n return filterIntersectionInRef([p1, p2]);\n}\n","import { EllipseArc } from \"../../models/segments/EllipseArc.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { Vector } from \"../../definitions.js\";\nimport removeDuplicatePoints from \"../../utils/removeDuplicatePoints.js\";\nimport { solveGenericPolynomial } from \"../solvers/solvePolynomials.js\";\n\n// inspired by https://gist.github.com/drawable/92792f59b6ff8869d8b1\n\nexport function ellipseEllipseIntersection(\n arc1: EllipseArc | Arc,\n arc2: EllipseArc,\n): Vector[] {\n const epsilon = Math.max(arc1.precision, arc2.precision);\n\n const el1 = arc1.coefficients;\n const a1 = el1.x2;\n const b1 = el1.xy;\n const c1 = el1.y2;\n const d1 = el1.x;\n const e1 = el1.y;\n const f1 = el1.c;\n\n const el2 = arc2.coefficients;\n\n const a2 = el2.x2;\n const b2 = el2.xy;\n const c2 = el2.y2;\n const d2 = el2.x;\n const e2 = el2.y;\n const f2 = el2.c;\n\n const polynomial = {\n z0:\n f1 * a1 * d2 * d2 +\n a1 * a1 * f2 * f2 -\n d1 * a1 * d2 * f2 +\n a2 * a2 * f1 * f1 -\n 2 * a1 * f2 * a2 * f1 -\n d1 * d2 * a2 * f1 +\n a2 * d1 * d1 * f2,\n\n z1:\n e2 * d1 * d1 * a2 -\n f2 * d2 * a1 * b1 -\n 2 * a1 * f2 * a2 * e1 -\n f1 * a2 * b2 * d1 +\n 2 * d2 * b2 * a1 * f1 +\n 2 * e2 * f2 * a1 * a1 +\n d2 * d2 * a1 * e1 -\n e2 * d2 * a1 * d1 -\n 2 * a1 * e2 * a2 * f1 -\n f1 * a2 * d2 * b1 +\n 2 * f1 * e1 * a2 * a2 -\n f2 * b2 * a1 * d1 -\n e1 * a2 * d2 * d1 +\n 2 * f2 * b1 * a2 * d1,\n\n z2:\n e2 * e2 * a1 * a1 +\n 2 * c2 * f2 * a1 * a1 -\n e1 * a2 * d2 * b1 +\n f2 * a2 * b1 * b1 -\n e1 * a2 * b2 * d1 -\n f2 * b2 * a1 * b1 -\n 2 * a1 * e2 * a2 * e1 +\n 2 * d2 * b2 * a1 * e1 -\n c2 * d2 * a1 * d1 -\n 2 * a1 * c2 * a2 * f1 +\n b2 * b2 * a1 * f1 +\n 2 * e2 * b1 * a2 * d1 +\n e1 * e1 * a2 * a2 -\n c1 * a2 * d2 * d1 -\n e2 * b2 * a1 * d1 +\n 2 * f1 * c1 * a2 * a2 -\n f1 * a2 * b2 * b1 +\n c2 * d1 * d1 * a2 +\n d2 * d2 * a1 * c1 -\n e2 * d2 * a1 * b1 -\n 2 * a1 * f2 * a2 * c1,\n\n z3:\n -2 * a1 * a2 * c1 * e2 +\n e2 * a2 * b1 * b1 +\n 2 * c2 * b1 * a2 * d1 -\n c1 * a2 * b2 * d1 +\n b2 * b2 * a1 * e1 -\n e2 * b2 * a1 * b1 -\n 2 * a1 * c2 * a2 * e1 -\n e1 * a2 * b2 * b1 -\n c2 * b2 * a1 * d1 +\n 2 * e2 * c2 * a1 * a1 +\n 2 * e1 * c1 * a2 * a2 -\n c1 * a2 * d2 * b1 +\n 2 * d2 * b2 * a1 * c1 -\n c2 * d2 * a1 * b1,\n\n z4:\n a1 * a1 * c2 * c2 -\n 2 * a1 * c2 * a2 * c1 +\n a2 * a2 * c1 * c1 -\n b1 * a1 * b2 * c2 -\n b1 * b2 * a2 * c1 +\n b1 * b1 * a2 * c2 +\n c1 * a1 * b2 * b2,\n };\n\n const yValues = solveGenericPolynomial(\n [polynomial.z0, polynomial.z1, polynomial.z2, polynomial.z3, polynomial.z4],\n epsilon,\n );\n\n const points = yValues.flatMap((y) => {\n const denom = a1 * b2 * y + a1 * d2 - a2 * b1 * y - a2 * d1;\n\n if (denom) {\n const x =\n -(\n a1 * f2 +\n a1 * c2 * y * y -\n a2 * c1 * y * y +\n a1 * e2 * y -\n a2 * e1 * y -\n a2 * f1\n ) / denom;\n return [[x, y] as Vector];\n }\n\n const bb = b1 * y + d1;\n const v = -bb / (2 * a1);\n\n const cc = c1 * y * y + e1 * y + f1;\n const discriminant = (bb * bb) / (4 * a1 * a1) - cc / a1;\n\n if (Math.abs(discriminant) < epsilon) {\n return [[v, y] as Vector];\n }\n if (discriminant > 0) {\n const sqrt = Math.sqrt(discriminant);\n return [[v + sqrt, y] as Vector, [v - sqrt, y] as Vector];\n }\n\n return [];\n });\n\n return removeDuplicatePoints(points, epsilon);\n}\n","import type { EllipseArc } from \"../../models/segments/EllipseArc.js\";\nimport type { Arc } from \"../../models/segments/Arc.js\";\nimport { ellipseEllipseIntersection } from \"./ellipseEllipseIntersection.js\";\n\nexport function arcEllipseArcIntersection(arc: Arc, ellipseArc: EllipseArc) {\n const points = ellipseEllipseIntersection(arc, ellipseArc);\n return points.filter((p) => arc.isOnSegment(p) && ellipseArc.isOnSegment(p));\n}\n","import { Vector } from \"../../definitions.js\";\nimport { EllipseArc } from \"../../models/segments/EllipseArc.js\";\nimport removeDuplicatePoints from \"../../utils/removeDuplicatePoints.js\";\nimport { sameVector } from \"../../vectorOperations.js\";\nimport { ellipseEllipseIntersection } from \"./ellipseEllipseIntersection.js\";\n\nconst complementArc = (arc: EllipseArc): EllipseArc => {\n const {\n firstPoint,\n lastPoint,\n center,\n majorRadius,\n minorRadius,\n tiltAngle,\n clockwise,\n } = arc;\n return new EllipseArc(\n lastPoint,\n firstPoint,\n center,\n majorRadius,\n minorRadius,\n tiltAngle,\n clockwise,\n {\n ignoreChecks: true,\n angleUnits: \"rad\",\n },\n );\n};\n\nconst handleOverlaps = (arc1: EllipseArc, arc2: EllipseArc): EllipseArc[] => {\n // handle the case with common points at start or end first\n if (arc1.isSame(arc2)) {\n return [arc1];\n }\n // two arcs with common points at start and end (but not the same arc)\n\n const partialArc = (firstPoint: Vector, lastPoint: Vector) =>\n new EllipseArc(\n firstPoint,\n lastPoint,\n arc1.center,\n arc1.majorRadius,\n arc1.minorRadius,\n arc1.tiltAngle,\n arc1.clockwise,\n { ignoreChecks: true, angleUnits: \"rad\" },\n );\n\n const points = removeDuplicatePoints(\n [\n arc2.isOnSegment(arc1.firstPoint) ? arc1.firstPoint : null,\n arc2.isOnSegment(arc1.lastPoint) ? arc1.lastPoint : null,\n arc1.isOnSegment(arc2.firstPoint) ? arc2.firstPoint : null,\n arc1.isOnSegment(arc2.lastPoint) ? arc2.lastPoint : null,\n ].filter((p) => p !== null) as Vector[],\n // We sort by the param value of the first arc. This means that the points\n // will be sorted with the same orientation than arc1\n ).sort((a, b) => arc1.pointToParam(a) - arc1.pointToParam(b));\n\n if (points.length === 0) return [];\n // We consider the case when the arcs touch only on\n // the last point. We consider that they do not overlap there\n //\n // We might want to revisit this choice\n else if (points.length === 1) return [];\n else if (points.length === 2) {\n // Similar to the case with length 1, we ignore the double overlapping point\n if (arc1.isSame(complementArc(arc2))) return [];\n return [partialArc(points[0], points[1])];\n } else if (points.length === 3) {\n // Similar to the case with length 1, we ignore the single overlapping point\n const startIndex =\n sameVector(points[0], arc2.lastPoint) ||\n sameVector(points[0], arc2.firstPoint)\n ? 1\n : 0;\n return [partialArc(points[0 + startIndex], points[1 + startIndex])];\n } else if (points.length === 4) {\n return [partialArc(points[0], points[1]), partialArc(points[2], points[3])];\n }\n throw new Error(\"Bug in the ellipse arc ellipse arc overlap algorithm\");\n};\n\nexport function ellipseArcEllipseArcIntersection(\n arc1: EllipseArc,\n arc2: EllipseArc,\n includeOverlaps = false,\n): Vector[] | EllipseArc[] {\n const epsilon = Math.max(arc1.precision, arc2.precision);\n const sameEllipse =\n sameVector(arc1.center, arc2.center) &&\n Math.abs(arc1.majorRadius - arc2.majorRadius) < epsilon &&\n Math.abs(arc1.minorRadius - arc2.minorRadius) < epsilon &&\n (Math.abs(arc1.tiltAngle - arc2.tiltAngle) < epsilon ||\n Math.abs(Math.abs(arc1.tiltAngle - arc2.tiltAngle) - Math.PI) < epsilon);\n if (sameEllipse) {\n if (includeOverlaps) return handleOverlaps(arc1, arc2);\n else return [];\n }\n const points = ellipseEllipseIntersection(arc1, arc2);\n return points.filter((p) => arc1.isOnSegment(p) && arc2.isOnSegment(p));\n}\n","import { Line } from \"../../models/segments/Line.js\";\nimport { CubicBezier } from \"../../models/segments/CubicBezier.js\";\nimport { TransformationMatrix } from \"../../models/TransformationMatrix.js\";\nimport { QuadraticBezier } from \"../../models/segments/QuadraticBezier.js\";\nimport { Vector } from \"../../definitions.js\";\n\nexport function lineBezierIntersection(\n line: Line,\n curve: CubicBezier | QuadraticBezier,\n): Vector[] {\n const [x1, y1] = line.firstPoint;\n const [x2, y2] = line.lastPoint;\n\n const transform = new TransformationMatrix()\n .rotate(-Math.atan2(y2 - y1, x2 - x1))\n .translate(-x1, -y1);\n\n const inverseTransform = transform.clone().inverse();\n\n const axisAlignedCurve = curve.transform(transform);\n return axisAlignedCurve\n .paramsAtY(0)\n .map((t) => {\n return axisAlignedCurve.paramPoint(t);\n })\n .map((point) => {\n return inverseTransform.transform(point);\n })\n .filter((point) => {\n return line.isOnSegment(point);\n });\n}\n","const asFixed = (p: number, precision = 1e-9): string => {\n let num = p;\n if (Math.abs(p) < precision) num = 0;\n return num.toFixed(-Math.log10(precision));\n};\nexport default function removeDuplicateValues(\n points: number[],\n precision = 1e-9,\n): number[] {\n return Array.from(\n new Map(points.map((p) => [asFixed(p, precision), p])).values(),\n );\n}\n","import { EllipseArc } from \"../../models/segments/EllipseArc.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { Vector } from \"../../definitions.js\";\nimport removeDuplicateValues from \"../../utils/removeDuplicateValues.js\";\nimport { solveGenericPolynomial } from \"../solvers/solvePolynomials.js\";\nimport { CubicBezier } from \"../../models/segments/CubicBezier.js\";\n\n/*\n * We use wolfram alpha to do the analitical resolution of the intersection\n * Collect[ Eliminate[{a*x^2+b*x*y+c*y^2+d * x + e * y + f == 0, p3 * t^3 + p2 * t^2 + p1 * t +p0 == x,q3*t^3+q2*t^2+q1*t+q0==y}, {x,y}], t ]\n * */\n\nconst intersectionsPolynomial = (arc: EllipseArc | Arc, curve: CubicBezier) => {\n const [[p0, p1, p2, p3], [q0, q1, q2, q3]] = curve.polynomialCoefficients;\n\n const el1 = arc.coefficients;\n const a = el1.x2;\n const b = el1.xy;\n const c = el1.y2;\n const d = el1.x;\n const e = el1.y;\n const f = el1.c;\n\n const p02 = p0 * p0;\n const p12 = p1 * p1;\n const p22 = p2 * p2;\n const p32 = p3 * p3;\n const q02 = q0 * q0;\n const q12 = q1 * q1;\n const q22 = q2 * q2;\n const q32 = q3 * q3;\n\n const z0 = f + d * p0 + a * p02 + e * q0 + b * p0 * q0 + c * q02;\n const z1 =\n d * p1 +\n 2 * a * p0 * p1 +\n b * p1 * q0 +\n e * q1 +\n b * p0 * q1 +\n 2 * c * q0 * q1;\n const z2 =\n a * p12 +\n d * p2 +\n 2 * a * p0 * p2 +\n b * p2 * q0 +\n b * p1 * q1 +\n c * q12 +\n e * q2 +\n b * p0 * q2 +\n 2 * c * q0 * q2;\n const z3 =\n 2 * a * p1 * p2 +\n d * p3 +\n 2 * a * p0 * p3 +\n b * p3 * q0 +\n b * p2 * q1 +\n b * p1 * q2 +\n 2 * c * q1 * q2 +\n e * q3 +\n b * p0 * q3 +\n 2 * c * q0 * q3;\n const z4 =\n a * p22 +\n 2 * a * p1 * p3 +\n b * p3 * q1 +\n b * p2 * q2 +\n c * q22 +\n b * p1 * q3 +\n 2 * c * q1 * q3;\n const z5 = 2 * a * p2 * p3 + b * p3 * q2 + b * p2 * q3 + 2 * c * q2 * q3;\n const z6 = a * p32 + b * p3 * q3 + c * q32;\n\n return [z0, z1, z2, z3, z4, z5, z6];\n};\n\nexport function arcsCubicBezierIntersection(\n arc: EllipseArc | Arc,\n curve: CubicBezier,\n): Vector[] {\n const epsilon = Math.max(arc.precision, curve.precision);\n\n const polynomial = intersectionsPolynomial(arc, curve);\n const solutions = solveGenericPolynomial(polynomial, epsilon).filter((t) => {\n return t >= -curve.precision && t <= 1 + curve.precision;\n });\n\n return removeDuplicateValues(solutions, epsilon)\n .map((t) => {\n return curve.paramPoint(t);\n })\n .filter((p) => {\n return arc.isOnSegment(p);\n });\n}\n","import { EllipseArc } from \"../../models/segments/EllipseArc.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { Vector } from \"../../definitions.js\";\nimport removeDuplicateValues from \"../../utils/removeDuplicateValues.js\";\nimport { solveQuartic } from \"../solvers/solvePolynomials.js\";\nimport { QuadraticBezier } from \"../../models/segments/QuadraticBezier.js\";\n\n/*\n * We use wolfram alpha to do the analitical resolution of the intersection\n * Collect[ Eliminate[{a*x^2+b*x*y+c*y^2+d * x + e * y + f == 0, p2 * t^2 + p1 * t +p0 == x,q2*t^2+q1*t+q0==y}, {x,y}], t ]\n * */\n\nconst intersectionsPolynomial = (\n arc: EllipseArc | Arc,\n curve: QuadraticBezier,\n): [number, number, number, number, number] => {\n const [[p0, p1, p2], [q0, q1, q2]] = curve.polynomialCoefficients;\n\n const el1 = arc.coefficients;\n const a = el1.x2;\n const b = el1.xy;\n const c = el1.y2;\n const d = el1.x;\n const e = el1.y;\n const f = el1.c;\n\n const p02 = p0 * p0;\n const p12 = p1 * p1;\n const p22 = p2 * p2;\n const q02 = q0 * q0;\n const q12 = q1 * q1;\n const q22 = q2 * q2;\n\n const z0 = a * p02 + b * p0 * q0 + c * q02 + d * p0 + e * q0 + f;\n const z1 =\n 2 * a * p0 * p1 +\n b * p0 * q1 +\n b * p1 * q0 +\n 2 * c * q0 * q1 +\n d * p1 +\n e * q1;\n const z2 =\n 2 * a * p0 * p2 +\n a * p12 +\n b * p0 * q2 +\n b * p1 * q1 +\n b * p2 * q0 +\n 2 * c * q0 * q2 +\n c * q12 +\n d * p2 +\n e * q2;\n\n const z3 = 2 * a * p1 * p2 + b * p1 * q2 + b * p2 * q1 + 2 * c * q1 * q2;\n const z4 = a * p22 + b * p2 * q2 + c * q22;\n\n return [z0, z1, z2, z3, z4];\n};\n\nexport function arcsQuadraticBezierIntersection(\n arc: EllipseArc | Arc,\n curve: QuadraticBezier,\n): Vector[] {\n const epsilon = Math.max(arc.precision, curve.precision);\n\n const polynomial = intersectionsPolynomial(arc, curve);\n const solutions = solveQuartic(...polynomial).filter((t) => {\n return t >= -curve.precision && t <= 1 + curve.precision;\n });\n\n return removeDuplicateValues(solutions, epsilon)\n .map((t) => {\n return curve.paramPoint(t);\n })\n .filter((p) => {\n return arc.isOnSegment(p);\n });\n}\n","import { Vector } from \"../../definitions.js\";\nimport { CubicBezier } from \"../../models/segments/CubicBezier.js\";\nimport { QuadraticBezier } from \"../../models/segments/QuadraticBezier.js\";\nimport removeDuplicatePoints from \"../../utils/removeDuplicatePoints.js\";\nimport {\n subtract,\n length,\n crossProduct,\n squareLength,\n perpendicular,\n add,\n sameVector,\n} from \"../../vectorOperations.js\";\n\nfunction orientedDistanceToLine(\n point: Vector,\n { firstPoint, lastPoint }: { firstPoint: Vector; lastPoint: Vector },\n epsilon = 1e-9,\n) {\n const direction = subtract(lastPoint, firstPoint);\n\n // Case of an vertical line\n if (Math.abs(direction[0]) < epsilon) {\n return direction[1] > 0\n ? firstPoint[0] - point[0]\n : point[0] - firstPoint[0];\n }\n\n // Case of an horizontal line\n if (Math.abs(direction[1]) < epsilon) {\n return direction[0] > 0\n ? point[1] - firstPoint[1]\n : firstPoint[1] - point[1];\n }\n\n return (\n crossProduct(direction, subtract(point, firstPoint)) / length(direction)\n );\n}\n\nclass FatLine {\n constructor(\n public readonly firstPoint: Vector,\n public readonly lastPoint: Vector,\n public negativeThickness: number,\n public positiveThickness: number,\n ) {}\n\n get width() {\n return this.positiveThickness - this.negativeThickness;\n }\n}\n\nconst V_3_4 = 3 / 4;\nconst V_4_9 = 4 / 9;\nexport function fatLineFromCubicCurve(curve: CubicBezier) {\n const d1 = orientedDistanceToLine(curve.firstControlPoint, curve);\n const d2 = orientedDistanceToLine(curve.lastControlPoint, curve);\n\n // We use the quick approximation of the fat line\n const factor = d1 * d2 > 0 ? V_3_4 : V_4_9;\n\n return new FatLine(\n curve.firstPoint,\n curve.lastPoint,\n factor * Math.min(0, d1, d2),\n factor * Math.max(0, d1, d2),\n );\n}\n\nexport function fatLineFromQuadratic(curve: QuadraticBezier) {\n const d1 = orientedDistanceToLine(curve.controlPoint, curve);\n\n return new FatLine(\n curve.firstPoint,\n curve.lastPoint,\n Math.min(0, d1 / 2),\n Math.max(0, d1 / 2),\n );\n}\n\nexport function fatLineFromCurve(curve: CubicBezier | QuadraticBezier) {\n if (curve instanceof CubicBezier) {\n return fatLineFromCubicCurve(curve);\n }\n if (curve instanceof QuadraticBezier) {\n return fatLineFromQuadratic(curve);\n }\n throw new Error(\"Not implemented\");\n}\n\nexport function perpendicularFatLineFromCurve(\n curve: CubicBezier | QuadraticBezier,\n) {\n const midPoint = curve.paramPoint(0.5);\n const offset = perpendicular(subtract(midPoint, curve.firstPoint));\n\n const targetPoint = add(midPoint, offset);\n\n const curvePoints = {\n firstPoint: midPoint,\n lastPoint: targetPoint,\n };\n\n const distances = [\n orientedDistanceToLine(curve.firstPoint, curvePoints),\n orientedDistanceToLine(curve.lastPoint, curvePoints),\n ];\n\n if (curve instanceof CubicBezier) {\n distances.push(\n orientedDistanceToLine(curve.firstControlPoint, curvePoints),\n orientedDistanceToLine(curve.lastControlPoint, curvePoints),\n );\n } else if (curve instanceof QuadraticBezier) {\n distances.push(orientedDistanceToLine(curve.controlPoint, curvePoints));\n }\n\n return new FatLine(\n midPoint,\n targetPoint,\n Math.min(...distances),\n Math.max(...distances),\n );\n}\n\nfunction intersectionParameter(linePoints: Vector[], bound: number) {\n const parameters = [];\n for (let i = 1; i < linePoints.length; i++) {\n const point = linePoints[i];\n if (point[1] === bound) {\n parameters.push(point[0]);\n continue;\n }\n\n const previousPoint = linePoints[i - 1];\n\n const previousDistanceToBound = bound - previousPoint[1];\n const distanceToBound = bound - point[1];\n\n if (previousDistanceToBound * distanceToBound < 0) {\n parameters.push(\n previousPoint[0] +\n ((bound - previousPoint[1]) * (point[0] - previousPoint[0])) /\n (point[1] - previousPoint[1]),\n );\n continue;\n }\n }\n\n return parameters;\n}\n\nclass ClippingBounds {\n constructor(\n public readonly from: number | \"start\",\n public readonly to: number | \"end\",\n ) {}\n\n get size() {\n if (this.from === \"start\") {\n if (this.to === \"end\") {\n return 1;\n } else {\n return this.to;\n }\n } else {\n if (this.to === \"end\") {\n return 1 - this.from;\n } else {\n return Math.abs(this.from - this.to);\n }\n }\n }\n\n clipCurve(curve: QuadraticBezier | CubicBezier) {\n if (this.from === \"start\") {\n if (this.to === \"end\") {\n return curve;\n } else {\n return curve.splitAtParameters([this.to])[0];\n }\n } else {\n if (this.to === \"end\") {\n return curve.splitAtParameters([this.from])[1];\n } else {\n return curve.splitAtParameters([this.from, this.to])[1];\n }\n }\n }\n}\n\nfunction createDistanceHull(\n curve: QuadraticBezier | CubicBezier,\n fatLine: FatLine,\n) {\n if (curve instanceof CubicBezier) {\n return new DistanceToFatLineCubicCurve([\n orientedDistanceToLine(curve.firstPoint, fatLine),\n orientedDistanceToLine(curve.firstControlPoint, fatLine),\n orientedDistanceToLine(curve.lastControlPoint, fatLine),\n orientedDistanceToLine(curve.lastPoint, fatLine),\n ]);\n }\n if (curve instanceof QuadraticBezier) {\n return new DistanceToFatLineQuadraticCurve([\n orientedDistanceToLine(curve.firstPoint, fatLine),\n orientedDistanceToLine(curve.controlPoint, fatLine),\n orientedDistanceToLine(curve.lastPoint, fatLine),\n ]);\n }\n throw new Error(\"Not implemented\");\n}\n\nclass DistanceToFatLineQuadraticCurve {\n public readonly topHull: Vector[] = [];\n public readonly bottomHull: Vector[] = [];\n\n constructor(public readonly distances: [number, number, number]) {\n const [d1, d2, d3] = distances;\n\n const p1: Vector = [0, d1];\n const p2: Vector = [1 / 2, d2];\n const p3: Vector = [1, d3];\n\n // We want to have the hull defined by these points\n const midLineSlope = d3 - d1;\n const midLineIntercept = d1;\n\n const deltaAtD2 = d2 - (midLineSlope * (1 / 2) + midLineIntercept);\n\n if (deltaAtD2 > 0) {\n this.topHull = [p1, p2, p3];\n this.bottomHull = [p1, p3];\n } else {\n this.topHull = [p1, p3];\n this.bottomHull = [p1, p2, p3];\n }\n }\n\n get startDistance() {\n return this.distances[0];\n }\n\n get endDistance() {\n return this.distances[2];\n }\n}\n\nclass DistanceToFatLineCubicCurve {\n public readonly topHull: Vector[] = [];\n public readonly bottomHull: Vector[] = [];\n\n constructor(public readonly distances: [number, number, number, number]) {\n const [d1, d2, d3, d4] = distances;\n\n const p1: Vector = [0, d1];\n const p2: Vector = [1 / 3, d2];\n const p3: Vector = [2 / 3, d3];\n const p4: Vector = [1, d4];\n\n // We want to have the hull defined by these points\n const midLineSlope = d4 - d1;\n const midLineIntercept = d1;\n\n const deltaAtD2 = d2 - (midLineSlope * (1 / 3) + midLineIntercept);\n const deltaAtD3 = d3 - (midLineSlope * (2 / 3) + midLineIntercept);\n\n let topHull = null;\n let bottomHull = null;\n\n const crossesMidLine = deltaAtD2 * deltaAtD3 < 0;\n\n // We first assume that d2 is above the mid line\n if (crossesMidLine) {\n topHull = [p1, p2, p4];\n bottomHull = [p1, p3, p4];\n } else {\n // We know that the x distance is 1/3 so we can only care about the ratio\n // of y to figure out if we need to include the points in the hull\n const ratio = deltaAtD2 / deltaAtD3;\n if (ratio >= 2) {\n topHull = [p1, p2, p4];\n bottomHull = [p1, p4];\n } else if (ratio <= 0.5) {\n topHull = [p1, p3, p4];\n bottomHull = [p1, p4];\n } else {\n topHull = [p1, p2, p3, p4];\n bottomHull = [p1, p4];\n }\n }\n if (deltaAtD2 < 0) {\n [topHull, bottomHull] = [bottomHull, topHull];\n }\n\n this.topHull = topHull;\n this.bottomHull = bottomHull;\n }\n\n get startDistance() {\n return this.distances[0];\n }\n\n get endDistance() {\n return this.distances[3];\n }\n}\n\nexport function fatLineIntersections(\n fatLine: FatLine,\n curve: QuadraticBezier | CubicBezier,\n): ClippingBounds | null {\n // These correspond to the y values of the distance curve\n const distancesAtParam = createDistanceHull(curve, fatLine);\n\n // We want to compute the places where the hull of distance is outside of the\n // bound of the fat line\n const t1 = intersectionParameter(\n distancesAtParam.topHull,\n fatLine.negativeThickness,\n );\n const t2 = intersectionParameter(\n distancesAtParam.bottomHull,\n fatLine.positiveThickness,\n );\n\n const endsWithinBounds =\n distancesAtParam.endDistance >= fatLine.negativeThickness &&\n distancesAtParam.endDistance <= fatLine.positiveThickness;\n\n if (!t1.length && !t2.length) {\n if (endsWithinBounds) return new ClippingBounds(\"start\", \"end\");\n else return null;\n }\n\n if (t1.length === 1 && t2.length === 1) {\n return new ClippingBounds(t1[0], t2[0]);\n }\n\n if (t1.length === 2 && t2.length === 2) {\n throw new Error(\n \"Bug in the clipping algorithm, unexpected number of crossing points\",\n );\n }\n\n const t: number[] = t1.length ? t1 : t2;\n\n if (t.length === 2) {\n return new ClippingBounds(t[0], t[1]);\n }\n\n if (endsWithinBounds) return new ClippingBounds(t[0], \"end\");\n else return new ClippingBounds(\"start\", t[0]);\n}\n\nexport function clipFatLineIntersections(\n curve1: QuadraticBezier | CubicBezier,\n curve2: QuadraticBezier | CubicBezier,\n) {\n const fatLine = fatLineFromCurve(curve1);\n\n const limits = fatLineIntersections(fatLine, curve2);\n if (!limits) {\n return null; // there is no intersection\n }\n\n const perpendicularFatLine = perpendicularFatLineFromCurve(curve1);\n\n const perpendicularLimits = fatLineIntersections(\n perpendicularFatLine,\n curve2,\n );\n if (!perpendicularLimits) {\n return null; // there is no intersection\n }\n\n if (limits.size > perpendicularLimits.size) {\n return perpendicularLimits.clipCurve(curve2);\n }\n return limits.clipCurve(curve2);\n}\n\nconst hullSquareLength = (curve: QuadraticBezier | CubicBezier) => {\n if (curve instanceof QuadraticBezier) {\n return (\n squareLength(subtract(curve.controlPoint, curve.firstPoint)) +\n squareLength(subtract(curve.controlPoint, curve.lastPoint))\n );\n }\n return (\n squareLength(subtract(curve.firstControlPoint, curve.firstPoint)) +\n squareLength(subtract(curve.lastControlPoint, curve.firstControlPoint)) +\n squareLength(subtract(curve.lastControlPoint, curve.lastPoint))\n );\n};\n\n/* Bézier clipping algorithm\n *\n * This algorithm is based on the paper \"Curve intersections using Bézier\n * Clipping\" by Sederberg and Nishita.\n *\n * Note that we assume that the curves are not overlapping\n *\n * This implementation has been inspired by both the rust implementation of\n * https://github.com/Logicalshift/flo_curves and the javascript one of\n * https://github.com/alexkirsz/curve-intersection\n *\n * */\nexport function bezierClip(\n curve1: CubicBezier | QuadraticBezier,\n curve2: CubicBezier | QuadraticBezier,\n precision = 1e-9,\n { maxIterations = 100 } = {},\n): Vector[] {\n // I should understand better how to handle the bottom of the precision\n // better\n const squarePrecision = Math.max(precision * precision, Number.EPSILON * 10);\n\n let pCurve = curve1;\n let qCurve = curve2;\n\n let pCurveLength = hullSquareLength(pCurve);\n let qCurveLength = hullSquareLength(qCurve);\n\n for (let it = 0; it < maxIterations; it++) {\n const pCurveClipped =\n pCurveLength > squarePrecision\n ? clipFatLineIntersections(qCurve, pCurve)\n : pCurve;\n if (!pCurveClipped) return [];\n const pCurveClippedLength = hullSquareLength(pCurveClipped);\n\n const qCurveClipped =\n qCurveLength > squarePrecision\n ? clipFatLineIntersections(pCurveClipped, qCurve)\n : qCurve;\n if (!qCurveClipped) return [];\n const qCurveClippedLength = hullSquareLength(qCurveClipped);\n\n // We found a good enough approximation\n if (\n pCurveClippedLength <= squarePrecision &&\n qCurveClippedLength <= squarePrecision\n ) {\n return [\n pCurveClipped.boundingBox.intersection(qCurveClipped.boundingBox)\n .center,\n ];\n }\n\n // Another way to detect that we are close enough (i.e. the curves are\n // nearly a point\n if (\n sameVector(pCurveClipped.firstPoint, pCurveClipped.lastPoint) &&\n qCurveClipped.isOnSegment(pCurveClipped.firstPoint)\n ) {\n return [pCurveClipped.firstPoint];\n }\n if (\n sameVector(qCurveClipped.firstPoint, qCurveClipped.lastPoint) &&\n pCurveClipped.isOnSegment(qCurveClipped.firstPoint)\n ) {\n return [qCurveClipped.firstPoint];\n }\n\n if (\n pCurveClippedLength > 0.8 * pCurveLength &&\n qCurveClippedLength > 0.8 * qCurveLength\n ) {\n // It seems that we need to split the curves\n if (\n pCurveClippedLength / pCurveLength >\n qCurveClippedLength / qCurveLength\n ) {\n const [pCurveLeft, pCurveRight] = pCurveClipped.splitAtParameters([\n 0.5,\n ]);\n return removeDuplicatePoints(\n [\n ...bezierClip(pCurveLeft, qCurveClipped, precision, {\n maxIterations: maxIterations - it,\n }),\n ...bezierClip(pCurveRight, qCurveClipped, precision, {\n maxIterations: maxIterations - it,\n }),\n ],\n precision,\n );\n } else {\n const [qCurveLeft, qCurveRight] = qCurveClipped.splitAtParameters([\n 0.5,\n ]);\n return removeDuplicatePoints(\n [\n ...bezierClip(pCurveClipped, qCurveLeft, precision, {\n maxIterations: maxIterations - it,\n }),\n ...bezierClip(pCurveClipped, qCurveRight, precision, {\n maxIterations: maxIterations - it,\n }),\n ],\n precision,\n );\n }\n }\n\n pCurve = pCurveClipped;\n qCurve = qCurveClipped;\n pCurveLength = pCurveClippedLength;\n qCurveLength = qCurveClippedLength;\n }\n\n throw new Error(\"Bézier clip: Maximum number of iterations reached\");\n}\n","import { Vector } from \"../../definitions.js\";\nimport { CubicBezier } from \"../../models/segments/CubicBezier.js\";\nimport { sameVector } from \"../../vectorOperations.js\";\nimport { bezierClip } from \"./bezierClip.js\";\n\nexport function handleOverlaps(curve1: CubicBezier, curve2: CubicBezier) {\n const commonPoints: Vector[] = [];\n const toTest: [Vector, CubicBezier][] = [\n [curve1.firstPoint, curve2],\n [curve1.lastPoint, curve2],\n [curve2.firstPoint, curve1],\n [curve2.lastPoint, curve1],\n ];\n\n // This could be optimised by doing only one vector => parameter conversion\n\n toTest.forEach(([point, curve]) => {\n if (curve.isOnSegment(point)) {\n commonPoints.push(point);\n }\n });\n\n if (commonPoints.length < 2) {\n // no overlap\n return null;\n }\n\n if (commonPoints.length === 2) {\n return [curve1.splitAt(commonPoints)[1]];\n }\n\n if (commonPoints.length === 3) {\n // there is one curve that is within the other\n if (\n sameVector(commonPoints[0], curve1.firstPoint) &&\n sameVector(commonPoints[1], curve1.lastPoint)\n ) {\n return [curve1];\n }\n return [curve2];\n }\n\n if (commonPoints.length === 4) {\n return [curve1];\n }\n}\n\nexport function cubicBezierCubicBezierIntersection(\n curve1: CubicBezier,\n curve2: CubicBezier,\n includeOverlaps = false,\n) {\n const epsilon = Math.max(curve1.precision, curve2.precision);\n\n if (includeOverlaps) {\n const overlappingCurve = handleOverlaps(curve1, curve2);\n if (overlappingCurve) {\n return overlappingCurve;\n }\n }\n\n return bezierClip(curve1, curve2, epsilon);\n}\n","import { Vector } from \"../../definitions.js\";\nimport { QuadraticBezier } from \"../../models/segments/QuadraticBezier.js\";\nimport { sameVector } from \"../../vectorOperations.js\";\nimport { bezierClip } from \"./bezierClip.js\";\n\nexport function handleOverlaps(\n curve1: QuadraticBezier,\n curve2: QuadraticBezier,\n) {\n const commonPoints: Vector[] = [];\n const toTest: [Vector, QuadraticBezier][] = [\n [curve1.firstPoint, curve2],\n [curve1.lastPoint, curve2],\n [curve2.firstPoint, curve1],\n [curve2.lastPoint, curve1],\n ];\n\n // This could be optimised by doing only one vector => parameter conversion\n\n toTest.forEach(([point, curve]) => {\n if (curve.isOnSegment(point)) {\n commonPoints.push(point);\n }\n });\n\n if (commonPoints.length < 2) {\n // no overlap\n return null;\n }\n\n if (commonPoints.length === 2) {\n return [curve1.splitAt(commonPoints)[1]];\n }\n\n if (commonPoints.length === 3) {\n // there is one curve that is within the other\n if (\n sameVector(commonPoints[0], curve1.firstPoint) &&\n sameVector(commonPoints[1], curve1.lastPoint)\n ) {\n return [curve1];\n }\n return [curve2];\n }\n\n if (commonPoints.length === 4) {\n return [curve1];\n }\n}\n\nexport function quadraticBezierQuadraticBezierIntersection(\n curve1: QuadraticBezier,\n curve2: QuadraticBezier,\n includeOverlaps = false,\n) {\n const epsilon = Math.max(curve1.precision, curve2.precision);\n\n if (includeOverlaps) {\n const overlappingCurve = handleOverlaps(curve1, curve2);\n if (overlappingCurve) {\n return overlappingCurve;\n }\n }\n\n return bezierClip(curve1, curve2, epsilon);\n}\n","import { Line } from \"../../models/segments/Line.js\";\n\nimport type { Vector } from \"../../definitions.js\";\nimport { Segment } from \"../../models/segments/Segment.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { CubicBezier } from \"../../models/segments/CubicBezier.js\";\nimport { lineArcIntersection } from \"./lineArcIntersection.js\";\nimport { lineLineIntersection } from \"./lineLineIntersection.js\";\nimport { arcArcIntersection } from \"./arcArcIntersection.js\";\nimport { EllipseArc } from \"../../models/segments/EllipseArc.js\";\nimport { lineEllipseArcIntersection } from \"./lineEllipseArcIntersection.js\";\nimport { arcEllipseArcIntersection } from \"./arcEllipseArcIntersection.js\";\nimport { ellipseArcEllipseArcIntersection } from \"./ellipseArcEllipseArcIntersection.js\";\nimport { lineBezierIntersection } from \"./lineBezierIntersection.js\";\nimport { arcsCubicBezierIntersection } from \"./arcsCubicBezierIntersection.js\";\nimport { QuadraticBezier } from \"../../models/segments/QuadraticBezier.js\";\nimport { arcsQuadraticBezierIntersection } from \"./arcsQuadraticBezierIntersection.js\";\nimport { bezierClip } from \"./bezierClip.js\";\nimport { cubicBezierCubicBezierIntersection } from \"./cubicBezierCubicBezierIntersection.js\";\nimport { quadraticBezierQuadraticBezierIntersection } from \"./quadraticBezierQuadraticBezierIntersection.js\";\n\nexport function findIntersections(\n segment1: Segment,\n segment2: Segment,\n precision?: number,\n): Vector[] {\n if (segment1 instanceof Line && segment2 instanceof Line) {\n const intersection = lineLineIntersection(\n segment1,\n segment2,\n false,\n precision,\n );\n if (intersection === null) return [];\n return [intersection as Vector];\n }\n if (segment1 instanceof Line && segment2 instanceof Arc) {\n return lineArcIntersection(segment1, segment2, precision);\n }\n if (segment1 instanceof Arc && segment2 instanceof Line) {\n return lineArcIntersection(segment2, segment1, precision);\n }\n if (segment1 instanceof Arc && segment2 instanceof Arc) {\n return arcArcIntersection(segment1, segment2, false, precision) as Vector[];\n }\n\n throw new Error(\"Not implemented\");\n}\n\nexport function findIntersectionsAndOverlaps(\n segment1: Segment,\n segment2: Segment,\n precision?: number,\n): { intersections: Vector[]; overlaps: Segment[]; count: number } {\n // If we have two lines, checks are fast enough to not use bounding boxes\n if (segment1 instanceof Line && segment2 instanceof Line) {\n const intersection = lineLineIntersection(\n segment1,\n segment2,\n true,\n precision,\n );\n if (intersection === null)\n return { intersections: [], overlaps: [], count: 0 };\n if (intersection instanceof Line)\n return { intersections: [], overlaps: [intersection], count: 1 };\n return { intersections: [intersection], overlaps: [], count: 1 };\n }\n\n if (!segment1.boundingBox.overlaps(segment2.boundingBox)) {\n return { intersections: [], overlaps: [], count: 0 };\n }\n\n if (segment1 instanceof Line && segment2 instanceof Arc) {\n const intersections = lineArcIntersection(segment1, segment2, precision);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (segment1 instanceof Arc && segment2 instanceof Line) {\n const intersections = lineArcIntersection(segment2, segment1, precision);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (segment1 instanceof Arc && segment2 instanceof Arc) {\n const intersections = arcArcIntersection(\n segment1,\n segment2,\n true,\n precision,\n );\n if (!intersections.length)\n return { intersections: [], overlaps: [], count: 0 };\n if (intersections[0] instanceof Arc)\n return {\n intersections: [],\n overlaps: intersections as Arc[],\n count: intersections.length,\n };\n return {\n intersections: intersections as Vector[],\n overlaps: [],\n count: intersections.length,\n };\n }\n\n if (segment1 instanceof Line && segment2 instanceof EllipseArc) {\n const intersections = lineEllipseArcIntersection(\n segment1,\n segment2,\n precision,\n );\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (segment2 instanceof Line && segment1 instanceof EllipseArc) {\n const intersections = lineEllipseArcIntersection(\n segment2,\n segment1,\n precision,\n );\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (segment1 instanceof Arc && segment2 instanceof EllipseArc) {\n const intersections = arcEllipseArcIntersection(segment1, segment2);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (segment2 instanceof Arc && segment1 instanceof EllipseArc) {\n const intersections = arcEllipseArcIntersection(segment2, segment1);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (segment1 instanceof EllipseArc && segment2 instanceof EllipseArc) {\n const intersections = ellipseArcEllipseArcIntersection(\n segment1,\n segment2,\n true,\n );\n if (!intersections.length)\n return { intersections: [], overlaps: [], count: 0 };\n if (intersections[0] instanceof EllipseArc)\n return {\n intersections: [],\n overlaps: intersections as EllipseArc[],\n count: intersections.length,\n };\n return {\n intersections: intersections as Vector[],\n overlaps: [],\n count: intersections.length,\n };\n }\n\n if (\n segment1 instanceof Line &&\n (segment2 instanceof CubicBezier || segment2 instanceof QuadraticBezier)\n ) {\n const intersections = lineBezierIntersection(segment1, segment2);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (\n segment2 instanceof Line &&\n (segment1 instanceof CubicBezier || segment1 instanceof QuadraticBezier)\n ) {\n const intersections = lineBezierIntersection(segment2, segment1);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (\n (segment1 instanceof Arc || segment1 instanceof EllipseArc) &&\n segment2 instanceof QuadraticBezier\n ) {\n const intersections = arcsQuadraticBezierIntersection(segment1, segment2);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (\n (segment2 instanceof Arc || segment2 instanceof EllipseArc) &&\n segment1 instanceof QuadraticBezier\n ) {\n const intersections = arcsQuadraticBezierIntersection(segment2, segment1);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (\n (segment1 instanceof Arc || segment1 instanceof EllipseArc) &&\n segment2 instanceof CubicBezier\n ) {\n const intersections = arcsCubicBezierIntersection(segment1, segment2);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (\n (segment2 instanceof Arc || segment2 instanceof EllipseArc) &&\n segment1 instanceof CubicBezier\n ) {\n const intersections = arcsCubicBezierIntersection(segment2, segment1);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (\n segment1 instanceof QuadraticBezier &&\n segment2 instanceof QuadraticBezier\n ) {\n const intersections = quadraticBezierQuadraticBezierIntersection(\n segment1,\n segment2,\n );\n if (!intersections.length)\n return { intersections: [], overlaps: [], count: 0 };\n if (intersections[0] instanceof QuadraticBezier)\n return {\n intersections: [],\n overlaps: intersections as QuadraticBezier[],\n count: intersections.length,\n };\n return {\n intersections: intersections as Vector[],\n overlaps: [],\n count: intersections.length,\n };\n }\n\n if (\n (segment1 instanceof QuadraticBezier && segment2 instanceof CubicBezier) ||\n (segment2 instanceof QuadraticBezier && segment1 instanceof CubicBezier)\n ) {\n const intersections = bezierClip(segment1, segment2);\n return { intersections, overlaps: [], count: intersections.length };\n }\n\n if (segment1 instanceof CubicBezier && segment2 instanceof CubicBezier) {\n const intersections = cubicBezierCubicBezierIntersection(\n segment1,\n segment2,\n );\n if (!intersections.length)\n return { intersections: [], overlaps: [], count: 0 };\n if (intersections[0] instanceof CubicBezier)\n return {\n intersections: [],\n overlaps: intersections as CubicBezier[],\n count: intersections.length,\n };\n return {\n intersections: intersections as Vector[],\n overlaps: [],\n count: intersections.length,\n };\n }\n\n throw new Error(\"Not implemented\");\n}\n","export function allCombinations(count: number): [number, number][] {\n const result: [number, number][] = [];\n\n for (let i = 0; i < count; i++) {\n for (let j = 0; j <= i; j++) {\n result.push([i, j]);\n }\n }\n\n return result;\n}\n\nexport function* combineDifferentValues<T>(array: T[]): Generator<[T, T]> {\n for (const [i, j] of allCombinations(array.length)) {\n if (i === j) continue;\n yield [array[i], array[j]];\n }\n}\n","import { BoundingBox } from \"./BoundingBox.js\";\nimport { Vector } from \"../definitions.js\";\nimport { findIntersectionsAndOverlaps } from \"../algorithms/intersections\";\nimport { Segment } from \"./segments/Segment.js\";\nimport { TransformationMatrix } from \"./TransformationMatrix.js\";\nimport { allCombinations } from \"../utils/allCombinations.js\";\nimport zip from \"../utils/zip.js\";\nimport { sameVector } from \"../vectorOperations.js\";\nimport { Transformable } from \"./utils/Transformable.js\";\n\nexport type Stroke = AbstractStroke<any>;\n\nexport abstract class AbstractStroke<\n T extends AbstractStroke<T>,\n> extends Transformable<T> {\n readonly segments: Segment[];\n\n abstract strokeType: string;\n\n get repr(): string {\n return this.segments.map((segment) => segment.repr).join(\"\\n\") + \"\\n\";\n }\n get info(): string {\n return this.repr;\n }\n constructor(segments: Segment[], { ignoreChecks = false } = {}) {\n super();\n if (!ignoreChecks) checkValidStroke(segments);\n this.segments = segments;\n }\n\n get firstPoint(): Vector {\n return this.segments[0].firstPoint;\n }\n\n get lastPoint(): Vector {\n return this.segments[this.segments.length - 1].lastPoint;\n }\n\n get segmentsCount(): number {\n return this.segments.length;\n }\n\n onStroke(point: Vector): boolean {\n return this.segments.some((segment) => segment.isOnSegment(point));\n }\n\n intersects(other: Stroke): boolean {\n if (!this.boundingBox.overlaps(other.boundingBox)) return false;\n return this.segments.some((segment) =>\n other.segments.some(\n (otherSegment) =>\n findIntersectionsAndOverlaps(segment, otherSegment).count > 0,\n ),\n );\n }\n\n overlappingSegments(other: Stroke): Segment[] {\n return this.segments.flatMap((segment) => {\n return other.segments.flatMap((otherSegment) => {\n if (!segment.boundingBox.overlaps(otherSegment.boundingBox)) return [];\n return findIntersectionsAndOverlaps(segment, otherSegment).overlaps;\n });\n });\n }\n\n private _boundingBox: BoundingBox | null = null;\n get boundingBox(): BoundingBox {\n if (this._boundingBox === null) {\n let bbox = this.segments[0].boundingBox;\n\n this.segments.slice(1).forEach((segment) => {\n bbox = bbox.merge(segment.boundingBox);\n });\n this._boundingBox = bbox;\n }\n return this._boundingBox;\n }\n\n abstract reverse(): T;\n\n abstract clone(): T;\n\n abstract transform(matrix: TransformationMatrix): T;\n\n abstract simplify(): T;\n\n [Symbol.for(\"nodejs.util.inspect.custom\")]() {\n return this.repr;\n }\n}\n\nexport function checkSelfIntersections(\n segments: Segment[],\n type = \"Stroke\",\n): void {\n allCombinations(segments.length).forEach(\n ([segmentIndex, otherSegmentIndex]) => {\n if (segmentIndex === otherSegmentIndex) return;\n const segment = segments[segmentIndex];\n const otherSegment = segments[otherSegmentIndex];\n\n const intersections = findIntersectionsAndOverlaps(segment, otherSegment);\n const epsilon = Math.max(segment.precision, otherSegment.precision);\n\n if (intersections.count === 0) return;\n if (intersections.count === 1 && !intersections.overlaps.length) {\n const distance = segmentIndex - otherSegmentIndex;\n\n const intersection = intersections.intersections[0];\n\n if (distance === 1) {\n if (sameVector(segment.firstPoint, intersection, epsilon)) return;\n }\n if (distance === -1) {\n if (sameVector(segment.lastPoint, intersection, epsilon)) return;\n }\n if (distance === segments.length - 1) {\n if (\n sameVector(segment.lastPoint, intersection, epsilon) &&\n sameVector(otherSegment.firstPoint, intersection, epsilon)\n )\n return;\n }\n if (-distance === segments.length - 1) {\n if (\n sameVector(segment.firstPoint, intersection, epsilon) &&\n sameVector(otherSegment.lastPoint, intersection, epsilon)\n )\n return;\n }\n }\n if (intersections.count === 2 && segments.length === 2) {\n if (\n (sameVector(\n segment.firstPoint,\n intersections.intersections[0],\n epsilon,\n ) &&\n sameVector(\n segment.lastPoint,\n intersections.intersections[1],\n epsilon,\n )) ||\n (sameVector(\n segment.firstPoint,\n intersections.intersections[1],\n epsilon,\n ) &&\n sameVector(\n segment.lastPoint,\n intersections.intersections[0],\n epsilon,\n ))\n )\n return;\n }\n\n throw new Error(\n `${type} segments must not intersect, but segments ${\n segment.info\n } and ${otherSegment.info} do at ${JSON.stringify(\n intersections.intersections,\n )}`,\n );\n },\n );\n}\n\nexport function checkValidStroke(segments: Segment[], type = \"Stroke\"): void {\n if (segments.length === 0)\n throw new Error(`${type} must have at least one segment`);\n\n zip([segments.slice(0, -1), segments.slice(1)]).forEach(\n ([segment, nextSegment]) => {\n if (!sameVector(segment.lastPoint, nextSegment.firstPoint))\n throw new Error(\n `${type} segments must be connected, but ${segment.info} and ${nextSegment.info} are not`,\n );\n },\n );\n\n checkSelfIntersections(segments, type);\n}\n","import type { Stroke } from \"../models/Stroke.js\";\nimport { Line } from \"../models/segments/Line.js\";\nimport { Segment } from \"../models/segments/Segment.js\";\nimport { parallel, sameVector } from \"../vectorOperations.js\";\nimport { Arc } from \"../models/segments/Arc.js\";\n\nfunction canExtendSegment(segment1: Segment, segment2: Segment): boolean {\n if (segment1 instanceof Line && segment2 instanceof Line) {\n if (parallel(segment1.V, segment2.V)) {\n return true;\n }\n }\n\n if (segment1 instanceof Arc && segment2 instanceof Arc) {\n if (\n sameVector(segment1.center, segment2.center) &&\n segment1.radius - segment2.radius < segment1.precision\n ) {\n return true;\n }\n }\n return false;\n}\n\nfunction extendSegment(segment1: Segment, segment2: Segment): Segment {\n if (segment1 instanceof Line && segment2 instanceof Line) {\n return new Line(segment1.firstPoint, segment2.lastPoint);\n }\n if (segment1 instanceof Arc && segment2 instanceof Arc) {\n // clockwise is the same for both segments, we would otherwise have some\n // self-intersections in the stroke\n return new Arc(\n segment1.firstPoint,\n segment2.lastPoint,\n segment1.center,\n segment1.clockwise,\n );\n }\n\n throw new Error(\"Not implemented\");\n}\n\nexport function simplifySegments(stroke: Stroke): Segment[] | null {\n let foundSimplification = false;\n const simplifiedSegments: Segment[] = [];\n\n for (const segment of stroke.segments) {\n if (simplifiedSegments.length === 0) {\n simplifiedSegments.push(segment);\n continue;\n }\n\n const lastSegment = simplifiedSegments[simplifiedSegments.length - 1];\n if (canExtendSegment(lastSegment, segment)) {\n foundSimplification = true;\n simplifiedSegments.pop();\n simplifiedSegments.push(extendSegment(lastSegment, segment));\n } else {\n simplifiedSegments.push(segment);\n }\n }\n\n if (sameVector(stroke.firstPoint, stroke.lastPoint)) {\n if (\n canExtendSegment(\n simplifiedSegments[0],\n simplifiedSegments[simplifiedSegments.length - 1],\n )\n ) {\n foundSimplification = true;\n // eslint-disable-next-line @typescript-eslint/no-non-null-assertion\n const lastSegment = simplifiedSegments.pop()!;\n simplifiedSegments[0] = extendSegment(lastSegment, simplifiedSegments[0]);\n }\n }\n\n if (!foundSimplification) return null;\n return simplifiedSegments;\n}\n","import { AbstractStroke } from \"./Stroke.js\";\n\nimport { TransformationMatrix } from \"./TransformationMatrix.js\";\nimport { sameVector } from \"../vectorOperations.js\";\nimport { simplifySegments } from \"../algorithms/simplify.js\";\n\nexport class Strand extends AbstractStroke<Strand> {\n strokeType = \"STRAND\";\n reverse(): Strand {\n const reversedSegments = this.segments.map((segment) => segment.reverse());\n reversedSegments.reverse();\n return new Strand(reversedSegments, { ignoreChecks: true });\n }\n\n clone(): Strand {\n return new Strand(\n this.segments.map((segment) => segment.clone()),\n { ignoreChecks: true },\n );\n }\n\n extend(strand: Strand): Strand {\n if (!sameVector(this.lastPoint, strand.firstPoint)) {\n console.error(this.repr, strand.repr);\n throw new Error(\"Cannot extend strand: connection point is not the same\");\n }\n return new Strand([...this.segments, ...strand.segments]);\n }\n\n simplify(): Strand {\n const newSegments = simplifySegments(this);\n if (!newSegments) return this;\n return new Strand(newSegments, { ignoreChecks: true });\n }\n\n transform(matrix: TransformationMatrix): Strand {\n return new Strand(\n this.segments.map((segment) => segment.transform(matrix)),\n { ignoreChecks: true },\n );\n }\n}\n","import { Line } from \"../../models/segments/Line.js\";\nimport { lineLineParams } from \"./lineLineIntersection.js\";\nimport { lineEllipseArcIntersection } from \"./lineEllipseArcIntersection.js\";\nimport type { Vector } from \"../../definitions.js\";\nimport { Segment } from \"../../models/segments/Segment.js\";\nimport { sameVector, squareDistance } from \"../../vectorOperations.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { EllipseArc } from \"../../models/segments/EllipseArc.js\";\nimport { CubicBezier } from \"../../models/segments/CubicBezier.js\";\nimport { QuadraticBezier } from \"../../models/segments/QuadraticBezier.js\";\n\nconst rayLineIntersectionsCount = (point: Vector, line: Line) => {\n const intersectionParams = lineLineParams(line, {\n V: [1, 0],\n firstPoint: point,\n precision: line.precision,\n });\n if (intersectionParams === \"parallel\") {\n // When the ray is parallel with the line, we can ignore its extremities.\n // They will be handled by the segments getting into and out of this one.\n return 0;\n }\n\n const { intersectionParam1, intersectionParam2 } = intersectionParams;\n\n if (!line.isValidParameter(intersectionParam1)) return 0;\n // With the ray we only check one side of the parameter\n if (intersectionParam2 <= -line.precision) return 0;\n\n // We need to check if the ray intersects the line segment at the extremities\n // In that case we considers that it crosses the segment if its midpoint is\n // above the line.\n\n if (\n Math.abs(intersectionParam1) < line.precision ||\n Math.abs(intersectionParam1 - 1) < line.precision\n ) {\n const [, y] = line.midPoint;\n return point[1] - y < 0 ? 1 : 0;\n }\n\n return 1;\n};\n\nclass IntersectionCounter {\n private _count = 0;\n private readonly segment: Segment;\n\n constructor(segment: Segment) {\n this.segment = segment;\n }\n\n update(intersectionPoint: Vector, isOnSegment = false) {\n if (!isOnSegment && !this.segment.isOnSegment(intersectionPoint)) return;\n\n // We extend the convention of the line ray interaction. We look at the\n // tangent at the point of intersection. If it is pointing to the top we\n // consider that the ray is crossing the arc.\n if (sameVector(intersectionPoint, this.segment.firstPoint)) {\n this._count += this.segment.tangentAtFirstPoint[1] > 0 ? 1 : 0;\n } else if (sameVector(intersectionPoint, this.segment.lastPoint)) {\n this._count += this.segment.tangentAtLastPoint[1] > 0 ? 0 : 1;\n } else {\n this._count += 1;\n }\n }\n\n get count() {\n return this._count;\n }\n}\n\nconst rayArcIntersectionsCount = (point: Vector, arc: Arc) => {\n const epsilon = arc.precision;\n\n const verticalDistance = Math.abs(point[1] - arc.center[1]);\n\n // the line is above or below the circle\n if (verticalDistance > arc.radius + epsilon) return 0;\n\n const squareDist = squareDistance(point, arc.center);\n const squareR = arc.radius * arc.radius;\n const squareEpsilon = epsilon * epsilon;\n\n // On the border\n if (Math.abs(squareDist - squareR) < squareEpsilon && arc.isOnSegment(point))\n return 0;\n\n const pointOutsideCircle = squareDist - squareR > squareEpsilon;\n\n // the point is at the right of the circle\n if (pointOutsideCircle && arc.center[0] < point[0]) return 0;\n\n // delta corresponds to the length between the project center on the line and\n // the crossing points\n const delta = Math.sqrt(\n arc.radius * arc.radius - verticalDistance * verticalDistance,\n );\n\n const counter = new IntersectionCounter(arc);\n\n // We might be able to optimise the check on segment, but it is not clear\n // that it is worth it\n counter.update([arc.center[0] + delta, point[1]]);\n\n if (pointOutsideCircle) {\n counter.update([arc.center[0] - delta, point[1]]);\n }\n\n return counter.count;\n};\n\nconst rayEllipseArcIntersectionsCount = (point: Vector, arc: EllipseArc) => {\n const end = arc.boundingBox.xMax + arc.boundingBox.width / 2;\n const ray = new Line(point, [end, point[1]]);\n\n const counter = new IntersectionCounter(arc);\n lineEllipseArcIntersection(ray, arc).forEach((intersection) => {\n // We already know that the intersection is on the ellipse, se we se\n // isOnSegment as true\n counter.update(intersection, true);\n });\n\n return counter.count;\n};\n\nconst rayBezierIntersectionsCount = (\n point: Vector,\n curve: CubicBezier | QuadraticBezier,\n) => {\n // We rely on the fact that the ray is horizontal\n\n const counter = new IntersectionCounter(curve);\n curve\n .paramsAtY(point[1])\n .map((p) => {\n try {\n return curve.paramPoint(p);\n } catch (e) {\n return null;\n }\n })\n .filter((p) => p !== null)\n .filter((p) => {\n const [x] = p!;\n return x >= point[0];\n })\n .forEach((param) => {\n counter.update(param!, true);\n });\n\n return counter.count;\n};\n\nexport function rayIntersectionsCount(point: Vector, segment: Segment): number {\n if (segment instanceof Line) {\n return rayLineIntersectionsCount(point, segment);\n }\n\n if (segment instanceof Arc) {\n return rayArcIntersectionsCount(point, segment);\n }\n\n if (segment instanceof EllipseArc) {\n return rayEllipseArcIntersectionsCount(point, segment);\n }\n\n if (segment instanceof CubicBezier || segment instanceof QuadraticBezier) {\n return rayBezierIntersectionsCount(point, segment);\n }\n\n throw new Error(\"Not implemented\");\n}\n","import type { Vector } from \"../definitions.js\";\nimport { rayIntersectionsCount } from \"../algorithms/intersections/rayIntersections.js\";\nimport { AbstractStroke, checkValidStroke } from \"./Stroke.js\";\nimport type { TransformationMatrix } from \"./TransformationMatrix.js\";\nimport { simplifySegments } from \"../algorithms/simplify.js\";\nimport { Segment } from \"./segments/Segment.js\";\nimport { sameVector } from \"../vectorOperations.js\";\nimport { Line } from \"./segments/Line.js\";\n\nexport class Loop extends AbstractStroke<Loop> {\n strokeType = \"LOOP\";\n\n constructor(segments: Segment[], { ignoreChecks = false } = {}) {\n super(segments, { ignoreChecks: true });\n if (!ignoreChecks) checkValidLoop(segments);\n }\n\n private _clockwise: boolean | null = null;\n get clockwise(): boolean {\n if (this._clockwise === null) {\n const vertices = this.segments.flatMap((c) => {\n if (!(c instanceof Line)) {\n // We just go with a simple approximation here, we should use some extrema\n // points instead, but this is quick (and good enough for now)\n return [c.firstPoint, c.paramPoint(0.5)];\n }\n return [c.firstPoint];\n });\n\n const approximateArea = vertices\n .map((v1, i) => {\n const v2 = vertices[(i + 1) % vertices.length];\n return (v2[0] - v1[0]) * (v2[1] + v1[1]);\n })\n .reduce((a, b) => a + b, 0);\n\n this._clockwise = approximateArea > 0;\n }\n return this._clockwise;\n }\n\n clone(): Loop {\n return new Loop(\n this.segments.map((segment) => segment.clone()),\n { ignoreChecks: true },\n );\n }\n\n reverse(): Loop {\n const reversedSegments = this.segments.map((segment) => segment.reverse());\n reversedSegments.reverse();\n return new Loop(reversedSegments, { ignoreChecks: true });\n }\n\n transform(matrix: TransformationMatrix): Loop {\n return new Loop(\n this.segments.map((segment) => segment.transform(matrix)),\n { ignoreChecks: true },\n );\n }\n\n contains(point: Vector): boolean {\n if (this.onStroke(point)) return false;\n if (!this.boundingBox.contains(point)) return false;\n\n const intersections = this.segments.reduce((acc, segment) => {\n return acc + rayIntersectionsCount(point, segment);\n }, 0);\n\n return intersections % 2 === 1;\n }\n\n simplify(): Loop {\n const newSegments = simplifySegments(this);\n if (!newSegments) return this;\n return new Loop(newSegments, { ignoreChecks: true });\n }\n}\n\nexport function checkValidLoop(segments: Segment[]): void {\n checkValidStroke(segments, \"Loop\");\n if (\n !sameVector(segments[0].firstPoint, segments[segments.length - 1].lastPoint)\n )\n throw new Error(\"Loop segment must be closed\");\n}\n","import { Arc } from \"../Arc.js\";\nimport { CubicBezier } from \"../CubicBezier.js\";\nimport { EllipseArc } from \"../EllipseArc.js\";\nimport { Line } from \"../Line.js\";\nimport { QuadraticBezier } from \"../QuadraticBezier.js\";\nimport { Segment } from \"../Segment.js\";\n\nexport const ALL_SEGMENT_CLASSES = [\n Line,\n Arc,\n EllipseArc,\n QuadraticBezier,\n CubicBezier,\n];\n\nexport function isSegment(s: unknown): s is Segment {\n return ALL_SEGMENT_CLASSES.some((cls) => s instanceof cls);\n}\n","import { Arc } from \"../../models/segments/Arc.js\";\nimport { CubicBezier } from \"../../models/segments/CubicBezier.js\";\nimport { EllipseArc } from \"../../models/segments/EllipseArc.js\";\nimport { Line } from \"../../models/segments/Line.js\";\nimport { QuadraticBezier } from \"../../models/segments/QuadraticBezier.js\";\nimport { Segment } from \"../../models/segments/Segment.js\";\n\nexport function jsonSegment(segment: Segment) {\n if (segment instanceof Line) {\n return {\n type: segment.segmentType,\n firstPoint: segment.firstPoint,\n lastPoint: segment.lastPoint,\n };\n }\n if (segment instanceof Arc) {\n return {\n type: segment.segmentType,\n firstPoint: segment.firstPoint,\n lastPoint: segment.lastPoint,\n center: segment.center,\n clockwise: segment.clockwise,\n };\n }\n\n if (segment instanceof EllipseArc) {\n return {\n type: segment.segmentType,\n firstPoint: segment.firstPoint,\n lastPoint: segment.lastPoint,\n center: segment.center,\n clockwise: segment.clockwise,\n majorRadius: segment.majorRadius,\n minorRadius: segment.minorRadius,\n tiltAngle: segment.tiltAngle,\n };\n }\n\n if (segment instanceof QuadraticBezier) {\n return {\n type: segment.segmentType,\n firstPoint: segment.firstPoint,\n lastPoint: segment.lastPoint,\n controlPoint: segment.controlPoint,\n };\n }\n\n if (segment instanceof CubicBezier) {\n return {\n type: segment.segmentType,\n firstPoint: segment.firstPoint,\n lastPoint: segment.lastPoint,\n firstControlPoint: segment.firstControlPoint,\n lastControlPoint: segment.lastControlPoint,\n };\n }\n\n throw new Error(\"Unknown segment type\");\n}\n","import type { Loop } from \"../../models/Loop.js\";\nimport { jsonSegment } from \"./jsonSegment.js\";\n\nexport function jsonLoop(loop: Loop) {\n return {\n type: \"LOOP\",\n segments: loop.segments.map(jsonSegment),\n };\n}\n","import type { Figure } from \"../../models/Figure.js\";\nimport { jsonLoop } from \"./jsonLoop.js\";\n\nexport function jsonFigure(figure: Figure) {\n return {\n type: \"FIGURE\",\n contour: jsonLoop(figure.contour),\n holes: figure.holes.map(jsonLoop),\n };\n}\n","import { Diagram } from \"../../models/Diagram.js\";\nimport { jsonFigure } from \"./jsonFigure.js\";\n\nexport function jsonDiagram(diagram: Diagram) {\n return {\n type: \"DIAGRAM\",\n figures: diagram.figures.map(jsonFigure),\n };\n}\n","import { Segment } from \"../../main.js\";\nimport { Diagram } from \"../../models/Diagram.js\";\nimport { Figure } from \"../../models/Figure.js\";\nimport { Loop } from \"../../models/Loop.js\";\nimport { isSegment } from \"../../models/segments/utils/isSegment.js\";\nimport { jsonDiagram } from \"./jsonDiagram.js\";\nimport { jsonFigure } from \"./jsonFigure.js\";\nimport { jsonLoop } from \"./jsonLoop.js\";\nimport { jsonSegment } from \"./jsonSegment.js\";\n\ntype Shape = Loop | Figure | Diagram | Segment;\n\nexport function exportJSON(shape: Shape) {\n if (shape instanceof Diagram) {\n return jsonDiagram(shape);\n } else if (shape instanceof Figure) {\n return jsonFigure(shape);\n } else if (shape instanceof Loop) {\n return jsonLoop(shape);\n } else if (isSegment(shape)) {\n return jsonSegment(shape);\n } else {\n throw new Error(\"Unknown shape type\");\n }\n}\n","\nexport default class FlatQueue {\n\n constructor() {\n this.ids = [];\n this.values = [];\n this.length = 0;\n }\n\n clear() {\n this.length = 0;\n }\n\n push(id, value) {\n let pos = this.length++;\n\n while (pos > 0) {\n const parent = (pos - 1) >> 1;\n const parentValue = this.values[parent];\n if (value >= parentValue) break;\n this.ids[pos] = this.ids[parent];\n this.values[pos] = parentValue;\n pos = parent;\n }\n\n this.ids[pos] = id;\n this.values[pos] = value;\n }\n\n pop() {\n if (this.length === 0) return undefined;\n\n const top = this.ids[0];\n this.length--;\n\n if (this.length > 0) {\n const id = this.ids[0] = this.ids[this.length];\n const value = this.values[0] = this.values[this.length];\n const halfLength = this.length >> 1;\n let pos = 0;\n\n while (pos < halfLength) {\n let left = (pos << 1) + 1;\n const right = left + 1;\n let bestIndex = this.ids[left];\n let bestValue = this.values[left];\n const rightValue = this.values[right];\n\n if (right < this.length && rightValue < bestValue) {\n left = right;\n bestIndex = this.ids[right];\n bestValue = rightValue;\n }\n if (bestValue >= value) break;\n\n this.ids[pos] = bestIndex;\n this.values[pos] = bestValue;\n pos = left;\n }\n\n this.ids[pos] = id;\n this.values[pos] = value;\n }\n\n return top;\n }\n\n peek() {\n if (this.length === 0) return undefined;\n return this.ids[0];\n }\n\n peekValue() {\n if (this.length === 0) return undefined;\n return this.values[0];\n }\n\n shrink() {\n this.ids.length = this.values.length = this.length;\n }\n}\n","import FlatQueue from 'flatqueue';\n\nconst ARRAY_TYPES = [\n Int8Array, Uint8Array, Uint8ClampedArray, Int16Array, Uint16Array,\n Int32Array, Uint32Array, Float32Array, Float64Array\n];\n\nconst VERSION = 3; // serialized format version\n\nexport default class Flatbush {\n\n static from(data) {\n if (!data || data.byteLength === undefined || data.buffer) {\n throw new Error('Data must be an instance of ArrayBuffer or SharedArrayBuffer.');\n }\n const [magic, versionAndType] = new Uint8Array(data, 0, 2);\n if (magic !== 0xfb) {\n throw new Error('Data does not appear to be in a Flatbush format.');\n }\n if (versionAndType >> 4 !== VERSION) {\n throw new Error(`Got v${versionAndType >> 4} data when expected v${VERSION}.`);\n }\n const [nodeSize] = new Uint16Array(data, 2, 1);\n const [numItems] = new Uint32Array(data, 4, 1);\n\n return new Flatbush(numItems, nodeSize, ARRAY_TYPES[versionAndType & 0x0f], undefined, data);\n }\n\n constructor(numItems, nodeSize = 16, ArrayType = Float64Array, ArrayBufferType = ArrayBuffer, data) {\n if (numItems === undefined) throw new Error('Missing required argument: numItems.');\n if (isNaN(numItems) || numItems <= 0) throw new Error(`Unexpected numItems value: ${numItems}.`);\n\n this.numItems = +numItems;\n this.nodeSize = Math.min(Math.max(+nodeSize, 2), 65535);\n\n // calculate the total number of nodes in the R-tree to allocate space for\n // and the index of each tree level (used in search later)\n let n = numItems;\n let numNodes = n;\n this._levelBounds = [n * 4];\n do {\n n = Math.ceil(n / this.nodeSize);\n numNodes += n;\n this._levelBounds.push(numNodes * 4);\n } while (n !== 1);\n\n this.ArrayType = ArrayType || Float64Array;\n this.IndexArrayType = numNodes < 16384 ? Uint16Array : Uint32Array;\n\n const arrayTypeIndex = ARRAY_TYPES.indexOf(this.ArrayType);\n const nodesByteSize = numNodes * 4 * this.ArrayType.BYTES_PER_ELEMENT;\n\n if (arrayTypeIndex < 0) {\n throw new Error(`Unexpected typed array class: ${ArrayType}.`);\n }\n\n if (data && data.byteLength !== undefined && !data.buffer) {\n this.data = data;\n this._boxes = new this.ArrayType(this.data, 8, numNodes * 4);\n this._indices = new this.IndexArrayType(this.data, 8 + nodesByteSize, numNodes);\n\n this._pos = numNodes * 4;\n this.minX = this._boxes[this._pos - 4];\n this.minY = this._boxes[this._pos - 3];\n this.maxX = this._boxes[this._pos - 2];\n this.maxY = this._boxes[this._pos - 1];\n\n } else {\n this.data = new ArrayBufferType(8 + nodesByteSize + numNodes * this.IndexArrayType.BYTES_PER_ELEMENT);\n this._boxes = new this.ArrayType(this.data, 8, numNodes * 4);\n this._indices = new this.IndexArrayType(this.data, 8 + nodesByteSize, numNodes);\n this._pos = 0;\n this.minX = Infinity;\n this.minY = Infinity;\n this.maxX = -Infinity;\n this.maxY = -Infinity;\n\n new Uint8Array(this.data, 0, 2).set([0xfb, (VERSION << 4) + arrayTypeIndex]);\n new Uint16Array(this.data, 2, 1)[0] = nodeSize;\n new Uint32Array(this.data, 4, 1)[0] = numItems;\n }\n\n // a priority queue for k-nearest-neighbors queries\n this._queue = new FlatQueue();\n }\n\n add(minX, minY, maxX, maxY) {\n const index = this._pos >> 2;\n const boxes = this._boxes;\n this._indices[index] = index;\n boxes[this._pos++] = minX;\n boxes[this._pos++] = minY;\n boxes[this._pos++] = maxX;\n boxes[this._pos++] = maxY;\n\n if (minX < this.minX) this.minX = minX;\n if (minY < this.minY) this.minY = minY;\n if (maxX > this.maxX) this.maxX = maxX;\n if (maxY > this.maxY) this.maxY = maxY;\n\n return index;\n }\n\n finish() {\n if (this._pos >> 2 !== this.numItems) {\n throw new Error(`Added ${this._pos >> 2} items when expected ${this.numItems}.`);\n }\n const boxes = this._boxes;\n\n if (this.numItems <= this.nodeSize) {\n // only one node, skip sorting and just fill the root box\n boxes[this._pos++] = this.minX;\n boxes[this._pos++] = this.minY;\n boxes[this._pos++] = this.maxX;\n boxes[this._pos++] = this.maxY;\n return;\n }\n\n const width = (this.maxX - this.minX) || 1;\n const height = (this.maxY - this.minY) || 1;\n const hilbertValues = new Uint32Array(this.numItems);\n const hilbertMax = (1 << 16) - 1;\n\n // map item centers into Hilbert coordinate space and calculate Hilbert values\n for (let i = 0, pos = 0; i < this.numItems; i++) {\n const minX = boxes[pos++];\n const minY = boxes[pos++];\n const maxX = boxes[pos++];\n const maxY = boxes[pos++];\n const x = Math.floor(hilbertMax * ((minX + maxX) / 2 - this.minX) / width);\n const y = Math.floor(hilbertMax * ((minY + maxY) / 2 - this.minY) / height);\n hilbertValues[i] = hilbert(x, y);\n }\n\n // sort items by their Hilbert value (for packing later)\n sort(hilbertValues, boxes, this._indices, 0, this.numItems - 1, this.nodeSize);\n\n // generate nodes at each tree level, bottom-up\n for (let i = 0, pos = 0; i < this._levelBounds.length - 1; i++) {\n const end = this._levelBounds[i];\n\n // generate a parent node for each block of consecutive <nodeSize> nodes\n while (pos < end) {\n const nodeIndex = pos;\n\n // calculate bbox for the new node\n let nodeMinX = boxes[pos++];\n let nodeMinY = boxes[pos++];\n let nodeMaxX = boxes[pos++];\n let nodeMaxY = boxes[pos++];\n for (let j = 1; j < this.nodeSize && pos < end; j++) {\n nodeMinX = Math.min(nodeMinX, boxes[pos++]);\n nodeMinY = Math.min(nodeMinY, boxes[pos++]);\n nodeMaxX = Math.max(nodeMaxX, boxes[pos++]);\n nodeMaxY = Math.max(nodeMaxY, boxes[pos++]);\n }\n\n // add the new node to the tree data\n this._indices[this._pos >> 2] = nodeIndex;\n boxes[this._pos++] = nodeMinX;\n boxes[this._pos++] = nodeMinY;\n boxes[this._pos++] = nodeMaxX;\n boxes[this._pos++] = nodeMaxY;\n }\n }\n }\n\n search(minX, minY, maxX, maxY, filterFn) {\n if (this._pos !== this._boxes.length) {\n throw new Error('Data not yet indexed - call index.finish().');\n }\n\n let nodeIndex = this._boxes.length - 4;\n const queue = [];\n const results = [];\n\n while (nodeIndex !== undefined) {\n // find the end index of the node\n const end = Math.min(nodeIndex + this.nodeSize * 4, upperBound(nodeIndex, this._levelBounds));\n\n // search through child nodes\n for (let pos = nodeIndex; pos < end; pos += 4) {\n // check if node bbox intersects with query bbox\n if (maxX < this._boxes[pos]) continue; // maxX < nodeMinX\n if (maxY < this._boxes[pos + 1]) continue; // maxY < nodeMinY\n if (minX > this._boxes[pos + 2]) continue; // minX > nodeMaxX\n if (minY > this._boxes[pos + 3]) continue; // minY > nodeMaxY\n\n const index = this._indices[pos >> 2] | 0;\n\n if (nodeIndex >= this.numItems * 4) {\n queue.push(index); // node; add it to the search queue\n\n } else if (filterFn === undefined || filterFn(index)) {\n results.push(index); // leaf item\n }\n }\n\n nodeIndex = queue.pop();\n }\n\n return results;\n }\n\n neighbors(x, y, maxResults = Infinity, maxDistance = Infinity, filterFn) {\n if (this._pos !== this._boxes.length) {\n throw new Error('Data not yet indexed - call index.finish().');\n }\n\n let nodeIndex = this._boxes.length - 4;\n const q = this._queue;\n const results = [];\n const maxDistSquared = maxDistance * maxDistance;\n\n while (nodeIndex !== undefined) {\n // find the end index of the node\n const end = Math.min(nodeIndex + this.nodeSize * 4, upperBound(nodeIndex, this._levelBounds));\n\n // add child nodes to the queue\n for (let pos = nodeIndex; pos < end; pos += 4) {\n const index = this._indices[pos >> 2] | 0;\n\n const dx = axisDist(x, this._boxes[pos], this._boxes[pos + 2]);\n const dy = axisDist(y, this._boxes[pos + 1], this._boxes[pos + 3]);\n const dist = dx * dx + dy * dy;\n\n if (nodeIndex >= this.numItems * 4) {\n q.push(index << 1, dist); // node (use even id)\n\n } else if (filterFn === undefined || filterFn(index)) {\n q.push((index << 1) + 1, dist); // leaf item (use odd id)\n }\n }\n\n // pop items from the queue\n while (q.length && (q.peek() & 1)) {\n const dist = q.peekValue();\n if (dist > maxDistSquared) {\n q.clear();\n return results;\n }\n results.push(q.pop() >> 1);\n\n if (results.length === maxResults) {\n q.clear();\n return results;\n }\n }\n\n nodeIndex = q.pop() >> 1;\n }\n\n q.clear();\n return results;\n }\n}\n\nfunction axisDist(k, min, max) {\n return k < min ? min - k : k <= max ? 0 : k - max;\n}\n\n// binary search for the first value in the array bigger than the given\nfunction upperBound(value, arr) {\n let i = 0;\n let j = arr.length - 1;\n while (i < j) {\n const m = (i + j) >> 1;\n if (arr[m] > value) {\n j = m;\n } else {\n i = m + 1;\n }\n }\n return arr[i];\n}\n\n// custom quicksort that partially sorts bbox data alongside the hilbert values\nfunction sort(values, boxes, indices, left, right, nodeSize) {\n if (Math.floor(left / nodeSize) >= Math.floor(right / nodeSize)) return;\n\n const pivot = values[(left + right) >> 1];\n let i = left - 1;\n let j = right + 1;\n\n while (true) {\n do i++; while (values[i] < pivot);\n do j--; while (values[j] > pivot);\n if (i >= j) break;\n swap(values, boxes, indices, i, j);\n }\n\n sort(values, boxes, indices, left, j, nodeSize);\n sort(values, boxes, indices, j + 1, right, nodeSize);\n}\n\n// swap two values and two corresponding boxes\nfunction swap(values, boxes, indices, i, j) {\n const temp = values[i];\n values[i] = values[j];\n values[j] = temp;\n\n const k = 4 * i;\n const m = 4 * j;\n\n const a = boxes[k];\n const b = boxes[k + 1];\n const c = boxes[k + 2];\n const d = boxes[k + 3];\n boxes[k] = boxes[m];\n boxes[k + 1] = boxes[m + 1];\n boxes[k + 2] = boxes[m + 2];\n boxes[k + 3] = boxes[m + 3];\n boxes[m] = a;\n boxes[m + 1] = b;\n boxes[m + 2] = c;\n boxes[m + 3] = d;\n\n const e = indices[i];\n indices[i] = indices[j];\n indices[j] = e;\n}\n\n// Fast Hilbert curve algorithm by http://threadlocalmutex.com/\n// Ported from C++ https://github.com/rawrunprotected/hilbert_curves (public domain)\nfunction hilbert(x, y) {\n let a = x ^ y;\n let b = 0xFFFF ^ a;\n let c = 0xFFFF ^ (x | y);\n let d = x & (y ^ 0xFFFF);\n\n let A = a | (b >> 1);\n let B = (a >> 1) ^ a;\n let C = ((c >> 1) ^ (b & (d >> 1))) ^ c;\n let D = ((a & (c >> 1)) ^ (d >> 1)) ^ d;\n\n a = A; b = B; c = C; d = D;\n A = ((a & (a >> 2)) ^ (b & (b >> 2)));\n B = ((a & (b >> 2)) ^ (b & ((a ^ b) >> 2)));\n C ^= ((a & (c >> 2)) ^ (b & (d >> 2)));\n D ^= ((b & (c >> 2)) ^ ((a ^ b) & (d >> 2)));\n\n a = A; b = B; c = C; d = D;\n A = ((a & (a >> 4)) ^ (b & (b >> 4)));\n B = ((a & (b >> 4)) ^ (b & ((a ^ b) >> 4)));\n C ^= ((a & (c >> 4)) ^ (b & (d >> 4)));\n D ^= ((b & (c >> 4)) ^ ((a ^ b) & (d >> 4)));\n\n a = A; b = B; c = C; d = D;\n C ^= ((a & (c >> 8)) ^ (b & (d >> 8)));\n D ^= ((b & (c >> 8)) ^ ((a ^ b) & (d >> 8)));\n\n a = C ^ (C >> 1);\n b = D ^ (D >> 1);\n\n let i0 = x ^ y;\n let i1 = b | (0xFFFF ^ (i0 | a));\n\n i0 = (i0 | (i0 << 8)) & 0x00FF00FF;\n i0 = (i0 | (i0 << 4)) & 0x0F0F0F0F;\n i0 = (i0 | (i0 << 2)) & 0x33333333;\n i0 = (i0 | (i0 << 1)) & 0x55555555;\n\n i1 = (i1 | (i1 << 8)) & 0x00FF00FF;\n i1 = (i1 | (i1 << 4)) & 0x0F0F0F0F;\n i1 = (i1 | (i1 << 2)) & 0x33333333;\n i1 = (i1 | (i1 << 1)) & 0x55555555;\n\n return ((i1 << 1) | i0) >>> 0;\n}\n","import Flatbush from \"flatbush\";\nimport { Segment } from \"../models/segments/Segment.js\";\n\nexport function stitchSegments(\n segments: Segment[],\n precision = 1e-7,\n): Segment[][] {\n if (segments.length === 0) return [];\n if (segments.length === 1) return [segments];\n\n // We create a spacial index of the startpoints\n const startPoints = new Flatbush(segments.length);\n segments.forEach((c) => {\n const [x, y] = c.firstPoint;\n startPoints.add(x - precision, y - precision, x + precision, y + precision);\n });\n startPoints.finish();\n\n const stitchedSegments: Segment[][] = [];\n const visited = new Set<number>();\n\n segments.forEach((segment, index) => {\n if (visited.has(index)) return;\n\n const connectedSegments: Segment[] = [segment];\n let currentIndex = index;\n\n visited.add(index);\n\n // Once we have started a connected segment segment, we look for the next\n\n let maxLoops = segments.length;\n // eslint-disable-next-line no-constant-condition\n while (true) {\n if (maxLoops-- < 0) {\n throw new Error(\"Infinite loop detected\");\n }\n\n const lastPoint =\n connectedSegments[connectedSegments.length - 1].lastPoint;\n\n const [x, y] = lastPoint;\n const neighbors = startPoints.search(\n x - precision,\n y - precision,\n x + precision,\n y + precision,\n );\n\n const indexDistance = (otherIndex: number) =>\n Math.abs((currentIndex - otherIndex) % segments.length);\n const potentialNextSegments = neighbors\n .filter((neighborIndex) => !visited.has(neighborIndex))\n .map((neighborIndex): [Segment, number, number] => [\n segments[neighborIndex],\n neighborIndex,\n indexDistance(neighborIndex),\n ])\n .sort(([, , a], [, , b]) => indexDistance(a) - indexDistance(b));\n\n if (potentialNextSegments.length === 0) {\n // No more segments to connect we should have wrapped\n stitchedSegments.push(connectedSegments);\n break;\n }\n\n const [nextSegment, nextSegmentIndex] = potentialNextSegments[0];\n\n connectedSegments.push(nextSegment);\n visited.add(nextSegmentIndex);\n currentIndex = nextSegmentIndex;\n }\n });\n\n return stitchedSegments;\n}\n","import { Vector } from \"../definitions.js\";\nimport { TransformationMatrix } from \"./TransformationMatrix.js\";\nimport type { BoundingBox } from \"./BoundingBox.js\";\nimport { Loop } from \"./Loop.js\";\nimport { Strand } from \"./Strand.js\";\nimport type { Stroke } from \"./Stroke.js\";\nimport { combineDifferentValues } from \"../utils/allCombinations.js\";\nimport { Transformable } from \"./utils/Transformable.js\";\nimport { exportJSON } from \"../export/json/exportJSON.js\";\nimport { stitchSegments } from \"../algorithms/stitchSegments.js\";\n\nexport class Figure extends Transformable<Figure> {\n readonly contour: Loop;\n readonly holes: Loop[];\n\n constructor(\n contour: Loop,\n holes: Loop[] = [],\n { ignoreChecks = false } = {},\n ) {\n super();\n if (!ignoreChecks) checkIsValidFigure(contour, holes);\n this.contour = contour;\n this.holes = holes;\n }\n\n get boundingBox(): BoundingBox {\n return this.contour.boundingBox;\n }\n\n get isFull(): boolean {\n return this.holes.length === 0;\n }\n\n get allLoops(): Loop[] {\n return [this.contour, ...this.holes];\n }\n\n clone(): Figure {\n return new Figure(\n this.contour.clone(),\n this.holes.map((hole) => hole.clone()),\n );\n }\n\n transform(matrix: TransformationMatrix): Figure {\n return new Figure(\n this.contour.transform(matrix),\n this.holes.map((hole) => hole.transform(matrix)),\n );\n }\n\n contains(point: Vector): boolean {\n return (\n this.contour.contains(point) &&\n !this.holes.some((hole) => hole.contains(point))\n );\n }\n\n intersects(other: Figure): boolean {\n return this.allLoops.some((loop) =>\n other.allLoops.some((otherLoop) => loop.intersects(otherLoop)),\n );\n }\n\n overlappingStrands(other: Figure | Stroke): Strand[] {\n const otherStrokes = other instanceof Figure ? other.allLoops : [other];\n const overlappingSegments = this.allLoops.flatMap((loop) => {\n return otherStrokes.flatMap((otherLoop) => {\n return loop.overlappingSegments(otherLoop);\n });\n });\n\n return stitchSegments(overlappingSegments).map((segments) => {\n return new Strand(segments);\n });\n }\n}\n\nexport function checkIsValidFigure(contour?: Loop, holes: Loop[] = []): void {\n if (!contour) throw new Error(\"Figure must have a contour\");\n for (const [loop1, loop2] of combineDifferentValues([contour, ...holes])) {\n if (loop1.intersects(loop2)) {\n throw new Error(\"Loops in a figure must not intersect\");\n }\n }\n\n if (\n holes.some(\n (hole) =>\n !contour.contains(hole.firstPoint) &&\n !contour.onStroke(hole.firstPoint),\n )\n ) {\n throw new Error(\"Holes must be inside the contour\");\n }\n\n for (const [hole1, hole2] of combineDifferentValues(holes)) {\n if (hole1.contains(hole2.firstPoint)) {\n console.error(exportJSON(hole1), exportJSON(hole2));\n throw new Error(\"Holes must not be inside other holes\");\n }\n }\n}\n","import { Figure } from \"../models/Figure\";\nimport { Loop } from \"../models/Loop\";\n\nconst groupByBoundingBoxOverlap = (loops: Loop[]): Loop[][] => {\n const overlaps = loops.map((loop, i) => {\n return loops\n .slice(i + 1)\n .map((v, j): [number, Loop] => [j + i + 1, v])\n .filter(([, other]) => loop.boundingBox.overlaps(other.boundingBox))\n .map(([index]) => index);\n });\n const groups: Loop[][] = [];\n const groupsInOverlaps = Array(overlaps.length);\n\n overlaps.forEach((indices, i) => {\n let myGroup = groupsInOverlaps[i];\n if (!myGroup) {\n myGroup = [];\n groups.push(myGroup);\n }\n\n myGroup.push(loops[i]);\n\n if (indices.length) {\n indices.forEach((index) => {\n groupsInOverlaps[index] = myGroup;\n });\n }\n });\n\n return groups;\n};\n\ninterface ContainedLoop {\n loop: Loop;\n isIn: Loop[];\n}\n\nconst addContainmentInfo = (groupedLoops: Loop[]): ContainedLoop[] => {\n return groupedLoops.map((loop, index) => {\n const firstCurve = loop.segments[0];\n const point = firstCurve.midPoint;\n\n const isIn = groupedLoops.filter((potentialOuterLoop, j) => {\n if (index === j) return false;\n return potentialOuterLoop.contains(point);\n });\n\n return {\n loop,\n isIn,\n };\n });\n};\n\nconst splitMultipleOuterLoops = (\n outerLoops: ContainedLoop[],\n allLoops: ContainedLoop[],\n): ContainedLoop[][] => {\n return outerLoops.flatMap(({ loop: outerLoop }) => {\n return cleanEdgeCases(\n allLoops.filter(\n ({ loop, isIn }) =>\n loop === outerLoop || isIn.indexOf(outerLoop) !== -1,\n ),\n );\n });\n};\n\nconst handleNestedLoops = (\n nestedLoops: ContainedLoop[],\n allLoops: ContainedLoop[],\n): ContainedLoop[][] => {\n const firstLevelOuterLoops = allLoops.filter(({ isIn }) => isIn.length <= 1);\n\n const innerLevelsLoops = cleanEdgeCases(\n addContainmentInfo(nestedLoops.map(({ loop }) => loop)),\n );\n return [firstLevelOuterLoops, ...innerLevelsLoops];\n};\n\nconst cleanEdgeCases = (groupedLoops: ContainedLoop[]): ContainedLoop[][] => {\n if (!groupedLoops.length) return [];\n\n const outerLoops = groupedLoops.filter(({ isIn }) => !isIn.length);\n const nestedLoops = groupedLoops.filter(({ isIn }) => isIn.length > 1);\n\n if (outerLoops.length === 1 && nestedLoops.length === 0) {\n return [groupedLoops];\n } else if (outerLoops.length > 1) {\n return splitMultipleOuterLoops(outerLoops, groupedLoops);\n } else {\n return handleNestedLoops(nestedLoops, groupedLoops);\n }\n};\n\n/**\n * Groups an array of loops such that loops that correspond to holes\n * in other loops are set in a Figure\n *\n * This algorithm assumes non intersecting loops.\n */\nexport function organiseLoops(loops: Loop[]): Figure[] {\n const basicGrouping =\n groupByBoundingBoxOverlap(loops).map(addContainmentInfo);\n return basicGrouping.flatMap(cleanEdgeCases).map((compounds) => {\n if (compounds.length === 1) return new Figure(compounds[0].loop);\n\n compounds.sort((a, b) => a.isIn.length - b.isIn.length);\n const [contour, ...holes] = compounds.map(({ loop }) => loop);\n return new Figure(contour, holes);\n });\n}\n","export function allPairs<S, T>(list1: T[], list2: S[]): [T, S][] {\n const result: [T, S][] = [];\n\n for (const l1 of list1) {\n for (const l2 of list2) {\n result.push([l1, l2]);\n }\n }\n\n return result;\n}\n","import { Vector } from \"../../definitions\";\nimport { Segment } from \"../../models/segments/Segment\";\nimport { Strand } from \"../../models/Strand\";\nimport { sameVector } from \"../../vectorOperations\";\n\nexport function* strandsBetweenIntersections(\n segments: Segment[],\n allIntersections: Vector[],\n allCommonSegments: Segment[],\n): Generator<Strand> {\n const endsAtIntersection = (segment: Segment) => {\n return allIntersections.some((intersection) => {\n return sameVector(intersection, segment.lastPoint);\n });\n };\n\n const isCommonSegment = (commonSegment: Segment) => {\n return allCommonSegments.some((segment) => {\n return commonSegment.isSame(segment);\n });\n };\n\n let currentCurves: Segment[] = [];\n for (const segment of segments) {\n // We ignore the checks at strand creation as these strands are part of\n // a loop and can be trusted to be valid\n if (endsAtIntersection(segment)) {\n currentCurves.push(segment);\n yield new Strand(currentCurves, { ignoreChecks: true });\n currentCurves = [];\n } else if (isCommonSegment(segment)) {\n if (currentCurves.length) {\n yield new Strand(currentCurves, { ignoreChecks: true });\n currentCurves = [];\n }\n yield new Strand([segment], { ignoreChecks: true });\n } else {\n currentCurves.push(segment);\n }\n }\n if (currentCurves.length) {\n yield new Strand(currentCurves, { ignoreChecks: true });\n }\n}\n","import { Vector } from \"../../definitions\";\nimport zip from \"../../utils/zip\";\n\nimport { Segment } from \"../../models/segments/Segment\";\nimport { Strand } from \"../../models/Strand\";\nimport { reprVector, sameVector } from \"../../vectorOperations\";\nimport { Loop } from \"../../models/Loop\";\nimport { findIntersectionsAndOverlaps } from \"../intersections\";\nimport removeDuplicatePoints from \"../../utils/removeDuplicatePoints\";\nimport { stitchSegments } from \"../stitchSegments\";\nimport { strandsBetweenIntersections } from \"./strandsBetweenIntersections\";\n\nconst rotateToStartAt = (segments: Segment[], point: Vector) => {\n const startIndex = segments.findIndex((segment: Segment) => {\n return sameVector(point, segment.firstPoint);\n });\n\n const start = segments.slice(0, startIndex);\n const end = segments.slice(startIndex);\n\n return end.concat(start);\n};\n\nconst rotateToStartAtSegment = (segments: Segment[], segment: Segment) => {\n let usedSegments = segments;\n\n const onSegment = (seg: Segment) => {\n return (\n sameVector(seg.firstPoint, segment.firstPoint) &&\n sameVector(seg.lastPoint, segment.lastPoint)\n );\n };\n\n let startIndex = segments.findIndex(onSegment);\n\n // it is also possible that the segment is oriented the other way. We still\n // need to align a start point\n if (startIndex === -1) {\n const reversedSegments = segments.map((s) => s.reverse());\n reversedSegments.reverse();\n startIndex = reversedSegments.findIndex(onSegment);\n if (startIndex === -1) {\n console.error(\n reversedSegments.map((c) => c.repr),\n segment.repr,\n );\n throw new Error(\"Failed to rotate to segment start\");\n }\n usedSegments = reversedSegments;\n }\n\n const start = usedSegments.slice(0, startIndex);\n const end = usedSegments.slice(startIndex);\n\n return end.concat(start);\n};\n\ntype IntersectionStrand = [Strand, Strand | \"same\"];\n\nfunction removeNonCrossingPoint(\n allIntersections: Vector[],\n segmentedCurve: Segment[],\n loopToCheck: Loop,\n) {\n return allIntersections.filter((intersection: Vector) => {\n const segmentsOfIntersection = segmentedCurve.filter((s) => {\n return (\n sameVector(s.firstPoint, intersection) ||\n sameVector(s.lastPoint, intersection)\n );\n });\n if (segmentsOfIntersection.length % 2) {\n throw new Error(\"Bug in the intersection algo on non crossing point\");\n }\n\n const isInside = segmentsOfIntersection.map((segment: Segment): boolean => {\n return loopToCheck.contains(segment.midPoint);\n });\n\n // Either they are all inside or outside\n const segmentsOnTheSameSide =\n isInside.every((i) => i) || !isInside.some((i) => i);\n\n return !segmentsOnTheSameSide;\n });\n}\n\n/* When two shape intersect we cut them into segments between the intersection\n * points.\n *\n * This function returns the list of segments that have the same start and end\n * at the same intersection points or null if there is no intersection.\n */\nfunction loopIntersectionStrands(\n first: Loop,\n second: Loop,\n precision?: number,\n): IntersectionStrand[] | null {\n // For each segment of each blueprint we figure out where the intersection\n // points are.\n let allIntersections: Vector[] = [];\n const allCommonSegments: Segment[] = [];\n\n const firstCurvePoints: Vector[][] = new Array(first.segments.length)\n .fill(0)\n .map(() => []);\n const secondCurvePoints: Vector[][] = new Array(second.segments.length)\n .fill(0)\n .map(() => []);\n\n first.segments.forEach((thisSegments, firstIndex) => {\n second.segments.forEach((otherSegments, secondIndex) => {\n const { intersections, overlaps } = findIntersectionsAndOverlaps(\n thisSegments,\n otherSegments,\n precision,\n );\n\n allIntersections.push(...intersections);\n firstCurvePoints[firstIndex].push(...intersections);\n secondCurvePoints[secondIndex].push(...intersections);\n\n allCommonSegments.push(...overlaps);\n const commonSegmentsPoints = overlaps.flatMap((s) => [\n s.firstPoint,\n s.lastPoint,\n ]);\n allIntersections.push(...commonSegmentsPoints);\n firstCurvePoints[firstIndex].push(...commonSegmentsPoints);\n secondCurvePoints[secondIndex].push(...commonSegmentsPoints);\n });\n });\n\n allIntersections = removeDuplicatePoints(allIntersections, precision);\n\n // If there is only one intersection point we consider that the loops\n // are not intersecting\n if (!allIntersections.length || allIntersections.length === 1) return null;\n\n // We further split the segments at the intersections\n const cutCurve = ([segment, intersections]: [\n Segment,\n Vector[],\n ]): Segment[] => {\n if (!intersections.length) return [segment];\n return segment.splitAt(intersections);\n };\n let firstCurveSegments = zip([first.segments, firstCurvePoints] as [\n Segment[],\n Vector[][],\n ]).flatMap(cutCurve);\n\n let secondCurveSegments = zip([second.segments, secondCurvePoints] as [\n Segment[],\n Vector[][],\n ]).flatMap(cutCurve);\n\n // We need to remove intersection points that are not crossing into each\n // other (i.e. the two blueprints are only touching in one point and not\n // intersecting there.)\n allIntersections = removeNonCrossingPoint(\n allIntersections,\n firstCurveSegments,\n second,\n );\n\n if (!allIntersections.length && !allCommonSegments.length) return null;\n\n // We align the beginning of the segments\n if (!allCommonSegments.length) {\n const startAt = allIntersections[0];\n firstCurveSegments = rotateToStartAt(firstCurveSegments, startAt);\n secondCurveSegments = rotateToStartAt(secondCurveSegments, startAt);\n } else {\n // When there are common segments we always start on one\n const startSegment = allCommonSegments[0];\n firstCurveSegments = rotateToStartAtSegment(\n firstCurveSegments,\n startSegment,\n );\n secondCurveSegments = rotateToStartAtSegment(\n secondCurveSegments,\n startSegment,\n );\n }\n\n // We group segments between intersections in strands\n let strandsFromFirst = Array.from(\n strandsBetweenIntersections(\n firstCurveSegments,\n allIntersections,\n allCommonSegments,\n ),\n );\n\n let strandsFromSecond = Array.from(\n strandsBetweenIntersections(\n secondCurveSegments,\n allIntersections,\n allCommonSegments,\n ),\n );\n\n if (\n !sameVector(\n strandsFromSecond[0].lastPoint,\n strandsFromFirst[0].lastPoint,\n ) ||\n (allCommonSegments.length > 0 && strandsFromSecond[0].segmentsCount !== 1)\n ) {\n strandsFromSecond = strandsFromSecond.map((s) => s.reverse()).reverse();\n if (\n !sameVector(strandsFromSecond[0].lastPoint, strandsFromFirst[0].lastPoint)\n ) {\n strandsFromFirst = strandsFromFirst.map((s) => s.reverse()).reverse();\n }\n }\n\n return zip([strandsFromFirst, strandsFromSecond]).map(([first, second]) => {\n if (\n first.segmentsCount === 1 &&\n allCommonSegments.some((commonSegment) => {\n return first.segments[0].isSame(commonSegment);\n })\n ) {\n return [first, \"same\"];\n }\n return [first, second];\n });\n}\n\nfunction mergeStrandsAsLoop(strands: Strand[]) {\n let outStrand = strands[0];\n\n for (const strand of strands.slice(1)) {\n outStrand = outStrand.extend(strand);\n }\n\n if (!sameVector(outStrand.firstPoint, outStrand.lastPoint)) {\n console.error(\n reprVector(outStrand.firstPoint),\n reprVector(outStrand.lastPoint),\n );\n throw new Error(\"Bug in the intersection algo on non closing strand\");\n }\n\n return new Loop(outStrand.segments);\n}\n\nfunction mergeDiscontinuities(\n inputStrands: Strand[],\n discontinuities: number[],\n) {\n const strands = zip([\n discontinuities.slice(0, -1),\n discontinuities.slice(1),\n ]).map(([start, end]) => {\n return mergeStrandsAsLoop(inputStrands.slice(start, end));\n });\n\n let lastStrand = inputStrands.slice(\n discontinuities[discontinuities.length - 1],\n );\n if (discontinuities[0] !== 0) {\n lastStrand = lastStrand.concat(inputStrands.slice(0, discontinuities[0]));\n }\n strands.push(mergeStrandsAsLoop(lastStrand));\n\n return strands;\n}\n\nfunction groupLoops(inputStrands: Strand[]): Loop[] {\n if (!inputStrands.length) return [];\n\n const startPoints = inputStrands.map((c) => c.firstPoint);\n let endPoints = inputStrands.map((c) => c.lastPoint);\n endPoints = endPoints.slice(-1).concat(endPoints.slice(0, -1));\n\n const discontinuities = zip([startPoints, endPoints]).flatMap(\n ([startPoint, endPoint], index) => {\n if (!sameVector(startPoint, endPoint)) {\n return index;\n }\n return [];\n },\n );\n\n try {\n return mergeDiscontinuities(inputStrands, discontinuities);\n } catch (e) {\n // Sometimes the shapes are weird enough that our assumptions about the\n // strands do not work\n return stitchSegments(inputStrands.flatMap((s) => s.segments))\n .filter((c) => c.length > 1)\n .filter((c) => sameVector(c[0].firstPoint, c.at(-1)!.lastPoint))\n .map((c) => new Loop(c));\n }\n}\n\nconst extendStrandList = (strandList: Strand[], strand: Strand) => {\n if (strandList.length === 0) return [strand];\n const lastStrand = strandList.at(-1)!;\n if (sameVector(lastStrand.lastPoint, strand.firstPoint)) {\n return strandList.slice(0, -1).concat([lastStrand.extend(strand)]);\n } else if (sameVector(lastStrand.lastPoint, strand.lastPoint)) {\n return strandList\n .slice(0, -1)\n .concat([lastStrand.extend(strand.reverse())]);\n } else {\n return strandList.concat([strand]);\n }\n};\n\nconst prependStrandList = (strandList: Strand[], strand: Strand) => {\n if (strandList.length === 0) return [strand];\n if (sameVector(strandList[0].firstPoint, strand.lastPoint)) {\n return [strand.extend(strandList[0])].concat(strandList.slice(1));\n } else {\n return [strand].concat(strandList);\n }\n};\n\nexport function loopBooleanOperation(\n first: Loop,\n second: Loop,\n {\n firstInside,\n secondInside,\n }: {\n firstInside: \"keep\" | \"remove\";\n secondInside: \"keep\" | \"remove\";\n },\n):\n | Loop[]\n | { identical: true }\n | {\n firstCurveInSecond: boolean;\n secondCurveInFirst: boolean;\n identical: false;\n } {\n const strands = loopIntersectionStrands(first, second);\n\n // The case where we have no intersections\n if (!strands) {\n const firstStrandPoint = first.segments[0].midPoint;\n const firstCurveInSecond = second.contains(firstStrandPoint);\n\n const secondStrandPoint = second.segments[0].midPoint;\n const secondCurveInFirst = first.contains(secondStrandPoint);\n\n return {\n identical: false,\n firstCurveInSecond,\n secondCurveInFirst,\n };\n }\n\n if (strands.every(([, secondStrand]) => secondStrand === \"same\")) {\n return { identical: true };\n }\n\n let lastWasSame: null | Strand = null;\n let strandsIn: number | null = null;\n\n const s = strands.flatMap(([firstStrand, secondStrand]) => {\n let mergedStrands: Strand[] = [];\n let strandsOut = 0;\n\n // When two strands are on top of each other we base our decision on the\n // fact that every point should have one strand entering, and one going\n // out.\n if (secondStrand === \"same\") {\n if (strandsIn === 1) {\n strandsIn = 1;\n return firstStrand;\n }\n\n if (strandsIn === 2 || strandsIn === 0) {\n strandsIn = null;\n return [];\n }\n\n if (strandsIn === null) {\n if (!lastWasSame) lastWasSame = firstStrand;\n else lastWasSame = lastWasSame.extend(firstStrand);\n return [];\n }\n\n console.error(\"weird situation\");\n return [];\n }\n\n // Every strand is kept or removed according to the fact that it is within\n // or not of the other closed loop\n\n const firstSegmentPoint = firstStrand.segments[0].midPoint;\n const firstSegmentInSecondShape = second.contains(firstSegmentPoint);\n\n if (\n (firstInside === \"keep\" && firstSegmentInSecondShape) ||\n (firstInside === \"remove\" && !firstSegmentInSecondShape)\n ) {\n strandsOut += 1;\n mergedStrands = extendStrandList(mergedStrands, firstStrand);\n }\n\n const secondSegmentPoint = secondStrand.segments[0].midPoint;\n const secondSegmentInFirstShape = first.contains(secondSegmentPoint);\n\n if (\n (secondInside === \"keep\" && secondSegmentInFirstShape) ||\n (secondInside === \"remove\" && !secondSegmentInFirstShape)\n ) {\n const strandToAdd = secondStrand;\n\n strandsOut += 1;\n\n if (strandsOut === 2 && mergedStrands.length) {\n mergedStrands = extendStrandList(mergedStrands, strandToAdd);\n lastWasSame = null;\n } else {\n mergedStrands = [strandToAdd];\n }\n }\n\n // This is the case where the information about the strands entering the\n // previous node where not known and no strand was selected\n if (strandsIn === null && strandsOut === 1 && lastWasSame) {\n mergedStrands = prependStrandList(mergedStrands, lastWasSame);\n }\n\n if (strandsOut === 1) {\n strandsIn = strandsOut;\n lastWasSame = null;\n }\n if (!mergedStrands.length) {\n lastWasSame = null;\n return [];\n }\n return mergedStrands;\n });\n\n // We now have a bunch of strands, we need to group them into loops\n return groupLoops(s);\n}\n\nexport const fuseLoops = (first: Loop, second: Loop): Loop[] => {\n const result = loopBooleanOperation(first, second, {\n firstInside: \"remove\",\n secondInside: \"remove\",\n });\n\n if (Array.isArray(result)) return result;\n\n if (result.identical) {\n return [first];\n }\n\n if (result.firstCurveInSecond) {\n return [second];\n }\n\n if (result.secondCurveInFirst) {\n return [first];\n }\n\n return [first, second];\n};\n\nexport const cutLoops = (first: Loop, second: Loop): Loop[] => {\n const result = loopBooleanOperation(first, second, {\n firstInside: \"remove\",\n secondInside: \"keep\",\n });\n\n if (Array.isArray(result)) return result;\n\n if (result.identical) {\n return [];\n }\n\n if (result.firstCurveInSecond) {\n return [];\n }\n\n if (result.secondCurveInFirst) {\n return [first, second];\n }\n\n return [first];\n};\n\nexport const intersectLoops = (first: Loop, second: Loop): Loop[] => {\n const result = loopBooleanOperation(first, second, {\n firstInside: \"keep\",\n secondInside: \"keep\",\n });\n\n if (Array.isArray(result)) return result;\n\n if (result.identical) {\n return [first];\n }\n\n if (result.firstCurveInSecond) {\n return [first];\n }\n\n if (result.secondCurveInFirst) {\n return [second];\n }\n\n return [];\n};\n","import { Figure } from \"../../models/Figure\";\nimport { organiseLoops } from \"../organiseLoops\";\nimport { allPairs } from \"../../utils/allPairs\";\nimport { cutLoops, fuseLoops, intersectLoops } from \"./loopBooleans\";\n\nexport function fuseIntersectingFigures(figures: Figure[]) {\n const fused = new Map();\n\n const output: { current: Figure[] }[] = [];\n\n figures.forEach((inputFigure, i) => {\n let savedFigures: {\n current: Figure[];\n fusedWith: Set<number>;\n };\n\n if (fused.has(i)) {\n savedFigures = fused.get(i);\n } else {\n savedFigures = { current: [inputFigure], fusedWith: new Set([i]) };\n output.push(savedFigures);\n }\n\n figures.slice(i + 1).forEach((inputOtherFigure, j) => {\n const figure = savedFigures.current;\n\n const currentIndex = i + j + 1;\n\n if (savedFigures.fusedWith.has(currentIndex)) return;\n\n let otherFigure = [inputOtherFigure];\n let otherIsFused = false;\n\n if (fused.has(currentIndex)) {\n otherFigure = fused.get(currentIndex).current;\n otherIsFused = true;\n }\n\n const doListIntersect = figure.some((f) =>\n otherFigure.some((s) => f.intersects(s)),\n );\n if (!doListIntersect) return;\n\n let newFused: Figure[];\n if (figure.length > 1 || otherFigure.length > 1) {\n newFused = fuseFiguresLists(figure, otherFigure);\n } else {\n newFused = fuseFigures(figure[0], otherFigure[0]);\n }\n\n savedFigures.fusedWith.add(currentIndex);\n savedFigures.current = newFused;\n if (!otherIsFused) fused.set(currentIndex, savedFigures);\n });\n });\n\n return output.flatMap(({ current }) => current);\n}\n\nexport function fuseFigures(first: Figure, second: Figure) {\n const outerFused = fuseLoops(first.contour, second.contour);\n\n const inner1Fused = second.holes.flatMap((c) => cutLoops(c, first.contour));\n const inner2Fused = first.holes.flatMap((c) => cutLoops(c, second.contour));\n\n const innerIntersections = allPairs(first.holes, second.holes).flatMap(\n ([first, second]) => intersectLoops(first, second),\n );\n\n return organiseLoops([\n ...outerFused,\n ...inner1Fused,\n ...inner2Fused,\n ...innerIntersections,\n ]);\n}\n\nexport function cutFigures(first: Figure, second: Figure): Figure[] {\n if (first.isFull && second.isFull) {\n return organiseLoops(cutLoops(first.contour, second.contour));\n }\n\n if (first.isFull) {\n const cutContour = cutLoops(first.contour, second.contour);\n const cutHoles = second.holes.flatMap((c) =>\n intersectLoops(c, first.contour),\n );\n // We might be able to assume that the contour and the holes are already\n // distinct figures.\n return organiseLoops([...cutContour, ...cutHoles]);\n } else if (second.isFull) {\n if (!first.contour.intersects(second.contour)) {\n if (!first.contour.contains(second.contour.firstPoint)) {\n // nothing to do here, the second figure is outside the first\n return [first];\n } else {\n const fusedCuts = fuseFiguresLists(\n first.holes.map((h) => new Figure(h)),\n [second],\n );\n\n return organiseLoops([\n first.contour,\n ...fusedCuts.flatMap((f) => f.allLoops),\n ]);\n }\n }\n }\n\n // We turn the last case in one where the second is full\n let newFigures = cutFigures(new Figure(first.contour), second);\n first.holes.forEach((cut) => {\n newFigures = newFigures.flatMap((c) => cutFigures(c, new Figure(cut)));\n });\n\n return newFigures;\n}\n\nexport function intersectFigures(first: Figure, second: Figure): Figure[] {\n const outerIntersection = intersectLoops(first.contour, second.contour);\n if (!outerIntersection.length) return [];\n\n let out = organiseLoops(outerIntersection);\n out = cutFiguresLists(\n out,\n first.holes.map((h) => new Figure(h)),\n );\n\n // Here we need to do the cut in two steps, because the holes might intersect\n return cutFiguresLists(\n out,\n second.holes.map((h) => new Figure(h)),\n );\n}\n\nexport function fuseFiguresLists(first: Figure[], second: Figure[]): Figure[] {\n if (!first.length) return second;\n if (!second.length) return first;\n\n if (\n (first.length === 1 && second.length > 1) ||\n (second.length === 1 && first.length > 1)\n ) {\n return fuseIntersectingFigures([...first, ...second]);\n }\n\n if (first.length > 1 && second.length > 1) {\n let out = fuseFiguresLists([first[0]], second);\n\n first.slice(1).forEach((fig) => {\n out = fuseFiguresLists([fig], out);\n });\n return out;\n }\n\n if (first.length === 1 && second.length === 1) {\n return fuseFigures(first[0], second[0]);\n }\n\n return [];\n}\n\nexport function cutFiguresLists(first: Figure[], second: Figure[]): Figure[] {\n if (!first.length) return [];\n if (!second.length) return first;\n\n // The easy case\n if (first.length === 1 && second.length === 1) {\n return cutFigures(first[0], second[0]);\n }\n\n if (first.length > 1) {\n // All the figures here are independant, so we can cut them independently\n return first.flatMap((fig) => cutFiguresLists([fig], second));\n }\n\n // We are now in the case where there is only one figure in the first list\n // and multiple figures in the second list\n //\n // We turn it in the case with (potentially) multiple figures in the first list\n // and one figure in the second list\n\n let out = cutFigures(first[0], second[0]);\n second.slice(1).forEach((fig) => {\n out = cutFiguresLists(out, [fig]);\n });\n return out;\n}\n\nexport function intersectFiguresLists(\n first: Figure[],\n second: Figure[],\n): Figure[] {\n if (!first.length || !second.length) {\n return [];\n }\n\n if (first.length === 1 && second.length === 1) {\n return intersectFigures(first[0], second[0]);\n }\n\n if (first.length > 1) {\n return first.flatMap((fig) => intersectFiguresLists([fig], second));\n }\n\n return second.flatMap((fig) => intersectFiguresLists(first, [fig]));\n}\n","import type { Vector } from \"../definitions.js\";\nimport { BoundingBox } from \"./BoundingBox.js\";\nimport type { Figure } from \"./Figure.js\";\nimport type { TransformationMatrix } from \"./TransformationMatrix.js\";\n\nimport {\n cutFiguresLists,\n fuseFiguresLists,\n intersectFiguresLists,\n} from \"../algorithms/boolean/figureBooleans\";\nimport { combineDifferentValues } from \"../utils/allCombinations.js\";\nimport { Transformable } from \"./utils/Transformable.js\";\nimport { Strand } from \"./Strand.js\";\nimport type { Stroke } from \"./Stroke.js\";\n\nexport class Diagram extends Transformable<Diagram> {\n figures: Figure[];\n\n constructor(figures: Figure[] = [], { ignoreChecks = false } = {}) {\n super();\n if (!ignoreChecks) checkIsValidDiagram(figures);\n this.figures = figures;\n }\n\n private _boundingBox: BoundingBox | null = null;\n\n get isEmpty(): boolean {\n return this.figures.length === 0;\n }\n\n get boundingBox(): BoundingBox {\n if (this.isEmpty) return new BoundingBox();\n if (this._boundingBox === null) {\n let boundingBox = this.figures[0].boundingBox;\n for (const figure of this.figures.slice(1)) {\n boundingBox = boundingBox.merge(figure.boundingBox);\n }\n this._boundingBox = boundingBox;\n }\n return this._boundingBox;\n }\n\n clone(): Diagram {\n return new Diagram(this.figures.map((figure) => figure.clone()));\n }\n\n transform(matrix: TransformationMatrix): Diagram {\n return new Diagram(this.figures.map((figure) => figure.transform(matrix)));\n }\n\n contains(point: Vector): boolean {\n return this.figures.some((figure) => figure.contains(point));\n }\n\n intersects(other: Diagram): boolean {\n return this.figures.some((figure) =>\n other.figures.some((otherFigure) => figure.intersects(otherFigure)),\n );\n }\n\n overlappingStrands(other: Diagram | Figure | Stroke): Strand[] {\n return this.figures.flatMap((figure) => {\n if (!(other instanceof Diagram)) {\n return figure.overlappingStrands(other);\n }\n\n return other.figures.flatMap((otherFigure) =>\n figure.overlappingStrands(otherFigure),\n );\n });\n }\n\n fuse(other: Diagram): Diagram {\n return new Diagram(fuseFiguresLists(this.figures, other.figures));\n }\n\n cut(other: Diagram): Diagram {\n return new Diagram(cutFiguresLists(this.figures, other.figures));\n }\n\n intersect(other: Diagram): Diagram {\n return new Diagram(intersectFiguresLists(this.figures, other.figures));\n }\n}\n\nexport function checkIsValidDiagram(figures: Figure[]): void {\n for (const [figure, otherFigure] of combineDifferentValues(figures)) {\n if (figure.intersects(otherFigure)) {\n throw new Error(\"Diagram figures must not intersect\");\n }\n }\n}\n"],"names":["projectPointOnLine","line","point","delta","subtract","u","dotProduct","lineArcIntersection","arc","precision","epsilon","centerOnLine","centerDistance","distance","intersectionPoint","intersections","lineDir","p1","add","scalarMultiply","p2","complementArc","firstPoint","lastPoint","center","clockwise","Arc","handleOverlaps","arc1","arc2","points","removeDuplicatePoints","p","a","b","startIndex","sameVector","arcArcIntersection","includeOverlaps","centersDistance","radiusSum","radiusDifference","centersVector","normalize","isOutsideTangent","orientation","radiusToChord","midPoint","halfChord","chordVector","perpendicular","lineEllipseArcIntersection","lineP","m","c","a2","b2","ab","m2","c2","filterIntersectionInRef","x","y","discriminant","denominator","sqrtDiscriminant","ellipseEllipseIntersection","el1","a1","b1","c1","d1","e1","f1","el2","d2","e2","f2","polynomial","solveGenericPolynomial","denom","bb","v","cc","sqrt","arcEllipseArcIntersection","ellipseArc","majorRadius","minorRadius","tiltAngle","EllipseArc","partialArc","ellipseArcEllipseArcIntersection","lineBezierIntersection","curve","x1","y1","x2","y2","transform","TransformationMatrix","inverseTransform","axisAlignedCurve","t","asFixed","num","removeDuplicateValues","intersectionsPolynomial","p0","p3","q0","q1","q2","q3","e","f","p02","p12","p22","p32","q02","q12","q22","q32","z0","z1","z2","z3","z4","z5","z6","arcsCubicBezierIntersection","solutions","d","arcsQuadraticBezierIntersection","solveQuartic","orientedDistanceToLine","direction","crossProduct","length","FatLine","negativeThickness","positiveThickness","V_3_4","V_4_9","fatLineFromCubicCurve","factor","fatLineFromQuadratic","fatLineFromCurve","CubicBezier","QuadraticBezier","perpendicularFatLineFromCurve","offset","targetPoint","curvePoints","distances","intersectionParameter","linePoints","bound","parameters","i","previousPoint","previousDistanceToBound","distanceToBound","ClippingBounds","from","to","createDistanceHull","fatLine","DistanceToFatLineCubicCurve","DistanceToFatLineQuadraticCurve","__publicField","d3","midLineSlope","midLineIntercept","d4","p4","deltaAtD2","deltaAtD3","topHull","bottomHull","ratio","fatLineIntersections","distancesAtParam","t1","t2","endsWithinBounds","clipFatLineIntersections","curve1","curve2","limits","perpendicularFatLine","perpendicularLimits","hullSquareLength","squareLength","bezierClip","maxIterations","squarePrecision","pCurve","qCurve","pCurveLength","qCurveLength","it","pCurveClipped","pCurveClippedLength","qCurveClipped","qCurveClippedLength","pCurveLeft","pCurveRight","qCurveLeft","qCurveRight","commonPoints","cubicBezierCubicBezierIntersection","overlappingCurve","quadraticBezierQuadraticBezierIntersection","findIntersections","segment1","segment2","Line","intersection","lineLineIntersection","findIntersectionsAndOverlaps","allCombinations","count","result","j","combineDifferentValues","array","AbstractStroke","Transformable","segments","ignoreChecks","checkValidStroke","segment","other","otherSegment","bbox","checkSelfIntersections","type","segmentIndex","otherSegmentIndex","zip","nextSegment","canExtendSegment","parallel","extendSegment","simplifySegments","stroke","foundSimplification","simplifiedSegments","lastSegment","Strand","reversedSegments","strand","newSegments","matrix","rayLineIntersectionsCount","intersectionParams","lineLineParams","intersectionParam1","intersectionParam2","IntersectionCounter","isOnSegment","rayArcIntersectionsCount","verticalDistance","squareDist","squareDistance","squareR","squareEpsilon","pointOutsideCircle","counter","rayEllipseArcIntersectionsCount","end","ray","rayBezierIntersectionsCount","param","rayIntersectionsCount","Loop","checkValidLoop","vertices","approximateArea","v1","v2","acc","ALL_SEGMENT_CLASSES","isSegment","s","cls","jsonSegment","jsonLoop","loop","jsonFigure","figure","jsonDiagram","diagram","exportJSON","shape","Diagram","Figure","FlatQueue","id","value","pos","parent","parentValue","top","halfLength","left","right","bestIndex","bestValue","rightValue","ARRAY_TYPES","VERSION","Flatbush","data","magic","versionAndType","nodeSize","numItems","ArrayType","ArrayBufferType","n","numNodes","arrayTypeIndex","nodesByteSize","minX","minY","maxX","maxY","index","boxes","width","height","hilbertValues","hilbertMax","hilbert","sort","nodeIndex","nodeMinX","nodeMinY","nodeMaxX","nodeMaxY","filterFn","queue","results","upperBound","maxResults","maxDistance","q","maxDistSquared","dx","axisDist","dy","dist","k","min","max","arr","values","indices","pivot","swap","temp","A","B","C","D","i0","i1","stitchSegments","startPoints","stitchedSegments","visited","connectedSegments","currentIndex","maxLoops","neighbors","indexDistance","otherIndex","potentialNextSegments","neighborIndex","nextSegmentIndex","contour","holes","checkIsValidFigure","hole","otherLoop","otherStrokes","overlappingSegments","loop1","loop2","hole1","hole2","groupByBoundingBoxOverlap","loops","overlaps","groups","groupsInOverlaps","myGroup","addContainmentInfo","groupedLoops","isIn","potentialOuterLoop","splitMultipleOuterLoops","outerLoops","allLoops","outerLoop","cleanEdgeCases","handleNestedLoops","nestedLoops","firstLevelOuterLoops","innerLevelsLoops","organiseLoops","compounds","allPairs","list1","list2","l1","l2","strandsBetweenIntersections","allIntersections","allCommonSegments","endsAtIntersection","isCommonSegment","commonSegment","currentCurves","rotateToStartAt","start","rotateToStartAtSegment","usedSegments","onSegment","seg","removeNonCrossingPoint","segmentedCurve","loopToCheck","segmentsOfIntersection","isInside","loopIntersectionStrands","first","second","firstCurvePoints","secondCurvePoints","thisSegments","firstIndex","otherSegments","secondIndex","commonSegmentsPoints","cutCurve","firstCurveSegments","secondCurveSegments","startSegment","startAt","strandsFromFirst","strandsFromSecond","mergeStrandsAsLoop","strands","outStrand","reprVector","mergeDiscontinuities","inputStrands","discontinuities","lastStrand","groupLoops","endPoints","startPoint","endPoint","extendStrandList","strandList","prependStrandList","loopBooleanOperation","firstInside","secondInside","firstStrandPoint","firstCurveInSecond","secondStrandPoint","secondCurveInFirst","secondStrand","lastWasSame","strandsIn","firstStrand","mergedStrands","strandsOut","firstSegmentPoint","firstSegmentInSecondShape","secondSegmentPoint","secondSegmentInFirstShape","strandToAdd","fuseLoops","cutLoops","intersectLoops","fuseIntersectingFigures","figures","fused","output","inputFigure","savedFigures","inputOtherFigure","otherFigure","otherIsFused","newFused","fuseFiguresLists","fuseFigures","current","outerFused","inner1Fused","inner2Fused","innerIntersections","cutFigures","cutContour","cutHoles","fusedCuts","h","newFigures","cut","intersectFigures","outerIntersection","out","cutFiguresLists","fig","intersectFiguresLists","checkIsValidDiagram","BoundingBox","boundingBox"],"mappings":"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","x_google_ignoreList":[27,28]}