pantograph2d 0.8.0 → 0.9.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 (167) hide show
  1. package/LICENSE +4 -658
  2. package/dist/QuadraticBezier-BKElJOgn.cjs +9 -0
  3. package/dist/QuadraticBezier-BKElJOgn.cjs.map +1 -0
  4. package/dist/QuadraticBezier-PcRS9HZK.js +4773 -0
  5. package/dist/QuadraticBezier-PcRS9HZK.js.map +1 -0
  6. package/dist/draw-L71G180-.cjs +2 -0
  7. package/dist/draw-L71G180-.cjs.map +1 -0
  8. package/dist/draw-N2ntigsw.js +417 -0
  9. package/dist/draw-N2ntigsw.js.map +1 -0
  10. package/dist/models-BXU-Gx3U.cjs +4 -0
  11. package/dist/models-BXU-Gx3U.cjs.map +1 -0
  12. package/dist/{Diagram-2450b2e6.js → models-BjaFYsN2.js} +278 -279
  13. package/dist/models-BjaFYsN2.js.map +1 -0
  14. package/dist/pantograph/drawShape.cjs +1 -1
  15. package/dist/pantograph/drawShape.cjs.map +1 -1
  16. package/dist/pantograph/drawShape.js +12 -14
  17. package/dist/pantograph/drawShape.js.map +1 -1
  18. package/dist/pantograph/models.cjs +1 -1
  19. package/dist/pantograph/models.js +2 -2
  20. package/dist/pantograph/svg.cjs +1 -1
  21. package/dist/pantograph/svg.js +5 -6
  22. package/dist/pantograph/svg.js.map +1 -1
  23. package/dist/pantograph.cjs +2 -2
  24. package/dist/pantograph.cjs.map +1 -1
  25. package/dist/pantograph.js +432 -400
  26. package/dist/pantograph.js.map +1 -1
  27. package/dist/{wrapSVG-02b823ac.cjs → svg-ZTvNxsWu.cjs} +2 -2
  28. package/dist/svg-ZTvNxsWu.cjs.map +1 -0
  29. package/dist/{wrapSVG-0ec8a111.js → svg-hNHYuj_r.js} +2 -2
  30. package/dist/svg-hNHYuj_r.js.map +1 -0
  31. package/dist/types/examples/importSVG.d.ts +4 -0
  32. package/dist/{algorithms → types/src/algorithms}/boolean/figureBooleans.d.ts +1 -1
  33. package/dist/{algorithms → types/src/algorithms}/boolean/loopBooleans.d.ts +1 -1
  34. package/dist/{algorithms → types/src/algorithms}/boolean/strandBoolean.d.ts +4 -4
  35. package/dist/{algorithms → types/src/algorithms}/boolean/strandsBetweenIntersections.d.ts +3 -3
  36. package/dist/types/src/algorithms/conversions/bezierToArcs.d.ts +7 -0
  37. package/dist/types/src/algorithms/conversions/bezierToSafeBezier.d.ts +12 -0
  38. package/dist/types/src/algorithms/conversions/ellipseToArcs.d.ts +0 -0
  39. package/dist/types/src/algorithms/conversions/ellipseToBezier.d.ts +3 -0
  40. package/dist/types/src/algorithms/conversions/helpers.d.ts +13 -0
  41. package/dist/{algorithms → types/src/algorithms}/distances/arcArcDistance.d.ts +1 -1
  42. package/dist/{algorithms → types/src/algorithms}/distances/genericDistance.d.ts +1 -1
  43. package/dist/{algorithms → types/src/algorithms}/distances/index.d.ts +1 -1
  44. package/dist/types/src/algorithms/distances/lineArcDistance.d.ts +3 -0
  45. package/dist/{algorithms → types/src/algorithms}/distances/lineLineDistance.d.ts +1 -1
  46. package/dist/{algorithms → types/src/algorithms}/filletSegments.d.ts +1 -1
  47. package/dist/{algorithms → types/src/algorithms}/intersections/arcArcIntersection.d.ts +2 -2
  48. package/dist/types/src/algorithms/intersections/arcEllipseArcIntersection.d.ts +3 -0
  49. package/dist/types/src/algorithms/intersections/arcsCubicBezierIntersection.d.ts +5 -0
  50. package/dist/types/src/algorithms/intersections/arcsQuadraticBezierIntersection.d.ts +5 -0
  51. package/dist/{algorithms → types/src/algorithms}/intersections/bezierClip.d.ts +3 -3
  52. package/dist/{algorithms → types/src/algorithms}/intersections/cubicBezierCubicBezierIntersection.d.ts +2 -2
  53. package/dist/{algorithms → types/src/algorithms}/intersections/ellipseArcEllipseArcIntersection.d.ts +2 -2
  54. package/dist/types/src/algorithms/intersections/ellipseEllipseIntersection.d.ts +4 -0
  55. package/dist/types/src/algorithms/intersections/fullLinesIntersection.d.ts +18 -0
  56. package/dist/{algorithms → types/src/algorithms}/intersections/index.d.ts +2 -2
  57. package/dist/types/src/algorithms/intersections/lineArcIntersection.d.ts +4 -0
  58. package/dist/types/src/algorithms/intersections/lineBezierIntersection.d.ts +5 -0
  59. package/dist/types/src/algorithms/intersections/lineEllipseArcIntersection.d.ts +4 -0
  60. package/dist/{algorithms → types/src/algorithms}/intersections/lineLineIntersection.d.ts +4 -4
  61. package/dist/{algorithms → types/src/algorithms}/intersections/quadraticBezierQuadraticBezierIntersection.d.ts +2 -2
  62. package/dist/types/src/algorithms/intersections/rayIntersections.d.ts +3 -0
  63. package/dist/{algorithms → types/src/algorithms}/offsets/offsetFigure.d.ts +2 -2
  64. package/dist/types/src/algorithms/offsets/offsetSegment.d.ts +15 -0
  65. package/dist/types/src/algorithms/offsets/offsetStroke.d.ts +11 -0
  66. package/dist/{algorithms → types/src/algorithms}/organiseLoops.d.ts +2 -2
  67. package/dist/types/src/algorithms/simplify.d.ts +3 -0
  68. package/dist/types/src/algorithms/solvers/findZeroViaNewton.d.ts +1 -0
  69. package/dist/{algorithms → types/src/algorithms}/stitchSegments.d.ts +1 -1
  70. package/dist/types/src/api/drawShape.d.ts +2 -0
  71. package/dist/types/src/api/models.d.ts +1 -0
  72. package/dist/types/src/api/svg.d.ts +1 -0
  73. package/dist/{booleanOperations.d.ts → types/src/booleanOperations.d.ts} +5 -5
  74. package/dist/types/src/conversionOperations.d.ts +8 -0
  75. package/dist/{draw.d.ts → types/src/draw.d.ts} +4 -4
  76. package/dist/{drawShape → types/src/drawShape}/drawCircle.d.ts +1 -1
  77. package/dist/types/src/drawShape/drawEllipse.d.ts +2 -0
  78. package/dist/{drawShape → types/src/drawShape}/drawRect.d.ts +1 -1
  79. package/dist/types/src/drawShape/drawSVGPath.d.ts +2 -0
  80. package/dist/types/src/drawShape/index.d.ts +4 -0
  81. package/dist/{export → types/src/export}/json/exportJSON.d.ts +94 -94
  82. package/dist/{export → types/src/export}/json/jsonDiagram.d.ts +31 -31
  83. package/dist/{export → types/src/export}/json/jsonFigure.d.ts +31 -31
  84. package/dist/{export → types/src/export}/json/jsonLoop.d.ts +16 -16
  85. package/dist/{export → types/src/export}/json/jsonSegment.d.ts +16 -16
  86. package/dist/types/src/export/svg/api.d.ts +6 -0
  87. package/dist/{export → types/src/export}/svg/exportSVG.d.ts +6 -6
  88. package/dist/{export → types/src/export}/svg/svgDiagram.d.ts +1 -1
  89. package/dist/{export → types/src/export}/svg/svgFigure.d.ts +1 -1
  90. package/dist/{export → types/src/export}/svg/svgLoop.d.ts +1 -1
  91. package/dist/{export → types/src/export}/svg/svgSegment.d.ts +1 -1
  92. package/dist/{export → types/src/export}/svg/svgStrand.d.ts +1 -1
  93. package/dist/{export → types/src/export}/svg/wrapSVG.d.ts +1 -1
  94. package/dist/types/src/import/json/importJSON.d.ts +9 -0
  95. package/dist/{main.d.ts → types/src/main.d.ts} +7 -7
  96. package/dist/{models → types/src/models}/BoundingBox.d.ts +1 -1
  97. package/dist/{models → types/src/models}/Diagram.d.ts +7 -7
  98. package/dist/{models → types/src/models}/Figure.d.ts +7 -7
  99. package/dist/{models → types/src/models}/Loop.d.ts +4 -4
  100. package/dist/{models → types/src/models}/Strand.d.ts +2 -2
  101. package/dist/{models → types/src/models}/Stroke.d.ts +5 -5
  102. package/dist/{models → types/src/models}/TransformationMatrix.d.ts +1 -1
  103. package/dist/types/src/models/exports.d.ts +15 -0
  104. package/dist/types/src/models/segments/AbstractSegment.d.ts +25 -0
  105. package/dist/{models → types/src/models}/segments/Arc.d.ts +5 -4
  106. package/dist/{models → types/src/models}/segments/CubicBezier.d.ts +11 -4
  107. package/dist/{models → types/src/models}/segments/EllipseArc.d.ts +5 -5
  108. package/dist/{models → types/src/models}/segments/Line.d.ts +4 -4
  109. package/dist/{models → types/src/models}/segments/QuadraticBezier.d.ts +9 -4
  110. package/dist/{models → types/src/models}/segments/Segment.d.ts +4 -4
  111. package/dist/{models → types/src/models}/segments/utils/deCasteljau.d.ts +1 -1
  112. package/dist/types/src/models/segments/utils/isSegment.d.ts +8 -0
  113. package/dist/{models → types/src/models}/utils/Transformable.d.ts +2 -2
  114. package/dist/{offsetOperations.d.ts → types/src/offsetOperations.d.ts} +4 -4
  115. package/dist/types/src/operations.d.ts +2 -0
  116. package/dist/types/src/utils/applyMixins.d.ts +1 -0
  117. package/dist/types/src/utils/listOfFigures.d.ts +4 -0
  118. package/dist/types/src/utils/projectPointOnLine.d.ts +3 -0
  119. package/dist/{utils → types/src/utils}/removeDuplicatePoints.d.ts +1 -1
  120. package/dist/{vectorOperations.d.ts → types/src/vectorOperations.d.ts} +1 -1
  121. package/package.json +4 -4
  122. package/dist/Diagram-2450b2e6.js.map +0 -1
  123. package/dist/Diagram-57e17509.cjs +0 -4
  124. package/dist/Diagram-57e17509.cjs.map +0 -1
  125. package/dist/QuadraticBezier-e116a2d6.js +0 -3647
  126. package/dist/QuadraticBezier-e116a2d6.js.map +0 -1
  127. package/dist/QuadraticBezier-e3d7218b.cjs +0 -9
  128. package/dist/QuadraticBezier-e3d7218b.cjs.map +0 -1
  129. package/dist/algorithms/distances/lineArcDistance.d.ts +0 -3
  130. package/dist/algorithms/intersections/arcEllipseArcIntersection.d.ts +0 -3
  131. package/dist/algorithms/intersections/arcsCubicBezierIntersection.d.ts +0 -5
  132. package/dist/algorithms/intersections/arcsQuadraticBezierIntersection.d.ts +0 -5
  133. package/dist/algorithms/intersections/ellipseEllipseIntersection.d.ts +0 -4
  134. package/dist/algorithms/intersections/lineArcIntersection.d.ts +0 -4
  135. package/dist/algorithms/intersections/lineBezierIntersection.d.ts +0 -5
  136. package/dist/algorithms/intersections/lineEllipseArcIntersection.d.ts +0 -4
  137. package/dist/algorithms/intersections/rayIntersections.d.ts +0 -3
  138. package/dist/algorithms/offsets/offsetSegment.d.ts +0 -12
  139. package/dist/algorithms/offsets/offsetStroke.d.ts +0 -9
  140. package/dist/algorithms/simplify.d.ts +0 -3
  141. package/dist/api/drawShape.d.ts +0 -2
  142. package/dist/api/models.d.ts +0 -1
  143. package/dist/api/svg.d.ts +0 -1
  144. package/dist/draw-27ac6dae.cjs +0 -2
  145. package/dist/draw-27ac6dae.cjs.map +0 -1
  146. package/dist/draw-c7b2705c.js +0 -344
  147. package/dist/draw-c7b2705c.js.map +0 -1
  148. package/dist/export/svg/api.d.ts +0 -6
  149. package/dist/import/json/importJSON.d.ts +0 -9
  150. package/dist/models/exports.d.ts +0 -15
  151. package/dist/models/segments/utils/isSegment.d.ts +0 -8
  152. package/dist/operations.d.ts +0 -2
  153. package/dist/utils/listOfFigures.d.ts +0 -4
  154. package/dist/utils/projectPointOnLine.d.ts +0 -3
  155. package/dist/wrapSVG-02b823ac.cjs.map +0 -1
  156. package/dist/wrapSVG-0ec8a111.js.map +0 -1
  157. /package/dist/{algorithms → types/src/algorithms}/optimisation/Brent.d.ts +0 -0
  158. /package/dist/{algorithms → types/src/algorithms}/optimisation/DiRect.d.ts +0 -0
  159. /package/dist/{algorithms → types/src/algorithms}/solvers/solvePolynomials.d.ts +0 -0
  160. /package/dist/{definitions.d.ts → types/src/definitions.d.ts} +0 -0
  161. /package/dist/{utils → types/src/utils}/allCombinations.d.ts +0 -0
  162. /package/dist/{utils → types/src/utils}/allPairs.d.ts +0 -0
  163. /package/dist/{utils → types/src/utils}/angularDistance.d.ts +0 -0
  164. /package/dist/{utils → types/src/utils}/range.d.ts +0 -0
  165. /package/dist/{utils → types/src/utils}/removeDuplicateValues.d.ts +0 -0
  166. /package/dist/{utils → types/src/utils}/unitAngle.d.ts +0 -0
  167. /package/dist/{utils → types/src/utils}/zip.d.ts +0 -0
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../Diagram-57e17509.cjs"),r=require("../QuadraticBezier-e3d7218b.cjs");exports.Diagram=e.Diagram;exports.Figure=e.Figure;exports.Loop=e.Loop;exports.Strand=e.Strand;exports.isSegment=e.isSegment;exports.Arc=r.Arc;exports.BoundingBox=r.BoundingBox;exports.CubicBezier=r.CubicBezier;exports.EllipseArc=r.EllipseArc;exports.Line=r.Line;exports.QuadraticBezier=r.QuadraticBezier;exports.Transformable=r.Transformable;exports.TransformationMatrix=r.TransformationMatrix;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const e=require("../models-BXU-Gx3U.cjs"),r=require("../QuadraticBezier-BKElJOgn.cjs");exports.Diagram=e.Diagram;exports.Figure=e.Figure;exports.Loop=e.Loop;exports.Strand=e.Strand;exports.isSegment=e.isSegment;exports.Arc=r.Arc;exports.BoundingBox=r.BoundingBox;exports.CubicBezier=r.CubicBezier;exports.EllipseArc=r.EllipseArc;exports.Line=r.Line;exports.QuadraticBezier=r.QuadraticBezier;exports.Transformable=r.Transformable;exports.TransformationMatrix=r.TransformationMatrix;
2
2
  //# sourceMappingURL=models.cjs.map
@@ -1,5 +1,5 @@
1
- import { D as s, F as e, L as i, S as o, e as n } from "../Diagram-2450b2e6.js";
2
- import { A as m, B as g, C as B, E as c, L as f, Q as p, g as u, T as x } from "../QuadraticBezier-e116a2d6.js";
1
+ import { D as s, F as e, L as i, S as o, g as n } from "../models-BjaFYsN2.js";
2
+ import { A as m, B as g, C as B, E as c, L as f, Q as p, F as u, T as x } from "../QuadraticBezier-PcRS9HZK.js";
3
3
  export {
4
4
  m as Arc,
5
5
  g as BoundingBox,
@@ -1,2 +1,2 @@
1
- "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("../wrapSVG-02b823ac.cjs");require("../QuadraticBezier-e3d7218b.cjs");exports.svgDiagram=g.svgDiagram;exports.svgFigure=g.svgFigure;exports.svgLoop=g.svgLoop;exports.svgSegmentToPath=g.svgSegmentToPath;exports.svgStrand=g.svgStrand;exports.svgViewbox=g.svgViewbox;
1
+ "use strict";Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const g=require("../svg-ZTvNxsWu.cjs");exports.svgDiagram=g.svgDiagram;exports.svgFigure=g.svgFigure;exports.svgLoop=g.svgLoop;exports.svgSegmentToPath=g.svgSegmentToPath;exports.svgStrand=g.svgStrand;exports.svgViewbox=g.svgViewbox;
2
2
  //# sourceMappingURL=svg.cjs.map
@@ -1,11 +1,10 @@
1
- import { s as o, a as e, b as r, d as v, c as t, e as i } from "../wrapSVG-0ec8a111.js";
2
- import "../QuadraticBezier-e116a2d6.js";
1
+ import { s as g, a as e, b as o, d as v, c as r, e as t } from "../svg-hNHYuj_r.js";
3
2
  export {
4
- o as svgDiagram,
3
+ g as svgDiagram,
5
4
  e as svgFigure,
6
- r as svgLoop,
5
+ o as svgLoop,
7
6
  v as svgSegmentToPath,
8
- t as svgStrand,
9
- i as svgViewbox
7
+ r as svgStrand,
8
+ t as svgViewbox
10
9
  };
11
10
  //# sourceMappingURL=svg.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"svg.js","sources":[],"sourcesContent":[],"names":[],"mappings":";;"}
1
+ {"version":3,"file":"svg.js","sources":[],"sourcesContent":[],"names":[],"mappings":";"}
@@ -1,3 +1,3 @@
1
- "use strict";var et=Object.defineProperty;var nt=(t,e,n)=>e in t?et(t,e,{enumerable:!0,configurable:!0,writable:!0,value:n}):t[e]=n;var d=(t,e,n)=>(nt(t,typeof e!="symbol"?e+"":e,n),n);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const I=require("./draw-27ac6dae.cjs"),a=require("./Diagram-57e17509.cjs"),c=require("./QuadraticBezier-e3d7218b.cjs"),w=require("./wrapSVG-02b823ac.cjs");function P(t){if(t instanceof a.Figure)return[t];if(t instanceof a.Loop)return[new a.Figure(t)];if(t instanceof a.Diagram)return t.figures;throw new Error("Unknown shape")}function _(t,e,n=1e-9){let i=[];const s=[],r=new Array(e.segments.length).fill(0).map(()=>[]);e.segments.forEach((u,l)=>{t.segments.forEach(f=>{const{intersections:h,overlaps:m}=a.findIntersectionsAndOverlaps(u,f,n);i.push(...h),r[l].push(...h),s.push(...m);const p=m.flatMap(g=>[g.firstPoint,g.lastPoint]);i.push(...p),r[l].push(...p)})}),i=c.removeDuplicatePoints(i,n);const o=c.zip([e.segments,r]).flatMap(([u,l])=>l.length?u.splitAt(l):[u]);return Array.from(a.strandsBetweenIntersections(o,i,s))}function C(t,e,n=!1){return _(e,t).filter(s=>{const r=s.segments[0].midPoint;return e.onStroke(r)?!n:!e.contains(r)})}function x(t,e,n=!1){return _(e,t).filter(s=>{const r=s.segments[0].midPoint;return e.onStroke(r)?!n:e.contains(r)})}function V(t,e,n=!1){const i=C(t,e.contour,n),s=e.holes.flatMap(r=>x(t,r,n));return[...i,...s]}function G(t,e,n=!1){let i=x(t,e.contour,n);return e.holes.forEach(s=>{i=i.flatMap(r=>C(r,s,n))}),i}function J(t,e){return new a.Diagram(a.fuseFiguresLists(P(t),P(e)))}function M(t){return t.reduce((e,n)=>J(e,n),new a.Diagram)}function O(t,e){return new a.Diagram(a.cutFiguresLists(P(t),P(e)))}function it(t,e){return new a.Diagram(a.intersectFiguresLists(P(t),P(e)))}function rt(t,e,n=!0){if(e instanceof a.Loop)return C(t,e,n);if(e instanceof a.Figure)return V(t,e,n);let i=[new a.Strand([...t.segments])];return e.figures.forEach(s=>{i=i.flatMap(r=>V(r,s,n))}),i}function st(t,e,n=!1){if(e instanceof a.Loop)return x(t,e,n);if(e instanceof a.Figure)return G(t,e,n);let i=[new a.Strand([...t.segments])];return e.figures.forEach(s=>{i=i.flatMap(r=>G(r,s,n))}),i}function T(t){return t<0?"before":t>1?"after":"between"}const $=(t,e,n)=>{if(n==="before")return t.distanceFrom(e.firstPoint);if(n==="after")return t.distanceFrom(e.lastPoint);throw new Error("Invalid position")};function ot(t,e){const n=c.lineLineParams(t,e);if(n==="parallel")return Math.min(t.distanceFrom(e.firstPoint),t.distanceFrom(e.lastPoint));const{intersectionParam1:i,intersectionParam2:s}=n,r=T(i),o=T(s);if(r==="between"&&o==="between")return 0;if(r==="between"&&o!=="between")return $(t,e,o);if(o==="between"&&r!=="between")return $(e,t,r);if(r==="before"&&o==="before")return c.distance(t.firstPoint,e.firstPoint);if(r==="after"&&o==="after")return c.distance(t.lastPoint,e.lastPoint);if(r==="before"&&o==="after")return c.distance(t.firstPoint,e.lastPoint);if(r==="after"&&o==="before")return c.distance(t.lastPoint,e.firstPoint);throw new Error("Invalid position")}function q(t,e){if(a.lineArcIntersection(t,e).length>0)return 0;const n=a.projectPointOnLine(t,e.center);if(t.isOnSegment(n)){const i=c.distance(n,e.center);if(Math.abs(i-e.radius)<t.precision&&e.isOnSegment(n))return 0;if(i-e.radius>t.precision){const s=c.normalize(c.subtract(n,e.center)),r=c.add(e.center,c.scalarMultiply(s,e.radius));if(e.isOnSegment(r))return c.distance(r,n)}}return Math.min(e.distanceFrom(t.firstPoint),e.distanceFrom(t.lastPoint),t.distanceFrom(e.firstPoint),t.distanceFrom(e.lastPoint))}const at=(t,e)=>{const n=t.angleToParam(e.firstAngle);if(t.isValidParameter(n))return!0;const i=t.angleToParam(e.lastAngle);return!!t.isValidParameter(i)};function ct(t,e){if(a.arcArcIntersection(t,e,!0).length>0)return 0;const n=c.distance(t.center,e.center);if(n<t.precision&&at(t,e))return Math.abs(t.radius-e.radius);const i=c.normalize(c.subtract(e.center,t.center)),s=n-Math.abs(t.radius-e.radius)<t.precision;let r=c.polarAngle(i);s&&e.radius>t.radius&&(r+=Math.PI);const o=s?r:r+Math.PI,u=t.angleToParam(r),l=e.angleToParam(o);return t.isValidParameter(u)&&e.isValidParameter(l)?c.distance(t.paramPoint(u),e.paramPoint(l)):Math.min(t.distanceFrom(e.firstPoint),t.distanceFrom(e.lastPoint),e.distanceFrom(t.firstPoint),e.distanceFrom(t.lastPoint))}function ft(t,e,n){let i=0,s=t.length-1;for(;i<=s;){const r=Math.floor((i+s)/2),o=n(t[r],e);if(o<0)i=r+1;else if(o>0)s=r-1;else return r}return-(i+1)}function ut(t,e,n){const i=ft(t,e,n);i<0?t.splice(-(i+1),0,e):t.splice(i,0,e)}class lt{constructor(){d(this,"buckets");this.buckets=[]}addInterval(e){const n=this.buckets[e.rectangle.diagonalBucketIndex];n===void 0?this.buckets[e.rectangle.diagonalBucketIndex]=[e]:ut(n,e,(i,s)=>i.value-s.value)}removeInterval(e){const n=this.buckets[e.rectangle.diagonalBucketIndex];if(n===void 0)throw new Error("Interval not found");n.shift()}getBottomRightHullIntervals(){const e=[];for(let n=this.buckets.length-1;n>=0;n--){const i=this.buckets[n];if(!i===void 0)continue;const s=i[0];if(s!==void 0){if(!e.length){e.push(s);continue}for(;e.length&&e[e.length-1].value>=s.value;)e.pop();for(;e.length>=2;){const r=e[e.length-1],o=e[e.length-2],u=(s.value-o.value)/((s.rectangle.diagonal-o.rectangle.diagonal)*2);if(o.value+(r.rectangle.diagonal-o.rectangle.diagonal)/2*u<r.value)e.pop();else break}e.push(s)}}return e}}class gt{constructor(e,n){d(this,"diagonal");d(this,"diagonalBucketIndex");d(this,"xLength");d(this,"yLength");d(this,"index");this.x=e,this.y=n,this.xLength=Math.pow(3,-e),this.yLength=Math.pow(3,-n),this.diagonal=Math.sqrt(this.xLength*this.xLength+this.yLength*this.yLength),this.diagonalBucketIndex=e+n,this.index=`${e},${n}`}}class ht{constructor(e,n=1e-8,i=1e3,s=1e-6){d(this,"rectangles");d(this,"buckets");d(this,"fMin");d(this,"argMin");d(this,"tol");this.fcn=e,this.endTolerance=n,this.maxIterations=i,this.epsilon=s,this.fcn=e,this.epsilon=s,this.endTolerance=n,this.maxIterations=i,this.rectangles=new Map,this.buckets=new lt;const r=[.5,.5],o=this.rect(0,0),u=this.fcn(r);this.buckets.addInterval(new b(r,u,o)),this.fMin=u,this.argMin=r,this.tol=o.diagonal}registerInterval(e){this.buckets.addInterval(e),e.value<=this.fMin&&(this.fMin=e.value,this.argMin=e.center,this.tol=e.rectangle.diagonal)}rect(e,n){const i=`${e},${n}`;return this.rectangles.has(i)||this.rectangles.set(i,new gt(e,n)),this.rectangles.get(i)}splitInterval(e){let n,i,s;const[r,o]=e.center;return e.rectangle.x<=e.rectangle.y?(n=this.rect(e.rectangle.x+1,e.rectangle.y),i=[r-n.xLength,o],s=[r+n.xLength,o]):(n=this.rect(e.rectangle.x,e.rectangle.y+1),i=[r,o-n.yLength],s=[r,o+n.yLength]),[new b(i,this.fcn(i),n),new b(e.center,e.value,n),new b(s,this.fcn(s),n)]}single_iteration(){const e=this.buckets.getBottomRightHullIntervals();for(;e.length>=2;){const n=e[0],i=e[1],s=(i.value-n.value)/((i.rectangle.diagonal-n.rectangle.diagonal)/2),r=n.value-s*i.value/2;if((this.fMin-r)/Math.abs(this.fMin)<this.epsilon)e.shift();else break}e.forEach(n=>{this.buckets.removeInterval(n)});for(const n of e){const[i,s,r]=this.splitInterval(n);this.registerInterval(i),this.registerInterval(s),this.registerInterval(r)}}run(){let e=0;for(;this.tol>this.endTolerance/2&&(this.single_iteration(),e++,!(e>this.maxIterations)););return{fMin:this.fMin,argMin:this.argMin,tol:this.tol,iterations:e}}}class b{constructor(e,n,i){this.center=e,this.value=n,this.rectangle=i}}function pt(t,e=1e-8,n=1e3,i=1e-6){return new ht(t,e,n,i).run()}function dt(t,e,n=1e-9){const i=pt(s=>{const r=t.paramPoint(s[0]),o=e.paramPoint(s[1]);return c.squareDistance(r,o)},n);return Math.sqrt(i.fMin)}function mt(t,e){return t instanceof c.Line&&e instanceof c.Line?ot(t,e):t instanceof c.Line&&e instanceof c.Arc?q(t,e):t instanceof c.Arc&&e instanceof c.Line?q(e,t):t instanceof c.Arc&&e instanceof c.Arc?ct(t,e):dt(t,e)}const R=1e-8;function k(t,e,n=!0){const i=t.map(f=>({offset:I.offsetSegment(f,e),original:f})),s=[];let r=n?null:i.at(-1),o=n?i.at(-1):null;if(s.length===1)return s;const u=f=>{r?f.offset instanceof I.DegenerateSegment?c.sameVector(f.offset.firstPoint,f.offset.lastPoint)||s.push(new c.Line(f.offset.firstPoint,f.offset.lastPoint)):s.push(f.offset):r=f},l=function*(){for(const f of i.slice(0,-1))yield f;if(!r)throw new Error("Bug in the offset algorithm");yield r};for(const f of l()){if(!o){o=f;continue}const h=o.offset.lastPoint,m=f.offset.firstPoint;if(c.sameVector(h,m)){u(o),o=f;continue}let p=[];if(!(o.offset instanceof I.DegenerateSegment)&&!(f.offset instanceof I.DegenerateSegment)){const{intersections:S,overlaps:D}=a.findIntersectionsAndOverlaps(o.offset,f.offset,R/100);p=[...S,...D.flatMap(L=>[L.firstPoint,L.lastPoint])]}if(p.length>0){let S=p[0];if(p.length>1){const j=o==null?void 0:o.original.lastPoint,B=p.map(tt=>c.squareDistance(tt,j));S=p[B.indexOf(Math.min(...B))]}const D=o.offset.splitAt([S])[0],L=f.offset.splitAt([S]).at(-1);if(!L)throw new Error("Bug in the splitting algo in offset");u({offset:D,original:o.original}),o={offset:L,original:f.original};continue}const g=o.original.lastPoint,A=c.crossProduct(c.subtract(m,g),c.subtract(h,g))>0,Y=new c.Arc(h,m,g,A);u(o),s.push(Y),o=f}return o&&u(o),s}function Q(t){const e=new Map,n=(i,s)=>{const r=e.get(i)||[];e.set(i,[...r,...s])};return t.forEach((i,s)=>{t.slice(s+1).forEach((r,o)=>{const{intersections:u,overlaps:l}=a.findIntersectionsAndOverlaps(i,r,R),f=[...u,...l.flatMap(h=>[h.firstPoint,h.lastPoint])].filter(h=>{const m=c.sameVector(h,i.firstPoint)||c.sameVector(h,i.lastPoint),p=c.sameVector(h,r.firstPoint)||c.sameVector(h,r.lastPoint);return!(m&&p)});f.length&&(n(s,f),n(o+s+1,f))})}),e}function Z(t,e){return e.flatMap((n,i)=>{if(!t.has(i))return n;const s=t.get(i);return s?n.splitAt(s):n})}function H(t,e,n){return t.filter(i=>!e.segments.some(r=>mt(r,i)<Math.abs(n)-R))}function v(t,e){const n=t.clockwise?e:-e,i=k(t.segments,n);if(i.length<2)return new a.Diagram;const s=Q(i);if(!s.size){const f=new a.Loop(i);return new a.Diagram([new a.Figure(f)])}const r=Z(s,i),o=H(r,t,e);if(!o.length)return new a.Diagram;const l=a.stitchSegments(o).filter(f=>f.length>1).filter(f=>c.sameVector(f[0].firstPoint,f.at(-1).lastPoint)).map(f=>new a.Loop(f));return l.length?new a.Diagram(l.map(f=>new a.Figure(f))):new a.Diagram}function Pt(t,e,n="round"){const i=e/2,s=k(t.segments,i,!1),r=k(t.segments,-i,!1).map(g=>g.reverse());r.reverse();const o=(g,A)=>n==="round"?c.tangentArc(g.lastPoint,A.firstPoint,g.tangentAtLastPoint):new c.Line(g.lastPoint,A.firstPoint),u=[...s,o(s[s.length-1],r[0]),...r,o(r[r.length-1],s[0])],l=Q(u);if(!l.size){const g=new a.Loop(u);return new a.Diagram([new a.Figure(g)])}const f=Z(l,u),h=H(f,t,i);if(!h.length)return new a.Diagram;const p=a.stitchSegments(h).filter(g=>g.length>1).filter(g=>c.sameVector(g[0].firstPoint,g.at(-1).lastPoint)).map(g=>new a.Loop(g));return p.length?new a.Diagram(p.map(g=>new a.Figure(g))):new a.Diagram}function wt(t,e){const n=t.map(i=>{const s=M(i.holes.map(r=>v(r,e)));return O(v(i.contour,e),s)});return M(n)}function St(t,e){const n=Math.abs(e/2),i=t.map(s=>M(s.allLoops.map(r=>O(v(r,n),v(r,-n)))));return M(i)}function Lt(t,e){return wt(P(t),e)}function It(t,e,{endCap:n="round"}={}){return t instanceof a.Strand?Pt(t,e,n):St(P(t),e)}function y(t){if(t instanceof a.Diagram)return w.svgDiagram(t);if(t instanceof a.Figure)return w.svgFigure(t);if(t instanceof a.Loop)return`<path d="${w.svgLoop(t)}" />`;if(t instanceof a.Strand)return`<path d="${w.svgStrand(t)}" />`;if(a.isSegment(t))return`<path d="${`M ${t.firstPoint.join(" ")}`} ${w.svgSegmentToPath(t)}" />`;throw new Error("Unknown shape type")}const U=t=>"shape"in t?t.shape:t,z=(t,e)=>{if(!("shape"in t))return e;const{color:n}=t;return n?`<g stroke="${n}">${e}</g>`:e},N=t=>new c.BoundingBox(t.xMin,-t.yMax,t.xMax,-t.yMin);function Mt(t,{margin:e=1,unit:n=null,viewBox:i}={}){if(Array.isArray(t)){const r=t.map(l=>U(l).mirror()),o=r.map((l,f)=>z(t[f],y(l))).join(`
2
- `),u=r.slice(1).reduce((l,f)=>l.merge(f.boundingBox),r[0].boundingBox);return w.wrapSVG(o,i?N(i):u,e,n)}const s=U(t).mirror();return w.wrapSVG(z(t,y(s)),i?N(i):s.boundingBox,e,n)}const W=t=>{if(t.type==="LINE")return new c.Line(t.firstPoint,t.lastPoint);if(t.type==="ARC")return new c.Arc(t.firstPoint,t.lastPoint,t.center,t.clockwise);if(t.type==="ELLIPSE_ARC")return new c.EllipseArc(t.firstPoint,t.lastPoint,t.center,t.majorRadius,t.minorRadius,t.tiltAngle,t.clockwise,{angleUnits:"rad"});if(t.type==="QUADRATIC_BEZIER")return new c.QuadraticBezier(t.firstPoint,t.lastPoint,t.controlPoint);if(t.type==="CUBIC_BEZIER")return new c.CubicBezier(t.firstPoint,t.lastPoint,t.firstControlPoint,t.lastControlPoint);throw new Error("Unknown segment type")},E=t=>{const e=t.segments.map(W);return new a.Loop(e)},K=t=>{const e=E(t.contour),n=t.holes.map(E);return new a.Figure(e,n)},At=t=>{const e=t.figures.map(K);return new a.Diagram(e)};function bt(t){if(t.type==="DIAGRAM")return At(t);if(t.type==="FIGURE")return K(t);if(t.type==="LOOP")return E(t);if(t.type==="LINE"||t.type==="ARC"||t.type==="ELLIPSE_ARC"||t.type==="CUBIC_BEZIER")return W(t);throw new Error("Unknown shape type")}const F=Math.PI/180,X=180/Math.PI;function vt(t,e){const n=Math.cos(e*F)*t,i=Math.sin(e*F)*t;return[n,i]}function Dt([t,e]){const n=Math.sqrt(t*t+e*e),i=Math.atan2(e,t)*X;return[n,i]}exports.draw=I.draw;exports.exportJSON=a.exportJSON;exports.DEG2RAD=F;exports.RAD2DEG=X;exports.cartesianToPolar=Dt;exports.confineStrand=st;exports.cut=O;exports.eraseStrand=rt;exports.exportSVG=Mt;exports.fuse=J;exports.fuseAll=M;exports.importJSON=bt;exports.intersect=it;exports.offset=Lt;exports.outlineStroke=It;exports.polarToCartesian=vt;exports.svgBody=y;
1
+ "use strict";var ct=Object.defineProperty;var ft=(t,n,e)=>n in t?ct(t,n,{enumerable:!0,configurable:!0,writable:!0,value:e}):t[n]=e;var P=(t,n,e)=>ft(t,typeof n!="symbol"?n+"":n,e);Object.defineProperty(exports,Symbol.toStringTag,{value:"Module"});const v=require("./draw-L71G180-.cjs"),c=require("./models-BXU-Gx3U.cjs"),a=require("./QuadraticBezier-BKElJOgn.cjs"),b=require("./svg-ZTvNxsWu.cjs");function I(t){if(t instanceof c.Figure)return[t];if(t instanceof c.Loop)return[new c.Figure(t)];if(t instanceof c.Diagram)return t.figures;throw new Error("Unknown shape")}function W(t,n,e=1e-9){let r=[];const s=[],i=new Array(n.segments.length).fill(0).map(()=>[]);n.segments.forEach((l,u)=>{t.segments.forEach(f=>{const{intersections:g,overlaps:d}=c.findIntersectionsAndOverlaps(l,f,e);r.push(...g),i[u].push(...g),s.push(...d);const p=d.flatMap(m=>[m.firstPoint,m.lastPoint]);r.push(...p),i[u].push(...p)})}),r=a.removeDuplicatePoints(r,e);const o=a.zip([n.segments,i]).flatMap(([l,u])=>u.length?l.splitAt(u):[l]);return Array.from(c.strandsBetweenIntersections(o,r,s))}function z(t,n,e=!1){return W(n,t).filter(s=>{const i=s.segments[0].midPoint;return n.onStroke(i)?!e:!n.contains(i)})}function V(t,n,e=!1){return W(n,t).filter(s=>{const i=s.segments[0].midPoint;return n.onStroke(i)?!e:n.contains(i)})}function _(t,n,e=!1){const r=z(t,n.contour,e),s=n.holes.flatMap(i=>V(t,i,e));return[...r,...s]}function $(t,n,e=!1){let r=V(t,n.contour,e);return n.holes.forEach(s=>{r=r.flatMap(i=>z(i,s,e))}),r}function X(t,n){return new c.Diagram(c.fuseFiguresLists(I(t),I(n)))}function k(t){return t.reduce((n,e)=>X(n,e),new c.Diagram)}function G(t,n){return new c.Diagram(c.cutFiguresLists(I(t),I(n)))}function ut(t,n){return new c.Diagram(c.intersectFiguresLists(I(t),I(n)))}function lt(t,n,e=!0){if(n instanceof c.Loop)return z(t,n,e);if(n instanceof c.Figure)return _(t,n,e);let r=[new c.Strand([...t.segments])];return n.figures.forEach(s=>{r=r.flatMap(i=>_(i,s,e))}),r}function gt(t,n,e=!1){if(n instanceof c.Loop)return V(t,n,e);if(n instanceof c.Figure)return $(t,n,e);let r=[new c.Strand([...t.segments])];return n.figures.forEach(s=>{r=r.flatMap(i=>$(i,s,e))}),r}function q(t){return t<0?"before":t>1?"after":"between"}const U=(t,n,e)=>{if(e==="before")return t.distanceFrom(n.firstPoint);if(e==="after")return t.distanceFrom(n.lastPoint);throw new Error("Invalid position")};function ht(t,n){const e=a.lineLineParams(t,n);if(e==="parallel")return Math.min(t.distanceFrom(n.firstPoint),t.distanceFrom(n.lastPoint));const{intersectionParam1:r,intersectionParam2:s}=e,i=q(r),o=q(s);if(i==="between"&&o==="between")return 0;if(i==="between"&&o!=="between")return U(t,n,o);if(o==="between"&&i!=="between")return U(n,t,i);if(i==="before"&&o==="before")return a.distance(t.firstPoint,n.firstPoint);if(i==="after"&&o==="after")return a.distance(t.lastPoint,n.lastPoint);if(i==="before"&&o==="after")return a.distance(t.firstPoint,n.lastPoint);if(i==="after"&&o==="before")return a.distance(t.lastPoint,n.firstPoint);throw new Error("Invalid position")}function N(t,n){if(c.lineArcIntersection(t,n).length>0)return 0;const e=c.projectPointOnLine(t,n.center);if(t.isOnSegment(e)){const r=a.distance(e,n.center);if(Math.abs(r-n.radius)<t.precision&&n.isOnSegment(e))return 0;if(r-n.radius>t.precision){const s=a.normalize(a.subtract(e,n.center)),i=a.add(n.center,a.scalarMultiply(s,n.radius));if(n.isOnSegment(i))return a.distance(i,e)}}return Math.min(n.distanceFrom(t.firstPoint),n.distanceFrom(t.lastPoint),t.distanceFrom(n.firstPoint),t.distanceFrom(n.lastPoint))}const pt=(t,n)=>{const e=t.angleToParam(n.firstAngle);if(t.isValidParameter(e))return!0;const r=t.angleToParam(n.lastAngle);return!!t.isValidParameter(r)};function dt(t,n){if(c.arcArcIntersection(t,n,!0).length>0)return 0;const e=a.distance(t.center,n.center);if(e<t.precision&&pt(t,n))return Math.abs(t.radius-n.radius);const r=a.normalize(a.subtract(n.center,t.center)),s=e-Math.abs(t.radius-n.radius)<t.precision;let i=a.polarAngle(r);s&&n.radius>t.radius&&(i+=Math.PI);const o=s?i:i+Math.PI,l=t.angleToParam(i),u=n.angleToParam(o);return t.isValidParameter(l)&&n.isValidParameter(u)?a.distance(t.paramPoint(l),n.paramPoint(u)):Math.min(t.distanceFrom(n.firstPoint),t.distanceFrom(n.lastPoint),n.distanceFrom(t.firstPoint),n.distanceFrom(t.lastPoint))}function mt(t,n,e){let r=0,s=t.length-1;for(;r<=s;){const i=Math.floor((r+s)/2),o=e(t[i],n);if(o<0)r=i+1;else if(o>0)s=i-1;else return i}return-(r+1)}function Pt(t,n,e){const r=mt(t,n,e);r<0?t.splice(-(r+1),0,n):t.splice(r,0,n)}class wt{constructor(){P(this,"buckets");this.buckets=[]}addInterval(n){const e=this.buckets[n.rectangle.diagonalBucketIndex];e===void 0?this.buckets[n.rectangle.diagonalBucketIndex]=[n]:Pt(e,n,(r,s)=>r.value-s.value)}removeInterval(n){const e=this.buckets[n.rectangle.diagonalBucketIndex];if(e===void 0)throw new Error("Interval not found");e.shift()}getBottomRightHullIntervals(){const n=[];for(let e=this.buckets.length-1;e>=0;e--){const r=this.buckets[e];if(!r===void 0)continue;const s=r[0];if(s!==void 0){if(!n.length){n.push(s);continue}for(;n.length&&n[n.length-1].value>=s.value;)n.pop();for(;n.length>=2;){const i=n[n.length-1],o=n[n.length-2],l=(s.value-o.value)/((s.rectangle.diagonal-o.rectangle.diagonal)*2);if(o.value+(i.rectangle.diagonal-o.rectangle.diagonal)/2*l<i.value)n.pop();else break}n.push(s)}}return n}}class Mt{constructor(n,e){P(this,"diagonal");P(this,"diagonalBucketIndex");P(this,"xLength");P(this,"yLength");P(this,"index");this.x=n,this.y=e,this.xLength=Math.pow(3,-n),this.yLength=Math.pow(3,-e),this.diagonal=Math.sqrt(this.xLength*this.xLength+this.yLength*this.yLength),this.diagonalBucketIndex=n+e,this.index=`${n},${e}`}}class St{constructor(n,e=1e-8,r=1e3,s=1e-6){P(this,"rectangles");P(this,"buckets");P(this,"fMin");P(this,"argMin");P(this,"tol");this.fcn=n,this.endTolerance=e,this.maxIterations=r,this.epsilon=s,this.fcn=n,this.epsilon=s,this.endTolerance=e,this.maxIterations=r,this.rectangles=new Map,this.buckets=new wt;const i=[.5,.5],o=this.rect(0,0),l=this.fcn(i);this.buckets.addInterval(new E(i,l,o)),this.fMin=l,this.argMin=i,this.tol=o.diagonal}registerInterval(n){this.buckets.addInterval(n),n.value<=this.fMin&&(this.fMin=n.value,this.argMin=n.center,this.tol=n.rectangle.diagonal)}rect(n,e){const r=`${n},${e}`;return this.rectangles.has(r)||this.rectangles.set(r,new Mt(n,e)),this.rectangles.get(r)}splitInterval(n){let e,r,s;const[i,o]=n.center;return n.rectangle.x<=n.rectangle.y?(e=this.rect(n.rectangle.x+1,n.rectangle.y),r=[i-e.xLength,o],s=[i+e.xLength,o]):(e=this.rect(n.rectangle.x,n.rectangle.y+1),r=[i,o-e.yLength],s=[i,o+e.yLength]),[new E(r,this.fcn(r),e),new E(n.center,n.value,e),new E(s,this.fcn(s),e)]}single_iteration(){const n=this.buckets.getBottomRightHullIntervals();for(;n.length>=2;){const e=n[0],r=n[1],s=(r.value-e.value)/((r.rectangle.diagonal-e.rectangle.diagonal)/2),i=e.value-s*r.value/2;if((this.fMin-i)/Math.abs(this.fMin)<this.epsilon)n.shift();else break}n.forEach(e=>{this.buckets.removeInterval(e)});for(const e of n){const[r,s,i]=this.splitInterval(e);this.registerInterval(r),this.registerInterval(s),this.registerInterval(i)}}run(){let n=0;for(;this.tol>this.endTolerance/2&&(this.single_iteration(),n++,!(n>this.maxIterations)););return{fMin:this.fMin,argMin:this.argMin,tol:this.tol,iterations:n}}}class E{constructor(n,e,r){this.center=n,this.value=e,this.rectangle=r}}function It(t,n=1e-8,e=1e3,r=1e-6){return new St(t,n,e,r).run()}function Lt(t,n,e=1e-9){const r=It(s=>{const i=t.paramPoint(s[0]),o=n.paramPoint(s[1]);return a.squareDistance(i,o)},e);return Math.sqrt(r.fMin)}function bt(t,n){return t instanceof a.Line&&n instanceof a.Line?ht(t,n):t instanceof a.Line&&n instanceof a.Arc?N(t,n):t instanceof a.Arc&&n instanceof a.Line?N(n,t):t instanceof a.Arc&&n instanceof a.Arc?dt(t,n):Lt(t,n)}function Y(t){if(t instanceof a.CubicBezier){const s=a.subtract(t.lastPoint,t.firstPoint),i=a.subtract(t.firstControlPoint,t.firstPoint),o=a.subtract(t.lastControlPoint,t.firstPoint),l=a.angle(s,i),u=a.angle(s,o);if(l>0&&u<0||l<0&&u>0)return!1}const n=a.perpendicular(t.tangentAtFirstPoint),e=a.perpendicular(t.tangentAtLastPoint);let r=a.dotProduct(n,e);return Math.abs(Math.acos(r))<Math.PI/3}function C(t){if(Y(t))return[t];const[n,e]=t.splitAtParameters([.5]);return[...C(n),...C(e)]}function J(t){return Y(t)?[t]:t.splitAtParameters(t.getParametersOfExtrema()).flatMap(C)}function At(t){const n=t.deltaAngle,e=Math.ceil(Math.abs(n)/(Math.PI/2)),r=n/e,s=4*Math.tan(r/4)/3,i=t.clockwise?-1:1,o=Array.from({length:e+1},(u,f)=>t.firstAngle+f*r*i);return o.slice(0,-1).map((u,f)=>[u,o[f+1]]).map(([u,f])=>{const g=Math.cos(u),d=Math.sin(u),p=Math.cos(f),m=Math.sin(f),[h,M]=t.center,w=t.minorRadius,S=t.majorRadius,L=new a.TransformationMatrix().rotate(t.tiltAngle,t.center),A=at=>L.transform(at),D=A([h+S*g,M+w*d]),F=A([h+S*(g-s*d*i),M+w*(d+s*g*i)]),st=A([h+S*(p+s*m*i),M+w*(m-s*p*i)]),ot=A([h+S*p,M+w*m]);return new a.CubicBezier(D,ot,F,st)})}const T=1e-8,K=t=>t.flatMap(n=>n instanceof a.Line?[n]:n instanceof a.Arc?[n]:n instanceof a.EllipseArc?At(n).flatMap(e=>J(e)):n instanceof a.QuadraticBezier||n instanceof a.CubicBezier?J(n):[new a.Line(n.firstPoint,n.lastPoint)]);function x(t,n,e=!0){const r=t.map(f=>({offset:v.offsetSegment(f,n),original:f})),s=[];let i=e?null:r.at(-1),o=e?r.at(-1):null;if(s.length===1)return s;const l=f=>{i?f.offset instanceof v.DegenerateSegment?a.sameVector(f.offset.firstPoint,f.offset.lastPoint)||s.push(new a.Line(f.offset.firstPoint,f.offset.lastPoint)):s.push(f.offset):i=f},u=function*(){for(const f of r.slice(0,-1))yield f;if(!i)throw new Error("Bug in the offset algorithm");yield i};for(const f of u()){if(!o){o=f;continue}const g=o.offset.lastPoint,d=f.offset.firstPoint;if(a.sameVector(g,d)){l(o),o=f;continue}let p=[];if(!(o.offset instanceof v.DegenerateSegment)&&!(f.offset instanceof v.DegenerateSegment)){const{intersections:w,overlaps:S}=c.findIntersectionsAndOverlaps(o.offset,f.offset,T/100);p=[...w,...S.flatMap(L=>[L.firstPoint,L.lastPoint])]}if(p.length>0){let w=p[0];if(p.length>1){const A=o==null?void 0:o.original.lastPoint,D=p.map(F=>a.squareDistance(F,A));w=p[D.indexOf(Math.min(...D))]}const S=o.offset.splitAt([w])[0],L=f.offset.splitAt([w]).at(-1);if(!L)throw new Error("Bug in the splitting algo in offset");l({offset:S,original:o.original}),o={offset:L,original:f.original};continue}const m=o.original.lastPoint,h=a.crossProduct(a.subtract(d,m),a.subtract(g,m))>0,M=new a.Arc(g,d,m,h);l(o),s.push(M),o=f}return o&&l(o),s}function j(t){const n=new Map,e=(r,s)=>{const i=n.get(r)||[];n.set(r,[...i,...s])};return t.forEach((r,s)=>{t.slice(s+1).forEach((i,o)=>{const{intersections:l,overlaps:u}=c.findIntersectionsAndOverlaps(r,i,T),f=[...l,...u.flatMap(g=>[g.firstPoint,g.lastPoint])].filter(g=>{const d=a.sameVector(g,r.firstPoint)||a.sameVector(g,r.lastPoint),p=a.sameVector(g,i.firstPoint)||a.sameVector(g,i.lastPoint);return!(d&&p)});f.length&&(e(s,f),e(o+s+1,f))})}),n}function tt(t,n){return n.flatMap((e,r)=>{if(!t.has(r))return e;const s=t.get(r);return s?e.splitAt(s):e})}function nt(t,n,e){return t.filter(r=>!n.segments.some(i=>bt(i,r)<Math.abs(e)-T))}function y(t,n){const e=t.clockwise?n:-n,r=K(t.segments),s=x(r,e);if(s.length<2)return new c.Diagram;const i=j(s);if(!i.size){const g=new c.Loop(s);return new c.Diagram([new c.Figure(g)])}const o=tt(i,s),l=nt(o,t,n);if(!l.length)return new c.Diagram;const f=c.stitchSegments(l).filter(g=>g.length>1).filter(g=>a.sameVector(g[0].firstPoint,g.at(-1).lastPoint)).map(g=>new c.Loop(g));return f.length?new c.Diagram(f.map(g=>new c.Figure(g))):new c.Diagram}function vt(t,n,e="round"){const r=n/2,s=K(t.segments),i=x(s,r,!1),o=x(s,-r,!1).map(h=>h.reverse());o.reverse();const l=(h,M)=>e==="round"?a.tangentArc(h.lastPoint,M.firstPoint,h.tangentAtLastPoint):new a.Line(h.lastPoint,M.firstPoint),u=[...i,l(i[i.length-1],o[0]),...o,l(o[o.length-1],i[0])],f=j(u);if(!f.size){const h=new c.Loop(u);return new c.Diagram([new c.Figure(h)])}const g=tt(f,u),d=nt(g,t,r);if(!d.length)return new c.Diagram;const m=c.stitchSegments(d).filter(h=>h.length>1).filter(h=>a.sameVector(h[0].firstPoint,h.at(-1).lastPoint)).map(h=>new c.Loop(h));return m.length?new c.Diagram(m.map(h=>new c.Figure(h))):new c.Diagram}function kt(t,n){const e=t.map(r=>{const s=k(r.holes.map(i=>y(i,n)));return G(y(r.contour,n),s)});return k(e)}function Dt(t,n){const e=Math.abs(n/2),r=t.map(s=>k(s.allLoops.map(i=>G(y(i,e),y(i,-e)))));return k(r)}function Et(t,n){return kt(I(t),n)}function yt(t,n,{endCap:e="round"}={}){return t instanceof c.Strand?vt(t,n,e):Dt(I(t),n)}function O(t){if(t instanceof c.Diagram)return b.svgDiagram(t);if(t instanceof c.Figure)return b.svgFigure(t);if(t instanceof c.Loop)return`<path d="${b.svgLoop(t)}" />`;if(t instanceof c.Strand)return`<path d="${b.svgStrand(t)}" />`;if(c.isSegment(t))return`<path d="${`M ${t.firstPoint.join(" ")}`} ${b.svgSegmentToPath(t)}" />`;throw new Error("Unknown shape type")}const Q=t=>"shape"in t?t.shape:t,Z=(t,n)=>{if(!("shape"in t))return n;const{color:e}=t;return e?`<g stroke="${e}">${n}</g>`:n},H=t=>new a.BoundingBox(t.xMin,-t.yMax,t.xMax,-t.yMin);function Ft(t,{margin:n=1,unit:e=null,viewBox:r}={}){if(Array.isArray(t)){const i=t.map(u=>Q(u).mirror()),o=i.map((u,f)=>Z(t[f],O(u))).join(`
2
+ `),l=i.slice(1).reduce((u,f)=>u.merge(f.boundingBox),i[0].boundingBox);return b.wrapSVG(o,r?H(r):l,n,e)}const s=Q(t).mirror();return b.wrapSVG(Z(t,O(s)),r?H(r):s.boundingBox,n,e)}const et=t=>{if(t.type==="LINE")return new a.Line(t.firstPoint,t.lastPoint);if(t.type==="ARC")return new a.Arc(t.firstPoint,t.lastPoint,t.center,t.clockwise);if(t.type==="ELLIPSE_ARC")return new a.EllipseArc(t.firstPoint,t.lastPoint,t.center,t.majorRadius,t.minorRadius,t.tiltAngle,t.clockwise,{angleUnits:"rad"});if(t.type==="QUADRATIC_BEZIER")return new a.QuadraticBezier(t.firstPoint,t.lastPoint,t.controlPoint);if(t.type==="CUBIC_BEZIER")return new a.CubicBezier(t.firstPoint,t.lastPoint,t.firstControlPoint,t.lastControlPoint);throw new Error("Unknown segment type")},B=t=>{const n=t.segments.map(et);return new c.Loop(n)},rt=t=>{const n=B(t.contour),e=t.holes.map(B);return new c.Figure(n,e)},Ct=t=>{const n=t.figures.map(rt);return new c.Diagram(n)};function xt(t){if(t.type==="DIAGRAM")return Ct(t);if(t.type==="FIGURE")return rt(t);if(t.type==="LOOP")return B(t);if(t.type==="LINE"||t.type==="ARC"||t.type==="ELLIPSE_ARC"||t.type==="CUBIC_BEZIER")return et(t);throw new Error("Unknown shape type")}const R=Math.PI/180,it=180/Math.PI;function Ot(t,n){const e=Math.cos(n*R)*t,r=Math.sin(n*R)*t;return[e,r]}function Bt([t,n]){const e=Math.sqrt(t*t+n*n),r=Math.atan2(n,t)*it;return[e,r]}exports.draw=v.draw;exports.exportJSON=c.exportJSON;exports.DEG2RAD=R;exports.RAD2DEG=it;exports.cartesianToPolar=Bt;exports.confineStrand=gt;exports.cut=G;exports.eraseStrand=lt;exports.exportSVG=Ft;exports.fuse=X;exports.fuseAll=k;exports.importJSON=xt;exports.intersect=ut;exports.offset=Et;exports.outlineStroke=yt;exports.polarToCartesian=Ot;exports.svgBody=O;
3
3
  //# sourceMappingURL=pantograph.cjs.map
@@ -1 +1 @@
1
- {"version":3,"file":"pantograph.cjs","sources":["../src/utils/listOfFigures.ts","../src/algorithms/boolean/strandBoolean.ts","../src/booleanOperations.ts","../src/algorithms/distances/lineLineDistance.ts","../src/algorithms/distances/lineArcDistance.ts","../src/algorithms/distances/arcArcDistance.ts","../src/algorithms/optimisation/DiRect.ts","../src/algorithms/distances/genericDistance.ts","../src/algorithms/distances/index.ts","../src/algorithms/offsets/offsetStroke.ts","../src/algorithms/offsets/offsetFigure.ts","../src/offsetOperations.ts","../src/export/svg/exportSVG.ts","../src/import/json/importJSON.ts","../src/main.ts"],"sourcesContent":["import { Diagram } from \"../models/Diagram.js\";\nimport { Figure } from \"../models/Figure.js\";\nimport { Loop } from \"../models/Loop.js\";\n\nexport function listOfFigures(shape: Diagram | Figure | Loop): Figure[] {\n if (shape instanceof Figure) {\n return [shape];\n } else if (shape instanceof Loop) {\n return [new Figure(shape)];\n } else if (shape instanceof Diagram) {\n return shape.figures;\n }\n throw new Error(\"Unknown shape\");\n}\n","import { Vector } from \"../../definitions\";\nimport { Segment } from \"../../models/segments/Segment\";\nimport { Loop } from \"../../models/Loop\";\nimport { Strand } from \"../../models/Strand\";\nimport { findIntersectionsAndOverlaps } from \"../intersections\";\nimport removeDuplicatePoints from \"../../utils/removeDuplicatePoints\";\nimport zip from \"../../utils/zip\";\nimport { strandsBetweenIntersections } from \"./strandsBetweenIntersections\";\nimport type { Figure } from \"../../models/Figure\";\nimport type { Stroke } from \"../../models/Stroke\";\n\nfunction strandLoopSections(\n loop: Loop,\n strand: Stroke,\n precision = 1e-9,\n): Strand[] {\n let allIntersections: Vector[] = [];\n const allCommonSegments: Segment[] = [];\n\n const splitPoints: Vector[][] = new Array(strand.segments.length)\n .fill(0)\n .map(() => []);\n\n strand.segments.forEach((strandSegment, strandIndex) => {\n loop.segments.forEach((loopSegment) => {\n const { intersections, overlaps } = findIntersectionsAndOverlaps(\n strandSegment,\n loopSegment,\n precision,\n );\n\n allIntersections.push(...intersections);\n splitPoints[strandIndex].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 splitPoints[strandIndex].push(...commonSegmentsPoints);\n });\n });\n\n allIntersections = removeDuplicatePoints(allIntersections, precision);\n\n const strandSegments = zip([strand.segments, splitPoints] as [\n Segment[],\n Vector[][],\n ]).flatMap(([segment, intersections]: [Segment, Vector[]]): Segment[] => {\n if (!intersections.length) return [segment];\n return segment.splitAt(intersections);\n });\n\n return Array.from(\n strandsBetweenIntersections(\n strandSegments,\n allIntersections,\n allCommonSegments,\n ),\n );\n}\n\nexport function eraseStrandWithinLoop(\n strand: Stroke,\n loop: Loop,\n eraseOnBorder = false,\n) {\n const strands = strandLoopSections(loop, strand);\n\n // We keep only the strands that are outside the loop\n return strands.filter((strand) => {\n const strandCenter = strand.segments[0].midPoint;\n if (loop.onStroke(strandCenter)) return !eraseOnBorder;\n\n return !loop.contains(strandCenter);\n });\n}\n\nexport function eraseStrandOutsideLoop(\n strand: Stroke,\n loop: Loop,\n eraseOnBorder = false,\n) {\n const strands = strandLoopSections(loop, strand);\n\n // We keep only the strands that are outside the loop\n return strands.filter((strand) => {\n const strandCenter = strand.segments[0].midPoint;\n if (loop.onStroke(strandCenter)) return !eraseOnBorder;\n\n return loop.contains(strandCenter);\n });\n}\n\nexport function eraseStrandWithinFigure(\n strand: Stroke,\n figure: Figure,\n eraseOnBorder = false,\n) {\n const outsideStrands = eraseStrandWithinLoop(\n strand,\n figure.contour,\n eraseOnBorder,\n );\n\n const inLoopStrand = figure.holes.flatMap((hole: Loop) =>\n eraseStrandOutsideLoop(strand, hole, eraseOnBorder),\n );\n\n return [...outsideStrands, ...inLoopStrand];\n}\n\nexport function eraseStrandOutsideFigure(\n strand: Stroke,\n figure: Figure,\n eraseOnBorder = false,\n) {\n let insideStrands = eraseStrandOutsideLoop(\n strand,\n figure.contour,\n eraseOnBorder,\n );\n\n figure.holes.forEach((hole: Loop) => {\n insideStrands = insideStrands.flatMap((strand) =>\n eraseStrandWithinLoop(strand, hole, eraseOnBorder),\n );\n });\n\n return insideStrands;\n}\n","import {\n cutFiguresLists,\n fuseFiguresLists,\n intersectFiguresLists,\n} from \"./algorithms/boolean/figureBooleans\";\nimport { Strand } from \"./models/Strand\";\nimport { Diagram } from \"./models/Diagram\";\nimport { Figure } from \"./models/Figure\";\nimport { Loop } from \"./models/Loop\";\nimport { listOfFigures } from \"./utils/listOfFigures\";\nimport {\n eraseStrandOutsideFigure,\n eraseStrandOutsideLoop,\n eraseStrandWithinFigure,\n eraseStrandWithinLoop,\n} from \"./algorithms/boolean/strandBoolean\";\nimport { Stroke } from \"./main\";\n\nexport function fuse(\n first: Diagram | Figure | Loop,\n second: Diagram | Figure | Loop,\n): Diagram {\n return new Diagram(\n fuseFiguresLists(listOfFigures(first), listOfFigures(second)),\n );\n}\n\nexport function fuseAll(shapes: (Diagram | Figure | Loop)[]): Diagram {\n return shapes.reduce(\n (acc: Diagram, shape: Diagram | Figure | Loop) => fuse(acc, shape),\n new Diagram(),\n );\n}\n\nexport function cut(\n first: Diagram | Figure | Loop,\n second: Diagram | Figure | Loop,\n): Diagram {\n return new Diagram(\n cutFiguresLists(listOfFigures(first), listOfFigures(second)),\n );\n}\n\nexport function intersect(\n first: Diagram | Figure | Loop,\n second: Diagram | Figure | Loop,\n): Diagram {\n return new Diagram(\n intersectFiguresLists(listOfFigures(first), listOfFigures(second)),\n );\n}\n\nexport function eraseStrand(\n strand: Stroke,\n diagram: Diagram | Figure | Loop,\n eraseOnBorder = true,\n): Strand[] {\n if (diagram instanceof Loop) {\n return eraseStrandWithinLoop(strand, diagram, eraseOnBorder);\n }\n\n if (diagram instanceof Figure) {\n return eraseStrandWithinFigure(strand, diagram, eraseOnBorder);\n }\n\n let outStrands: Strand[] = [new Strand([...strand.segments])];\n diagram.figures.forEach((figure: Figure) => {\n outStrands = outStrands.flatMap((strand: Strand) => {\n return eraseStrandWithinFigure(strand, figure, eraseOnBorder);\n });\n });\n\n return outStrands;\n}\n\nexport function confineStrand(\n strand: Stroke,\n diagram: Diagram | Figure | Loop,\n eraseOnBorder = false,\n): Strand[] {\n if (diagram instanceof Loop) {\n return eraseStrandOutsideLoop(strand, diagram, eraseOnBorder);\n }\n\n if (diagram instanceof Figure) {\n return eraseStrandOutsideFigure(strand, diagram, eraseOnBorder);\n }\n\n let outStrands: Strand[] = [new Strand([...strand.segments])];\n diagram.figures.forEach((figure: Figure) => {\n outStrands = outStrands.flatMap((strand: Strand) => {\n return eraseStrandOutsideFigure(strand, figure, eraseOnBorder);\n });\n });\n\n return outStrands;\n}\n","import { lineLineParams } from \"../intersections/lineLineIntersection.js\";\nimport type { Line } from \"../../models/segments/Line.js\";\nimport { distance } from \"../../vectorOperations.js\";\n\nfunction segmentPosition(intersectionParam: number) {\n if (intersectionParam < 0) return \"before\";\n if (intersectionParam > 1) return \"after\";\n return \"between\";\n}\n\nconst handleBetween = (\n lineBetween: Line,\n otherLine: Line,\n otherPosition: \"before\" | \"after\",\n) => {\n if (otherPosition === \"before\")\n return lineBetween.distanceFrom(otherLine.firstPoint);\n else if (otherPosition === \"after\")\n return lineBetween.distanceFrom(otherLine.lastPoint);\n else throw new Error(\"Invalid position\");\n};\n\nexport function lineLineDistance(line1: Line, line2: Line): number {\n const intersectionParams = lineLineParams(line1, line2);\n\n if (intersectionParams === \"parallel\") {\n return Math.min(\n line1.distanceFrom(line2.firstPoint),\n line1.distanceFrom(line2.lastPoint),\n );\n }\n\n const { intersectionParam1, intersectionParam2 } = intersectionParams;\n\n const firstPosition = segmentPosition(intersectionParam1);\n const secondPosition = segmentPosition(intersectionParam2);\n\n if (firstPosition === \"between\" && secondPosition === \"between\") {\n return 0;\n } else if (firstPosition === \"between\" && secondPosition !== \"between\") {\n return handleBetween(line1, line2, secondPosition);\n } else if (secondPosition === \"between\" && firstPosition !== \"between\") {\n return handleBetween(line2, line1, firstPosition);\n } else if (firstPosition === \"before\" && secondPosition === \"before\") {\n return distance(line1.firstPoint, line2.firstPoint);\n } else if (firstPosition === \"after\" && secondPosition === \"after\") {\n return distance(line1.lastPoint, line2.lastPoint);\n } else if (firstPosition === \"before\" && secondPosition === \"after\") {\n return distance(line1.firstPoint, line2.lastPoint);\n } else if (firstPosition === \"after\" && secondPosition === \"before\") {\n return distance(line1.lastPoint, line2.firstPoint);\n } else {\n throw new Error(\"Invalid position\");\n }\n}\n","import type { Line } from \"../../models/segments/Line.js\";\nimport type { Arc } from \"../../models/segments/Arc.js\";\nimport {\n normalize,\n subtract,\n distance,\n add,\n scalarMultiply,\n} from \"../../vectorOperations\";\nimport { projectPointOnLine } from \"../../utils/projectPointOnLine.js\";\nimport { lineArcIntersection } from \"../intersections/lineArcIntersection.js\";\n\nexport function lineArcDistance(line: Line, arc: Arc): number {\n // We might be able to optimise this if necessary\n\n if (lineArcIntersection(line, arc).length > 0) {\n return 0;\n }\n\n const closestPointOnLine = projectPointOnLine(line, arc.center);\n\n if (line.isOnSegment(closestPointOnLine)) {\n const circleCenterLineDistance = distance(closestPointOnLine, arc.center);\n\n // The line is tangent to the circle\n if (Math.abs(circleCenterLineDistance - arc.radius) < line.precision) {\n if (arc.isOnSegment(closestPointOnLine)) {\n return 0;\n }\n }\n\n if (circleCenterLineDistance - arc.radius > line.precision) {\n const centerLineDirection = normalize(\n subtract(closestPointOnLine, arc.center),\n );\n\n const closestPointOnCircle = add(\n arc.center,\n scalarMultiply(centerLineDirection, arc.radius),\n );\n\n if (arc.isOnSegment(closestPointOnCircle)) {\n return distance(closestPointOnCircle, closestPointOnLine);\n }\n }\n }\n\n return Math.min(\n arc.distanceFrom(line.firstPoint),\n arc.distanceFrom(line.lastPoint),\n line.distanceFrom(arc.firstPoint),\n line.distanceFrom(arc.lastPoint),\n );\n}\n","import {\n distance,\n normalize,\n polarAngle,\n subtract,\n} from \"../../vectorOperations\";\nimport type { Arc } from \"../../models/segments/Arc.js\";\nimport { arcArcIntersection } from \"../intersections/arcArcIntersection.js\";\n\nconst overlappingAngles = (arc1: Arc, arc2: Arc): boolean => {\n const p1 = arc1.angleToParam(arc2.firstAngle);\n if (arc1.isValidParameter(p1)) return true;\n\n const p2 = arc1.angleToParam(arc2.lastAngle);\n if (arc1.isValidParameter(p2)) return true;\n return false;\n};\n\nexport function arcArcDistance(arc1: Arc, arc2: Arc): number {\n if (arcArcIntersection(arc1, arc2, true).length > 0) return 0;\n\n const centersDistance = distance(arc1.center, arc2.center);\n\n if (centersDistance < arc1.precision) {\n if (overlappingAngles(arc1, arc2)) {\n return Math.abs(arc1.radius - arc2.radius);\n }\n }\n\n const centerCenterDirection = normalize(subtract(arc2.center, arc1.center));\n\n const containedCircles =\n centersDistance - Math.abs(arc1.radius - arc2.radius) < arc1.precision;\n\n let arc1ClosestPointAngle = polarAngle(centerCenterDirection);\n if (containedCircles && arc2.radius > arc1.radius) {\n arc1ClosestPointAngle += Math.PI;\n }\n const arc2ClosestPointAngle = containedCircles\n ? arc1ClosestPointAngle\n : arc1ClosestPointAngle + Math.PI;\n\n const p1 = arc1.angleToParam(arc1ClosestPointAngle);\n const p2 = arc2.angleToParam(arc2ClosestPointAngle);\n\n if (arc1.isValidParameter(p1) && arc2.isValidParameter(p2)) {\n // There might be some optimization here (with the center distance and radius differences)\n return distance(arc1.paramPoint(p1), arc2.paramPoint(p2));\n }\n\n return Math.min(\n arc1.distanceFrom(arc2.firstPoint),\n arc1.distanceFrom(arc2.lastPoint),\n arc2.distanceFrom(arc1.firstPoint),\n arc2.distanceFrom(arc1.lastPoint),\n );\n}\n","// An implementation of the direct algorithm for computing the global minimum of\n// a funciton defined between 0 and 1. The algorithm is described in:\n// Jones, D.R., Perttunen, C.D. and Stuckman, B.E., 1993. Lipschitzian\n// optimization without the Lipschitz constant. Journal of Optimization Theory\n// and Applications, 79(1), pp.157-181.\n//\n// Also inspired by the implementation in the Direct package for rust\n// https://gitlab.com/blei42/direct\n\nfunction binarySearch<T>(\n array: T[],\n value: T,\n comparator: (a: T, b: T) => number,\n): number {\n let low = 0;\n let high = array.length - 1;\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const cmp = comparator(array[mid], value);\n if (cmp < 0) {\n low = mid + 1;\n } else if (cmp > 0) {\n high = mid - 1;\n } else {\n return mid;\n }\n }\n return -(low + 1);\n}\n\nfunction binaryInsert<T>(\n array: T[],\n value: T,\n comparator: (a: T, b: T) => number,\n) {\n const index = binarySearch(array, value, comparator);\n if (index < 0) {\n array.splice(-(index + 1), 0, value);\n } else {\n array.splice(index, 0, value);\n }\n}\n\nclass DiagonalBuckets {\n public readonly buckets: Interval[][];\n constructor() {\n this.buckets = [];\n }\n\n addInterval(interval: Interval) {\n const bucket = this.buckets[interval.rectangle.diagonalBucketIndex];\n if (bucket === undefined) {\n this.buckets[interval.rectangle.diagonalBucketIndex] = [interval];\n } else {\n binaryInsert(bucket, interval, (a, b) => a.value - b.value);\n }\n }\n\n removeInterval(interval: Interval) {\n const bucket = this.buckets[interval.rectangle.diagonalBucketIndex];\n if (bucket === undefined) {\n throw new Error(\"Interval not found\");\n }\n bucket.shift();\n }\n\n getBottomRightHullIntervals(): Interval[] {\n const intervals: Interval[] = [];\n for (let i = this.buckets.length - 1; i >= 0; i--) {\n const bucket = this.buckets[i];\n\n if (!bucket === undefined) continue;\n const interval = bucket[0];\n if (interval === undefined) continue;\n\n if (!intervals.length) {\n intervals.push(interval);\n continue;\n }\n\n // We want to keep only the right bottom hull of the intervals\n\n // First, we remove intervals with a bigger value\n while (\n intervals.length &&\n intervals[intervals.length - 1].value >= interval.value\n ) {\n intervals.pop();\n }\n\n // Then, we remove intervals that are covered by the previous interval\n // and the last updated\n while (intervals.length >= 2) {\n const lastInterval = intervals[intervals.length - 1];\n const secondToLastInterval = intervals[intervals.length - 2];\n\n const slope =\n (interval.value - secondToLastInterval.value) /\n ((interval.rectangle.diagonal -\n secondToLastInterval.rectangle.diagonal) *\n 2);\n const comparison =\n secondToLastInterval.value +\n ((lastInterval.rectangle.diagonal -\n secondToLastInterval.rectangle.diagonal) /\n 2.0) *\n slope;\n\n if (comparison < lastInterval.value) {\n intervals.pop();\n } else {\n break;\n }\n }\n\n intervals.push(interval);\n }\n\n return intervals;\n }\n}\n\nclass DivisionRectangle {\n public diagonal: number;\n public diagonalBucketIndex: number;\n\n public xLength: number;\n public yLength: number;\n\n public index: string;\n\n constructor(\n public x: number,\n public y: number,\n ) {\n this.xLength = Math.pow(3, -x);\n this.yLength = Math.pow(3, -y);\n\n this.diagonal = Math.sqrt(\n this.xLength * this.xLength + this.yLength * this.yLength,\n );\n this.diagonalBucketIndex = x + y;\n\n this.index = `${x},${y}`;\n }\n}\n\nexport class DiRectOptimisation {\n private rectangles: Map<string, DivisionRectangle>;\n private buckets: DiagonalBuckets;\n\n public fMin;\n public argMin;\n public tol;\n\n constructor(\n public fcn: ([x, y]: [number, number]) => number,\n public endTolerance = 1e-8,\n public maxIterations = 1000,\n public epsilon = 1e-6,\n ) {\n this.fcn = fcn;\n this.epsilon = epsilon;\n this.endTolerance = endTolerance;\n this.maxIterations = maxIterations;\n\n this.rectangles = new Map();\n this.buckets = new DiagonalBuckets();\n\n const center: [number, number] = [0.5, 0.5];\n const rect = this.rect(0, 0);\n const value = this.fcn(center);\n\n this.buckets.addInterval(new Interval(center, value, rect));\n this.fMin = value;\n this.argMin = center;\n this.tol = rect.diagonal;\n }\n\n registerInterval(interval: Interval) {\n this.buckets.addInterval(interval);\n if (interval.value <= this.fMin) {\n this.fMin = interval.value;\n this.argMin = interval.center;\n this.tol = interval.rectangle.diagonal;\n }\n }\n\n rect(x: number, y: number): DivisionRectangle {\n const index = `${x},${y}`;\n if (!this.rectangles.has(index)) {\n this.rectangles.set(index, new DivisionRectangle(x, y));\n }\n return this.rectangles.get(index)!;\n }\n\n splitInterval(interval: Interval): [Interval, Interval, Interval] {\n let rect: DivisionRectangle;\n let leftCenter: [number, number], rightCenter: [number, number];\n\n const [x, y] = interval.center;\n\n if (interval.rectangle.x <= interval.rectangle.y) {\n rect = this.rect(interval.rectangle.x + 1, interval.rectangle.y);\n leftCenter = [x - rect.xLength, y];\n rightCenter = [x + rect.xLength, y];\n } else {\n rect = this.rect(interval.rectangle.x, interval.rectangle.y + 1);\n leftCenter = [x, y - rect.yLength];\n rightCenter = [x, y + rect.yLength];\n }\n\n return [\n new Interval(leftCenter, this.fcn(leftCenter), rect),\n new Interval(interval.center, interval.value, rect),\n new Interval(rightCenter, this.fcn(rightCenter), rect),\n ];\n }\n\n single_iteration() {\n const intervals = this.buckets.getBottomRightHullIntervals();\n\n // We want to only keep the intervals that can significantly improve the\n // minimum\n\n while (intervals.length >= 2) {\n // Look at the left-most point, it's most heavily constrained by both slope and\n // possible distance.\n const i1 = intervals[0];\n const i2 = intervals[1];\n\n const k =\n (i2.value - i1.value) /\n ((i2.rectangle.diagonal - i1.rectangle.diagonal) / 2.0);\n const potentialFMin = i1.value - (k * i2.value) / 2.0;\n if ((this.fMin - potentialFMin) / Math.abs(this.fMin) < this.epsilon) {\n intervals.shift();\n } else {\n // The points to the right are even better than this one, bail out.\n break;\n }\n }\n\n intervals.forEach((interval) => {\n this.buckets.removeInterval(interval);\n });\n\n for (const interval of intervals) {\n const [left, middle, right] = this.splitInterval(interval);\n\n this.registerInterval(left);\n this.registerInterval(middle);\n this.registerInterval(right);\n }\n }\n\n run() {\n let i = 0;\n while (this.tol > this.endTolerance / 2) {\n this.single_iteration();\n i++;\n if (i > this.maxIterations) {\n break;\n }\n }\n return {\n fMin: this.fMin,\n argMin: this.argMin,\n tol: this.tol,\n iterations: i,\n };\n }\n}\n\nclass Interval {\n constructor(\n public center: [number, number],\n public value: number,\n public rectangle: DivisionRectangle,\n ) {}\n}\n\nexport function findGlobalMinimum(\n fun: (x: [number, number]) => number,\n tolerance = 1e-8,\n maxIterations = 1000,\n epsilon = 1e-6,\n) {\n const optimiser = new DiRectOptimisation(\n fun,\n tolerance,\n maxIterations,\n epsilon,\n );\n return optimiser.run();\n}\n","import { Vector } from \"../../definitions.js\";\nimport { squareDistance } from \"../../vectorOperations.js\";\nimport { findGlobalMinimum } from \"../optimisation/DiRect.js\";\n\ninterface WithParamPoint {\n paramPoint(t: number): Vector;\n}\n\nexport function genericDistance(\n segment1: WithParamPoint,\n segment2: WithParamPoint,\n precision = 1e-9,\n): number {\n const result = findGlobalMinimum((t) => {\n const p1 = segment1.paramPoint(t[0]);\n const p2 = segment2.paramPoint(t[1]);\n return squareDistance(p1, p2);\n }, precision);\n return Math.sqrt(result.fMin);\n}\n","import { Line } from \"../../models/segments/Line.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { lineLineDistance } from \"./lineLineDistance.js\";\nimport { lineArcDistance } from \"./lineArcDistance.js\";\nimport { arcArcDistance } from \"./arcArcDistance.js\";\nimport type { Segment } from \"../../models/segments/Segment.js\";\nimport { genericDistance } from \"./genericDistance.js\";\n\nexport function distance(segment1: Segment, segment2: Segment): number {\n if (segment1 instanceof Line && segment2 instanceof Line) {\n return lineLineDistance(segment1, segment2);\n }\n\n if (segment1 instanceof Line && segment2 instanceof Arc) {\n return lineArcDistance(segment1, segment2);\n }\n\n if (segment1 instanceof Arc && segment2 instanceof Line) {\n return lineArcDistance(segment2, segment1);\n }\n\n if (segment1 instanceof Arc && segment2 instanceof Arc) {\n return arcArcDistance(segment1, segment2);\n }\n\n return genericDistance(segment1, segment2);\n}\n","import { Line } from \"../../models/segments/Line.js\";\nimport { Loop } from \"../../models/Loop.js\";\nimport { Segment } from \"../../models/segments/Segment.js\";\nimport {\n crossProduct,\n sameVector,\n squareDistance,\n subtract,\n} from \"../../vectorOperations\";\nimport { distance } from \"../distances\";\nimport { offsetSegment, DegenerateSegment } from \"./offsetSegment.js\";\nimport { Vector } from \"../../definitions.js\";\nimport { Arc, tangentArc } from \"../../models/segments/Arc.js\";\nimport { Diagram } from \"../../models/Diagram.js\";\nimport { findIntersectionsAndOverlaps } from \"../intersections\";\nimport { Figure } from \"../../models/Figure.js\";\nimport { stitchSegments } from \"../stitchSegments.js\";\nimport { Stroke } from \"../../models/Stroke.js\";\nimport { Strand } from \"../../models/Strand.js\";\n\nconst PRECISION = 1e-8;\n\nexport function rawOffsets(\n segmentsToOffset: Segment[],\n offset: number,\n loop = true,\n): Segment[] {\n const offsetSegments: OffsetSegmentPair[] = segmentsToOffset.map((c) => ({\n offset: offsetSegment(c, offset),\n original: c,\n }));\n\n // Ideally we would use the length of the segment to make sure it is\n // not only a point, but the algo we have access to are a bit to\n // convoluted to be usable here\n\n const offsettedArray: Segment[] = [];\n\n let savedLastSegment = loop ? null : offsetSegments.at(-1)!;\n\n let previousSegment = loop ? offsetSegments.at(-1) : null;\n\n // We have no offseted segments\n if (offsettedArray.length === 1) return offsettedArray;\n\n const appendSegment = (segment: OffsetSegmentPair) => {\n if (!savedLastSegment) {\n savedLastSegment = segment;\n } else if (!(segment.offset instanceof DegenerateSegment)) {\n offsettedArray.push(segment.offset);\n } else if (\n !sameVector(segment.offset.firstPoint, segment.offset.lastPoint)\n ) {\n offsettedArray.push(\n new Line(segment.offset.firstPoint, segment.offset.lastPoint),\n );\n }\n };\n const iterateOffsetSegments = function* (): Generator<OffsetSegmentPair> {\n for (const segment of offsetSegments.slice(0, -1)) {\n yield segment;\n }\n // This should never happen\n if (!savedLastSegment) throw new Error(\"Bug in the offset algorithm\");\n yield savedLastSegment;\n };\n\n for (const segment of iterateOffsetSegments()) {\n if (!previousSegment) {\n previousSegment = segment;\n continue;\n }\n const previousLastPoint = previousSegment.offset.lastPoint;\n const firstPoint = segment.offset.firstPoint;\n\n // When the offset segments do still touch we do nothing\n if (sameVector(previousLastPoint, firstPoint)) {\n appendSegment(previousSegment);\n previousSegment = segment;\n continue;\n }\n\n let intersections: Vector[] = [];\n\n if (\n !(previousSegment.offset instanceof DegenerateSegment) &&\n !(segment.offset instanceof DegenerateSegment)\n ) {\n // When the offset segments intersect we cut them and save them at\n const { intersections: pointIntersections, overlaps } =\n findIntersectionsAndOverlaps(\n previousSegment.offset,\n segment.offset,\n PRECISION / 100,\n );\n intersections = [\n ...pointIntersections,\n ...overlaps.flatMap((c) => [c.firstPoint, c.lastPoint]),\n ];\n }\n\n if (intersections.length > 0) {\n let intersection = intersections[0];\n if (intersections.length > 1) {\n // We choose the intersection point the closest to the end of the\n // original segment endpoint (why? not sure, following\n // https://github.com/jbuckmccready/cavalier_contours/)\n\n const originalEndpoint = previousSegment?.original.lastPoint;\n const distances = intersections.map((i) =>\n squareDistance(i, originalEndpoint),\n );\n intersection = intersections[distances.indexOf(Math.min(...distances))];\n }\n\n // We need to be a lot more careful here with multiple intersections\n // as well as cases where segments overlap\n\n const splitPreviousSegment = (previousSegment.offset as Segment).splitAt([\n intersection,\n ])[0];\n const splitSegment = (segment.offset as Segment)\n .splitAt([intersection])\n .at(-1);\n\n if (!splitSegment) throw new Error(\"Bug in the splitting algo in offset\");\n\n appendSegment({\n offset: splitPreviousSegment,\n original: previousSegment.original,\n });\n previousSegment = { offset: splitSegment, original: segment.original };\n continue;\n }\n\n // When the offset segments do not intersect we link them with an arc of\n // radius offset\n const center = previousSegment.original.lastPoint;\n const clockwise =\n crossProduct(\n subtract(firstPoint, center),\n subtract(previousLastPoint, center),\n ) > 0;\n\n const joiner = new Arc(previousLastPoint, firstPoint, center, clockwise);\n\n appendSegment(previousSegment);\n offsettedArray.push(joiner);\n previousSegment = segment;\n }\n\n if (previousSegment) appendSegment(previousSegment);\n return offsettedArray;\n}\n\ninterface OffsetSegmentPair {\n offset: Segment | DegenerateSegment;\n original: Segment;\n}\n\nfunction findOffsetSelfIntersections(\n segments: Segment[],\n): Map<number, Vector[]> {\n // We remove the self intersections with the use the the algorithm as described in\n // https://github.com/jbuckmccready/CavalierContours#offset-algorithm-and-stepwise-example\n\n const allIntersections: Map<number, Vector[]> = new Map();\n const updateIntersections = (index: number, newPoints: Vector[]) => {\n const intersections = allIntersections.get(index) || [];\n allIntersections.set(index, [...intersections, ...newPoints]);\n };\n\n segments.forEach((firstSegment, firstIndex) => {\n segments.slice(firstIndex + 1).forEach((secondSegment, secondIndex) => {\n const { intersections: rawIntersections, overlaps } =\n findIntersectionsAndOverlaps(firstSegment, secondSegment, PRECISION);\n\n const intersections = [\n ...rawIntersections,\n ...overlaps.flatMap((c) => [c.firstPoint, c.lastPoint]),\n ].filter((intersection) => {\n const onFirstSegmentExtremity =\n sameVector(intersection, firstSegment.firstPoint) ||\n sameVector(intersection, firstSegment.lastPoint);\n\n const onSecondSegmentExtremity =\n sameVector(intersection, secondSegment.firstPoint) ||\n sameVector(intersection, secondSegment.lastPoint);\n\n return !(onFirstSegmentExtremity && onSecondSegmentExtremity);\n });\n\n if (!intersections.length) return;\n\n updateIntersections(firstIndex, intersections);\n updateIntersections(secondIndex + firstIndex + 1, intersections);\n });\n });\n\n return allIntersections;\n}\n\nfunction findIntersections(\n segments: Segment[],\n intersectWith: Segment[],\n): Map<number, Vector[]> {\n const allIntersections: Map<number, Vector[]> = new Map();\n const updateIntersections = (index: number, newPoints: Vector[]) => {\n const intersections = allIntersections.get(index) || [];\n allIntersections.set(index, [...intersections, ...newPoints]);\n };\n\n segments.forEach((firstSegment, firstIndex) => {\n intersectWith.forEach((segmentsToCheck) => {\n const { intersections: rawIntersections, overlaps } =\n findIntersectionsAndOverlaps(firstSegment, segmentsToCheck, PRECISION);\n\n const intersections = [\n ...rawIntersections,\n ...overlaps.flatMap((c) => [c.firstPoint, c.lastPoint]),\n ].filter((intersection) => {\n return (\n sameVector(intersection, firstSegment.firstPoint) ||\n sameVector(intersection, firstSegment.lastPoint)\n );\n });\n\n if (!intersections.length) return;\n\n updateIntersections(firstIndex, intersections);\n });\n });\n\n return allIntersections;\n}\n\nfunction findEndIntersections(\n segments: Segment[],\n strand: Strand,\n offset: number,\n) {\n const circle = new Loop([\n new Arc([-offset, 0], [offset, 0], [0, 0], true),\n new Arc([offset, 0], [-offset, 0], [0, 0], true),\n ]);\n\n const startCircle = circle.translateTo(strand.firstPoint);\n const endCircle = circle.translateTo(strand.lastPoint);\n\n return findIntersections(segments, [\n ...startCircle.segments,\n ...endCircle.segments,\n ]);\n}\n\nfunction mergeIntersectionMaps(maps: Map<number, Vector[]>[]) {\n const mergedMap = new Map<number, Vector[]>(maps[0]);\n maps.forEach((map) => {\n for (const [key, value] of map) {\n const previousValue = mergedMap.get(key) || [];\n mergedMap.set(key, [...previousValue, ...value]);\n }\n });\n return mergedMap;\n}\n\nfunction splitSegmentsAtIntersections(\n intersections: Map<number, Vector[]>,\n segments: Segment[],\n): Segment[] {\n return segments.flatMap((segment, index) => {\n if (!intersections.has(index)) return segment;\n\n const segmentIntersections = intersections.get(index);\n if (!segmentIntersections) return segment;\n\n return segment.splitAt(segmentIntersections);\n });\n}\n\nfunction pruneDegenerateSegments(\n segments: Segment[],\n originalStroke: Stroke,\n offset: number,\n): Segment[] {\n // We remove all the segments that are closer to the original segment than the offset\n return segments.filter((segment) => {\n const closeSegment = originalStroke.segments.some((c) => {\n return distance(c, segment) < Math.abs(offset) - PRECISION;\n });\n return !closeSegment;\n });\n}\n\nexport function offsetLoop(loop: Loop, offset: number): Diagram {\n const correctedOffset = loop.clockwise ? offset : -offset;\n const offsettedArray = rawOffsets(loop.segments, correctedOffset);\n\n if (offsettedArray.length < 2) return new Diagram();\n\n // We remove the self intersections with the use the the algorithm as described in\n // https://github.com/jbuckmccready/CavalierContours#offset-algorithm-and-stepwise-example\n\n const allIntersections = findOffsetSelfIntersections(offsettedArray);\n\n if (!allIntersections.size) {\n const offsettedLoop = new Loop(offsettedArray);\n return new Diagram([new Figure(offsettedLoop)]);\n /* this was in the replicad algorithm - not sure why\n if (!loop.intersects(offsettedLoop)) return offsettedLoop;\n return new Diagram();\n */\n }\n const splitSegments = splitSegmentsAtIntersections(\n allIntersections,\n offsettedArray,\n );\n\n // We remove all the segments that are closer to the original segment than the offset\n const prunedSegments = pruneDegenerateSegments(splitSegments, loop, offset);\n\n if (!prunedSegments.length) return new Diagram();\n\n const segmentsGrouped = stitchSegments(prunedSegments);\n\n const newLoops = segmentsGrouped\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 if (!newLoops.length) return new Diagram();\n return new Diagram(newLoops.map((l) => new Figure(l)));\n}\n\nexport function offsetStrand(strand: Strand, offset: number): Stroke[] {\n const offsettedArray = rawOffsets(strand.segments, offset, false);\n const backOffsettedArray = rawOffsets(strand.segments, -offset, false);\n\n // We remove the self intersections with the use the the algorithm as described in\n // https://github.com/jbuckmccready/CavalierContours#offset-algorithm-and-stepwise-example\n\n const allIntersections = mergeIntersectionMaps([\n findOffsetSelfIntersections(offsettedArray),\n findIntersections(offsettedArray, backOffsettedArray),\n findEndIntersections(offsettedArray, strand, offset),\n ]);\n\n if (!allIntersections.size) {\n return [new Strand(offsettedArray)];\n }\n const splitSegments = splitSegmentsAtIntersections(\n allIntersections,\n offsettedArray,\n );\n\n // We remove all the segments that are closer to the original segment than the offset\n const prunedSegments = pruneDegenerateSegments(splitSegments, strand, offset);\n\n if (!prunedSegments.length) return [];\n\n const segmentsGrouped = stitchSegments(prunedSegments);\n\n return segmentsGrouped.map((c) => {\n if (sameVector(c[0].firstPoint, c.at(-1)!.lastPoint)) return new Loop(c);\n return new Strand(c);\n });\n}\n\nexport function outlineStrand(\n strand: Strand,\n width: number,\n endCap: \"round\" | \"butt\" = \"round\",\n): Diagram {\n const offset = width / 2;\n const frontOffsettedArray = rawOffsets(strand.segments, offset, false);\n const backOffsettedArray = rawOffsets(strand.segments, -offset, false).map(\n (s) => s.reverse(),\n );\n backOffsettedArray.reverse();\n\n const makeJoiner = (fromSegment: Segment, toSegment: Segment) => {\n if (endCap === \"round\") {\n return tangentArc(\n fromSegment.lastPoint,\n toSegment.firstPoint,\n fromSegment.tangentAtLastPoint,\n );\n }\n return new Line(fromSegment.lastPoint, toSegment.firstPoint);\n };\n\n const offsettedArray = [\n ...frontOffsettedArray,\n makeJoiner(\n frontOffsettedArray[frontOffsettedArray.length - 1],\n backOffsettedArray[0],\n ),\n ...backOffsettedArray,\n makeJoiner(\n backOffsettedArray[backOffsettedArray.length - 1],\n frontOffsettedArray[0],\n ),\n ];\n\n const allIntersections = findOffsetSelfIntersections(offsettedArray);\n\n if (!allIntersections.size) {\n const offsettedLoop = new Loop(offsettedArray);\n return new Diagram([new Figure(offsettedLoop)]);\n }\n const splitSegments = splitSegmentsAtIntersections(\n allIntersections,\n offsettedArray,\n );\n\n // We remove all the segments that are closer to the original segment than the offset\n const prunedSegments = pruneDegenerateSegments(splitSegments, strand, offset);\n\n if (!prunedSegments.length) return new Diagram();\n\n const segmentsGrouped = stitchSegments(prunedSegments);\n\n const newLoops = segmentsGrouped\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 if (!newLoops.length) return new Diagram();\n return new Diagram(newLoops.map((l) => new Figure(l)));\n}\n","import { Figure } from \"../../models/Figure\";\nimport { Diagram } from \"../../models/Diagram\";\nimport { cut, fuseAll } from \"../../booleanOperations\";\nimport { offsetLoop } from \"./offsetStroke\";\n\nexport function offsetFigures(\n figures: Figure[],\n offsetDistance: number,\n): Diagram {\n const offsetFigures = figures.map((figure) => {\n const innerShape = fuseAll(\n figure.holes.map((l) => offsetLoop(l, offsetDistance)),\n );\n return cut(offsetLoop(figure.contour, offsetDistance), innerShape);\n });\n\n return fuseAll(offsetFigures);\n}\n\nexport function outlineStrokeFigures(\n figures: Figure[],\n width: number,\n): Diagram {\n const absOffset = Math.abs(width / 2);\n\n const offsetFigures = figures.map((figure) =>\n fuseAll(\n figure.allLoops.map((l) => {\n return cut(offsetLoop(l, absOffset), offsetLoop(l, -absOffset));\n }),\n ),\n );\n\n return fuseAll(offsetFigures);\n}\n","import {\n offsetFigures,\n outlineStrokeFigures,\n} from \"./algorithms/offsets/offsetFigure\";\nimport { outlineStrand } from \"./algorithms/offsets/offsetStroke.js\";\nimport { Strand } from \"./models/Strand.js\";\nimport { Diagram } from \"./models/Diagram.js\";\nimport { Figure } from \"./models/Figure.js\";\nimport { Loop } from \"./models/Loop.js\";\nimport { listOfFigures } from \"./utils/listOfFigures.js\";\n\nexport function offset(\n shape: Diagram | Figure | Loop,\n offsetDistance: number,\n): Diagram {\n return offsetFigures(listOfFigures(shape), offsetDistance);\n}\n\nexport function outlineStroke(\n shape: Diagram | Figure | Loop | Strand,\n outlineDistance: number,\n { endCap = \"round\" }: { endCap?: \"butt\" | \"round\" } = {},\n): Diagram {\n if (shape instanceof Strand) {\n return outlineStrand(shape, outlineDistance, endCap);\n }\n return outlineStrokeFigures(listOfFigures(shape), outlineDistance);\n}\n","import { Strand } from \"../../models/Strand.js\";\nimport { Diagram } from \"../../models/Diagram.js\";\nimport { Figure } from \"../../models/Figure.js\";\nimport { Loop } from \"../../models/Loop.js\";\nimport { BoundingBox } from \"../../models/BoundingBox.js\";\nimport { svgDiagram } from \"./svgDiagram.js\";\nimport { svgFigure } from \"./svgFigure.js\";\nimport { svgLoop } from \"./svgLoop.js\";\nimport { svgSegmentToPath } from \"./svgSegment.js\";\nimport { svgStrand } from \"./svgStrand.js\";\nimport { SVGUnit, wrapSVG } from \"./wrapSVG.js\";\nimport type { Stroke } from \"../../models/Stroke.js\";\nimport { Segment } from \"../../main.js\";\nimport { isSegment } from \"../../models/segments/utils/isSegment.js\";\n\ntype Shape = Figure | Diagram | Stroke | Segment;\n\nexport function svgBody(shape: Shape) {\n if (shape instanceof Diagram) {\n return svgDiagram(shape);\n } else if (shape instanceof Figure) {\n return svgFigure(shape);\n } else if (shape instanceof Loop) {\n return `<path d=\"${svgLoop(shape)}\" />`;\n } else if (shape instanceof Strand) {\n return `<path d=\"${svgStrand(shape)}\" />`;\n } else if (isSegment(shape)) {\n return `<path d=\"${`M ${shape.firstPoint.join(\" \")}`} ${svgSegmentToPath(\n shape,\n )}\" />`;\n } else {\n throw new Error(\"Unknown shape type\");\n }\n}\n\ntype ConfiguredShape = Shape | { shape: Shape; color?: string };\n\nconst extractShape = (shape: ConfiguredShape) =>\n \"shape\" in shape ? shape.shape : shape;\n\nconst addConfig = (shape: ConfiguredShape, body: string) => {\n if (!(\"shape\" in shape)) return body;\n const { color } = shape;\n if (!color) return body;\n return `<g stroke=\"${color}\">${body}</g>`;\n};\n\nconst flibBbox = (bbox: BoundingBox) => {\n return new BoundingBox(bbox.xMin, -bbox.yMax, bbox.xMax, -bbox.yMin);\n};\n\nexport function exportSVG(\n shape: ConfiguredShape | ConfiguredShape[],\n {\n margin = 1,\n unit = null,\n viewBox,\n }: {\n margin?: number;\n unit?: null | SVGUnit;\n viewBox?: BoundingBox;\n } = {},\n) {\n if (Array.isArray(shape)) {\n const flipped = shape.map((s) => extractShape(s).mirror());\n const body = flipped\n .map((s, i) => addConfig(shape[i], svgBody(s)))\n .join(\"\\n\");\n const bbox = flipped\n .slice(1)\n .reduce((bbox, s) => bbox.merge(s.boundingBox), flipped[0].boundingBox);\n\n return wrapSVG(body, viewBox ? flibBbox(viewBox) : bbox, margin, unit);\n }\n const flipped = extractShape(shape).mirror();\n return wrapSVG(\n addConfig(shape, svgBody(flipped)),\n viewBox ? flibBbox(viewBox) : flipped.boundingBox,\n margin,\n unit,\n );\n}\n","import { Line } from \"../../models/segments/Line.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { Loop } from \"../../models/Loop.js\";\nimport { Figure } from \"../../models/Figure.js\";\nimport { Diagram } from \"../../models/Diagram.js\";\nimport { EllipseArc } from \"../../models/segments/EllipseArc.js\";\nimport { CubicBezier } from \"../../models/segments/CubicBezier.js\";\nimport { QuadraticBezier } from \"../../models/segments/QuadraticBezier.js\";\n\nconst importSegment = (json: any) => {\n if (json.type === \"LINE\") {\n return new Line(json.firstPoint, json.lastPoint);\n }\n if (json.type === \"ARC\") {\n return new Arc(\n json.firstPoint,\n json.lastPoint,\n json.center,\n json.clockwise,\n );\n }\n if (json.type === \"ELLIPSE_ARC\") {\n return new EllipseArc(\n json.firstPoint,\n json.lastPoint,\n json.center,\n json.majorRadius,\n json.minorRadius,\n json.tiltAngle,\n json.clockwise,\n { angleUnits: \"rad\" },\n );\n }\n if (json.type === \"QUADRATIC_BEZIER\") {\n return new QuadraticBezier(\n json.firstPoint,\n json.lastPoint,\n json.controlPoint,\n );\n }\n if (json.type === \"CUBIC_BEZIER\") {\n return new CubicBezier(\n json.firstPoint,\n json.lastPoint,\n json.firstControlPoint,\n json.lastControlPoint,\n );\n }\n throw new Error(\"Unknown segment type\");\n};\n\nconst importLoop = (json: any) => {\n const segments = json.segments.map(importSegment);\n return new Loop(segments);\n};\n\nconst importFigure = (json: any) => {\n const contour = importLoop(json.contour);\n const holes = json.holes.map(importLoop);\n return new Figure(contour, holes);\n};\n\nconst importDiagram = (json: any) => {\n const figures = json.figures.map(importFigure);\n return new Diagram(figures);\n};\n\nexport function importJSON(json: any) {\n if (json.type === \"DIAGRAM\") {\n return importDiagram(json);\n }\n if (json.type === \"FIGURE\") {\n return importFigure(json);\n }\n if (json.type === \"LOOP\") {\n return importLoop(json);\n }\n if (\n json.type === \"LINE\" ||\n json.type === \"ARC\" ||\n json.type === \"ELLIPSE_ARC\" ||\n json.type === \"CUBIC_BEZIER\"\n ) {\n return importSegment(json);\n }\n throw new Error(\"Unknown shape type\");\n}\n","import type { Vector } from \"./definitions.js\";\nexport { Vector };\n\nexport const DEG2RAD = Math.PI / 180;\nexport const RAD2DEG = 180 / Math.PI;\n\nexport function polarToCartesian(r: number, theta: number): Vector {\n const x = Math.cos(theta * DEG2RAD) * r;\n const y = Math.sin(theta * DEG2RAD) * r;\n return [x, y];\n}\n\nexport function cartesianToPolar([x, y]: Vector): [number, number] {\n const r = Math.sqrt(x * x + y * y);\n const theta = Math.atan2(y, x) * RAD2DEG;\n return [r, theta];\n}\n\nexport type {\n Diagram,\n Figure,\n Loop,\n Strand,\n Stroke,\n TransformationMatrix,\n BoundingBox,\n Segment,\n Line,\n Arc,\n EllipseArc,\n CubicBezier,\n} from \"./models/exports.js\";\n\nexport { draw } from \"./draw.js\";\nexport {\n // Surface booleans\n fuseAll,\n fuse,\n cut,\n intersect,\n // Strand booleans\n eraseStrand,\n confineStrand,\n // Offset\n offset,\n outlineStroke,\n} from \"./operations.js\";\n\nexport { exportSVG, svgBody } from \"./export/svg/exportSVG.js\";\n\nexport { exportJSON } from \"./export/json/exportJSON.js\";\nexport { importJSON } from \"./import/json/importJSON.js\";\n"],"names":["listOfFigures","shape","Figure","Loop","Diagram","strandLoopSections","loop","strand","precision","allIntersections","allCommonSegments","splitPoints","strandSegment","strandIndex","loopSegment","intersections","overlaps","findIntersectionsAndOverlaps","commonSegmentsPoints","s","removeDuplicatePoints","strandSegments","zip","segment","strandsBetweenIntersections","eraseStrandWithinLoop","eraseOnBorder","strandCenter","eraseStrandOutsideLoop","eraseStrandWithinFigure","figure","outsideStrands","inLoopStrand","hole","eraseStrandOutsideFigure","insideStrands","fuse","first","second","fuseFiguresLists","fuseAll","shapes","acc","cut","cutFiguresLists","intersect","intersectFiguresLists","eraseStrand","diagram","outStrands","Strand","confineStrand","segmentPosition","intersectionParam","handleBetween","lineBetween","otherLine","otherPosition","lineLineDistance","line1","line2","intersectionParams","lineLineParams","intersectionParam1","intersectionParam2","firstPosition","secondPosition","distance","lineArcDistance","line","arc","lineArcIntersection","closestPointOnLine","projectPointOnLine","circleCenterLineDistance","centerLineDirection","normalize","subtract","closestPointOnCircle","add","scalarMultiply","overlappingAngles","arc1","arc2","p1","p2","arcArcDistance","arcArcIntersection","centersDistance","centerCenterDirection","containedCircles","arc1ClosestPointAngle","polarAngle","arc2ClosestPointAngle","binarySearch","array","value","comparator","low","high","mid","cmp","binaryInsert","index","DiagonalBuckets","__publicField","interval","bucket","a","b","intervals","i","lastInterval","secondToLastInterval","slope","DivisionRectangle","x","y","DiRectOptimisation","fcn","endTolerance","maxIterations","epsilon","center","rect","Interval","leftCenter","rightCenter","i1","i2","k","potentialFMin","left","middle","right","rectangle","findGlobalMinimum","fun","tolerance","genericDistance","segment1","segment2","result","t","squareDistance","Line","Arc","PRECISION","rawOffsets","segmentsToOffset","offset","offsetSegments","c","offsetSegment","offsettedArray","savedLastSegment","previousSegment","appendSegment","DegenerateSegment","sameVector","iterateOffsetSegments","previousLastPoint","firstPoint","pointIntersections","intersection","originalEndpoint","distances","splitPreviousSegment","splitSegment","clockwise","crossProduct","joiner","findOffsetSelfIntersections","segments","updateIntersections","newPoints","firstSegment","firstIndex","secondSegment","secondIndex","rawIntersections","onFirstSegmentExtremity","onSecondSegmentExtremity","splitSegmentsAtIntersections","segmentIntersections","pruneDegenerateSegments","originalStroke","offsetLoop","correctedOffset","offsettedLoop","splitSegments","prunedSegments","newLoops","stitchSegments","l","outlineStrand","width","endCap","frontOffsettedArray","backOffsettedArray","makeJoiner","fromSegment","toSegment","tangentArc","offsetFigures","figures","offsetDistance","innerShape","outlineStrokeFigures","absOffset","outlineStroke","outlineDistance","svgBody","svgDiagram","svgFigure","svgLoop","svgStrand","isSegment","svgSegmentToPath","extractShape","addConfig","body","color","flibBbox","bbox","BoundingBox","exportSVG","margin","unit","viewBox","flipped","wrapSVG","importSegment","json","EllipseArc","QuadraticBezier","CubicBezier","importLoop","importFigure","contour","holes","importDiagram","importJSON","DEG2RAD","RAD2DEG","polarToCartesian","r","theta","cartesianToPolar"],"mappings":"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"}
1
+ {"version":3,"file":"pantograph.cjs","sources":["../src/utils/listOfFigures.ts","../src/algorithms/boolean/strandBoolean.ts","../src/booleanOperations.ts","../src/algorithms/distances/lineLineDistance.ts","../src/algorithms/distances/lineArcDistance.ts","../src/algorithms/distances/arcArcDistance.ts","../src/algorithms/optimisation/DiRect.ts","../src/algorithms/distances/genericDistance.ts","../src/algorithms/distances/index.ts","../src/algorithms/conversions/bezierToSafeBezier.ts","../src/algorithms/conversions/ellipseToBezier.ts","../src/algorithms/offsets/offsetStroke.ts","../src/algorithms/offsets/offsetFigure.ts","../src/offsetOperations.ts","../src/export/svg/exportSVG.ts","../src/import/json/importJSON.ts","../src/main.ts"],"sourcesContent":["import { Diagram } from \"../models/Diagram.js\";\nimport { Figure } from \"../models/Figure.js\";\nimport { Loop } from \"../models/Loop.js\";\n\nexport function listOfFigures(shape: Diagram | Figure | Loop): Figure[] {\n if (shape instanceof Figure) {\n return [shape];\n } else if (shape instanceof Loop) {\n return [new Figure(shape)];\n } else if (shape instanceof Diagram) {\n return shape.figures;\n }\n throw new Error(\"Unknown shape\");\n}\n","import { Vector } from \"../../definitions\";\nimport { Segment } from \"../../models/segments/Segment\";\nimport { Loop } from \"../../models/Loop\";\nimport { Strand } from \"../../models/Strand\";\nimport { findIntersectionsAndOverlaps } from \"../intersections\";\nimport removeDuplicatePoints from \"../../utils/removeDuplicatePoints\";\nimport zip from \"../../utils/zip\";\nimport { strandsBetweenIntersections } from \"./strandsBetweenIntersections\";\nimport type { Figure } from \"../../models/Figure\";\nimport type { Stroke } from \"../../models/Stroke\";\n\nfunction strandLoopSections(\n loop: Loop,\n strand: Stroke,\n precision = 1e-9,\n): Strand[] {\n let allIntersections: Vector[] = [];\n const allCommonSegments: Segment[] = [];\n\n const splitPoints: Vector[][] = new Array(strand.segments.length)\n .fill(0)\n .map(() => []);\n\n strand.segments.forEach((strandSegment, strandIndex) => {\n loop.segments.forEach((loopSegment) => {\n const { intersections, overlaps } = findIntersectionsAndOverlaps(\n strandSegment,\n loopSegment,\n precision,\n );\n\n allIntersections.push(...intersections);\n splitPoints[strandIndex].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 splitPoints[strandIndex].push(...commonSegmentsPoints);\n });\n });\n\n allIntersections = removeDuplicatePoints(allIntersections, precision);\n\n const strandSegments = zip([strand.segments, splitPoints] as [\n Segment[],\n Vector[][],\n ]).flatMap(([segment, intersections]: [Segment, Vector[]]): Segment[] => {\n if (!intersections.length) return [segment];\n return segment.splitAt(intersections);\n });\n\n return Array.from(\n strandsBetweenIntersections(\n strandSegments,\n allIntersections,\n allCommonSegments,\n ),\n );\n}\n\nexport function eraseStrandWithinLoop(\n strand: Stroke,\n loop: Loop,\n eraseOnBorder = false,\n) {\n const strands = strandLoopSections(loop, strand);\n\n // We keep only the strands that are outside the loop\n return strands.filter((strand) => {\n const strandCenter = strand.segments[0].midPoint;\n if (loop.onStroke(strandCenter)) return !eraseOnBorder;\n\n return !loop.contains(strandCenter);\n });\n}\n\nexport function eraseStrandOutsideLoop(\n strand: Stroke,\n loop: Loop,\n eraseOnBorder = false,\n) {\n const strands = strandLoopSections(loop, strand);\n\n // We keep only the strands that are outside the loop\n return strands.filter((strand) => {\n const strandCenter = strand.segments[0].midPoint;\n if (loop.onStroke(strandCenter)) return !eraseOnBorder;\n\n return loop.contains(strandCenter);\n });\n}\n\nexport function eraseStrandWithinFigure(\n strand: Stroke,\n figure: Figure,\n eraseOnBorder = false,\n) {\n const outsideStrands = eraseStrandWithinLoop(\n strand,\n figure.contour,\n eraseOnBorder,\n );\n\n const inLoopStrand = figure.holes.flatMap((hole: Loop) =>\n eraseStrandOutsideLoop(strand, hole, eraseOnBorder),\n );\n\n return [...outsideStrands, ...inLoopStrand];\n}\n\nexport function eraseStrandOutsideFigure(\n strand: Stroke,\n figure: Figure,\n eraseOnBorder = false,\n) {\n let insideStrands = eraseStrandOutsideLoop(\n strand,\n figure.contour,\n eraseOnBorder,\n );\n\n figure.holes.forEach((hole: Loop) => {\n insideStrands = insideStrands.flatMap((strand) =>\n eraseStrandWithinLoop(strand, hole, eraseOnBorder),\n );\n });\n\n return insideStrands;\n}\n","import {\n cutFiguresLists,\n fuseFiguresLists,\n intersectFiguresLists,\n} from \"./algorithms/boolean/figureBooleans\";\nimport { Strand } from \"./models/Strand\";\nimport { Diagram } from \"./models/Diagram\";\nimport { Figure } from \"./models/Figure\";\nimport { Loop } from \"./models/Loop\";\nimport { listOfFigures } from \"./utils/listOfFigures\";\nimport {\n eraseStrandOutsideFigure,\n eraseStrandOutsideLoop,\n eraseStrandWithinFigure,\n eraseStrandWithinLoop,\n} from \"./algorithms/boolean/strandBoolean\";\nimport { Stroke } from \"./main\";\n\nexport function fuse(\n first: Diagram | Figure | Loop,\n second: Diagram | Figure | Loop,\n): Diagram {\n return new Diagram(\n fuseFiguresLists(listOfFigures(first), listOfFigures(second)),\n );\n}\n\nexport function fuseAll(shapes: (Diagram | Figure | Loop)[]): Diagram {\n return shapes.reduce(\n (acc: Diagram, shape: Diagram | Figure | Loop) => fuse(acc, shape),\n new Diagram(),\n );\n}\n\nexport function cut(\n first: Diagram | Figure | Loop,\n second: Diagram | Figure | Loop,\n): Diagram {\n return new Diagram(\n cutFiguresLists(listOfFigures(first), listOfFigures(second)),\n );\n}\n\nexport function intersect(\n first: Diagram | Figure | Loop,\n second: Diagram | Figure | Loop,\n): Diagram {\n return new Diagram(\n intersectFiguresLists(listOfFigures(first), listOfFigures(second)),\n );\n}\n\nexport function eraseStrand(\n strand: Stroke,\n diagram: Diagram | Figure | Loop,\n eraseOnBorder = true,\n): Strand[] {\n if (diagram instanceof Loop) {\n return eraseStrandWithinLoop(strand, diagram, eraseOnBorder);\n }\n\n if (diagram instanceof Figure) {\n return eraseStrandWithinFigure(strand, diagram, eraseOnBorder);\n }\n\n let outStrands: Strand[] = [new Strand([...strand.segments])];\n diagram.figures.forEach((figure: Figure) => {\n outStrands = outStrands.flatMap((strand: Strand) => {\n return eraseStrandWithinFigure(strand, figure, eraseOnBorder);\n });\n });\n\n return outStrands;\n}\n\nexport function confineStrand(\n strand: Stroke,\n diagram: Diagram | Figure | Loop,\n eraseOnBorder = false,\n): Strand[] {\n if (diagram instanceof Loop) {\n return eraseStrandOutsideLoop(strand, diagram, eraseOnBorder);\n }\n\n if (diagram instanceof Figure) {\n return eraseStrandOutsideFigure(strand, diagram, eraseOnBorder);\n }\n\n let outStrands: Strand[] = [new Strand([...strand.segments])];\n diagram.figures.forEach((figure: Figure) => {\n outStrands = outStrands.flatMap((strand: Strand) => {\n return eraseStrandOutsideFigure(strand, figure, eraseOnBorder);\n });\n });\n\n return outStrands;\n}\n","import { lineLineParams } from \"../intersections/lineLineIntersection.js\";\nimport type { Line } from \"../../models/segments/Line.js\";\nimport { distance } from \"../../vectorOperations.js\";\n\nfunction segmentPosition(intersectionParam: number) {\n if (intersectionParam < 0) return \"before\";\n if (intersectionParam > 1) return \"after\";\n return \"between\";\n}\n\nconst handleBetween = (\n lineBetween: Line,\n otherLine: Line,\n otherPosition: \"before\" | \"after\",\n) => {\n if (otherPosition === \"before\")\n return lineBetween.distanceFrom(otherLine.firstPoint);\n else if (otherPosition === \"after\")\n return lineBetween.distanceFrom(otherLine.lastPoint);\n else throw new Error(\"Invalid position\");\n};\n\nexport function lineLineDistance(line1: Line, line2: Line): number {\n const intersectionParams = lineLineParams(line1, line2);\n\n if (intersectionParams === \"parallel\") {\n return Math.min(\n line1.distanceFrom(line2.firstPoint),\n line1.distanceFrom(line2.lastPoint),\n );\n }\n\n const { intersectionParam1, intersectionParam2 } = intersectionParams;\n\n const firstPosition = segmentPosition(intersectionParam1);\n const secondPosition = segmentPosition(intersectionParam2);\n\n if (firstPosition === \"between\" && secondPosition === \"between\") {\n return 0;\n } else if (firstPosition === \"between\" && secondPosition !== \"between\") {\n return handleBetween(line1, line2, secondPosition);\n } else if (secondPosition === \"between\" && firstPosition !== \"between\") {\n return handleBetween(line2, line1, firstPosition);\n } else if (firstPosition === \"before\" && secondPosition === \"before\") {\n return distance(line1.firstPoint, line2.firstPoint);\n } else if (firstPosition === \"after\" && secondPosition === \"after\") {\n return distance(line1.lastPoint, line2.lastPoint);\n } else if (firstPosition === \"before\" && secondPosition === \"after\") {\n return distance(line1.firstPoint, line2.lastPoint);\n } else if (firstPosition === \"after\" && secondPosition === \"before\") {\n return distance(line1.lastPoint, line2.firstPoint);\n } else {\n throw new Error(\"Invalid position\");\n }\n}\n","import type { Line } from \"../../models/segments/Line.js\";\nimport type { Arc } from \"../../models/segments/Arc.js\";\nimport {\n normalize,\n subtract,\n distance,\n add,\n scalarMultiply,\n} from \"../../vectorOperations\";\nimport { projectPointOnLine } from \"../../utils/projectPointOnLine.js\";\nimport { lineArcIntersection } from \"../intersections/lineArcIntersection.js\";\n\nexport function lineArcDistance(line: Line, arc: Arc): number {\n // We might be able to optimise this if necessary\n\n if (lineArcIntersection(line, arc).length > 0) {\n return 0;\n }\n\n const closestPointOnLine = projectPointOnLine(line, arc.center);\n\n if (line.isOnSegment(closestPointOnLine)) {\n const circleCenterLineDistance = distance(closestPointOnLine, arc.center);\n\n // The line is tangent to the circle\n if (Math.abs(circleCenterLineDistance - arc.radius) < line.precision) {\n if (arc.isOnSegment(closestPointOnLine)) {\n return 0;\n }\n }\n\n if (circleCenterLineDistance - arc.radius > line.precision) {\n const centerLineDirection = normalize(\n subtract(closestPointOnLine, arc.center),\n );\n\n const closestPointOnCircle = add(\n arc.center,\n scalarMultiply(centerLineDirection, arc.radius),\n );\n\n if (arc.isOnSegment(closestPointOnCircle)) {\n return distance(closestPointOnCircle, closestPointOnLine);\n }\n }\n }\n\n return Math.min(\n arc.distanceFrom(line.firstPoint),\n arc.distanceFrom(line.lastPoint),\n line.distanceFrom(arc.firstPoint),\n line.distanceFrom(arc.lastPoint),\n );\n}\n","import {\n distance,\n normalize,\n polarAngle,\n subtract,\n} from \"../../vectorOperations\";\nimport type { Arc } from \"../../models/segments/Arc.js\";\nimport { arcArcIntersection } from \"../intersections/arcArcIntersection.js\";\n\nconst overlappingAngles = (arc1: Arc, arc2: Arc): boolean => {\n const p1 = arc1.angleToParam(arc2.firstAngle);\n if (arc1.isValidParameter(p1)) return true;\n\n const p2 = arc1.angleToParam(arc2.lastAngle);\n if (arc1.isValidParameter(p2)) return true;\n return false;\n};\n\nexport function arcArcDistance(arc1: Arc, arc2: Arc): number {\n if (arcArcIntersection(arc1, arc2, true).length > 0) return 0;\n\n const centersDistance = distance(arc1.center, arc2.center);\n\n if (centersDistance < arc1.precision) {\n if (overlappingAngles(arc1, arc2)) {\n return Math.abs(arc1.radius - arc2.radius);\n }\n }\n\n const centerCenterDirection = normalize(subtract(arc2.center, arc1.center));\n\n const containedCircles =\n centersDistance - Math.abs(arc1.radius - arc2.radius) < arc1.precision;\n\n let arc1ClosestPointAngle = polarAngle(centerCenterDirection);\n if (containedCircles && arc2.radius > arc1.radius) {\n arc1ClosestPointAngle += Math.PI;\n }\n const arc2ClosestPointAngle = containedCircles\n ? arc1ClosestPointAngle\n : arc1ClosestPointAngle + Math.PI;\n\n const p1 = arc1.angleToParam(arc1ClosestPointAngle);\n const p2 = arc2.angleToParam(arc2ClosestPointAngle);\n\n if (arc1.isValidParameter(p1) && arc2.isValidParameter(p2)) {\n // There might be some optimization here (with the center distance and radius differences)\n return distance(arc1.paramPoint(p1), arc2.paramPoint(p2));\n }\n\n return Math.min(\n arc1.distanceFrom(arc2.firstPoint),\n arc1.distanceFrom(arc2.lastPoint),\n arc2.distanceFrom(arc1.firstPoint),\n arc2.distanceFrom(arc1.lastPoint),\n );\n}\n","// An implementation of the direct algorithm for computing the global minimum of\n// a funciton defined between 0 and 1. The algorithm is described in:\n// Jones, D.R., Perttunen, C.D. and Stuckman, B.E., 1993. Lipschitzian\n// optimization without the Lipschitz constant. Journal of Optimization Theory\n// and Applications, 79(1), pp.157-181.\n//\n// Also inspired by the implementation in the Direct package for rust\n// https://gitlab.com/blei42/direct\n\nfunction binarySearch<T>(\n array: T[],\n value: T,\n comparator: (a: T, b: T) => number,\n): number {\n let low = 0;\n let high = array.length - 1;\n while (low <= high) {\n const mid = Math.floor((low + high) / 2);\n const cmp = comparator(array[mid], value);\n if (cmp < 0) {\n low = mid + 1;\n } else if (cmp > 0) {\n high = mid - 1;\n } else {\n return mid;\n }\n }\n return -(low + 1);\n}\n\nfunction binaryInsert<T>(\n array: T[],\n value: T,\n comparator: (a: T, b: T) => number,\n) {\n const index = binarySearch(array, value, comparator);\n if (index < 0) {\n array.splice(-(index + 1), 0, value);\n } else {\n array.splice(index, 0, value);\n }\n}\n\nclass DiagonalBuckets {\n public readonly buckets: Interval[][];\n constructor() {\n this.buckets = [];\n }\n\n addInterval(interval: Interval) {\n const bucket = this.buckets[interval.rectangle.diagonalBucketIndex];\n if (bucket === undefined) {\n this.buckets[interval.rectangle.diagonalBucketIndex] = [interval];\n } else {\n binaryInsert(bucket, interval, (a, b) => a.value - b.value);\n }\n }\n\n removeInterval(interval: Interval) {\n const bucket = this.buckets[interval.rectangle.diagonalBucketIndex];\n if (bucket === undefined) {\n throw new Error(\"Interval not found\");\n }\n bucket.shift();\n }\n\n getBottomRightHullIntervals(): Interval[] {\n const intervals: Interval[] = [];\n for (let i = this.buckets.length - 1; i >= 0; i--) {\n const bucket = this.buckets[i];\n\n if (!bucket === undefined) continue;\n const interval = bucket[0];\n if (interval === undefined) continue;\n\n if (!intervals.length) {\n intervals.push(interval);\n continue;\n }\n\n // We want to keep only the right bottom hull of the intervals\n\n // First, we remove intervals with a bigger value\n while (\n intervals.length &&\n intervals[intervals.length - 1].value >= interval.value\n ) {\n intervals.pop();\n }\n\n // Then, we remove intervals that are covered by the previous interval\n // and the last updated\n while (intervals.length >= 2) {\n const lastInterval = intervals[intervals.length - 1];\n const secondToLastInterval = intervals[intervals.length - 2];\n\n const slope =\n (interval.value - secondToLastInterval.value) /\n ((interval.rectangle.diagonal -\n secondToLastInterval.rectangle.diagonal) *\n 2);\n const comparison =\n secondToLastInterval.value +\n ((lastInterval.rectangle.diagonal -\n secondToLastInterval.rectangle.diagonal) /\n 2.0) *\n slope;\n\n if (comparison < lastInterval.value) {\n intervals.pop();\n } else {\n break;\n }\n }\n\n intervals.push(interval);\n }\n\n return intervals;\n }\n}\n\nclass DivisionRectangle {\n public diagonal: number;\n public diagonalBucketIndex: number;\n\n public xLength: number;\n public yLength: number;\n\n public index: string;\n\n constructor(\n public x: number,\n public y: number,\n ) {\n this.xLength = Math.pow(3, -x);\n this.yLength = Math.pow(3, -y);\n\n this.diagonal = Math.sqrt(\n this.xLength * this.xLength + this.yLength * this.yLength,\n );\n this.diagonalBucketIndex = x + y;\n\n this.index = `${x},${y}`;\n }\n}\n\nexport class DiRectOptimisation {\n private rectangles: Map<string, DivisionRectangle>;\n private buckets: DiagonalBuckets;\n\n public fMin;\n public argMin;\n public tol;\n\n constructor(\n public fcn: ([x, y]: [number, number]) => number,\n public endTolerance = 1e-8,\n public maxIterations = 1000,\n public epsilon = 1e-6,\n ) {\n this.fcn = fcn;\n this.epsilon = epsilon;\n this.endTolerance = endTolerance;\n this.maxIterations = maxIterations;\n\n this.rectangles = new Map();\n this.buckets = new DiagonalBuckets();\n\n const center: [number, number] = [0.5, 0.5];\n const rect = this.rect(0, 0);\n const value = this.fcn(center);\n\n this.buckets.addInterval(new Interval(center, value, rect));\n this.fMin = value;\n this.argMin = center;\n this.tol = rect.diagonal;\n }\n\n registerInterval(interval: Interval) {\n this.buckets.addInterval(interval);\n if (interval.value <= this.fMin) {\n this.fMin = interval.value;\n this.argMin = interval.center;\n this.tol = interval.rectangle.diagonal;\n }\n }\n\n rect(x: number, y: number): DivisionRectangle {\n const index = `${x},${y}`;\n if (!this.rectangles.has(index)) {\n this.rectangles.set(index, new DivisionRectangle(x, y));\n }\n return this.rectangles.get(index)!;\n }\n\n splitInterval(interval: Interval): [Interval, Interval, Interval] {\n let rect: DivisionRectangle;\n let leftCenter: [number, number], rightCenter: [number, number];\n\n const [x, y] = interval.center;\n\n if (interval.rectangle.x <= interval.rectangle.y) {\n rect = this.rect(interval.rectangle.x + 1, interval.rectangle.y);\n leftCenter = [x - rect.xLength, y];\n rightCenter = [x + rect.xLength, y];\n } else {\n rect = this.rect(interval.rectangle.x, interval.rectangle.y + 1);\n leftCenter = [x, y - rect.yLength];\n rightCenter = [x, y + rect.yLength];\n }\n\n return [\n new Interval(leftCenter, this.fcn(leftCenter), rect),\n new Interval(interval.center, interval.value, rect),\n new Interval(rightCenter, this.fcn(rightCenter), rect),\n ];\n }\n\n single_iteration() {\n const intervals = this.buckets.getBottomRightHullIntervals();\n\n // We want to only keep the intervals that can significantly improve the\n // minimum\n\n while (intervals.length >= 2) {\n // Look at the left-most point, it's most heavily constrained by both slope and\n // possible distance.\n const i1 = intervals[0];\n const i2 = intervals[1];\n\n const k =\n (i2.value - i1.value) /\n ((i2.rectangle.diagonal - i1.rectangle.diagonal) / 2.0);\n const potentialFMin = i1.value - (k * i2.value) / 2.0;\n if ((this.fMin - potentialFMin) / Math.abs(this.fMin) < this.epsilon) {\n intervals.shift();\n } else {\n // The points to the right are even better than this one, bail out.\n break;\n }\n }\n\n intervals.forEach((interval) => {\n this.buckets.removeInterval(interval);\n });\n\n for (const interval of intervals) {\n const [left, middle, right] = this.splitInterval(interval);\n\n this.registerInterval(left);\n this.registerInterval(middle);\n this.registerInterval(right);\n }\n }\n\n run() {\n let i = 0;\n while (this.tol > this.endTolerance / 2) {\n this.single_iteration();\n i++;\n if (i > this.maxIterations) {\n break;\n }\n }\n return {\n fMin: this.fMin,\n argMin: this.argMin,\n tol: this.tol,\n iterations: i,\n };\n }\n}\n\nclass Interval {\n constructor(\n public center: [number, number],\n public value: number,\n public rectangle: DivisionRectangle,\n ) {}\n}\n\nexport function findGlobalMinimum(\n fun: (x: [number, number]) => number,\n tolerance = 1e-8,\n maxIterations = 1000,\n epsilon = 1e-6,\n) {\n const optimiser = new DiRectOptimisation(\n fun,\n tolerance,\n maxIterations,\n epsilon,\n );\n return optimiser.run();\n}\n","import { Vector } from \"../../definitions.js\";\nimport { squareDistance } from \"../../vectorOperations.js\";\nimport { findGlobalMinimum } from \"../optimisation/DiRect.js\";\n\ninterface WithParamPoint {\n paramPoint(t: number): Vector;\n}\n\nexport function genericDistance(\n segment1: WithParamPoint,\n segment2: WithParamPoint,\n precision = 1e-9,\n): number {\n const result = findGlobalMinimum((t) => {\n const p1 = segment1.paramPoint(t[0]);\n const p2 = segment2.paramPoint(t[1]);\n return squareDistance(p1, p2);\n }, precision);\n return Math.sqrt(result.fMin);\n}\n","import { Line } from \"../../models/segments/Line.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { lineLineDistance } from \"./lineLineDistance.js\";\nimport { lineArcDistance } from \"./lineArcDistance.js\";\nimport { arcArcDistance } from \"./arcArcDistance.js\";\nimport type { Segment } from \"../../models/segments/Segment.js\";\nimport { genericDistance } from \"./genericDistance.js\";\n\nexport function distance(segment1: Segment, segment2: Segment): number {\n if (segment1 instanceof Line && segment2 instanceof Line) {\n return lineLineDistance(segment1, segment2);\n }\n\n if (segment1 instanceof Line && segment2 instanceof Arc) {\n return lineArcDistance(segment1, segment2);\n }\n\n if (segment1 instanceof Arc && segment2 instanceof Line) {\n return lineArcDistance(segment2, segment1);\n }\n\n if (segment1 instanceof Arc && segment2 instanceof Arc) {\n return arcArcDistance(segment1, segment2);\n }\n\n return genericDistance(segment1, segment2);\n}\n","import { CubicBezier } from \"../../models/segments/CubicBezier\";\nimport { QuadraticBezier } from \"../../models/segments/QuadraticBezier\";\nimport {\n angle,\n dotProduct,\n perpendicular,\n subtract,\n} from \"../../vectorOperations\";\n\n// This is based on https://github.com/Pomax/bezierjs\n\ntype Bezier = CubicBezier | QuadraticBezier;\n\nexport type SafeCubicBezier = CubicBezier & { readonly __safe: unique symbol };\nexport type SafeQuadraticBezier = QuadraticBezier & {\n readonly __safe: unique symbol;\n};\n\ntype SafeBezier = SafeCubicBezier | SafeQuadraticBezier;\n\nexport type SafeVersion<T> = T extends CubicBezier\n ? SafeCubicBezier\n : T extends QuadraticBezier\n ? SafeQuadraticBezier\n : never;\n\nfunction isOffsetSafeBezier(segment: Bezier): segment is SafeBezier {\n if (segment instanceof CubicBezier) {\n // We check that both control points are on the same side of the chord\n const chord = subtract(segment.lastPoint, segment.firstPoint);\n const v2 = subtract(segment.firstControlPoint, segment.firstPoint);\n const v3 = subtract(segment.lastControlPoint, segment.firstPoint);\n\n const a1 = angle(chord, v2);\n const a2 = angle(chord, v3);\n\n if ((a1 > 0 && a2 < 0) || (a1 < 0 && a2 > 0)) return false;\n }\n\n const n1 = perpendicular(segment.tangentAtFirstPoint);\n const n2 = perpendicular(segment.tangentAtLastPoint);\n\n let s = dotProduct(n1, n2);\n return Math.abs(Math.acos(s)) < Math.PI / 3;\n}\n\nfunction _splitIntoOffsetSafeBezier(\n segment: Bezier,\n): SafeVersion<typeof segment>[] {\n if (isOffsetSafeBezier(segment)) return [segment];\n\n const [left, right] = segment.splitAtParameters([0.5]);\n return [\n ..._splitIntoOffsetSafeBezier(left),\n ..._splitIntoOffsetSafeBezier(right),\n ];\n}\n\nexport function splitIntoOffsetSafeBezier(\n segment: Bezier,\n): SafeVersion<typeof segment>[] {\n if (isOffsetSafeBezier(segment)) return [segment];\n\n const segments = segment.splitAtParameters(segment.getParametersOfExtrema());\n return segments.flatMap(_splitIntoOffsetSafeBezier);\n}\n","import { CubicBezier } from \"../../models/segments/CubicBezier\";\nimport { TransformationMatrix } from \"../../models/TransformationMatrix\";\nimport type { EllipseArc } from \"../../models/segments/EllipseArc\";\n\nexport function approximateEllipticalArcAsCubicBeziers(\n ellipseArc: EllipseArc,\n): CubicBezier[] {\n const sweepAngle = ellipseArc.deltaAngle;\n const segments = Math.ceil(Math.abs(sweepAngle) / (Math.PI / 2));\n const anglePerSegment = sweepAngle / segments;\n const kappa = (4 * Math.tan(anglePerSegment / 4)) / 3;\n\n const orientation = ellipseArc.clockwise ? -1 : 1;\n\n const angles = Array.from(\n { length: segments + 1 },\n (_, i) => ellipseArc.firstAngle + i * anglePerSegment * orientation,\n );\n\n const zippedAngles = angles\n .slice(0, -1)\n .map((angle, index) => [angle, angles[index + 1]]);\n\n return zippedAngles.map(([startAngle, endAngle]) => {\n const cosStart = Math.cos(startAngle);\n const sinStart = Math.sin(startAngle);\n const cosEnd = Math.cos(endAngle);\n const sinEnd = Math.sin(endAngle);\n\n const [centerX, centerY] = ellipseArc.center;\n const r = ellipseArc.minorRadius;\n const R = ellipseArc.majorRadius;\n\n const rotationMatrix = new TransformationMatrix().rotate(\n ellipseArc.tiltAngle,\n ellipseArc.center,\n );\n const rotateInFrame = (p: [number, number]) => rotationMatrix.transform(p);\n\n const p0 = rotateInFrame([centerX + R * cosStart, centerY + r * sinStart]);\n const c0 = rotateInFrame([\n centerX + R * (cosStart - kappa * sinStart * orientation),\n centerY + r * (sinStart + kappa * cosStart * orientation),\n ]);\n const c1 = rotateInFrame([\n centerX + R * (cosEnd + kappa * sinEnd * orientation),\n centerY + r * (sinEnd - kappa * cosEnd * orientation),\n ]);\n const p1 = rotateInFrame([centerX + R * cosEnd, centerY + r * sinEnd]);\n\n return new CubicBezier(p0, p1, c0, c1);\n });\n}\n","import { Line } from \"../../models/segments/Line.js\";\nimport { Loop } from \"../../models/Loop.js\";\nimport { Segment } from \"../../models/segments/Segment.js\";\nimport {\n crossProduct,\n sameVector,\n squareDistance,\n subtract,\n} from \"../../vectorOperations\";\nimport { distance } from \"../distances\";\nimport {\n offsetSegment,\n DegenerateSegment,\n OffsettableSegment,\n} from \"./offsetSegment.js\";\nimport { Vector } from \"../../definitions.js\";\nimport { Arc, tangentArc } from \"../../models/segments/Arc.js\";\nimport { Diagram } from \"../../models/Diagram.js\";\nimport { findIntersectionsAndOverlaps } from \"../intersections\";\nimport { Figure } from \"../../models/Figure.js\";\nimport { stitchSegments } from \"../stitchSegments.js\";\nimport { Stroke } from \"../../models/Stroke.js\";\nimport { Strand } from \"../../models/Strand.js\";\nimport { splitIntoOffsetSafeBezier } from \"../conversions/bezierToSafeBezier.js\";\nimport {\n CubicBezier,\n EllipseArc,\n QuadraticBezier,\n} from \"../../models/exports.js\";\nimport { approximateEllipticalArcAsCubicBeziers } from \"../conversions/ellipseToBezier.js\";\n\n\nconst PRECISION = 1e-8;\n\nexport const transformForOffset = (\n segments: Segment[],\n): OffsettableSegment[] => {\n return segments.flatMap((segment: Segment): OffsettableSegment[] => {\n if (segment instanceof Line) {\n return [segment];\n } else if (segment instanceof Arc) {\n return [segment];\n } else if (segment instanceof EllipseArc) {\n return approximateEllipticalArcAsCubicBeziers(segment).flatMap((c) =>\n splitIntoOffsetSafeBezier(c),\n );\n } else if (\n segment instanceof QuadraticBezier ||\n segment instanceof CubicBezier\n ) {\n return splitIntoOffsetSafeBezier(segment);\n } else {\n return [new Line(segment.firstPoint, segment.lastPoint)];\n }\n });\n};\n\nexport function rawOffsets(\n segmentsToOffset: OffsettableSegment[],\n offset: number,\n loop = true,\n): Segment[] {\n const offsetSegments: OffsetSegmentPair[] = segmentsToOffset.map((c) => ({\n offset: offsetSegment(c, offset),\n original: c,\n }));\n\n // Ideally we would use the length of the segment to make sure it is\n // not only a point, but the algo we have access to are a bit to\n // convoluted to be usable here\n\n const offsettedArray: Segment[] = [];\n\n let savedLastSegment = loop ? null : offsetSegments.at(-1)!;\n\n let previousSegment = loop ? offsetSegments.at(-1) : null;\n\n // We have no offseted segments\n if (offsettedArray.length === 1) return offsettedArray;\n\n const appendSegment = (segment: OffsetSegmentPair) => {\n if (!savedLastSegment) {\n savedLastSegment = segment;\n } else if (!(segment.offset instanceof DegenerateSegment)) {\n offsettedArray.push(segment.offset);\n } else if (\n !sameVector(segment.offset.firstPoint, segment.offset.lastPoint)\n ) {\n offsettedArray.push(\n new Line(segment.offset.firstPoint, segment.offset.lastPoint),\n );\n }\n };\n const iterateOffsetSegments = function* (): Generator<OffsetSegmentPair> {\n for (const segment of offsetSegments.slice(0, -1)) {\n yield segment;\n }\n // This should never happen\n if (!savedLastSegment) throw new Error(\"Bug in the offset algorithm\");\n yield savedLastSegment;\n };\n\n for (const segment of iterateOffsetSegments()) {\n if (!previousSegment) {\n previousSegment = segment;\n continue;\n }\n const previousLastPoint = previousSegment.offset.lastPoint;\n const firstPoint = segment.offset.firstPoint;\n\n // When the offset segments do still touch we do nothing\n if (sameVector(previousLastPoint, firstPoint)) {\n appendSegment(previousSegment);\n previousSegment = segment;\n continue;\n }\n\n let intersections: Vector[] = [];\n\n if (\n !(previousSegment.offset instanceof DegenerateSegment) &&\n !(segment.offset instanceof DegenerateSegment)\n ) {\n // When the offset segments intersect we cut them and save them at\n const { intersections: pointIntersections, overlaps } =\n findIntersectionsAndOverlaps(\n previousSegment.offset,\n segment.offset,\n PRECISION / 100,\n );\n intersections = [\n ...pointIntersections,\n ...overlaps.flatMap((c) => [c.firstPoint, c.lastPoint]),\n ];\n }\n\n if (intersections.length > 0) {\n let intersection = intersections[0];\n if (intersections.length > 1) {\n // We choose the intersection point the closest to the end of the\n // original segment endpoint (why? not sure, following\n // https://github.com/jbuckmccready/cavalier_contours/)\n\n const originalEndpoint = previousSegment?.original.lastPoint;\n const distances = intersections.map((i) =>\n squareDistance(i, originalEndpoint),\n );\n intersection = intersections[distances.indexOf(Math.min(...distances))];\n }\n\n // We need to be a lot more careful here with multiple intersections\n // as well as cases where segments overlap\n\n const splitPreviousSegment = (previousSegment.offset as Segment).splitAt([\n intersection,\n ])[0];\n const splitSegment = (segment.offset as Segment)\n .splitAt([intersection])\n .at(-1);\n\n if (!splitSegment) throw new Error(\"Bug in the splitting algo in offset\");\n\n appendSegment({\n offset: splitPreviousSegment,\n original: previousSegment.original,\n });\n previousSegment = { offset: splitSegment, original: segment.original };\n continue;\n }\n\n // When the offset segments do not intersect we link them with an arc of\n // radius offset\n const center = previousSegment.original.lastPoint;\n const clockwise =\n crossProduct(\n subtract(firstPoint, center),\n subtract(previousLastPoint, center),\n ) > 0;\n\n const joiner = new Arc(previousLastPoint, firstPoint, center, clockwise);\n //const joiner = new Line(previousLastPoint, firstPoint);\n\n appendSegment(previousSegment);\n offsettedArray.push(joiner);\n previousSegment = segment;\n }\n\n if (previousSegment) appendSegment(previousSegment);\n return offsettedArray;\n}\n\ninterface OffsetSegmentPair {\n offset: Segment | DegenerateSegment;\n original: Segment;\n}\n\nfunction findOffsetSelfIntersections(\n segments: Segment[],\n): Map<number, Vector[]> {\n // We remove the self intersections with the use the the algorithm as described in\n // https://github.com/jbuckmccready/CavalierContours#offset-algorithm-and-stepwise-example\n\n const allIntersections: Map<number, Vector[]> = new Map();\n const updateIntersections = (index: number, newPoints: Vector[]) => {\n const intersections = allIntersections.get(index) || [];\n allIntersections.set(index, [...intersections, ...newPoints]);\n };\n\n segments.forEach((firstSegment, firstIndex) => {\n segments.slice(firstIndex + 1).forEach((secondSegment, secondIndex) => {\n const { intersections: rawIntersections, overlaps } =\n findIntersectionsAndOverlaps(firstSegment, secondSegment, PRECISION);\n\n const intersections = [\n ...rawIntersections,\n ...overlaps.flatMap((c) => [c.firstPoint, c.lastPoint]),\n ].filter((intersection) => {\n const onFirstSegmentExtremity =\n sameVector(intersection, firstSegment.firstPoint) ||\n sameVector(intersection, firstSegment.lastPoint);\n\n const onSecondSegmentExtremity =\n sameVector(intersection, secondSegment.firstPoint) ||\n sameVector(intersection, secondSegment.lastPoint);\n\n return !(onFirstSegmentExtremity && onSecondSegmentExtremity);\n });\n\n if (!intersections.length) return;\n\n updateIntersections(firstIndex, intersections);\n updateIntersections(secondIndex + firstIndex + 1, intersections);\n });\n });\n\n return allIntersections;\n}\n\nfunction findIntersections(\n segments: Segment[],\n intersectWith: Segment[],\n): Map<number, Vector[]> {\n const allIntersections: Map<number, Vector[]> = new Map();\n const updateIntersections = (index: number, newPoints: Vector[]) => {\n const intersections = allIntersections.get(index) || [];\n allIntersections.set(index, [...intersections, ...newPoints]);\n };\n\n segments.forEach((firstSegment, firstIndex) => {\n intersectWith.forEach((segmentsToCheck) => {\n const { intersections: rawIntersections, overlaps } =\n findIntersectionsAndOverlaps(firstSegment, segmentsToCheck, PRECISION);\n\n const intersections = [\n ...rawIntersections,\n ...overlaps.flatMap((c) => [c.firstPoint, c.lastPoint]),\n ].filter((intersection) => {\n return (\n sameVector(intersection, firstSegment.firstPoint) ||\n sameVector(intersection, firstSegment.lastPoint)\n );\n });\n\n if (!intersections.length) return;\n\n updateIntersections(firstIndex, intersections);\n });\n });\n\n return allIntersections;\n}\n\nfunction findEndIntersections(\n segments: Segment[],\n strand: Strand,\n offset: number,\n) {\n const circle = new Loop([\n new Arc([-offset, 0], [offset, 0], [0, 0], true),\n new Arc([offset, 0], [-offset, 0], [0, 0], true),\n ]);\n\n const startCircle = circle.translateTo(strand.firstPoint);\n const endCircle = circle.translateTo(strand.lastPoint);\n\n return findIntersections(segments, [\n ...startCircle.segments,\n ...endCircle.segments,\n ]);\n}\n\nfunction mergeIntersectionMaps(maps: Map<number, Vector[]>[]) {\n const mergedMap = new Map<number, Vector[]>(maps[0]);\n maps.forEach((map) => {\n for (const [key, value] of map) {\n const previousValue = mergedMap.get(key) || [];\n mergedMap.set(key, [...previousValue, ...value]);\n }\n });\n return mergedMap;\n}\n\nfunction splitSegmentsAtIntersections(\n intersections: Map<number, Vector[]>,\n segments: Segment[],\n): Segment[] {\n return segments.flatMap((segment, index) => {\n if (!intersections.has(index)) return segment;\n\n const segmentIntersections = intersections.get(index);\n if (!segmentIntersections) return segment;\n\n return segment.splitAt(segmentIntersections);\n });\n}\n\nfunction pruneDegenerateSegments(\n segments: Segment[],\n originalStroke: Stroke,\n offset: number,\n): Segment[] {\n // We remove all the segments that are closer to the original segment than the offset\n return segments.filter((segment) => {\n const closeSegment = originalStroke.segments.some((c) => {\n return distance(c, segment) < Math.abs(offset) - PRECISION;\n });\n return !closeSegment;\n });\n}\n\nexport function offsetLoop(loop: Loop, offset: number): Diagram {\n const correctedOffset = loop.clockwise ? offset : -offset;\n const transformedSegments = transformForOffset(loop.segments);\n const offsettedArray = rawOffsets(transformedSegments, correctedOffset);\n\n if (offsettedArray.length < 2) return new Diagram();\n\n // We remove the self intersections with the use the the algorithm as described in\n // https://github.com/jbuckmccready/CavalierContours#offset-algorithm-and-stepwise-example\n\n const allIntersections = findOffsetSelfIntersections(offsettedArray);\n\n if (!allIntersections.size) {\n const offsettedLoop = new Loop(offsettedArray);\n return new Diagram([new Figure(offsettedLoop)]);\n /* this was in the replicad algorithm - not sure why\n if (!loop.intersects(offsettedLoop)) return offsettedLoop;\n return new Diagram();\n */\n }\n const splitSegments = splitSegmentsAtIntersections(\n allIntersections,\n offsettedArray,\n );\n\n // We remove all the segments that are closer to the original segment than the offset\n const prunedSegments = pruneDegenerateSegments(splitSegments, loop, offset);\n\n if (!prunedSegments.length) return new Diagram();\n\n const segmentsGrouped = stitchSegments(prunedSegments);\n\n const newLoops = segmentsGrouped\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 if (!newLoops.length) return new Diagram();\n return new Diagram(newLoops.map((l) => new Figure(l)));\n}\n\nexport function offsetStrand(strand: Strand, offset: number): Stroke[] {\n const transformedSegments = transformForOffset(strand.segments);\n const offsettedArray = rawOffsets(transformedSegments, offset, false);\n const backOffsettedArray = rawOffsets(transformedSegments, -offset, false);\n\n // We remove the self intersections with the use the the algorithm as described in\n // https://github.com/jbuckmccready/CavalierContours#offset-algorithm-and-stepwise-example\n\n const allIntersections = mergeIntersectionMaps([\n findOffsetSelfIntersections(offsettedArray),\n findIntersections(offsettedArray, backOffsettedArray),\n findEndIntersections(offsettedArray, strand, offset),\n ]);\n\n if (!allIntersections.size) {\n return [new Strand(offsettedArray)];\n }\n const splitSegments = splitSegmentsAtIntersections(\n allIntersections,\n offsettedArray,\n );\n\n // We remove all the segments that are closer to the original segment than the offset\n const prunedSegments = pruneDegenerateSegments(splitSegments, strand, offset);\n\n if (!prunedSegments.length) return [];\n\n const segmentsGrouped = stitchSegments(prunedSegments);\n\n return segmentsGrouped.map((c) => {\n if (sameVector(c[0].firstPoint, c.at(-1)!.lastPoint)) return new Loop(c);\n return new Strand(c);\n });\n}\n\nexport function outlineStrand(\n strand: Strand,\n width: number,\n endCap: \"round\" | \"butt\" = \"round\",\n): Diagram {\n const offset = width / 2;\n const transformedSegments = transformForOffset(strand.segments);\n const frontOffsettedArray = rawOffsets(transformedSegments, offset, false);\n const backOffsettedArray = rawOffsets(\n transformedSegments,\n -offset,\n false,\n ).map((s) => s.reverse());\n backOffsettedArray.reverse();\n\n const makeJoiner = (fromSegment: Segment, toSegment: Segment) => {\n if (endCap === \"round\") {\n return tangentArc(\n fromSegment.lastPoint,\n toSegment.firstPoint,\n fromSegment.tangentAtLastPoint,\n );\n }\n return new Line(fromSegment.lastPoint, toSegment.firstPoint);\n };\n\n const offsettedArray = [\n ...frontOffsettedArray,\n makeJoiner(\n frontOffsettedArray[frontOffsettedArray.length - 1],\n backOffsettedArray[0],\n ),\n ...backOffsettedArray,\n makeJoiner(\n backOffsettedArray[backOffsettedArray.length - 1],\n frontOffsettedArray[0],\n ),\n ];\n\n const allIntersections = findOffsetSelfIntersections(offsettedArray);\n\n if (!allIntersections.size) {\n const offsettedLoop = new Loop(offsettedArray);\n return new Diagram([new Figure(offsettedLoop)]);\n }\n const splitSegments = splitSegmentsAtIntersections(\n allIntersections,\n offsettedArray,\n );\n\n // We remove all the segments that are closer to the original segment than the offset\n const prunedSegments = pruneDegenerateSegments(splitSegments, strand, offset);\n\n if (!prunedSegments.length) return new Diagram();\n\n const segmentsGrouped = stitchSegments(prunedSegments);\n\n const newLoops = segmentsGrouped\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 if (!newLoops.length) return new Diagram();\n return new Diagram(newLoops.map((l) => new Figure(l)));\n}\n","import { Figure } from \"../../models/Figure\";\nimport { Diagram } from \"../../models/Diagram\";\nimport { cut, fuseAll } from \"../../booleanOperations\";\nimport { offsetLoop } from \"./offsetStroke\";\n\nexport function offsetFigures(\n figures: Figure[],\n offsetDistance: number,\n): Diagram {\n const offsetFigures = figures.map((figure) => {\n const innerShape = fuseAll(\n figure.holes.map((l) => offsetLoop(l, offsetDistance)),\n );\n return cut(offsetLoop(figure.contour, offsetDistance), innerShape);\n });\n\n return fuseAll(offsetFigures);\n}\n\nexport function outlineStrokeFigures(\n figures: Figure[],\n width: number,\n): Diagram {\n const absOffset = Math.abs(width / 2);\n\n const offsetFigures = figures.map((figure) =>\n fuseAll(\n figure.allLoops.map((l) => {\n return cut(offsetLoop(l, absOffset), offsetLoop(l, -absOffset));\n }),\n ),\n );\n\n return fuseAll(offsetFigures);\n}\n","import {\n offsetFigures,\n outlineStrokeFigures,\n} from \"./algorithms/offsets/offsetFigure\";\nimport { outlineStrand } from \"./algorithms/offsets/offsetStroke.js\";\nimport { Strand } from \"./models/Strand.js\";\nimport { Diagram } from \"./models/Diagram.js\";\nimport { Figure } from \"./models/Figure.js\";\nimport { Loop } from \"./models/Loop.js\";\nimport { listOfFigures } from \"./utils/listOfFigures.js\";\n\nexport function offset(\n shape: Diagram | Figure | Loop,\n offsetDistance: number,\n): Diagram {\n return offsetFigures(listOfFigures(shape), offsetDistance);\n}\n\nexport function outlineStroke(\n shape: Diagram | Figure | Loop | Strand,\n outlineDistance: number,\n { endCap = \"round\" }: { endCap?: \"butt\" | \"round\" } = {},\n): Diagram {\n if (shape instanceof Strand) {\n return outlineStrand(shape, outlineDistance, endCap);\n }\n return outlineStrokeFigures(listOfFigures(shape), outlineDistance);\n}\n","import { Strand } from \"../../models/Strand.js\";\nimport { Diagram } from \"../../models/Diagram.js\";\nimport { Figure } from \"../../models/Figure.js\";\nimport { Loop } from \"../../models/Loop.js\";\nimport { BoundingBox } from \"../../models/BoundingBox.js\";\nimport { svgDiagram } from \"./svgDiagram.js\";\nimport { svgFigure } from \"./svgFigure.js\";\nimport { svgLoop } from \"./svgLoop.js\";\nimport { svgSegmentToPath } from \"./svgSegment.js\";\nimport { svgStrand } from \"./svgStrand.js\";\nimport { SVGUnit, wrapSVG } from \"./wrapSVG.js\";\nimport type { Stroke } from \"../../models/Stroke.js\";\nimport { Segment } from \"../../main.js\";\nimport { isSegment } from \"../../models/segments/utils/isSegment.js\";\n\ntype Shape = Figure | Diagram | Stroke | Segment;\n\nexport function svgBody(shape: Shape) {\n if (shape instanceof Diagram) {\n return svgDiagram(shape);\n } else if (shape instanceof Figure) {\n return svgFigure(shape);\n } else if (shape instanceof Loop) {\n return `<path d=\"${svgLoop(shape)}\" />`;\n } else if (shape instanceof Strand) {\n return `<path d=\"${svgStrand(shape)}\" />`;\n } else if (isSegment(shape)) {\n return `<path d=\"${`M ${shape.firstPoint.join(\" \")}`} ${svgSegmentToPath(\n shape,\n )}\" />`;\n } else {\n throw new Error(\"Unknown shape type\");\n }\n}\n\ntype ConfiguredShape = Shape | { shape: Shape; color?: string };\n\nconst extractShape = (shape: ConfiguredShape) =>\n \"shape\" in shape ? shape.shape : shape;\n\nconst addConfig = (shape: ConfiguredShape, body: string) => {\n if (!(\"shape\" in shape)) return body;\n const { color } = shape;\n if (!color) return body;\n return `<g stroke=\"${color}\">${body}</g>`;\n};\n\nconst flibBbox = (bbox: BoundingBox) => {\n return new BoundingBox(bbox.xMin, -bbox.yMax, bbox.xMax, -bbox.yMin);\n};\n\nexport function exportSVG(\n shape: ConfiguredShape | ConfiguredShape[],\n {\n margin = 1,\n unit = null,\n viewBox,\n }: {\n margin?: number;\n unit?: null | SVGUnit;\n viewBox?: BoundingBox;\n } = {},\n) {\n if (Array.isArray(shape)) {\n const flipped = shape.map((s) => extractShape(s).mirror());\n const body = flipped\n .map((s, i) => addConfig(shape[i], svgBody(s)))\n .join(\"\\n\");\n const bbox = flipped\n .slice(1)\n .reduce((bbox, s) => bbox.merge(s.boundingBox), flipped[0].boundingBox);\n\n return wrapSVG(body, viewBox ? flibBbox(viewBox) : bbox, margin, unit);\n }\n const flipped = extractShape(shape).mirror();\n return wrapSVG(\n addConfig(shape, svgBody(flipped)),\n viewBox ? flibBbox(viewBox) : flipped.boundingBox,\n margin,\n unit,\n );\n}\n","import { Line } from \"../../models/segments/Line.js\";\nimport { Arc } from \"../../models/segments/Arc.js\";\nimport { Loop } from \"../../models/Loop.js\";\nimport { Figure } from \"../../models/Figure.js\";\nimport { Diagram } from \"../../models/Diagram.js\";\nimport { EllipseArc } from \"../../models/segments/EllipseArc.js\";\nimport { CubicBezier } from \"../../models/segments/CubicBezier.js\";\nimport { QuadraticBezier } from \"../../models/segments/QuadraticBezier.js\";\n\nconst importSegment = (json: any) => {\n if (json.type === \"LINE\") {\n return new Line(json.firstPoint, json.lastPoint);\n }\n if (json.type === \"ARC\") {\n return new Arc(\n json.firstPoint,\n json.lastPoint,\n json.center,\n json.clockwise,\n );\n }\n if (json.type === \"ELLIPSE_ARC\") {\n return new EllipseArc(\n json.firstPoint,\n json.lastPoint,\n json.center,\n json.majorRadius,\n json.minorRadius,\n json.tiltAngle,\n json.clockwise,\n { angleUnits: \"rad\" },\n );\n }\n if (json.type === \"QUADRATIC_BEZIER\") {\n return new QuadraticBezier(\n json.firstPoint,\n json.lastPoint,\n json.controlPoint,\n );\n }\n if (json.type === \"CUBIC_BEZIER\") {\n return new CubicBezier(\n json.firstPoint,\n json.lastPoint,\n json.firstControlPoint,\n json.lastControlPoint,\n );\n }\n throw new Error(\"Unknown segment type\");\n};\n\nconst importLoop = (json: any) => {\n const segments = json.segments.map(importSegment);\n return new Loop(segments);\n};\n\nconst importFigure = (json: any) => {\n const contour = importLoop(json.contour);\n const holes = json.holes.map(importLoop);\n return new Figure(contour, holes);\n};\n\nconst importDiagram = (json: any) => {\n const figures = json.figures.map(importFigure);\n return new Diagram(figures);\n};\n\nexport function importJSON(json: any) {\n if (json.type === \"DIAGRAM\") {\n return importDiagram(json);\n }\n if (json.type === \"FIGURE\") {\n return importFigure(json);\n }\n if (json.type === \"LOOP\") {\n return importLoop(json);\n }\n if (\n json.type === \"LINE\" ||\n json.type === \"ARC\" ||\n json.type === \"ELLIPSE_ARC\" ||\n json.type === \"CUBIC_BEZIER\"\n ) {\n return importSegment(json);\n }\n throw new Error(\"Unknown shape type\");\n}\n","import type { Vector } from \"./definitions.js\";\nexport { Vector };\n\nexport const DEG2RAD = Math.PI / 180;\nexport const RAD2DEG = 180 / Math.PI;\n\nexport function polarToCartesian(r: number, theta: number): Vector {\n const x = Math.cos(theta * DEG2RAD) * r;\n const y = Math.sin(theta * DEG2RAD) * r;\n return [x, y];\n}\n\nexport function cartesianToPolar([x, y]: Vector): [number, number] {\n const r = Math.sqrt(x * x + y * y);\n const theta = Math.atan2(y, x) * RAD2DEG;\n return [r, theta];\n}\n\nexport type {\n Diagram,\n Figure,\n Loop,\n Strand,\n Stroke,\n TransformationMatrix,\n BoundingBox,\n Segment,\n Line,\n Arc,\n EllipseArc,\n CubicBezier,\n} from \"./models/exports.js\";\n\nexport { draw } from \"./draw.js\";\nexport {\n // Surface booleans\n fuseAll,\n fuse,\n cut,\n intersect,\n // Strand booleans\n eraseStrand,\n confineStrand,\n // Offset\n offset,\n outlineStroke,\n} from \"./operations.js\";\n\nexport { exportSVG, svgBody } from \"./export/svg/exportSVG.js\";\n\nexport { exportJSON } from \"./export/json/exportJSON.js\";\nexport { importJSON } from \"./import/json/importJSON.js\";\n"],"names":["listOfFigures","shape","Figure","Loop","Diagram","strandLoopSections","loop","strand","precision","allIntersections","allCommonSegments","splitPoints","strandSegment","strandIndex","loopSegment","intersections","overlaps","findIntersectionsAndOverlaps","commonSegmentsPoints","s","removeDuplicatePoints","strandSegments","zip","segment","strandsBetweenIntersections","eraseStrandWithinLoop","eraseOnBorder","strandCenter","eraseStrandOutsideLoop","eraseStrandWithinFigure","figure","outsideStrands","inLoopStrand","hole","eraseStrandOutsideFigure","insideStrands","fuse","first","second","fuseFiguresLists","fuseAll","shapes","acc","cut","cutFiguresLists","intersect","intersectFiguresLists","eraseStrand","diagram","outStrands","Strand","confineStrand","segmentPosition","intersectionParam","handleBetween","lineBetween","otherLine","otherPosition","lineLineDistance","line1","line2","intersectionParams","lineLineParams","intersectionParam1","intersectionParam2","firstPosition","secondPosition","distance","lineArcDistance","line","arc","lineArcIntersection","closestPointOnLine","projectPointOnLine","circleCenterLineDistance","centerLineDirection","normalize","subtract","closestPointOnCircle","add","scalarMultiply","overlappingAngles","arc1","arc2","p1","p2","arcArcDistance","arcArcIntersection","centersDistance","centerCenterDirection","containedCircles","arc1ClosestPointAngle","polarAngle","arc2ClosestPointAngle","binarySearch","array","value","comparator","low","high","mid","cmp","binaryInsert","index","DiagonalBuckets","__publicField","interval","bucket","a","b","intervals","i","lastInterval","secondToLastInterval","slope","DivisionRectangle","x","y","DiRectOptimisation","fcn","endTolerance","maxIterations","epsilon","center","rect","Interval","leftCenter","rightCenter","i1","i2","k","potentialFMin","left","middle","right","rectangle","findGlobalMinimum","fun","tolerance","genericDistance","segment1","segment2","result","t","squareDistance","Line","Arc","isOffsetSafeBezier","CubicBezier","chord","v2","v3","a1","angle","a2","n1","perpendicular","n2","dotProduct","_splitIntoOffsetSafeBezier","splitIntoOffsetSafeBezier","approximateEllipticalArcAsCubicBeziers","ellipseArc","sweepAngle","segments","anglePerSegment","kappa","orientation","angles","_","startAngle","endAngle","cosStart","sinStart","cosEnd","sinEnd","centerX","centerY","r","R","rotationMatrix","TransformationMatrix","rotateInFrame","p","p0","c0","c1","PRECISION","transformForOffset","EllipseArc","c","QuadraticBezier","rawOffsets","segmentsToOffset","offset","offsetSegments","offsetSegment","offsettedArray","savedLastSegment","previousSegment","appendSegment","DegenerateSegment","sameVector","iterateOffsetSegments","previousLastPoint","firstPoint","pointIntersections","intersection","originalEndpoint","distances","splitPreviousSegment","splitSegment","clockwise","crossProduct","joiner","findOffsetSelfIntersections","updateIntersections","newPoints","firstSegment","firstIndex","secondSegment","secondIndex","rawIntersections","onFirstSegmentExtremity","onSecondSegmentExtremity","splitSegmentsAtIntersections","segmentIntersections","pruneDegenerateSegments","originalStroke","offsetLoop","correctedOffset","transformedSegments","offsettedLoop","splitSegments","prunedSegments","newLoops","stitchSegments","l","outlineStrand","width","endCap","frontOffsettedArray","backOffsettedArray","makeJoiner","fromSegment","toSegment","tangentArc","offsetFigures","figures","offsetDistance","innerShape","outlineStrokeFigures","absOffset","outlineStroke","outlineDistance","svgBody","svgDiagram","svgFigure","svgLoop","svgStrand","isSegment","svgSegmentToPath","extractShape","addConfig","body","color","flibBbox","bbox","BoundingBox","exportSVG","margin","unit","viewBox","flipped","wrapSVG","importSegment","json","importLoop","importFigure","contour","holes","importDiagram","importJSON","DEG2RAD","RAD2DEG","polarToCartesian","theta","cartesianToPolar"],"mappings":"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"}